Guides
Gate deploys in CI
Fail a GitHub Actions job on a held release, make a deploy wait for the verdict, and send findings to GitHub's Security tab.
Every push is already checked through the GitHub App. These steps make your CI act on the verdict. They use the Stableship CLI, which needs Node 22 or newer.
Make a token for CI
In Stableship open Settings, then Connections, open API tokens and connected apps, and choose Create token. Give each job its own token, with only what it needs:
- Waiting for a verdict or reading findings: Read findings and rules.
- Starting a check: also Start checks and verify fixes.
Add it to the GitHub repository as a secret named STABLESHIP_TOKEN.
Hold a deploy until Stableship decides
For hosts that deploy from GitHub Actions or wait for CI (Railway, Fly and others), add a job that waits for Stableship's decision on the commit, and make the deploy depend on it:
jobs: gate: runs-on: ubuntu-latest timeout-minutes: 115 steps: - uses: actions/setup-node@v4 with: { node-version: 22 } - run: npx --yes @stableship/cli@1 wait --sha "$GITHUB_SHA" env: STABLESHIP_TOKEN: ${{ secrets.STABLESHIP_TOKEN }} deploy: needs: gate # your deployOn Railway, you can instead turn on Wait for CI for the service, so Railway deploys only after the workflow's checks pass.
| Stableship says | The job | The deploy |
|---|---|---|
| Passed, warned, skipped, or a person shipped it anyway | Succeeds | Goes out |
| A problem blocks the release | Fails | Waits: fix it, or ship anyway in Stableship and run the job again |
| Stableship could not finish, and the change is low-risk | Succeeds | Goes out |
| Stableship could not finish, and the change touches sign-in, data or payments | Fails | Waits for a person |
| No check started for the commit within 20 minutes | Succeeds, with a warning | Goes out |
While it waits, the Stableship check on the commit shows what is being tested and roughly how long is left.
Fail a job on a held release
To start a check from CI and wait for its verdict:
- name: Stableship run: npx --yes @stableship/cli@1 check --ref "$GITHUB_SHA" --wait --timeout 900 env: STABLESHIP_TOKEN: ${{ secrets.STABLESHIP_TOKEN }}| Exit code | Meaning |
|---|---|
| 0 | Passed, passed with warnings, skipped or shipped anyway. Also 0 when Stableship itself failed: the CLI prints a warning. |
| 1 | Held: a problem blocks the release. |
| 2 | Could not run: a usage error, a missing or rejected token, an API error, or the wait ran past --timeout. |
To fail the step only on a held release, not when it could not run, add || [ $? -eq 2 ] after the command.
The CLI finds your app from the repository's origin. Pass --project <id> (from stableship status) to choose one.
Findings in GitHub's Security tab
- run: npx --yes @stableship/cli@1 findings --sarif > stableship.sarif env: STABLESHIP_TOKEN: ${{ secrets.STABLESHIP_TOKEN }}- uses: github/codeql-action/upload-sarif@v3 with: { sarif_file: stableship.sarif, category: stableship }The job needs permissions: security-events: write.
A pre-push hook
stableship hook install adds a Git pre-push hook: a push to your default branch prints the open blocking problems first. With --strict it refuses the push while something blocks, unless the commit has a Gate: trailer. The hook never stops a push because Stableship could not be reached. stableship hook uninstall removes it.
For your coding agent: this page as Markdown