# Gated deploys

> How AI CodeOps hands a merged change to your deploy pipeline: the quality gate before merge, deploy webhooks, policy rules per environment and deploy records.

Source: https://aicodeops.dev/docs/gated-deploys · Last updated: 2026-10-18

AI CodeOps doesn't deploy code to your infrastructure. It gates the change before it merges, calls your deploy pipeline when it does, and keeps a record of every deployment. Your own pipeline does the build and the release.

## The path to a deploy

1. A session's change passes its tests and AI review, and a person approves it. See [Quality gates](https://aicodeops.dev/docs/quality-gates).
2. AI CodeOps opens the pull request.
3. You merge it from the console. The quality gate runs again first: open high or critical findings, failing tests, or an unfinished review stop the merge.
4. If the change's project has a deploy target, AI CodeOps calls its webhook and records a deployment.

Merging needs a role that can manage deployments: owners, admins, developers, members and DevOps admins. If the gate check can't run, the merge doesn't happen: "The release check couldn't run just now. Try again in a moment."

The gate on merge applies to pull requests AI CodeOps opened for a session. A pull request someone wrote by hand has no session, so the gate has no findings or tests to judge it on.

## Set a deploy target

1. Open **Release → Deployments** and choose **Deploy targets**.
2. For each project, enter the **Deploy webhook URL**. It must be a public `https://` address.
3. Enter the **Environment** it deploys to. The default is `production`.
4. Optionally enter a **Signing secret**.
5. Choose **Save**.

Leave the URL blank to turn automatic deploys off for that project. Setting deploy targets needs a role that can manage projects.

### What your webhook receives

When a change merges from the console, AI CodeOps sends a `POST` with this body:

```json
{
  "event": "pr_merged",
  "workspaceID": "wrk_…",
  "projectID": "billing-api",
  "repo": "acme/billing-api",
  "prNumber": 42,
  "prUrl": "https://github.com/acme/billing-api/pull/42"
}
```

With a signing secret, the request carries `X-CodeOps-Signature: sha256=<hex>`: an HMAC-SHA256 of the raw body, keyed with your secret. Check it before you deploy.

The call times out after 10 seconds and doesn't follow redirects. A `2xx` answer records the deployment as **in progress**. Anything else records it as **failed**, with "The deploy webhook answered HTTP …", and opens an incident. Choose **Retry delivery** on the row to send it again; each retry is a new record.

Your pipeline can't report the final result back to AI CodeOps, so a deploy sent by webhook stays **in progress** in the history. To log a finished deploy with its outcome, record it by hand (below).

## Allow or deny automatic deploys

Automatic deploys follow your workspace policy's `release.deploy` rules, matched on the environment name. For example, this rule stops automatic deploys to production:

```json
{ "id": "no-production-deploys", "action": "release.deploy", "resource": "production", "decision": "deny" }
```

A denied deploy is never sent. It's recorded as **canceled**, and the row shows "not deployed" with the reason. If the policy can't be loaded, the deploy is canceled the same way. These rules can allow or deny only; they can't wait for an approval. A person choosing **Retry delivery** is governed by their role, not by these rules. See [Approvals and policies](https://aicodeops.dev/docs/approvals-and-policies).

## Record a deployment by hand

For deploys that happen outside AI CodeOps:

1. Open **Release → Deployments** and choose **Record deployment**.
2. Pick the **Project** and enter the **Environment**.
3. Set the **Status**: succeeded, in progress, queued or failed.
4. Optionally add a **Version** and a **Commit SHA** (at least 7 characters).
5. Choose **Record deployment**.

## Deployment records

Each record has the project, environment and a sequence number per environment, the commit or version, the status, start and end times, and the session that produced the change. Statuses are queued, in progress, succeeded, failed, rolled back and canceled.

A deployment that succeeds for a session's change marks the change **deployed** under **Develop → Changes**. Records feed the delivery metrics on the dashboard, and the change's [evidence pack](https://aicodeops.dev/docs/evidence-packs).

## Check a release from CI

Your pipeline can ask the release gate before it deploys. Call `POST /api/release/check` with a workspace API key, the pull request URL or commit SHA, and options such as `requireDeployedTo`. With `"requireDeployedTo": "staging"`, the release is denied unless the change already has a succeeded deployment in staging: "Not yet deployed to "staging" — promote there before releasing". Check `allowed` in the response. The fields are on the [API page](https://aicodeops.dev/docs/api).

You can run the same check by hand under **Review & Gate → Release gate**: enter a pull request URL or commit SHA and choose **Evaluate gate**.

## Next steps

- [Rollback](https://aicodeops.dev/docs/rollback)
- [Quality gates](https://aicodeops.dev/docs/quality-gates)
- [Gated deploys and rollback tracking](https://aicodeops.dev/product/deploy)

## Frequently asked questions

### Does AI CodeOps deploy to my servers?

No. It calls a deploy webhook you set per project, and your own pipeline does the deploy. AI CodeOps holds no credentials for your infrastructure.

### Can a policy stop automatic deploys to production?

Yes. A release.deploy rule can deny automatic deploys per environment. A denied deploy is recorded as canceled, with the reason, and nothing is sent.

### Can a deploy wait for a human approval?

Not as a separate step. The approval happens earlier, on the change, before its pull request opens. Deploy rules can only allow or deny.
