Report LocalCI results to GitHub
This guide adds a LocalCI status to a commit so pull
requests containing that commit show whether your local checks passed.
Check output remains in your terminal.
1. Install and configure LocalCI
Follow the installation and first-run
instructions. Before enabling GitHub reporting, make sure your
configured check command passes with localci --dry-run.
You need a GitHub credential to post the status. No GitTrove key is involved at run time: the key you used to install LocalCI authenticates the package download only.
2. Give LocalCI access to GitHub
If you use the GitHub CLI, sign in:
gh auth login --hostname github.comLocalCI retrieves the token from gh without saving it in
your checkout. Alternatively, set GITHUB_TOKEN using your
secret manager. For example:
export GITHUB_TOKEN="$(gopass show -o github/localci)"Create and store that token first. A fine-grained token needs
Commit statuses: write access to the selected
repository. A classic token can use the narrower
repo:status scope. See GitHub's commit-status
API permissions. Organization policies may also require token
approval. GITHUB_TOKEN takes precedence over
gh when both are available.
3. Enable reporting and run
Add github = true to the existing table in the
repository's pyproject.toml. For example, a project using
npm tests would have:
[tool.localci]
command = ["npm", "test"]
github = true
github_context = "LocalCI"Keep your project's actual check command. Do not add a second
[tool.localci] table if one already exists.
Commit the configuration and all changes you want checked, then push your branch and run:
git push -u origin your-branch
localciPush first: GitHub must already know the commit before it can accept
a status. LocalCI requires a clean working tree for GitHub reporting. It
will also refuse to publish if the checks leave uncommitted changes or
HEAD moves during the run. Use
localci --no-github to check uncommitted work without
posting a status.
LocalCI: acme/widget at 0632064b651f
LocalCI: running npm test
...
LocalCI: reported success to GitHub as 'LocalCI'
Open the pull request to see the status, or query it directly,
replacing OWNER/NAME with your repository:
gh api "repos/OWNER/NAME/commits/$(git rev-parse HEAD)/statuses" \
--jq '.[] | {context, state, description}'A failed check posts a failure status. A rebase or amend
creates a new commit that needs a new run. By default LocalCI posts only
the final result. To show the run while it is happening, add
github_pending = true:
[tool.localci]
command = ["npm", "test"]
github = true
github_pending = trueLocalCI then posts pending before the checks start, and
a run that cannot start or times out closes it with an
error instead of leaving it waiting. A run that is
interrupted with Ctrl-C publishes nothing, which can leave a pending
status until another run replaces it. Pending is off by default because
a required status that is never replaced blocks the pull request. Asking
for it with reporting off is a configuration error.
Stopping a check that hangs
Set a deadline so a check that waits forever ends with a verdict:
[tool.localci]
command = ["npm", "test"]
timeout_seconds = 900--timeout SECONDS overrides the setting for one run, and
--timeout 0 removes the deadline. A timed-out run reports
timed out after 900s, exits 1, and never posts success. It
attempts an error status only when it had posted
pending.
Require the result before merging
Configure your GitHub branch protection or ruleset to require the
status named LocalCI, or the name you set in
github_context. Run LocalCI at least once so the status is
available to select. Availability depends on your GitHub plan and
repository visibility; see GitHub's protected
branch documentation.
A local status is a developer-reported result. Anyone permitted to post that status can affect the gate. Keep independent CI if your review policy requires verification outside a developer's machine.
GitHub Enterprise
Set the API URL and sign in to that host:
[tool.localci]
command = ["make", "check"]
github = true
github_url = "https://github.example/api/v3"gh auth login --hostname github.exampleLocalCI asks gh for the configured host's credential. An
explicit GITHUB_TOKEN still wins, so ensure it belongs to
the correct host. Use trusted HTTPS endpoints because the token is sent
to the configured API.
Troubleshooting
| Message or symptom | What to do |
|---|---|
| Missing GitHub credential | Sign in with gh for the correct host, or set
GITHUB_TOKEN. |
| Clean working tree required | Commit or stash changes, including untracked files, or use
--no-github. |
Working tree or HEAD changed during checks |
Inspect the changes, commit the intended ones, and run again. Ignore disposable artifacts; use formatter check modes. |
| HTTP 401 | Replace the expired or invalid token. |
| HTTP 403 | Check token permissions, organization policies, and API rate limits. |
| HTTP 404 | Check the repository identifier and that the token can access it.
Use --repository owner/name if needed. |
| HTTP 422 mentioning the SHA | Push the current commit before running again. |
| Exit 3 | Read the error: the GitHub status failed, or the checkout changed while checks ran. |
| Status stuck on pending | A run published pending and then died, or was interrupted. Run LocalCI again on the same commit to replace it. |
| Check never finishes | Set timeout_seconds, or pass
--timeout SECONDS, so the run ends with a clear message
instead of holding the terminal. |
| No status on the pull request | Confirm the PR head matches git rev-parse HEAD and that
the run used the right repository and context. |
--github enables reporting for one run;
--no-github disables it, which is how a dirty working tree
is checked locally. --github-pending and
--no-github-pending do the same for the pending status.
--dry-run prints the status payload without contacting
GitHub or looking up a token, and neither a dry run nor a run with
reporting off publishes a pending status.
Automated runs
LocalCI can run in an existing CI job after that job has installed
LocalCI and prepared the project's environment. The job needs the
GitTrove install key to download LocalCI from the private index, and a
GitHub job token with statuses: write. Check out the PR's
head commit when you want its status, and run only trusted code with
those credentials.
Fork pull requests normally do not receive repository secrets or a writable job token. Do not bypass that boundary to run untrusted code with secrets. Use your normal trusted review and CI process for those contributions.
See the README for exit codes and the data sent to each service.