Skip to content
GantryCD

Deployment status

GantryCD publishes every deployment’s live state back to the source-control platform, so a developer looking at a commit or pull request sees whether GantryCD deployed it — and can jump straight to the deployment.

On GitHub this surfaces in two places at once:

  • A commit/build status on the deployed commit. Lane deployments use gantrycd/<stack>; pull-request previews use gantrycd/<stack>/preview so a promoted lane deployment cannot overwrite the preview result. It appears on the commit and in the pull request’s checks area, with a link to the deployment.
  • A GitHub Deployment object, created on the fly, with deployment statuses. It appears in the repository’s Environments view and the pull request timeline (“Deployed to <stack>”).

The state tracks the deployment as it moves: queued → in progress → success / failure / cancelled. A deployment waiting on a human shows in progress, and the description says which decision is outstanding: “Awaiting approval” at the apply gate, “Awaiting approval to run the preview plan” for a pull request preview the stack holds.

A deployment that was skipped — superseded by a newer commit, aged out by a timeout, or skipped by hand — leaves the commit’s check exactly as it was. GantryCD publishes no new commit status for it. A lane deployment records the skip on its GitHub Deployment object, which has a real inactive state. Read-only previews intentionally have no Deployment object.

That looks like an omission and is a decision. A deployment publishes a pending check when it is created, so a skip leaves that pending check standing. Where that lands is the whole point:

  • On a pull request whose preview plan never ran, it sits on the live head — so a required check keeps the PR from merging. For a gate that means “this pull request’s plan has not run”, blocking is the right answer, not a defect.
  • On a superseded preview it sits on a commit the pull request has already moved past, and branch protection only reads the head. Lane deployments use a separate context, including promoted deployments that may still reference the live PR head.

The tempting alternatives are both worse, and both were tried: reporting a skip as passing lets an unapproved preview go green the moment it times out, so the gate is defeated by ignoring it. Reporting it as failing permanently red-Xes a superseded preview SHA.

The practical consequence: make gantrycd/<stack>/preview a required check. The pull-request gate only gates anything if you do.

This is SCM-implementation agnostic. GitHub maps to commit statuses + Deployments today; other platforms (GitLab, Bitbucket, …) are an extension point and map the same neutral states to their native mechanism (e.g. GitLab commit statuses + environments).

Configuration

There is nothing to turn on. Publishing is always on: whenever a deployment’s stack repository matches one of your SCM integrations, GantryCD publishes statuses using that integration’s existing credentials. It covers every deployment — manual, push-triggered, and pull-request — because every deployment carries a real commit SHA.

If no SCM integration matches a stack’s repository, nothing is published (and nothing breaks).

Required GitHub App permissions

Grant the GitHub App these repository permissions (in addition to what the App already needs for webhooks and clone credentials):

PermissionAccessUsed for
Commit statusesRead and writeThe per-commit / PR check line
DeploymentsRead and writeThe Deployment object + its statuses

After changing permissions, accept the updated permission request on the installation. A missing permission makes a publish fail permanently (GitHub returns 403); the failure is recorded on the delivery and not retried — fix the permission and the next transition publishes normally.

Delivery guarantees

Publishing is asynchronous and durable. Each deployment has a single coalescing outbox row: rapid transitions collapse into one in-flight publish, and a stale state can never overwrite a newer one. Transient failures (rate limits, 5xx) are retried with backoff; permanent failures (missing permission, deleted repo) are dead-lettered. A reconcile sweep re-publishes any deployment whose status drifted from what was last published, so terminal states are always eventually correct.

The deep link points at the deployment in the GantryCD web UI; it is included only when the backend’s public base URL (GANTRYCD_BACKEND_PUBLIC_BASE_URL) is configured.

For the internals — the outbox schema, the coalescing/ordering guarantees, the state mapping, and operator configuration — see the SCM status reference.