> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ctrlplane.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Deployments

> Define what to deploy and how — services, versions, and execution

A **Deployment** defines **what** you want to deploy and **how** it gets
deployed. It represents a service or application along with its job agent
configuration — connecting the *what* (your service and its versions) with the
*how* (the agent and workflow that executes the deployment).

<Tip>
  In Ctrlplane's mental model: **Deployments** = what & how, [**Environments**](./environments) = where, [**Policies**](../policies/overview) = when.
</Tip>

## What is a Deployment?

A deployment is a logical unit of software that you want to orchestrate:

* **API Service** - Your backend API
* **Frontend Application** - Web or mobile frontend
* **Background Worker** - Async job processor
* **Database Migration** - Schema changes
* **Configuration Update** - Infrastructure configuration

Each deployment can have multiple **versions** (builds, releases) that get deployed to different environments and resources.

## Deployment Properties

| Property           | Type   | Required | Description                                             |
| ------------------ | ------ | -------- | ------------------------------------------------------- |
| `id`               | string | Auto     | Unique identifier                                       |
| `name`             | string | Yes      | Human-readable display name                             |
| `slug`             | string | Yes      | URL-friendly identifier, unique within the workspace    |
| `description`      | string | No       | What this deployment does                               |
| `resourceSelector` | string | No       | CEL expression limiting which resources can be targeted |
| `jobAgents`        | array  | No       | Job agent configurations (see below)                    |
| `metadata`         | object | No       | Key-value pairs for classification                      |

### name

Human-readable display name for the deployment.

**Examples**: "API Service", "Frontend Application", "Payment Processor"

### slug

URL-friendly identifier, unique within the workspace. In the Terraform provider,
the slug is auto-generated from the `name` field.

**Examples**: `api-service`, `frontend-app`, `payment-processor`

### resourceSelector

A CEL expression that limits which resources this deployment can target. If
specified, only resources matching this expression will have release targets
created.

**Examples**:

```
resource.kind == "Kubernetes"
```

```
resource.version == 'ctrlplane.dev/kubernetes/cluster/v1' && resource.metadata['kubernetes/status'] == 'running'
```

```
resource.metadata['region'] == 'us-east-1'
```

If not specified, the deployment can target any resource in its environments.

### jobAgents

An array of job agent configurations that execute deployment jobs. Each entry
specifies which agent to use and how to configure it, with optional routing
via selectors.

| Field      | Type   | Required | Description                                      |
| ---------- | ------ | -------- | ------------------------------------------------ |
| `ref`      | string | Yes      | Job agent reference identifier                   |
| `config`   | object | Yes      | Agent-specific configuration                     |
| `selector` | string | No       | CEL expression for routing to specific resources |

When multiple job agents are configured, the `selector` field determines which
agent handles which resources. This enables patterns like using ArgoCD for
some clusters and GitHub Actions for others within the same deployment.

### metadata

Optional key-value pairs for classification and policy matching:

```json theme={null}
{
  "team": "backend",
  "language": "nodejs",
  "tier": "critical"
}
```

Metadata can be referenced in policy selectors (e.g.,
`deployment.metadata['tier'] == 'critical'`).

## Creating a Deployment

### Via Terraform

<Tabs>
  <Tab title="GitHub Actions Agent">
    ```hcl theme={null}
    resource "ctrlplane_deployment" "api" {
      name              = "API Service"
      resource_selector = "resource.version == 'ctrlplane.dev/kubernetes/cluster/v1' && resource.metadata['kubernetes/status'] == 'running'"

      metadata = {
        team    = "backend"
        service = "api"
      }

      job_agent {
        id = ctrlplane_job_agent.github.id

        github {
          owner       = "my-org"
          repo        = "api-service"
          workflow_id = 12345678
        }
      }
    }

    resource "ctrlplane_deployment_system_link" "api" {
      deployment_id = ctrlplane_deployment.api.id
      system_id     = ctrlplane_system.main.id
    }
    ```
  </Tab>

  <Tab title="ArgoCD Agent">
    ```hcl theme={null}
    resource "ctrlplane_deployment" "operator" {
      name              = "Weights & Biases Operator"
      resource_selector = "resource.version == 'ctrlplane.dev/kubernetes/cluster/v1' && resource.metadata['kubernetes/status'] == 'running'"
      metadata          = {}

      job_agent {
        id = ctrlplane_job_agent.argocd.id

        argocd {
          template = file("${path.module}/templates/application.yaml")
        }
      }
    }

    resource "ctrlplane_deployment_system_link" "operator" {
      deployment_id = ctrlplane_deployment.operator.id
      system_id     = ctrlplane_system.main.id
    }
    ```
  </Tab>
