Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

92 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

gh-log-ci logo and example output

gh-log-ci

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.

Quickstart

zread

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 bash

The script will detect an unsupported Bash and fail with an actionable error pointing you here.

  1. Install GitHub CLI
  2. Authenticate: gh auth login
  3. (Optional) Ensure you have access to private repos you care about
  4. Install the extension: gh extension install xpepper/gh-log-ci (or gh extension install . from local checkout)
  5. Run: gh log-ci on a GitHub repo
  6. Profit! βœ… πŸš€

Usage

Basic usage (auto-detect default branch):

gh log-ci

Flags

  --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 error

Specify a branch explicitly:

gh log-ci release-branch

Branch resolution order when no argument is provided:

  1. GitHub default branch (gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)
  2. master if present
  3. main if present
  4. Current local HEAD branch

Commit SHA Mode

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)

Output Example

$ 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]>

Icons Legend

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

Features

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

Event-Based Filtering

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.

Permissions

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

How It Works

  1. Determines input type (branch name or commit SHA).
  2. For branch mode: Fetches commits from origin/<branch>. For commit SHA mode: Validates and resolves the SHA.
  3. Emits a tab-delimited git log (single commit for SHA mode, last 15 for branch mode).
  4. 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.
  5. REST API mode (explicit): Use --use-rest flag or LOG_CI_FORCE_REST=1 to 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
  6. Maps combined conclusions to an icon and prints decorated line.

When to Use REST Mode

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-rest as 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

Configuration (Current)

  • Branch: positional argument or --branch (auto-detected if omitted).
  • Commit count: --limit / -n (default 15) or environment LOG_CI_LIMIT.
  • Concurrency: --concurrency / -c (default 4) or environment LOG_CI_CONCURRENCY.
  • Per-check detail: --checks / -C or environment LOG_CI_SHOW_CHECKS=1.
  • Spinner: disable with --no-spinner or LOG_CI_NO_SPINNER=1.
  • API request timeout: --api-timeout <secs> (default 30) or LOG_CI_API_TIMEOUT.
  • Watch mode: --watch continuously refresh; --watch-interval <s> (default 10) or LOG_CI_WATCH_INTERVAL.
  • Success cache (success-only): TTL LOG_CI_CACHE_TTL (default 86400s / 24h); directory LOG_CI_CACHE_DIR (default ~/.cache/gh-log-ci); debug LOG_CI_CACHE_DEBUG=1.
  • Cache bypass: --no-cache to force fresh API calls for all commits.
  • Event-based filtering: Non-push workflows excluded from status aggregation; excluded checks displayed with -C marked as [non-push].
  • REST API mode: --use-rest flag or LOG_CI_FORCE_REST=1 to bypass GraphQL (required for GHES <3.4).

Limitations

  • 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 origin remote name.
  • GraphQL queries limited to 100 check suites per commit (use --use-rest for 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-rest for those.

Roadmap

  • 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).

Testing

We use bats for basic behavioral tests and shellcheck for static analysis.

Run locally:

shellcheck gh-log-ci
bats tests

CI runs automatically on pushes / PRs (see .github/workflows/ci.yml).

Convenience local CI script (runs both):

./ci-local.sh

Without 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"

Makefile Tasks

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 files

See make help for a complete list of available tasks.

Contributing

  1. Fork and clone.
  2. Create a feature branch.
  3. Make changes + add tests (when available).
  4. Open a PR.

Troubleshooting

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

License

See LICENSE.

Disclaimer

This tool is under active development. While stable for everyday use, expect new features and improvements in future releases.

Changelog

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

About

A GitHub CLI extension that displays CI status next to commit logs. It shows recent commits with inline summary icons indicating GitHub Check/Actions status (βœ… green, ❌ failing, πŸ•“ pending, or 🚫 cancelled).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Sponsor this project

Contributors

Languages