AI coding agents open pull requests faster than teams can review them. Branch protection helps, but a green CI run only tells you the build passed. It doesn't tell you whether the change was reviewed, whether serious findings are still open, or whether the tests ran on the version you're about to merge.
This tutorial adds one required check to your pipeline. It asks the AI CodeOps release gate whether a pull request may ship, prints the reasons, and fails the job when the answer is no.
What the gate checks
The release gate looks at every AI CodeOps session that touched the change and applies the same rules as the console:
- The project's tests passed, on the version being merged
- The AI review completed and no blocking findings are open (high or critical by default)
- Approvals are in place
You can make it stricter per pipeline: a coverage floor, required workflows, disallowed licenses from the project's SBOM, or a requirement that the change already deployed to an environment such as staging.
Two details matter for CI:
- A denial is still HTTP 200. You read the
allowedfield, not the status code. - It fails closed. If the evaluation itself fails, you get
allowed: falsewith the summary "Evaluation failed". A change with no matching sessions is also denied.
Step 1: Create an API key
In the console, open Configure → API Keys and create a key. The secret starts with sk- and is shown once. The key acts as the member who created it, so create it from an account whose role can read the workspace.
Store it as a CI secret named AICODEOPS_API_KEY.
Step 2: GitHub Actions
AI CodeOps opens its pull requests on branches named codeops/run-<id>. Scoping the job to those branches means pull requests written by people aren't affected.
{% raw %} name: AI CodeOps release gate on: pull_request: types: [opened, synchronize, reopened, ready_for_review] jobs: release-gate: if: startsWith(github.head_ref, 'codeops/run-') runs-on: ubuntu-latest steps: - name: Ask the release gate env: AICODEOPS_API_KEY: ${{ secrets.AICODEOPS_API_KEY }} PR_URL: ${{ github.event.pull_request.html_url }} run: | body=$(jq -n --arg pr "$PR_URL" '{pullRequestURL: $pr, minCoveragePct: 80}') verdict=$(curl -sSf -X POST "https://console.aicodeops.dev/api/release/check" \ -H "Authorization: Bearer $AICODEOPS_API_KEY" \ -H "Content-Type: application/json" \ -d "$body") echo "$verdict" | jq -r '.summary' echo "$verdict" | jq -r '.reasons[]?' test "$(echo "$verdict" | jq r '.allowed')" = "true" {% endraw %} curl -f makes the job fail on an auth or network error, and the last line fails it on a denial. Either way, nothing gets through by accident.
Then make it required: Settings → Rules → Rulesets (or branch protection) on your main branch, and add release-gate as a required status check. When the job is skipped for a human pull request, GitHub treats the skipped check as passing.
Step 3: GitLab CI
The same idea in .gitlab-ci.yml. The pullRequestURL field takes your merge request URL as it appears on GitLab.
release-gate: stage: test image: alpine:3.20 rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^codeops\/run-/' script: - apk add --no-cache curl jq - MR_URL="$CI_PROJECT_URL/-/merge_requests/$CI_MERGE_REQUEST_IID" - BODY=$(jq -n --arg pr "$MR_URL" '{pullRequestURL: $pr}') - > VERDICT=$(curl -sSf -X POST "https://console.aicodeops.dev/api/release/check" -H "Authorization: Bearer $AICODEOPS_API_KEY" -H "Content-Type: application/json" -d "$BODY") - echo "$VERDICT" | jq -r '.summary, (.reasons[]?)' - test "$(echo "$VERDICT" | jq -r '.allowed')" = "true" Add AICODEOPS_API_KEY under Settings → CI/CD → Variables (masked), and turn on Pipelines must succeed under Settings → Merge requests.
Step 4: Tune it
All of these go in the request body:
| Field | What it does | Default |
|---|---|---|
blockingSeverity | Open findings at or above this block | high |
blockOnTestFailure | Failing tests block | true |
minCoveragePct | Coverage floor for the latest test run | not gated |
requiredWorkflows | Workflows that must have completed | none |
disallowedLicenses | License ids that must not be in the SBOM | none |
requireDeployedTo | An environment the change must already be deployed to | none |
blockOnInFlight | Deny while a session is still running | false |
A stricter release branch might send "blockingSeverity": "medium", "requireDeployedTo": "staging".
Good to know
- The workspace limit is 60 checks a minute. A
429response includesRetry-After. - The API is deliberately small during the open beta: this endpoint, plus public keys for verifying evidence packs.
- The same check is in the console under Review & Gate → Release gate, if you want to see a verdict before wiring up CI.
Full reference: https://aicodeops.dev/docs/api/release-check
Drafted with AI assistance and edited by the AI CodeOps team.