</Tabs>

<Note>
  Deployments must be linked to a system using `ctrlplane_deployment_system_link`.
  This is a separate resource that associates a deployment with a system.
</Note>

### Via REST API

```bash theme={null}
curl -X POST https://api.ctrlplane.com/v1/workspaces/{workspaceId}/deployments \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "API Service",
    "slug": "api-service",
    "description": "Main backend API service",
    "resourceSelector": "resource.kind == '\''Kubernetes'\''",
    "jobAgents": [
      {
        "ref": "github-actions-agent",
        "config": {
          "workflow": "deploy.yml",
          "owner": "my-org",
          "repo": "api-service"
        }
      }
    ],
    "metadata": {
      "team": "backend",
      "language": "nodejs"
    }
  }'
```

The API returns `202 Accepted` with the deployment `id`. Reads are available
immediately via `GET /v1/workspaces/{workspaceId}/deployments/{deploymentId}`.

### Via CLI (YAML)

```yaml theme={null}
# deployment.yaml
type: Deployment
name: API Service
slug: api-service
description: Main backend API service
jobAgent:
  ref: github-actions-agent
jobAgentConfig:
  workflow: deploy.yml
  owner: my-org
  repo: api-service
resourceSelector: resource.kind == "Kubernetes"
```

```bash theme={null}
ctrlc apply -f deployment.yaml
```

### Multiple Deployments

<Tabs>
  <Tab title="Terraform">
    ```hcl theme={null}
    resource "ctrlplane_deployment" "api" {
      name              = "API Service"
      resource_selector = "resource.kind == 'Kubernetes'"
      metadata          = { service = "api" }

      job_agent {
        id = ctrlplane_job_agent.github.id
        github {
          owner       = "my-org"
          repo        = "api-service"
          workflow_id = 12345678
        }
      }
    }

    resource "ctrlplane_deployment" "frontend" {
      name              = "Frontend App"
      resource_selector = "resource.kind == 'Kubernetes'"
      metadata          = { service = "frontend" }

      job_agent {
        id = ctrlplane_job_agent.github.id
        github {
          owner       = "my-org"
          repo        = "frontend-app"
          workflow_id = 87654321
        }
      }
    }

    resource "ctrlplane_deployment_system_link" "api" {
      deployment_id = ctrlplane_deployment.api.id
      system_id     = ctrlplane_system.main.id
    }

    resource "ctrlplane_deployment_system_link" "frontend" {
      deployment_id = ctrlplane_deployment.frontend.id
      system_id     = ctrlplane_system.main.id
    }
    ```
  </Tab>

  <Tab title="CLI">
    ```yaml theme={null}
    # deployments.yaml
    ---
    type: Deployment
    name: API Service
    slug: api-service
    description: Main backend API service
    jobAgent:
      ref: github-actions-agent
    jobAgentConfig:
      workflow: deploy.yml
      owner: my-org
      repo: api-service
    ---
    type: Deployment
    name: Frontend App
    slug: frontend-app
    description: Customer-facing web application
    jobAgent:
      ref: kubernetes-agent
    jobAgentConfig:
      namespace: default
    ```

    ```bash theme={null}
    ctrlc apply -f deployments.yaml
    ```
  </Tab>
</Tabs>

## Job Agent Configuration

Each `job_agent` block (Terraform) or entry in the `jobAgents` array (API)
configures how a specific agent executes deployments. The Terraform provider
supports typed provider blocks for each agent type.

### GitHub Actions

```hcl theme={null}
job_agent {
  id = ctrlplane_job_agent.github.id

  github {
    owner       = "my-org"
    repo        = "api-service"
    workflow_id = 12345678
    ref         = "main"
  }
}
```

