Deployments API
Report deployments from any CI, see every deployment of a repository and its environments in one place, require them before a merge, and hear of them by webhook.
A repository keeps one list of its deployments, wherever they ran. A
deployment is one commit sent to one environment, such as production or
staging. An environment is the place it went: a name, and the address it
is served at. Each deployment has a list of statuses that say how it went,
and its latest status is its state.
Deployments reach that list three ways. Each deployment says which in its
source:
source |
Made by | Ids |
|---|---|---|
api |
Any CI or script, through the routes on this page, with an access token. | dep_… |
actions |
A g1t Actions job with an environment:, by itself. |
dep_… |
g1t_page |
A g1t.page build of a project, to the production or preview environment. |
dpl_… |
A status’s id starts dst_. Every deployment, whatever its source, shows
on the repository’s Deployments page, sets a check on its commit, and
sends webhooks.
Report a deployment from any CI
Section titled “Report a deployment from any CI”You report a deployment by creating it, then adding a status each time it
moves on. The base URL is https://api.g1t.sh, and every request carries
an access token as Authorization: Bearer g1t_….
Make a token
Section titled “Make a token”- Open your Settings → Access tokens, or a workspace’s Settings → Access tokens for a token that belongs to the workspace.
- Give the token a name, such as
release-pipeline. - Select the CI preset. It includes
deployments:readanddeployments:write. To report deployments and nothing else, tick onlydeployments:writeunder Deployments. - Choose an expiry and select Create token. Copy the token now: it is not shown again.
- Store it in your CI as a secret named
G1T_TOKEN.
Reporting also needs the Write role on the repository. See scopes.
Create the deployment
Section titled “Create the deployment”POST /repos/{owner}/{name}/deployments creates a deployment. Give it
state: "in_progress" when the deploy has started:
curl -X POST https://api.g1t.sh/repos/acme/web/deployments \ -H "Authorization: Bearer $G1T_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "ref": "main", "environment": "staging", "description": "Deployed by the release pipeline", "state": "in_progress", "log_url": "https://ci.example.com/pipelines/4182" }'The answer is the deployment, with its first status in statuses. Keep
its id for the next call.
| Field | Default | |
|---|---|---|
ref |
Required | The branch, tag or commit deployed, such as main or v1.4.0. |
sha |
Resolved from ref |
The commit deployed. Give the whole commit id to skip resolving ref. |
environment |
production |
Any name up to 255 characters, such as staging or review/feature-x. Names are matched without regard to case, and the first spelling is kept. |
task |
deploy |
What kind of deployment, such as deploy:migrations. Up to 100 characters. |
description |
None | A short note, up to 1,000 characters. |
payload |
{} |
Anything else to keep with it: a JSON object, or a JSON string of one, up to 64 KB. Returned as given. |
production_environment |
true for production, else false |
Whether people use this environment directly. |
transient_environment |
false |
Whether the environment goes away, such as a review app. |
state |
queued |
Its first status. See statuses. |
environment_url |
None | Where it is served, an http or https address. |
log_url |
None | Where its output can be read, an http or https address. |
Report how it went
Section titled “Report how it went”POST /repos/{owner}/{name}/deployments/{id}/statuses adds a status. When
the deploy succeeds, give the address it is served at:
curl -X POST https://api.g1t.sh/repos/acme/web/deployments/dep_01kq7z9a1c3e5g7j9m1p3r5t7v/statuses \ -H "Authorization: Bearer $G1T_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "state": "success", "environment_url": "https://staging.example.com", "log_url": "https://ci.example.com/pipelines/4182" }'When it fails:
curl -X POST https://api.g1t.sh/repos/acme/web/deployments/dep_01kq7z9a1c3e5g7j9m1p3r5t7v/statuses \ -H "Authorization: Bearer $G1T_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "state": "failure", "description": "Smoke tests failed", "log_url": "https://ci.example.com/pipelines/4182" }'| Field | Default | |
|---|---|---|
state |
Required | queued, in_progress, success, failure, error or inactive. |
description |
None | A short note, up to 1,000 characters. |
environment_url |
None | Where it is served, an http or https address. |
log_url |
None | Where its output can be read, an http or https address. |
auto_inactive |
true |
On a success, give the environment’s older successful deployments an inactive status. See auto_inactive. |
The deployment takes the status’s state, and any address the status gives.
A script for any CI
Section titled “A script for any CI”This script wraps a deploy command. It needs curl, jq, and three
variables: G1T_TOKEN, G1T_REPO (such as acme/web) and GIT_COMMIT
(the commit being deployed). Change ENVIRONMENT, ENVIRONMENT_URL and
the deploy command to yours.
#!/bin/shset -eu
API="https://api.g1t.sh/repos/$G1T_REPO/deployments"ENVIRONMENT="staging"ENVIRONMENT_URL="https://staging.example.com"
report() { curl -fsS -X POST "$1" \ -H "Authorization: Bearer $G1T_TOKEN" \ -H "Content-Type: application/json" \ -d "$2"}
# 1. Create the deployment, in progress.ID=$(report "$API" "$(jq -n \ --arg ref "$GIT_COMMIT" \ --arg environment "$ENVIRONMENT" \ '{ref: $ref, environment: $environment, state: "in_progress"}')" | jq -r .id)
# 2. Deploy, then report how it went.if ./deploy.sh; then report "$API/$ID/statuses" "$(jq -n --arg url "$ENVIRONMENT_URL" \ '{state: "success", environment_url: $url}')" > /dev/nullelse report "$API/$ID/statuses" '{"state": "failure", "description": "The deploy command failed"}' > /dev/null exit 1fiGive log_url in both calls to link the deployment to your CI’s page for
the job.
Statuses
Section titled “Statuses”| State | Means | The commit’s check |
|---|---|---|
queued |
It is waiting to start. | Pending |
in_progress |
It is deploying. | Pending |
success |
It is live. | Success |
failure |
It did not go live. | Failure |
error |
Something went wrong around it, such as a cancelled run. | Error |
inactive |
It is no longer what the environment serves. | Left as it was |
A g1t.page build’s statuses are read from the build itself: queued, then
in_progress while it builds, then how it ended, and inactive once a
newer build replaced it or it was taken down. You cannot add statuses to a
g1t.page build: POST …/deployments/dpl_…/statuses answers 409.
auto_inactive
Section titled “auto_inactive”An environment serves one deployment at a time. When a deployment
succeeds, the environment’s older successful deployments each get an
inactive status, so only the newest stays current. To keep them as they
are, for example when several deployments are live side by side, send
"auto_inactive": false with the success.
Environments
Section titled “Environments”An environment exists once something deploys to it. You do not create environments first.
- Production environments are those people use directly. An
environment named
productionis one unless the deployment says"production_environment": false. Set it totruefor others, such aslive. - Transient environments go away, such as a review app for one pull
request. Set
"transient_environment": trueon their deployments.
GET /repos/{owner}/{name}/environments lists them: production first,
then other production environments, then the rest, most recently deployed
first. Each has:
| Field | |
|---|---|
name |
The environment’s name, as first spelled. |
url |
Where it is served: current’s environment_url. |
production_environment, transient_environment |
As its deployments said. |
deployments_count |
How many deployments went to it. |
latest |
Its newest deployment, whatever its state. |
current |
Its newest successful deployment that is still active. Null when none is. |
updated_at |
When it last changed. |
total_count counts deployments across every environment.
GET /repos/{owner}/{name}/environments/{environment} returns one, matched
without regard to case. URL-encode a name with slashes:
…/environments/review%2Ffeature-x.
An environment with protection rules
also has protection_rules (required_reviewers, wait_timer,
branch_policy), deployment_branch_policy, branch_policies and
can_admins_bypass, and is listed even before anything deploys to it.
PUT …/environments/{environment} sets the rules and DELETE removes
them.
Read deployments
Section titled “Read deployments”| Route | What it returns |
|---|---|
GET /repos/{owner}/{name}/deployments |
Deployments, newest first, as { deployments, total_count, page, per_page }. |
GET /repos/{owner}/{name}/deployments/{id} |
One deployment, with every status in statuses, oldest first. |
GET /repos/{owner}/{name}/deployments/{id}/statuses |
Its statuses, newest first. |
GET /repos/{owner}/{name}/environments |
The environments, as above. |
GET /repos/{owner}/{name}/environments/{environment} |
One environment. |
The list takes these filters:
| Query | |
|---|---|
environment |
Only this environment’s, matched without regard to case. |
ref |
Only deployments of this branch, tag or commit, as it was given. |
sha |
Only deployments of this commit, or of commits starting with it. |
task |
Only this task’s. |
state |
Only deployments whose latest status has this state. |
source |
api, actions or g1t_page. |
creator |
Only those this username made, or g1t. |
page, per_page |
Which page, from 1, and how many on it: 30 unless you say, at most 100. |
curl "https://api.g1t.sh/repos/acme/web/deployments?environment=production&state=success&per_page=5" \ -H "Authorization: Bearer $G1T_TOKEN"A deployment has these fields:
| Field | |
|---|---|
id |
dep_…, or dpl_… for a g1t.page build. |
environment, ref, sha, task, description, payload |
As reported. |
production_environment, transient_environment |
As reported. |
state |
Its latest status’s state. |
environment_url, log_url |
The latest addresses it was given. |
creator |
The username of whoever reported it or started its run, or g1t. |
source |
api, actions or g1t_page. |
run_id, run_url |
The g1t Actions run that made it. Null for other sources. |
project, number |
For a g1t.page build: the project, and for a preview its pull request’s number. Null for other sources. |
created_at, updated_at |
When it was made, and when it last changed. |
Reading needs the deployments:read scope and the Read role. A public
repository’s deployments can be read by anyone. Reporting needs
deployments:write and the Write role, and an
archived repository refuses it with
409. Every route, with its example, is in the
API reference.
The commit’s check
Section titled “The commit’s check”Every status sets a check on the deployment’s commit, named
deploy / <environment>, such as deploy / staging. It links to the
deployment’s page, https://g1t.sh/{owner}/{name}/deployments/{id}. The
statuses table says which state the check takes. A pull
request whose head was deployed shows the check with its other checks.
g1t.page builds keep their own check, g1t / deploy. See
previews of branches.
Require a deployment before merging
Section titled “Require a deployment before merging”A ruleset’s Require deployments to succeed rule
(required_deployments) holds a pull request until its head has deployed
successfully to each environment it names. A successful
deploy / <environment> check meets it, so any environment you report to,
from anywhere, can be required:
curl -X POST https://api.g1t.sh/repos/acme/web/rulesets \ -H "Authorization: Bearer $G1T_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "ruleset_name": "Staging first", "conditions": { "ref_name": { "include": ["~DEFAULT_BRANCH"] } }, "rules": [ { "type": "required_deployments", "parameters": { "environments": ["staging"] } } ] }'For this to work, your CI deploys each pull request’s head to staging
and reports it. See rules.
Deployments from g1t Actions
Section titled “Deployments from g1t Actions”A g1t Actions job with an environment: makes a
deployment by itself. You do not call the API.
jobs: deploy: runs-on: ubuntu-latest environment: production steps: - uses: actions/checkout@v4 - run: ./deploy.shGive the environment’s address with url. Its expressions are filled in
from the github, inputs and matrix contexts, and it must be an
http or https address:
jobs: deploy: runs-on: ubuntu-latest environment: name: staging url: https://staging.example.com/${{ github.sha }} steps: - uses: actions/checkout@v4 - run: ./deploy.sh stagingA run makes one deployment per environment, however many of its jobs name
it. A matrix that deploys to three regions makes one production
deployment, not three:
jobs: deploy: runs-on: ubuntu-latest strategy: matrix: region: [us-east, eu-west, ap-south] environment: production steps: - uses: actions/checkout@v4 - run: ./deploy.sh ${{ matrix.region }}How the deployment goes:
- It is made,
in_progress, when the first job that names the environment starts. - If one of those jobs fails, it is marked
failureat once, unless the job hascontinue-on-error. - When the run finishes, it settles:
failureif any of those jobs failed,errorif the run was cancelled, andsuccessotherwise. Jobs that were skipped do not count. If none of them ran, no deployment is made.
Its ref is the run’s branch, sha the run’s commit, creator whoever
started the run, and log_url and run_url the run’s page. A run
attempted again makes a deployment of its own. Jobs on
self-hosted runners make deployments the
same way.
A job that needs an environment’s
secrets and variables
but does not deploy, such as one that plans a change, says
deployment: false:
jobs: plan: runs-on: ubuntu-latest environment: name: production deployment: false steps: - uses: actions/checkout@v4 - run: ./plan.shA job’s G1T_TOKEN can also report deployments of its own with the API,
given deployments: write in its permissions:.
A job that names an environment with protection rules waits for them before it starts, and its deployment is made only once it does.
Webhooks
Section titled “Webhooks”Webhooks send two events for deployments of every source, g1t.page builds included:
| Event | When | data |
|---|---|---|
deployment.created |
A deployment was made. | repo_id, deployment (without payload) |
deployment_status.created |
A deployment got a status. | repo_id, deployment (without payload), deployment_status |
deployment.succeeded and deployment.failed are sent for g1t.page builds
only.
The workflow tool has an action for each route:
| Action | Route |
|---|---|
list_deployments |
GET /repos/{owner}/{name}/deployments |
get_deployment |
GET /repos/{owner}/{name}/deployments/{id} |
create_deployment |
POST /repos/{owner}/{name}/deployments |
deployment_statuses |
GET /repos/{owner}/{name}/deployments/{id}/statuses |
create_deployment_status |
POST /repos/{owner}/{name}/deployments/{id}/statuses |
list_environments |
GET /repos/{owner}/{name}/environments |
get_environment |
GET /repos/{owner}/{name}/environments/{environment} |
update_environment |
PUT /repos/{owner}/{name}/environments/{environment} |
delete_environment |
DELETE /repos/{owner}/{name}/environments/{environment} |
They take the repository as repo, written owner/name, and the same
fields as the routes.
On the site
Section titled “On the site”- The Deployments page,
g1t.sh/<owner>/<project>/deployments, shows a card for each environment: its state, address, commit, ref, who deployed it and from where, when, and how many deployments it has had. Below is every deployment, newest first, filtered by Environment, State, Source, Creator and Ref. Projects deployed to g1t.page manage their apps under On g1t.page on the same page. - A deployment’s page,
g1t.sh/<owner>/<project>/deployments/<id>, shows its statuses in order, links to its log and run, and its payload. Only the newest status can show as still under way; aqueuedorin_progressone that a later status followed shows as over. - Every link to where something runs, a g1t.page address, an environment’s URL, a pull request’s preview or a project’s homepage, opens in a new tab, wherever on the site it appears.
- The repository’s code page and the project’s overview show a Deployments panel with how many there are, and each environment’s latest deployment and when. It links to the Deployments page.
- The project’s overview shows a production environment deployed elsewhere in its production card: its address, state, commit and when it went up.