{"id":39918056,"url":"https://github.com/xpepper/gh-log-ci","last_synced_at":"2026-01-18T17:05:53.742Z","repository":{"id":320261948,"uuid":"1081439988","full_name":"xpepper/gh-log-ci","owner":"xpepper","description":"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).","archived":false,"fork":false,"pushed_at":"2026-01-11T12:10:27.000Z","size":1454,"stargazers_count":0,"open_issues_count":13,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-01-11T15:31:10.897Z","etag":null,"topics":["bash","cli","continuous-integration","gh-extension"],"latest_commit_sha":null,"homepage":"https://github.com/xpepper/gh-log-ci","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xpepper.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"custom":["https://www.paypal.me/pierodibello"]}},"created_at":"2025-10-22T19:35:29.000Z","updated_at":"2026-01-11T12:06:35.000Z","dependencies_parsed_at":"2025-10-22T21:34:17.518Z","dependency_job_id":null,"html_url":"https://github.com/xpepper/gh-log-ci","commit_stats":null,"previous_names":["xpepper/gh-log-ci"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/xpepper/gh-log-ci","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpepper%2Fgh-log-ci","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpepper%2Fgh-log-ci/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpepper%2Fgh-log-ci/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpepper%2Fgh-log-ci/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xpepper","download_url":"https://codeload.github.com/xpepper/gh-log-ci/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xpepper%2Fgh-log-ci/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28543708,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T14:59:57.589Z","status":"ssl_error","status_checked_at":"2026-01-18T14:59:46.540Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","cli","continuous-integration","gh-extension"],"created_at":"2026-01-18T17:05:53.610Z","updated_at":"2026-01-18T17:05:53.728Z","avatar_url":"https://github.com/xpepper.png","language":"Shell","funding_links":["https://www.paypal.me/pierodibello"],"categories":["🆕 Recently Updated"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/gh-log-ci-banner.png\" alt=\"gh-log-ci logo and example output\" width=\"340\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003egh-log-ci\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\u003cem\u003eA GitHub CLI extension that shows CI status next to commit logs\u003c/em\u003e\u003c/p\u003e\n\n`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.\n\n## Quickstart\n\n`gh log-ci` works with GitHub.com and GitHub Enterprise Server (any version that supports Checks API).\n\n1. Install [GitHub CLI](https://cli.github.com/)\n2. Authenticate: `gh auth login`\n3. (Optional) Ensure you have access to private repos you care about\n4. Install the extension: `gh extension install xpepper/gh-log-ci` (or `gh extension install .` from local checkout)\n5. Run: `gh log-ci` on a GitHub repo\n6. Profit! ✅ 🚀\n\n## Usage\n\nBasic usage (auto-detect default branch):\n```shell\ngh log-ci\n```\n\n### Flags\n```\n  --branch \u003cname\u003e        Use a specific branch (overrides auto-detect)\n  --limit, -n \u003cn\u003e        Number of commits to display (default: 15; env LOG_CI_LIMIT)\n  --concurrency, -c \u003cn\u003e  Parallel API calls (default: 4; env LOG_CI_CONCURRENCY)\n  --checks, -C           Show per-check run summaries\n  --no-spinner           Disable loading spinner (env LOG_CI_NO_SPINNER=1)\n  --api-timeout \u003csecs\u003e   Max seconds per API request (default: 30; env LOG_CI_API_TIMEOUT)\n  --watch                Continuously poll and update commit statuses\n  --watch-interval \u003cs\u003e   Seconds between polls in watch mode (default: 10; env LOG_CI_WATCH_INTERVAL)\n  --no-cache             Ignore success cache, force fresh API calls for all commits\n  --use-rest             Force REST API mode, bypass GraphQL (env LOG_CI_FORCE_REST=1)\n  --help, -h             Show help / usage\n  --version              Show version\n```\n\nHelp example:\n```shell\n$ gh log-ci --help\ngh log-ci - show CI status next to recent commits\n\nUsage:\n  gh log-ci [options] [\u003cbranch\u003e|\u003ccommit-sha\u003e]\n\nOptions:\n  --branch \u003cname\u003e        Branch to inspect (alternative to positional \u003cbranch\u003e)\n  --limit, -n \u003cn\u003e        Number of commits to display (default: 15; env LOG_CI_LIMIT)\n  --concurrency, -c \u003cn\u003e  Parallel API calls (default: 4; env LOG_CI_CONCURRENCY)\n  --checks, -C           Show per-check run summaries\n  --no-spinner           Disable loading spinner (env LOG_CI_NO_SPINNER=1)\n  --api-timeout \u003csecs\u003e   Max seconds per API request (default: 30; env LOG_CI_API_TIMEOUT)\n  --use-rest             Force REST API mode, bypass GraphQL (env LOG_CI_FORCE_REST=1)\n  --help, -h             Show this help text\n  --version              Show version\n  --no-cache             Ignore success cache, force fresh API calls for all commits\n\n```\n\nSpecify a branch explicitly:\n```shell\ngh log-ci release-branch\n```\nBranch resolution order when no argument is provided:\n1. GitHub default branch (`gh repo view --json defaultBranchRef --jq .defaultBranchRef.name`)\n2. `master` if present\n3. `main` if present\n4. Current local HEAD branch\n\n### Commit SHA Mode\n\nYou can also pass a commit SHA (full or short) to check the CI status of a single commit:\n\n```shell\n# Full commit SHA\ngh log-ci 1055e83327fe2415e117ec67fbc8412f9093504f\n\n# Short commit SHA (at least 7 characters)\ngh log-ci 1055e83\n\n# Using git rev-parse output\ngh log-ci $(git rev-parse HEAD~5)\n```\n\nIn commit SHA mode:\n- Shows exactly 1 commit (the specified SHA)\n- No remote branch warnings\n- Works with both GraphQL (default) and REST API modes (`--use-rest`)\n- Accepts both full 40-character SHAs and short SHAs (≥7 characters)\n\n\n## Output Example\n```\n$ gh log-ci\n✅  49b3e7623 - (HEAD -\u003e master, origin/master, origin/HEAD) refactor(component): improve caching (Wed Oct 22 15:15:13 2025 +0200) \u003cJane Doe\u003e\n❌  c4f35260a - feat(auth): add MFA (Wed Oct 22 09:25:09 2025 +0200) \u003cJohn Smith\u003e\n🕓  a390e5998 - chore(deps): bump library (Tue Oct 21 16:52:40 2025 +0200) \u003cdependabot[bot]\u003e\n```\n\n## Icons Legend\n| Icon | Meaning |\n|------|---------|\n| ✅ | All completed check runs succeeded (no failures/pending) |\n| ❌ | At least one failing/timed_out/action_required check run |\n| 🕓 | One or more check runs still in progress / queued and no failures yet |\n| 🔁 | Queued run blocked by earlier in-progress run of same workflow |\n| 🚫 | One or more cancelled runs and no failures/pending (takes precedence over success) |\n| ⚠ | Mixed: successes and failures both present |\n| ⏲ | Timed out while fetching check runs (API didn't respond within --api-timeout) |\n| ➖ | Neutral/skipped/stale (shown only in per-check detail) |\n| 🤖 | Non-push workflow (excluded from status aggregation) |\n| ❔ | Fallback / unknown state |\n\n## Features\n| Capability | Description |\n|------------|-------------|\n| Auto branch | Detects default branch, falls back to master/main/HEAD |\n| Commit SHA mode | Check CI status for a single commit by SHA (full or short) |\n| Status aggregation | Smarter overall icon (pending vs all-green vs mixed failure) |\n| GraphQL batch query | Single batch query fetches all commit statuses (use --use-rest for REST API mode) |\n| Per-check summaries | Optional detailed list via `--checks` / `LOG_CI_SHOW_CHECKS=1` |\n| Parallel fetching | Concurrency-controlled API calls (`--concurrency`) |\n| Colorized log | Mirrors `git log` pretty format with colors |\n| Lightweight | Single Bash script, no external deps beyond `gh` |\n| Progress spinner | Shows animated spinner with live completed/total count (disable with --no-spinner) |\n| API timeouts | Per-request timeout preventing hangs (`--api-timeout`, shows ⏲ on timeout) |\n| Watch mode | Continuously polls to surface new commits and evolving statuses (`--watch`, `--watch-interval`) |\n| Success caching | Skips API calls for commits already successful within TTL (success-only, configurable) |\n| Blocked detection | Distinguishes queued runs blocked by in-progress workflow (🔁 icon) |\n| Event-based filtering | Excludes non-push workflows from status aggregation while keeping them visible with `-C` |\n\n## Event-Based Filtering\n\nBy 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.\n\nGitHub 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.\n\n**Excluded checks are still displayed** when using the `-C` flag, marked with a 🤖 icon and `[non-push]` label for visibility.\n\nThis behavior matches GitHub's `statusCheckRollup` logic, which only includes checks from `push` events.\n\n## Permissions\n\n`gh log-ci` uses the credentials configured via [`gh auth login`](https://cli.github.com/manual/gh_auth_login) or any supported `gh` environment variables. Required scopes depend on what you want to read:\n\nTypical token (user) scopes:\n- `repo` (private repository commit metadata \u0026 checks)\n- `read:org` (if accessing private org repos)\n\nGitHub App / server-to-server tokens need read access to:\n- Repository Contents\n- Repository Metadata\n- Actions / Checks (implicitly via Checks API)\n\nIf you see authentication errors, re-run:\n```shell\ngh auth status\ngh auth login\n```\n\n## How It Works\n1. Determines input type (branch name or commit SHA).\n2. **For branch mode**: Fetches commits from `origin/\u003cbranch\u003e`. **For commit SHA mode**: Validates and resolves the SHA.\n3. Emits a tab-delimited `git log` (single commit for SHA mode, last 15 for branch mode).\n4. **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.\n5. **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:\n   - GitHub Enterprise Server versions \u003c 3.4 (GraphQL Checks API unavailable)\n   - Commits with \u003e100 check suites (GraphQL query limit)\n   - Troubleshooting or comparing GraphQL vs REST behavior\n6. Maps combined conclusions to an icon and prints decorated line.\n\n### When to Use REST Mode\n\nBy default, `gh log-ci` uses GraphQL batch queries for optimal performance. Use REST mode (`--use-rest` or `LOG_CI_FORCE_REST=1`) when:\n\n- **GitHub Enterprise Server \u003c 3.4**: GraphQL Checks API not available on older GHES versions\n- **Commits with \u003e100 check suites**: GraphQL query limited to 100 check suites per commit\n- **GraphQL errors**: If you encounter GraphQL API errors, the tool will suggest using `--use-rest` as a workaround\n- **Debugging**: Comparing behavior between GraphQL and REST API responses\n\nExample:\n```shell\n# Force REST API mode with flag\ngh log-ci --use-rest\n\n# Force REST API mode with environment variable\nLOG_CI_FORCE_REST=1 gh log-ci\n\n# Combine with other options\ngh log-ci --use-rest --concurrency 8 --limit 20\n```\n\n## Configuration (Current)\n- Branch: positional argument or `--branch` (auto-detected if omitted).\n- Commit count: `--limit` / `-n` (default 15) or environment `LOG_CI_LIMIT`.\n- Concurrency: `--concurrency` / `-c` (default 4) or environment `LOG_CI_CONCURRENCY`.\n- Per-check detail: `--checks` / `-C` or environment `LOG_CI_SHOW_CHECKS=1`.\n- Spinner: disable with `--no-spinner` or `LOG_CI_NO_SPINNER=1`.\n- API request timeout: `--api-timeout \u003csecs\u003e` (default 30) or `LOG_CI_API_TIMEOUT`.\n- Watch mode: `--watch` continuously refresh; `--watch-interval \u003cs\u003e` (default 10) or `LOG_CI_WATCH_INTERVAL`.\n- 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`.\n- Cache bypass: `--no-cache` to force fresh API calls for all commits.\n- Event-based filtering: Non-push workflows excluded from status aggregation; excluded checks displayed with `-C` marked as `[non-push]`.\n- REST API mode: `--use-rest` flag or `LOG_CI_FORCE_REST=1` to bypass GraphQL (required for GHES \u003c3.4).\n\n## Limitations\n- Per-check summaries increase output size (consider piping/grep).\n- Neutral/skipped/stale checks don't affect overall icon yet.\n- No JSON / alternative formats yet.\n- Assumes `origin` remote name.\n- GraphQL queries limited to 100 check suites per commit (use `--use-rest` for commits with \u003e100 suites).\n\n## Roadmap\n- Rate-limit handling with backoff + user notice.\n- Workflow names and URLs (opt-in with a flag).\n- Filtering: author, status, date range, grep on commit message.\n- Semantic versioning policy (documented in README).\n\n## Testing\nWe use [bats](https://github.com/bats-core/bats-core) for basic behavioral tests and [shellcheck](https://www.shellcheck.net/) for static analysis.\n\nRun locally:\n```bash\nshellcheck gh-log-ci\nbats tests\n```\nCI runs automatically on pushes / PRs (see `.github/workflows/ci.yml`).\n\nConvenience local CI script (runs both):\n```bash\n./ci-local.sh\n```\n\nWithout Homebrew (alternative via Docker):\n```bash\ndocker run --rm -v \"$PWD\":/work -w /work ubuntu:22.04 bash -c \\\n  \"apt-get update \u0026\u0026 apt-get install -y bats shellcheck git \u0026\u0026 bats tests\"\n```\n\n## Makefile Tasks\n\nFor easier development and maintenance, this project includes a Makefile with common tasks:\n\n```bash\nmake help              # List all available tasks\nmake test              # Run all tests (shellcheck + bats)\nmake shellcheck        # Run shellcheck only\nmake bats              # Run bats tests only\nmake ci-local          # Run local CI script\nmake clean-cache       # Remove all cache files\nmake list-cache        # List cache files\n```\n\nSee `make help` for a complete list of available tasks.\n\n## Contributing\n1. Fork and clone.\n2. Create a feature branch.\n3. Make changes + add tests (when available).\n4. Open a PR.\n\n## Troubleshooting\n| Issue | Suggestion |\n|-------|------------|\n| Remote URL error | Ensure you're inside a GitHub repo with an `origin` remote |\n| Auth errors | Run `gh auth status` then `gh auth login` |\n| All 🕓 icons | Checks not started yet or using legacy status API |\n| GraphQL errors | Try `--use-rest` flag to bypass GraphQL (required for GHES \u003c3.4) |\n| Slow output | Use GraphQL mode (default) for best performance; reduce `--limit` if needed |\n\n## License\nSee `LICENSE`.\n\n## Disclaimer\nThis tool is under active development. While stable for everyday use, expect new features and improvements in future releases.\n\n## Changelog\n\n| Version | Date | Notes |\n|---------|------|-------|\n| 0.7.0 | 2026-01-06 | GraphQL batch query (93% API call reduction); `--use-rest` flag for GHES \u003c3.4 compatibility; 54% faster for 15+ commits |\n| 0.6.0 | 2025-11-17 | Distinguish blocked queued runs (🔁 icon); update legend \u0026 features |\n| 0.5.0 | 2025-11-04 | Add --no-cache flag to bypass success cache and force fresh API calls |\n| 0.4.1 | 2025-10-23 | Success-only caching (TTL, dir config, debug env) skips API calls for cached successes |\n| 0.4.0 | 2025-10-22 | Watch mode (`--watch`, `--watch-interval`); refactored core for repeated polling |\n| 0.3.4 | 2025-10-22 | Progress-aware spinner (`--no-spinner`) option (shows completed/total); per-request `--api-timeout` with ⏲ icon on timeout |\n| 0.3.3 | 2025-10-22 | Removed header banner from output for compact display |\n| 0.3.2 | 2025-10-22 | Cancelled status precedence fix (show 🚫 when any cancelled and no failures) |\n| 0.3.1 | 2025-10-22 | Added tests (bats) \u0026 CI workflow (shellcheck + tests) |\n| 0.3.0 | 2025-10-22 | Per-check summaries (`--checks`) and richer status aggregation |\n| 0.2.0 | 2025-10-22 | Concurrency flag (`--concurrency`) parallel API calls |\n| 0.1.0 | 2025-10-22 | Basic functionality with branch auto-detect \u0026 limit |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxpepper%2Fgh-log-ci","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxpepper%2Fgh-log-ci","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxpepper%2Fgh-log-ci/lists"}