| Attribute         | Type   | Description                              |
| ----------------- | ------ | ---------------------------------------- |
| `owner`           | string | GitHub repository owner                  |
| `repo`            | string | GitHub repository name                   |
| `workflow_id`     | int    | GitHub Actions workflow ID               |
| `ref`             | string | Git ref to run on (defaults to `"main"`) |
| `installation_id` | int    | GitHub App installation ID               |

### ArgoCD

```hcl theme={null}
job_agent {
  id = ctrlplane_job_agent.argocd.id

  argocd {
    template   = file("${path.module}/application.yaml")
    server_url = "https://argocd.example.com"
  }
}
```

| Attribute    | Type   | Description                  |
| ------------ | ------ | ---------------------------- |
| `template`   | string | ArgoCD Application template  |
| `server_url` | string | ArgoCD server address        |
| `api_key`    | string | ArgoCD API token (sensitive) |

### Terraform Cloud

```hcl theme={null}
job_agent {
  id = ctrlplane_job_agent.tfc.id

  terraform_cloud {
    organization = "my-org"
    template     = file("${path.module}/workspace.json")
    token        = var.tfc_token
  }
}
```

| Attribute      | Type   | Description                       |
| -------------- | ------ | --------------------------------- |
| `organization` | string | Terraform Cloud organization name |
| `template`     | string | Workspace template                |
| `address`      | string | Terraform Cloud address           |
| `token`        | string | API token (sensitive)             |

### Agent Routing with Selectors

When a deployment uses multiple job agents, use `selector` to route to specific
resources:

```hcl theme={null}
resource "ctrlplane_deployment" "app" {
  name              = "Application"
  resource_selector = "resource.kind == 'Kubernetes'"

  job_agent {
    id       = ctrlplane_job_agent.argocd.id
    selector = "resource.metadata['cluster-type'] == 'managed'"

    argocd {
      template = file("${path.module}/managed-app.yaml")
    }
  }

  job_agent {
    id       = ctrlplane_job_agent.github.id
    selector = "resource.metadata['cluster-type'] == 'self-hosted'"

    github {
      owner       = "my-org"
      repo        = "app-deploy"
      workflow_id = 12345678
    }
  }
}
```

## Deployment Versions

Versions represent specific builds or releases of your deployment. They are
typically created by your CI system after building.

### Version Properties

