Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
306 linesCodeBlameRaw
1---
2title: Checks
3description: Report what CI and integrations find on a commit as statuses and check runs, see them beside every commit, and require them before a merge.
4---
5
6Every commit can carry checks: what your workflows, your CI, your
7deployments and any integration say about it. g1t shows them beside the
8commit wherever it appears, so you can tell at a glance whether a change
9works and how far along it is.
10
11- A green check: every check passed.
12- A red cross: at least one failed.
13- An amber dot: at least one is still running or queued.
14
15Select the mark to see the list: a headline ("All checks have passed",
16"Some checks were not successful" or "Some checks haven't completed yet"),
17how many passed, failed and are running, and each check with how it went,
18how long it took, and a **Details** link.
19
20## Where checks show
21
22| Page | Where |
23| --- | --- |
24| **Code** | Beside the latest commit, above the files |
25| **Commits** | Beside each commit |
26| A commit's page | Beside its hash |
27| **Branches** | Beside each branch's latest commit |
28| **Tags** | Beside each tagged commit |
29| A pull request | Beside its head commit, in the sidebar; its merge box lists them too |
30| A project's overview | Beside the latest commit, and each active branch |
31
32A page reads the checks of all its commits at once, after the page itself
33has loaded: each mark shows a placeholder until they arrive.
34
35## Statuses and check runs
36
37There are two ways to report a check. Use either, or both.
38
39| | A status | A check run |
40| --- | --- | --- |
41| What it is | A state for one context on a commit, such as `ci/build` | One run of one check, with a life of its own |
42| States | `pending`, `success`, `failure`, `error` | `status`: `queued`, `in_progress`, `completed`; once completed, a `conclusion`: `success`, `failure`, `neutral`, `cancelled`, `skipped`, `timed_out` or `action_required` |
43| Report | A short `description` and a `target_url` | A `title`, a Markdown `summary` and `text`, up to 1,000 annotations on lines of files, and up to 3 buttons |
44| On g1t | Listed with a link to `target_url` | Its own page under the repository, linked from the list |
45| Set again | Replaces the context's status on that commit | Update the same run, or create a new one |
46| Use it for | A quick pass or fail from any tool | Test, lint and scan results someone needs to read |
47
48Every job of a [workflow](/guides/actions/) run is a check run, named
49`Workflow / job (event)` in the list, such as `CI / test (push)`, and its
50**Details** opens the job's log. You do not report those: g1t does.
51
52## Report a status
53
54You need a token with the `checks:write` scope (see
55[scopes](/guides/authentication/#scopes)) and the Write
56[role](/guides/access-and-roles/) on the repository.
57
58```sh
59curl -X POST https://api.g1t.sh/repos/<workspace>/<repo>/statuses/<sha> \
60 -H "Authorization: Bearer $G1T_TOKEN" \
61 -H "Content-Type: application/json" \
62 -d '{
63 "state": "success",
64 "context": "ci/build",
65 "description": "Build #4821 passed",
66 "target_url": "https://ci.example.com/builds/4821"
67 }'
68```
69
70| Field | Required | What it is |
71| --- | --- | --- |
72| `state` | Yes | `pending`, `success`, `failure` or `error`. `error` counts as a failure. |
73| `context` | No | What reports it, such as `ci/build`; `default` when left out. At most 100 characters. |
74| `description` | No | A short word on it, at most 140 characters. |
75| `target_url` | No | Where to see more: an `http` or `https` address. |
76
77[`create_commit_status`](/reference/api/checks/create-commit-status/)
78returns the status. Set a context again to replace it: report `pending`
79when a build starts, then `success` or `failure` when it ends.
80[`get_combined_status`](/reference/api/checks/get-combined-status/) gives
81a commit's statuses and what they add up to:
82`GET /repos/<workspace>/<repo>/commits/<ref>/status`, where `<ref>` is a
83commit SHA, a branch or a tag.
84
85## Report a check run
86
87A check run is reported in two steps: create it when the work starts,
88then complete it.
89
901. Create it, in progress:
91
92 ```sh
93 curl -X POST https://api.g1t.sh/repos/<workspace>/<repo>/check-runs \
94 -H "Authorization: Bearer $G1T_TOKEN" \
95 -H "Content-Type: application/json" \
96 -d '{"name": "lint", "head_sha": "<sha>", "status": "in_progress", "details_url": "https://ci.example.com/builds/4821"}'
97 ```
98
99 The answer has its `id`, such as `cr_01kq4b7c8d9e0f1g2h3j4k5m6n`.
100
1012. Complete it with a `conclusion`, a report and annotations:
102
103 ```sh
104 curl -X PATCH https://api.g1t.sh/repos/<workspace>/<repo>/check-runs/<id> \
105 -H "Authorization: Bearer $G1T_TOKEN" \
106 -H "Content-Type: application/json" \
107 -d '{
108 "conclusion": "failure",
109 "output": {
110 "title": "2 problems",
111 "summary": "**2** problems in `src/parse.rs`.",
112 "annotations": [
113 {"path": "src/parse.rs", "start_line": 42, "end_line": 42, "annotation_level": "warning", "message": "unused variable: `depth`"},
114 {"path": "src/parse.rs", "start_line": 57, "end_line": 60, "annotation_level": "failure", "message": "this match is not exhaustive"}
115 ]
116 }
117 }'
118 ```
119
120Giving a `conclusion` completes the run; `started_at` and `completed_at`
121are filled in when you leave them out. A run can also be created already
122completed, in one call.
123
124| Field | What it is |
125| --- | --- |
126| `name` | The check's name, at most 100 characters. Required to create one. |
127| `head_sha` | The commit it is about. Required to create one. |
128| `status` | `queued` (the default), `in_progress` or `completed`. |
129| `conclusion` | `success`, `failure`, `neutral`, `cancelled`, `skipped`, `timed_out` or `action_required`. |
130| `started_at`, `completed_at` | When it started and ended, in RFC 3339. |
131| `details_url` | Your own page for it. |
132| `external_id` | Your own id for it. |
133| `output` | `title`, `summary` and `text` (Markdown, at most 65,535 characters each) and `annotations`. |
134| `actions` | Up to 3 buttons: `label` (20 characters), `description` (40) and `identifier` (20). |
135| `app` | Who reports it, such as `Codecov`. By default, your token's name. |
136
137### A minimal reporter
138
139This script runs a command and reports it as a check run, from any CI that
140has `curl` and `jq`:
141
142```sh
143#!/bin/sh
144# check.sh <name> <command…>: report a command as a g1t check run.
145set -u
146name=$1; shift
147api="https://api.g1t.sh/repos/$G1T_REPO"
148auth="Authorization: Bearer $G1T_TOKEN"
149
150id=$(curl -sf -X POST "$api/check-runs" -H "$auth" -H "Content-Type: application/json" \
151 -d "$(jq -n --arg name "$name" --arg sha "$G1T_SHA" '{name: $name, head_sha: $sha, status: "in_progress"}')" | jq -r .id)
152
153if output=$("$@" 2>&1); then conclusion=success; else conclusion=failure; fi
154
155curl -sf -X PATCH "$api/check-runs/$id" -H "$auth" -H "Content-Type: application/json" \
156 -d "$(jq -n --arg c "$conclusion" --arg log "$(printf '%s' "$output" | tail -c 60000)" \
157 '{conclusion: $c, output: {title: $c, summary: ("```\n" + $log + "\n```")}}')" > /dev/null
158[ "$conclusion" = success ]
159```
160
161```sh
162G1T_REPO=acme/web G1T_SHA=$(git rev-parse HEAD) ./check.sh lint npm run lint
163```
164
165### Annotations
166
167An annotation points at lines of a file at the run's commit: `path`,
168`start_line` and `end_line` (from 1), and for one line, `start_column`
169and `end_column`. `annotation_level` is `notice`, `warning` or `failure`;
170`message` says what is wrong, `title` names it, and `raw_details` holds
171anything longer.
172
173Send at most 50 in one request; each update adds to those the run has,
174up to 1,000. On the check run's page they are grouped by file, each
175linking to its lines.
176[`list_check_run_annotations`](/reference/api/checks/list-check-run-annotations/)
177returns them in the order they were reported.
178
179### Buttons
180
181`actions` puts up to 3 buttons on the check run's page, such as **Fix
182this** or **Ignore**. When someone with the Write role presses one, g1t
183sends your webhook a `check_run.requested_action` event with the button's
184`identifier` in `data.requested_action`. What happens next is up to you.
185
186### Check suites
187
188Each reporter's check runs on a commit form one check suite, with a
189status and conclusion worked out from its latest runs: in progress while any
190is, then the worst conclusion. A workflow run is the suite of its jobs.
191[`list_check_suites_for_ref`](/reference/api/checks/list-check-suites-for-ref/)
192lists a commit's suites. A suite completing sends `check_suite.completed`.
193
194## From a workflow
195
196A workflow job reports extra check runs with its own `G1T_TOKEN`, given
197`checks: write` in its [`permissions:`](/guides/actions/#the-jobs-token). They
198report as **g1t Actions**:
199
200```yaml
201- name: Report coverage
202 if: always()
203 env:
204 G1T_TOKEN: ${{ secrets.G1T_TOKEN }}
205 run: |
206 curl -sf -X POST "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs" \
207 -H "Authorization: Bearer $G1T_TOKEN" -H "Content-Type: application/json" \
208 -d "{\"name\": \"coverage\", \"head_sha\": \"$GITHUB_SHA\", \"conclusion\": \"neutral\", \"output\": {\"title\": \"81% covered\", \"summary\": \"Up 2% from main.\"}}"
209```
210
211On a pull request's run, `GITHUB_SHA` is its
212[test merge commit](/guides/actions/#what-a-pull-requests-run-builds), as on
213GitHub: to show the check on the pull request, report it on the head,
214`${{ github.event.pull_request.head.sha || github.sha }}`.
215
216A pull request's runs from someone without the Write role get no token
217that can write, so they cannot report checks.
218
219## Required checks
220
221A [required status check](/guides/pull-requests/#required-status-checks),
222in branch protection or a [ruleset](/guides/rules/), is met by a status of
223its name or a check run of its name alike:
224
225| What reported it | Counts as |
226| --- | --- |
227| A status `success` | Passing |
228| A status `failure` or `error` | Failing |
229| A status `pending` | Running: the merge waits |
230| A check run not yet completed | Running: the merge waits |
231| A check run completed `success`, `neutral` or `skipped` | Passing |
232| A check run completed `failure`, `cancelled`, `timed_out` or `action_required` | Failing |
233| Nothing yet | Expected: the merge waits |
234
235A workflow is required by its name, such as `CI`, which all its jobs
236report under. To require only what was reported through the API, pin the
237check to the `api` integration in a ruleset:
238`{"context": "lint", "integration": "api"}`.
239
240A pull request [g1t is working on](/guides/working-with-g1t/#seeing-it-through)
241goes back to g1t when a check fails, whatever reported it.
242
243## Run again
244
245[`rerequest_check_run`](/reference/api/checks/rerequest-check-run/) and
246[`rerequest_check_suite`](/reference/api/checks/rerequest-check-suite/), or
247**Re-run** on a check run's page, ask for it to run again. A check run
248reported through the API sends its reporter `check_run.rerequested` (or
249`check_suite.rerequested`): run it again and report a new check run. A
250workflow job's run runs again, which also needs `workflows:write`.
251
252## Webhooks
253
254[Webhooks](/guides/webhooks/) can be sent:
255
256| Event | When |
257| --- | --- |
258| `status.created` | A status was set on a commit, through the API or by g1t: a workflow run, a deploy. |
259| `check_run.created` | A check run was reported. |
260| `check_run.completed` | A check run completed. |
261| `check_run.rerequested` | Someone asked for a check run to run again. |
262| `check_run.requested_action` | Someone pressed one of a check run's buttons. |
263| `check_suite.completed` | Every latest check run of a suite completed. |
264| `check_suite.rerequested` | Someone asked for a check suite to run again. |
265
266These are left out of a repository's timeline.
267
268## Who can report checks
269
270| | Can |
271| --- | --- |
272| Anyone who can read the repository | See its checks, and read them through the API with `checks:read` (no token for a public repository) |
273| The Write role and up, with `checks:write` | Report statuses and check runs, and ask for them to run again |
274| A workflow job, with `G1T_TOKEN` and `checks: write` or `statuses: write` | The same, in its repository |
275| g1t's agents | Read checks, never report them |
276
277An agent's own work is never judged by checks it reported: what a check
278says is up to your CI and integrations.
279
280## From the API and MCP
281
282| Route | Operation |
283| --- | --- |
284| `POST /repos/{owner}/{name}/statuses/{sha}` | [`create_commit_status`](/reference/api/checks/create-commit-status/) |
285| `GET /repos/{owner}/{name}/commits/{ref}/statuses` | [`list_commit_statuses`](/reference/api/checks/list-commit-statuses/) |
286| `GET /repos/{owner}/{name}/commits/{ref}/status` | [`get_combined_status`](/reference/api/checks/get-combined-status/) |
287| `POST /repos/{owner}/{name}/check-runs` | [`create_check_run`](/reference/api/checks/create-check-run/) |
288| `PATCH /repos/{owner}/{name}/check-runs/{id}` | [`update_check_run`](/reference/api/checks/update-check-run/) |
289| `GET /repos/{owner}/{name}/check-runs/{id}` | [`get_check_run`](/reference/api/checks/get-check-run/) |
290| `GET /repos/{owner}/{name}/check-runs/{id}/annotations` | [`list_check_run_annotations`](/reference/api/checks/list-check-run-annotations/) |
291| `POST /repos/{owner}/{name}/check-runs/{id}/rerequest` | [`rerequest_check_run`](/reference/api/checks/rerequest-check-run/) |
292| `GET /repos/{owner}/{name}/commits/{ref}/check-runs` | [`list_check_runs_for_ref`](/reference/api/checks/list-check-runs-for-ref/) |
293| `GET /repos/{owner}/{name}/commits/{ref}/check-suites` | [`list_check_suites_for_ref`](/reference/api/checks/list-check-suites-for-ref/) |
294| `GET /repos/{owner}/{name}/check-suites/{id}` | [`get_check_suite`](/reference/api/checks/get-check-suite/) |
295| `POST /repos/{owner}/{name}/check-suites/{id}/rerequest` | [`rerequest_check_suite`](/reference/api/checks/rerequest-check-suite/) |
296
297[`list_check_runs_for_ref`](/reference/api/checks/list-check-runs-for-ref/)
298gives each name's latest run and each workflow's latest run per event;
299`filter=all` gives every one. Narrow it with `check_name`, `status` and
300`app` (a reporter's slug; `actions` for workflow jobs).
301
302On the [MCP server](/reference/mcp/#workflow), the `workflow` tool has an
303action for each: `combined_status`, `list_statuses`, `set_status`,
304`list_check_runs`, `get_check_run`, `check_run_annotations`,
305`create_check_run`, `update_check_run`, `rerequest_check_run`,
306`list_check_suites`, `get_check_suite` and `rerequest_check_suite`.