{"slug": "how-to-gate-ai-written-pull-requests-in-github-actions-and-gitlab-ci", "title": "How to Gate AI-Written Pull Requests in GitHub Actions and GitLab CI", "summary": "A developer documented a CI release-gate pattern that queries the AI CodeOps release-check API to block AI-authored pull requests before merge. The GitHub Actions and GitLab CI jobs trigger only on branches named codeops/run-<id>, post the PR or MR URL to the endpoint, print the summary and reasons, and fail the job unless the response's allowed field is true, with optional gates on coverage floor, required workflows, disallowed SBOM licenses, and prior staging deploys.", "body_md": "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.\n\nThis 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.\n\nThe release gate looks at every AI CodeOps session that touched the change and applies the same rules as the console:\n\nYou 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.\n\nTwo details matter for CI:\n\n`allowed` field, not the status code.`allowed: false` with the summary \"Evaluation failed\". A change with no matching sessions is also denied.\nIn 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.\n\nStore it as a CI secret named `AICODEOPS_API_KEY`.\n\nAI 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.\n\n```\n{% raw %}\nname: AI CodeOps release gate\n\non:\n  pull_request:\n    types: [opened, synchronize, reopened, ready_for_review]\n\njobs:\n  release-gate:\n    if: startsWith(github.head_ref, 'codeops/run-')\n    runs-on: ubuntu-latest\n    steps:\n      - name: Ask the release gate\n        env:\n          AICODEOPS_API_KEY: ${{ secrets.AICODEOPS_API_KEY }}\n          PR_URL: ${{ github.event.pull_request.html_url }}\n        run: |\n          body=$(jq -n --arg pr \"$PR_URL\" '{pullRequestURL: $pr, minCoveragePct: 80}')\n          verdict=$(curl -sSf -X POST \"https://console.aicodeops.dev/api/release/check\" \\\n            -H \"Authorization: Bearer $AICODEOPS_API_KEY\" \\\n            -H \"Content-Type: application/json\" \\\n            -d \"$body\")\n          echo \"$verdict\" | jq -r '.summary'\n          echo \"$verdict\" | jq -r '.reasons[]?'\n          test \"$(echo \"$verdict\" | jq r '.allowed')\" = \"true\"\n{% endraw %}\n```\n\n`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.\n\nThen 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.\n\nThe same idea in `.gitlab-ci.yml`. The `pullRequestURL` field takes your merge request URL as it appears on GitLab.\n\n```\nrelease-gate:\n  stage: test\n  image: alpine:3.20\n  rules:\n    - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\" && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^codeops\\/run-/'\n  script:\n    - apk add --no-cache curl jq\n    - MR_URL=\"$CI_PROJECT_URL/-/merge_requests/$CI_MERGE_REQUEST_IID\"\n    - BODY=$(jq -n --arg pr \"$MR_URL\" '{pullRequestURL: $pr}')\n    - >\n      VERDICT=$(curl -sSf -X POST \"https://console.aicodeops.dev/api/release/check\"\n      -H \"Authorization: Bearer $AICODEOPS_API_KEY\"\n      -H \"Content-Type: application/json\"\n      -d \"$BODY\")\n    - echo \"$VERDICT\" | jq -r '.summary, (.reasons[]?)'\n    - test \"$(echo \"$VERDICT\" | jq -r '.allowed')\" = \"true\"\n```\n\nAdd `AICODEOPS_API_KEY` under **Settings → CI/CD → Variables** (masked), and turn on **Pipelines must succeed** under **Settings → Merge requests**.\n\nAll of these go in the request body:\n\n| Field | What it does | Default | \n|---|---|---|\n| `blockingSeverity` | Open findings at or above this block | `high` | \n| `blockOnTestFailure` | Failing tests block | `true` | \n| `minCoveragePct` | Coverage floor for the latest test run | not gated | \n| `requiredWorkflows` | Workflows that must have completed | none | \n| `disallowedLicenses` | License ids that must not be in the SBOM | none | \n| `requireDeployedTo` | An environment the change must already be deployed to | none | \n| `blockOnInFlight` | Deny while a session is still running | `false` | \n\nA stricter release branch might send `\"blockingSeverity\": \"medium\", \"requireDeployedTo\": \"staging\"`.\n\n`429` response includes `Retry-After`.\nFull reference: [https://aicodeops.dev/docs/api/release-check](https://aicodeops.dev/docs/api/release-check)\n\n*Drafted with AI assistance and edited by the AI CodeOps team.*", "url": "https://wpnews.pro/news/how-to-gate-ai-written-pull-requests-in-github-actions-and-gitlab-ci", "canonical_source": "https://dev.to/aicodeops_dev/how-to-gate-ai-written-pull-requests-in-github-actions-and-gitlab-ci-2gm4", "published_at": "2026-11-02 01:41:39+00:00", "updated_at": "2026-11-02 01:52:17.494290+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools", "mlops"], "entities": ["AI CodeOps", "GitHub Actions", "GitLab CI", "GitHub"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/how-to-gate-ai-written-pull-requests-in-github-actions-and-gitlab-ci", "markdown": "https://wpnews.pro/news/how-to-gate-ai-written-pull-requests-in-github-actions-and-gitlab-ci.md", "text": "https://wpnews.pro/news/how-to-gate-ai-written-pull-requests-in-github-actions-and-gitlab-ci.txt", "jsonld": "https://wpnews.pro/news/how-to-gate-ai-written-pull-requests-in-github-actions-and-gitlab-ci.jsonld"}}