| Property         | Type   | Required | Description                                      |
| ---------------- | ------ | -------- | ------------------------------------------------ |
| `id`             | string | Auto     | Unique identifier                                |
| `deploymentId`   | string | Auto     | Parent deployment                                |
| `tag`            | string | Yes      | Version tag (e.g., `"v1.2.3"`, git SHA)          |
| `name`           | string | No       | Human-readable name                              |
| `status`         | string | No       | `building`, `ready`, or `failed`                 |
| `config`         | object | No       | General version configuration, visible in UI     |
| `jobAgentConfig` | object | No       | Execution config (overrides deployment's config) |
| `metadata`       | object | No       | Custom key-value pairs                           |
| `createdAt`      | string | Auto     | Creation timestamp                               |

### Creating Versions (from CI)

After your CI builds an artifact, create a version in Ctrlplane:

```yaml theme={null}
# GitHub Actions example
- name: Create Ctrlplane version
  env:
    CTRLPLANE_API_KEY: ${{ secrets.CTRLPLANE_API_KEY }}
  run: |
    ctrlc api upsert version \
      --workspace ${{ vars.CTRLPLANE_WORKSPACE }} \
      --deployment ${{ vars.CTRLPLANE_DEPLOYMENT_ID }} \
      --tag ${{ github.sha }} \
      --name "Build #${{ github.run_number }}" \
      --metadata git/commit=${{ github.sha }} \
      --metadata git/branch=${{ github.ref_name }} \
      --metadata build/number=${{ github.run_number }}
```

Or via the REST API:

```bash theme={null}
curl -X POST https://api.ctrlplane.com/v1/workspaces/{workspaceId}/deployments/{deploymentId}/versions \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tag": "v1.2.3",
    "name": "Release 1.2.3",
    "status": "ready",
    "config": {
      "buildNumber": "456"
    },
    "jobAgentConfig": {
      "imageTag": "my-org/api-service:v1.2.3"
    },
    "metadata": {
      "git_commit": "abc123def",
      "git_branch": "main"
    }
  }'
```

### Version Status

Versions have a status field:

* **`building`** - Version is being built (won't be deployed yet)
* **`ready`** - Version is ready for deployment (default for policies)
* **`failed`** - Build failed (won't be deployed)

**Workflow**:

1. CI starts building → Create version with status `building`
2. Build succeeds → Update status to `ready`
3. Ctrlplane creates releases/jobs for `ready` versions

Or simpler:

1. Build completes → Create version with status `ready` immediately

### Version Config vs Job Agent Config

**config**: General version configuration, visible in UI

```json theme={null}
{
  "buildNumber": "456",
  "gitCommit": "abc123"
}
```

**jobAgentConfig**: Specific configuration for job execution (merged with the
deployment's job agent config at runtime)

```json theme={null}
{
  "imageTag": "my-org/api-service:v1.2.3",
  "helmValues": {
    "replicas": 3
  }
}
```

## Deployment Variables

Variables allow environment-specific or resource-specific configuration that
gets resolved at job creation time and passed to the job agent.

### Via Terraform

The Terraform provider has dedicated resources for deployment variables and
their values:

```hcl theme={null}
resource "ctrlplane_deployment_variable" "replica_count" {
  deployment_id = ctrlplane_deployment.api.id
  key           = "REPLICA_COUNT"
  description   = "Number of replicas to run"
  default_value = "1"
}

resource "ctrlplane_deployment_variable_value" "replica_count_prod" {
  deployment_id     = ctrlplane_deployment.api.id
  variable_id       = ctrlplane_deployment_variable.replica_count.id
  priority          = 0
  resource_selector = "resource.metadata['environment'] == 'production'"
  literal_value     = "5"
}
```

#### Reference Values

Variable values can reference data from the workspace or resource metadata
instead of using literal values:

```hcl theme={null}
resource "ctrlplane_deployment_variable" "size" {
  deployment_id = ctrlplane_deployment.redis.id
  key           = "size"
  description   = "The size of the Redis deployment"
  default_value = "small"
}

resource "ctrlplane_deployment_variable_value" "size_from_workspace" {
  deployment_id     = ctrlplane_deployment.redis.id
  variable_id       = ctrlplane_deployment_variable.size.id
  priority          = 0
  resource_selector = "resource.version == 'ctrlplane.dev/kubernetes/cluster/v1'"

  reference_value = {
    reference = "workspace"
    path      = ["metadata", "size"]
  }
}
```

### Via REST API

**Create a variable:**

```bash theme={null}
curl -X PUT https://api.ctrlplane.com/v1/workspaces/{workspaceId}/deployments/{deploymentId}/variables/{variableId} \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "REPLICA_COUNT",
    "description": "Number of replicas to run"
  }'
```

**Set an environment-specific value:**

```bash theme={null}
curl -X PUT https://api.ctrlplane.com/v1/workspaces/{workspaceId}/deployments/{deploymentId}/variables/{variableId}/values/{valueId} \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "priority": 0,
    "value": "5"
  }'
```

### Using Variables in Jobs

Variables are resolved during job creation and passed to the job agent:

```yaml theme={null}
# In GitHub Actions workflow
- name: Get job inputs
  uses: ctrlplanedev/get-job-inputs@v1
  id: job
  with:
    job_id: ${{ inputs.job_id }}

- name: Deploy with variables
  run: |
    echo "Replicas: ${{ steps.job.outputs.variable_REPLICA_COUNT }}"
    helm upgrade my-app ./chart \
      --set replicaCount=${{ steps.job.outputs.variable_REPLICA_COUNT }}
```

## Release Targets

When you create a deployment, Ctrlplane automatically creates **release targets** by crossing the deployment with environments and resources.

**Formula**: `Deployment × Environment × Resource = Release Targets`

**Example**:

Given:

* Deployment: "API Service"
* Environments: Development, Staging, Production
* Resources in Production: 3 clusters

Release Targets Created:

1. API Service → Development → dev-cluster
2. API Service → Staging → staging-cluster
3. API Service → Production → prod-cluster-1
4. API Service → Production → prod-cluster-2
5. API Service → Production → prod-cluster-3

Each release target can receive deployment versions independently.

### Filtering Release Targets

Use the deployment's `resourceSelector` to limit which targets are created:

```
resource.version == 'ctrlplane.dev/kubernetes/cluster/v1' && resource.metadata['kubernetes/status'] == 'running'
```

Only resources matching this CEL expression will have release targets for this
deployment.

## Deployment Lifecycle

### 1. Create Deployment

Define the deployment in Ctrlplane with job agent configuration.

### 2. CI Builds and Creates Version

Your CI pipeline builds the artifact and creates a deployment version.

### 3. Ctrlplane Evaluates Policies

Ctrlplane checks policies (approvals, environment progression, etc.).

### 4. Jobs Created

For each release target that should receive the version, a job is created.

### 5. Job Agent Executes

The configured job agent picks up the job and executes the deployment.

### 6. Status Updated

The job reports status back to Ctrlplane.

## REST API Reference

### Deployment CRUD

**Create:**

```
POST /v1/workspaces/{workspaceId}/deployments
```

**Get:**

```
GET /v1/workspaces/{workspaceId}/deployments/{deploymentId}
```

**Update:**

```
PUT /v1/workspaces/{workspaceId}/deployments/{deploymentId}
```

**Delete:**

```
DELETE /v1/workspaces/{workspaceId}/deployments/{deploymentId}
```

**List:**

```
GET /v1/workspaces/{workspaceId}/deployments
```

### Versions

**Create version:**

```
POST /v1/workspaces/{workspaceId}/deployments/{deploymentId}/versions
```

**List versions:**

```
GET /v1/workspaces/{workspaceId}/deployments/{deploymentId}/versions
```

**Update version:**

```
PATCH /v1/workspaces/{workspaceId}/deployment-versions/{deploymentVersionId}
```

### Variables

**Upsert variable:**

```
PUT /v1/workspaces/{workspaceId}/deployments/{deploymentId}/variables/{variableId}
```

**Upsert variable value:**

```
PUT /v1/workspaces/{workspaceId}/deployments/{deploymentId}/variables/{variableId}/values/{valueId}
```

## Terraform Provider Reference

| Resource                              | Description                                  |
| ------------------------------------- | -------------------------------------------- |
| `ctrlplane_deployment`                | The deployment itself                        |
| `ctrlplane_deployment_system_link`    | Links a deployment to a system               |
| `ctrlplane_deployment_variable`       | Defines a deployment variable                |
| `ctrlplane_deployment_variable_value` | Sets a value for a variable (with selectors) |

## Viewing Deployment Status

### Via Web UI

1. Navigate to the deployment
2. See tabs:
   * **Versions**: All versions created
   * **Releases**: Active releases across targets
   * **Jobs**: Execution history
   * **Variables**: Configured variables

### Via API

**Get deployment details:**

```bash theme={null}
curl https://api.ctrlplane.com/v1/workspaces/{workspaceId}/deployments/{deploymentId} \
  -H "Authorization: Bearer $TOKEN"
```

**List versions:**

```bash theme={null}
curl https://api.ctrlplane.com/v1/workspaces/{workspaceId}/deployments/{deploymentId}/versions \
  -H "Authorization: Bearer $TOKEN"
```

## Common Patterns

### Microservices

<Tabs>
  <Tab title="Terraform">
    ```hcl theme={null}
    resource "ctrlplane_deployment" "user_service" {
      name              = "User Service"
      resource_selector = "resource.kind == 'Kubernetes'"
      metadata          = { service = "user" }

      job_agent {
        id = ctrlplane_job_agent.argocd.id
        argocd { template = file("${path.module}/user-service.yaml") }
      }
    }

    resource "ctrlplane_deployment" "order_service" {
      name              = "Order Service"
      resource_selector = "resource.kind == 'Kubernetes'"
      metadata          = { service = "order" }

      job_agent {
        id = ctrlplane_job_agent.argocd.id
        argocd { template = file("${path.module}/order-service.yaml") }
      }
    }

    resource "ctrlplane_deployment" "payment_service" {
      name              = "Payment Service"
      resource_selector = "resource.kind == 'Kubernetes'"
      metadata          = { service = "payment" }

      job_agent {
        id = ctrlplane_job_agent.argocd.id
        argocd { template = file("${path.module}/payment-service.yaml") }
      }
    }
    ```
  </Tab>

  <Tab title="CLI">
    ```yaml theme={null}
    # microservices.yaml
    ---
    type: Deployment
    name: User Service
    slug: user-service
    jobAgent:
      ref: argocd-agent
    ---
    type: Deployment
    name: Order Service
    slug: order-service
    jobAgent:
      ref: argocd-agent
    ---
    type: Deployment
    name: Payment Service
    slug: payment-service
    jobAgent:
      ref: argocd-agent
    ```

    ```bash theme={null}
    ctrlc apply -f microservices.yaml
    ```
  </Tab>
</Tabs>

### Database + Application

```hcl theme={null}
resource "ctrlplane_deployment" "database_migration" {
  name              = "Database Migration"
  resource_selector = "resource.kind == 'Kubernetes'"

  job_agent {
    id = ctrlplane_job_agent.github.id
    github {
      owner       = "my-org"
      repo        = "migrations"
      workflow_id = 11111111
    }
  }
}

resource "ctrlplane_deployment" "api_service" {
  name              = "API Service"
  resource_selector = "resource.kind == 'Kubernetes'"

  job_agent {
    id = ctrlplane_job_agent.github.id
    github {
      owner       = "my-org"
      repo        = "api-service"
      workflow_id = 22222222
    }
  }
}
```

Use a [Deployment Dependency](../policies/deployment-dependency) policy to
ensure migrations complete before the API deploys.

### Multi-Platform

```hcl theme={null}
resource "ctrlplane_deployment" "web_service" {
  name              = "Web Service"
  resource_selector = "resource.kind == 'Kubernetes'"

  job_agent {
    id = ctrlplane_job_agent.argocd.id
    argocd { template = file("${path.module}/web.yaml") }
  }
}

resource "ctrlplane_deployment" "lambda_function" {
  name              = "Lambda Function"
  resource_selector = "resource.kind == 'AWSLambda'"

  job_agent {
    id = ctrlplane_job_agent.github.id
    github {
      owner       = "my-org"
      repo        = "lambda-deploy"
      workflow_id = 33333333
    }
  }
}
```

## Best Practices

### Naming

**Good Names**:

* ✅ "API Service"
* ✅ "Frontend Application"
* ✅ "Payment Processor"

**Good Slugs**:

* ✅ `api-service`
* ✅ `frontend-app`
* ✅ `payment-processor`

**Avoid**:

* ❌ "Service" (too generic)
* ❌ "api\_service" (use hyphens)
* ❌ "API-SERVICE" (use lowercase)

### Job Agent Configuration

**Do**:

* ✅ Use version's `jobAgentConfig` for version-specific values (like image tags)
* ✅ Use deployment's job agent config for stable configuration
* ✅ Keep sensitive data in secrets (not in config)
* ✅ Use agent `selector` when routing to different resource types

### Version Tags

**Good Tags**:

* ✅ `v1.2.3` (semantic version)
* ✅ `2024-01-15-prod` (date-based)
* ✅ `abc123def` (git commit)

**Avoid**:

* ❌ `latest` (not specific)
* ❌ `prod` (not a version)
* ❌ `test` (too vague)

### Resource Selectors

Use CEL resource selectors to:

* Limit Kubernetes deployments to Kubernetes resources
* Filter by resource status (e.g., `resource.metadata['status'] == 'running'`)
* Separate platform-specific deployments
* Control which resources can receive a deployment

## Troubleshooting

### No release targets created

* Check `resourceSelector` CEL expression matches some resources
* Verify environments have matching resources
* Ensure deployment is linked to a system (via `ctrlplane_deployment_system_link`
  in Terraform)

### Jobs not being created for new versions

* Check version status is `ready`
* Review policies for denials/pending approvals
* Verify job agent is configured
* Check release target exists

### Job agent config not working

* Verify job agent block matches the agent type (e.g., `github {}` for GitHub
  Actions agents)
* Check version's `jobAgentConfig` overrides correctly
* Review job agent logs for configuration errors

## Next Steps

* [Releases and Jobs](./releases-and-jobs) - Understand version lifecycle
* [Release Targets](./release-targets) - How the deployment matrix works
* [CI/CD Integration](../integrations/cicd) - Integrate with your CI system
* [Job Agents](../integrations/job-agents/github) - Configure deployment executors
* [Policies](../policies/overview) - Control when and how deployments proceed
