A GitHub CLI extension that shows CI status next to commit logs
gh log-ci displays recent commits with an inline summary icon of their GitHub Check / Actions status so you can instantly see which commits are green, failing, pending, or cancelled.
gh log-ci works with GitHub.com and GitHub Enterprise Server (any version that supports Checks API).
Requirements: GitHub CLI and Bash 4.0 or newer. macOS ships Bash 3.2 as the default
/bin/bash; install a newer Bash first:brew install bashThe script will detect an unsupported Bash and fail with an actionable error pointing you here.
- Install GitHub CLI
- Authenticate:
gh auth login - (Optional) Ensure you have access to private repos you care about
- Install the extension:
gh extension install xpepper/gh-log-ci(orgh extension install .from local checkout) - Run:
gh log-cion a GitHub repo - Profit! β π
Basic usage (auto-detect default branch):
gh log-ci --branch <name> Use a specific branch (overrides auto-detect)
--limit, -n <n> Number of commits to display (default: 15; env LOG_CI_LIMIT)
--concurrency, -c <n> Parallel API calls (default: 4; env LOG_CI_CONCURRENCY)
--checks, -C Show per-check run summaries
--no-spinner Disable loading spinner (env LOG_CI_NO_SPINNER=1)
--api-timeout <secs> Max seconds per API request (default: 30; env LOG_CI_API_TIMEOUT)
--watch Continuously poll and update commit statuses
--watch-interval <s> Seconds between polls in watch mode (default: 10; env LOG_CI_WATCH_INTERVAL)
--no-cache Ignore success cache, force fresh API calls for all commits
--use-rest Force REST API mode, bypass GraphQL (env LOG_CI_FORCE_REST=1)
--help, -h Show help / usage
--version Show version
Help example:
$ gh log-ci --help
gh log-ci - show CI status next to recent commits
Usage:
gh log-ci [options] [<branch>|<commit-sha>]
Options:
--branch <name> Branch to inspect (alternative to positional <branch>)
--limit, -n <n> Number of commits to display (default: 15; env LOG_CI_LIMIT overrides)
--concurrency, -c <n> Max parallel API calls (default: 4; env LOG_CI_CONCURRENCY overrides)
--checks, -C Show per-check run summaries beneath each commit (env LOG_CI_SHOW_CHECKS=1)
--no-spinner Disable loading spinner (env LOG_CI_NO_SPINNER=1)
--api-timeout <secs> Max seconds per API request (default: 30; env LOG_CI_API_TIMEOUT)
--watch Continuously poll and update commit statuses
--watch-interval <s> Seconds between polls in watch mode (default: 10; env LOG_CI_WATCH_INTERVAL)
--no-cache Ignore success cache, force fresh API calls for all commits
--use-rest Force REST API mode, bypass GraphQL (env LOG_CI_FORCE_REST=1)
Branch auto-detect order when <branch> not supplied:
1. GitHub default branch (via gh repo view)
2. master (if exists)
3. main (if exists)
4. current HEAD branch
Commit SHA mode:
When a valid commit SHA (full or short) is provided as the first argument,
gh log-ci displays status for that single commit only.
Examples:
gh log-ci # auto-detect branch
gh log-ci main # explicit positional branch
gh log-ci 7b60fc9 # show status for single commit
gh log-ci abc123def # works with full SHAs too
gh log-ci --branch develop --limit 30
gh log-ci -c 8 -n 50 # increase parallelism and number of commits
LOG_CI_SHOW_CHECKS=1 gh log-ci -n 10 # show per-check summaries (env)
gh log-ci -C --limit 5 # show per-check summaries (flag)
gh log-ci --watch # watch mode (poll every 10s)
gh log-ci --watch --watch-interval 30 # watch mode with custom interval
Additional environment:
LOG_CI_WATCH_INTERVAL Override default poll interval (10)
LOG_CI_WATCH_ONCE=1 Internal/testing: run only one watch iteration then exit
Exit codes:
0 success
1 setup or API errorSpecify a branch explicitly:
gh log-ci release-branchBranch resolution order when no argument is provided:
- GitHub default branch (
gh repo view --json defaultBranchRef --jq .defaultBranchRef.name) masterif presentmainif present- Current local HEAD branch
You can also pass a commit SHA (full or short) to check the CI status of a single commit:
# Full commit SHA
gh log-ci 1055e83327fe2415e117ec67fbc8412f9093504f
# Short commit SHA (at least 7 characters)
gh log-ci 1055e83
# Using git rev-parse output
gh log-ci $(git rev-parse HEAD~5)In commit SHA mode:
- Shows exactly 1 commit (the specified SHA)
- No remote branch warnings
- Works with both GraphQL (default) and REST API modes (
--use-rest) - Accepts both full 40-character SHAs and short SHAs (β₯7 characters)
$ gh log-ci
β
49b3e7623 - (HEAD -> master, origin/master, origin/HEAD) refactor(component): improve caching (Wed Oct 22 15:15:13 2025 +0200) <Jane Doe>
β c4f35260a - feat(auth): add MFA (Wed Oct 22 09:25:09 2025 +0200) <John Smith>
π a390e5998 - chore(deps): bump library (Tue Oct 21 16:52:40 2025 +0200) <dependabot[bot]>
| Icon | Meaning |
|---|---|
| β | All completed check runs succeeded (no failures/pending) |
| β | At least one failing/timed_out/action_required check run |
| π | One or more check runs still in progress / queued and no failures yet |
| π | Queued run blocked by earlier in-progress run of same workflow |
| π« | One or more cancelled runs and no failures/pending (takes precedence over success) |
| β | Mixed: successes and failures both present |
| β² | Timed out while fetching check runs (API didn't respond within --api-timeout) |
| β | Neutral/skipped/stale (shown only in per-check detail) |
| π€ | Non-push workflow (excluded from status aggregation) |
| β | Fallback / unknown state |
| Capability | Description |
|---|---|
| Auto branch | Detects default branch, falls back to master/main/HEAD |
| Commit SHA mode | Check CI status for a single commit by SHA (full or short) |
| Status aggregation | Smarter overall icon (pending vs all-green vs mixed failure) |
| GraphQL batch query | Single batch query fetches all commit statuses (use --use-rest for REST API mode) |
| Per-check summaries | Optional detailed list via --checks / LOG_CI_SHOW_CHECKS=1 |
| Parallel fetching | Concurrency-controlled API calls (--concurrency) |
| Colorized log | Mirrors git log pretty format with colors |
| Lightweight | Single Bash script, no external deps beyond gh |
| Progress spinner | Shows animated spinner with live completed/total count (disable with --no-spinner) |
| API timeouts | Per-request timeout preventing hangs (--api-timeout, shows β² on timeout) |
| Watch mode | Continuously polls to surface new commits and evolving statuses (--watch, --watch-interval) |
| Success caching | Skips API calls for commits already successful within TTL (success-only, configurable) |
| Blocked detection | Distinguishes queued runs blocked by in-progress workflow (π icon) |
| Event-based filtering | Excludes non-push workflows from status aggregation while keeping them visible with -C |
By default, gh-log-ci only includes check runs triggered by push events when computing the overall status icon. This prevents scheduled workflows (like Dependabot with event: "dynamic") from incorrectly marking commits as failed.
GitHub associates check suites with the HEAD commit at run time, not the commit that triggered the suite. Without event filtering, workflows triggered by other events would affect the status of otherwise successful commits.
Excluded checks are still displayed when using the -C flag, marked with a π€ icon and [non-push] label for visibility.
This behavior matches GitHub's statusCheckRollup logic, which only includes checks from push events.
gh log-ci uses the credentials configured via gh auth login or any supported gh environment variables. Required scopes depend on what you want to read:
Typical token (user) scopes:
repo(private repository commit metadata & checks)read:org(if accessing private org repos)
GitHub App / server-to-server tokens need read access to:
- Repository Contents
- Repository Metadata
- Actions / Checks (implicitly via Checks API)
If you see authentication errors, re-run:
gh auth status
gh auth login- Determines input type (branch name or commit SHA).
- For branch mode: Fetches commits from
origin/<branch>. For commit SHA mode: Validates and resolves the SHA. - Emits a tab-delimited
git log(single commit for SHA mode, last 15 for branch mode). - GraphQL batch query (default): Executes a single GraphQL query to fetch check run status for all commits at once (reduces API calls by ~93% for 15 commits). For commit SHA mode, queries the specific commit object.
- REST API mode (explicit): Use
--use-restflag orLOG_CI_FORCE_REST=1to make individual REST API calls per commit instead. Required for:- GitHub Enterprise Server versions < 3.4 (GraphQL Checks API unavailable)
- Commits with >100 check suites (GraphQL query limit)
- Troubleshooting or comparing GraphQL vs REST behavior
- Maps combined conclusions to an icon and prints decorated line.
By default, gh log-ci uses GraphQL batch queries for optimal performance. Use REST mode (--use-rest or LOG_CI_FORCE_REST=1) when:
- GitHub Enterprise Server < 3.4: GraphQL Checks API not available on older GHES versions
- Commits with >100 check suites: GraphQL query limited to 100 check suites per commit
- GraphQL errors: If you encounter GraphQL API errors, the tool will suggest using
--use-restas a workaround - Debugging: Comparing behavior between GraphQL and REST API responses
Example:
# Force REST API mode with flag
gh log-ci --use-rest
# Force REST API mode with environment variable
LOG_CI_FORCE_REST=1 gh log-ci
# Combine with other options
gh log-ci --use-rest --concurrency 8 --limit 20- Branch: positional argument or
--branch(auto-detected if omitted). - Commit count:
--limit/-n(default 15) or environmentLOG_CI_LIMIT. - Concurrency:
--concurrency/-c(default 4) or environmentLOG_CI_CONCURRENCY. - Per-check detail:
--checks/-Cor environmentLOG_CI_SHOW_CHECKS=1. - Spinner: disable with
--no-spinnerorLOG_CI_NO_SPINNER=1. - API request timeout:
--api-timeout <secs>(default 30) orLOG_CI_API_TIMEOUT. - Watch mode:
--watchcontinuously refresh;--watch-interval <s>(default 10) orLOG_CI_WATCH_INTERVAL. - Success cache (success-only): TTL
LOG_CI_CACHE_TTL(default 86400s / 24h); directoryLOG_CI_CACHE_DIR(default ~/.cache/gh-log-ci); debugLOG_CI_CACHE_DEBUG=1. - Cache bypass:
--no-cacheto force fresh API calls for all commits. - Event-based filtering: Non-push workflows excluded from status aggregation; excluded checks displayed with
-Cmarked as[non-push]. - REST API mode:
--use-restflag orLOG_CI_FORCE_REST=1to bypass GraphQL (required for GHES <3.4).
- Per-check summaries increase output size (consider piping/grep).
- Neutral/skipped/stale checks don't affect overall icon yet.
- No JSON / alternative formats yet.
- Assumes
originremote name. - GraphQL queries limited to 100 check suites per commit (use
--use-restfor commits with >100 suites). - GraphQL mode only knows about commits that exist on the remote. Querying a local-only
(unpushed) commit SHA fails with
GraphQL response missing expected data structure; use--use-restfor those.
- Rate-limit handling with backoff + user notice.
- Workflow names and URLs (opt-in with a flag).
- Filtering: author, status, date range, grep on commit message.
- Semantic versioning policy (documented in README).
We use bats for basic behavioral tests and shellcheck for static analysis.
Run locally:
shellcheck gh-log-ci
bats testsCI runs automatically on pushes / PRs (see .github/workflows/ci.yml).
Convenience local CI script (runs both):
./ci-local.shWithout Homebrew (alternative via Docker):
docker run --rm -v "$PWD":/work -w /work ubuntu:22.04 bash -c \
"apt-get update && apt-get install -y bats shellcheck git && bats tests"For easier development and maintenance, this project includes a Makefile with common tasks:
make help # List all available tasks
make test # Run all tests (shellcheck + bats)
make shellcheck # Run shellcheck only
make bats # Run bats tests only
make ci-local # Run local CI script
make clean-cache # Remove all cache files
make list-cache # List cache filesSee make help for a complete list of available tasks.
- Fork and clone.
- Create a feature branch.
- Make changes + add tests (when available).
- Open a PR.
| Issue | Suggestion |
|---|---|
| Remote URL error | Ensure you're inside a GitHub repo with an origin remote |
| Auth errors | Run gh auth status then gh auth login |
| All π icons | Checks not started yet or using legacy status API |
| GraphQL errors | Try --use-rest flag to bypass GraphQL (required for GHES <3.4) |
| Slow output | Use GraphQL mode (default) for best performance; reduce --limit if needed |
See LICENSE.
This tool is under active development. While stable for everyday use, expect new features and improvements in future releases.
| Version | Date | Notes |
|---|---|---|
| 0.8.0 | 2026-01-11 | Commit SHA mode: check a single commit by full or short SHA, in both GraphQL and REST modes |
| 0.7.0 | 2026-01-06 | GraphQL batch query (93% API call reduction); --use-rest flag for GHES <3.4 compatibility; 54% faster for 15+ commits |
| 0.6.0 | 2025-11-17 | Distinguish blocked queued runs (π icon); update legend & features |
| 0.5.0 | 2025-11-04 | Add --no-cache flag to bypass success cache and force fresh API calls |
| 0.4.1 | 2025-10-23 | Success-only caching (TTL, dir config, debug env) skips API calls for cached successes |
| 0.4.0 | 2025-10-22 | Watch mode (--watch, --watch-interval); refactored core for repeated polling |
| 0.3.4 | 2025-10-22 | Progress-aware spinner (--no-spinner) option (shows completed/total); per-request --api-timeout with β² icon on timeout |
| 0.3.3 | 2025-10-22 | Removed header banner from output for compact display |
| 0.3.2 | 2025-10-22 | Cancelled status precedence fix (show π« when any cancelled and no failures) |
| 0.3.1 | 2025-10-22 | Added tests (bats) & CI workflow (shellcheck + tests) |
| 0.3.0 | 2025-10-22 | Per-check summaries (--checks) and richer status aggregation |
| 0.2.0 | 2025-10-22 | Concurrency flag (--concurrency) parallel API calls |
| 0.1.0 | 2025-10-22 | Basic functionality with branch auto-detect & limit |