Created
February 3, 2026 00:19
-
-
Save simoninglis/884482b8e808dc588779d4612c6adb90 to your computer and use it in GitHub Desktop.
Revisions
-
simoninglis created this gist
Feb 3, 2026 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,117 @@ # CI Status in tmux Status Bar Put your CI build status in your tmux status bar. Know immediately when something breaks. ``` C:✓ B:✓ D:✓ V:✓ │ 14:32 01-Feb ``` ## Why? When you're doing trunk-based development, you need to know immediately when CI fails. Not 10 minutes later when you context-switch. Not at the end of the day. The best gate is one you can't forget to check. When it's in your peripheral vision all day, you're not going to forget. ## Scripts | Script | Platform | Requires | |--------|----------|----------| | `ci-status-github.sh` | GitHub Actions | [gh CLI](https://cli.github.com) | | `ci-status-gitea.sh` | Gitea Actions | [teax](https://github.com/simoninglis/teax) | ## Setup ### 1. Download the script ```bash # GitHub users curl -o ~/.local/bin/ci-status.sh \ https://gist.githubusercontent.com/.../ci-status-github.sh chmod +x ~/.local/bin/ci-status.sh # Gitea users curl -o ~/.local/bin/ci-status.sh \ https://gist.githubusercontent.com/.../ci-status-gitea.sh chmod +x ~/.local/bin/ci-status.sh ``` ### 2. Configure the script Edit the script and set your repo: ```bash REPO="owner/repo" ``` For Gitea with self-signed certs, uncomment: ```bash export TEAX_INSECURE=1 ``` ### 3. Add to tmux In your `.tmux.conf` or session script: ```bash # Simple - just CI status set -g status-right '#(~/.local/bin/ci-status.sh) │ %H:%M' # With refresh interval (default is 15s, this sets 30s) set -g status-interval 30 ``` ### 4. Per-project scripts For multiple projects, put the script in each project and reference it: ```bash # In your tmux session setup set -g status-right '#($PROJECT_DIR/scripts/ci-status.sh) │ %H:%M' ``` ## Output | Output | Meaning | |--------|---------| | `CI:✓` | All workflows passed | | `CI:✗` | Something failed | | `CI:⏳` | Running | | `CI:-` | No runs found for this commit | | `CI:?` | Error (not in repo, API issue, etc.) | | `+3` | 3 unpushed commits (showing remote CI status) | ### Gitea multi-workflow output The Gitea script shows individual workflow status: ``` C:✓ B:✓ D:✓ V:✓ ``` Where: - `C` = ci.yml (lint, test) - `B` = build.yml - `D` = staging-deploy.yml - `V` = staging-verify.yml Customize the `WORKFLOWS` variable to match your pipeline. ## Unpushed commit indicator When your local branch is ahead of remote, the scripts show what CI actually ran (remote HEAD) plus how many commits you haven't pushed: ``` CI:✓ +3 ``` This means: "CI passed for what's on the server, but you have 3 local commits not yet pushed." ## Related - [teax](https://github.com/simoninglis/teax) - CLI for Gitea Actions (fills gaps in `tea`) - [gh CLI](https://cli.github.com) - GitHub's official CLI - Blog post: [Solo Dev Release Process](https://simoninglis.com/posts/solo-dev-release-process) - Why CI visibility matters ## License MIT This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,50 @@ #!/bin/bash # CI status for tmux status bar - Gitea Actions version # Requires: teax (https://github.com/simoninglis/teax) # # Usage: Add to tmux status bar: # set -g status-right '#(/path/to/ci-status-gitea.sh)' # # Output examples: # C:✓ B:✓ D:✓ V:✓ # All green # C:✓ B:✗ D:- V:- # Build failed # C:✓ B:✓ D:✓ V:✓ +3 # Green but 3 unpushed commits # CI:? # Error or not in git repo # Configuration - customize these REPO="owner/repo" # Your Gitea repo WORKFLOWS="C:ci.yml,B:build.yml,D:staging-deploy.yml,V:staging-verify.yml" # For self-signed certs, uncomment: # export TEAX_INSECURE=1 cd "$(git rev-parse --show-toplevel 2>/dev/null)" || { echo "CI:?"; exit 0; } LOCAL_SHA=$(git rev-parse --short HEAD 2>/dev/null) || { echo "CI:?"; exit 0; } REMOTE_SHA=$(git rev-parse --short origin/main 2>/dev/null) || { echo "CI:?"; exit 0; } get_ci_status() { local sha="$1" local result local exit_code result=$(teax -o tmux runs status -r "$REPO" --sha "$sha" --show "$WORKFLOWS" 2>/dev/null) exit_code=$? case $exit_code in 0) echo "$result" ;; # All passed 1) echo "$result" ;; # Some failed (still show status) 2) echo "$result ⏳" ;; # Running 3) echo "CI:-" ;; # No runs found *) echo "CI:?" ;; # Error esac } if [ "$LOCAL_SHA" != "$REMOTE_SHA" ]; then # Local ahead of remote - show remote status + unpushed count AHEAD_COUNT=$(git rev-list origin/main..HEAD --count 2>/dev/null || echo "?") STATUS=$(get_ci_status "$REMOTE_SHA") echo "${STATUS} +${AHEAD_COUNT}" else get_ci_status "$LOCAL_SHA" fi This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,65 @@ #!/bin/bash # CI status for tmux status bar - GitHub Actions version # Requires: gh CLI (https://cli.github.com) # # Usage: Add to tmux status bar: # set -g status-right '#(/path/to/ci-status-github.sh)' # # Output examples: # CI:✓ # Latest run passed # CI:✗ # Latest run failed # CI:⏳ # Running # CI:✓ +3 # Passed but 3 unpushed commits # CI:? # Error or not in git repo # Configuration - customize these REPO="owner/repo" # Your GitHub repo (or leave empty to auto-detect) cd "$(git rev-parse --show-toplevel 2>/dev/null)" || { echo "CI:?"; exit 0; } # Auto-detect repo from git remote if not set if [ -z "$REPO" ]; then REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null) || { echo "CI:?"; exit 0; } fi LOCAL_SHA=$(git rev-parse --short HEAD 2>/dev/null) || { echo "CI:?"; exit 0; } REMOTE_SHA=$(git rev-parse --short origin/main 2>/dev/null) || { echo "CI:?"; exit 0; } get_ci_status() { local sha="$1" local status conclusion # Get the latest workflow run for this commit read -r status conclusion < <(gh run list --repo "$REPO" --commit "$sha" --limit 1 \ --json status,conclusion -q '.[0] | "\(.status) \(.conclusion)"' 2>/dev/null) if [ -z "$status" ]; then echo "CI:-" return fi case "$status" in completed) case "$conclusion" in success) echo "CI:✓" ;; failure) echo "CI:✗" ;; cancelled) echo "CI:⊘" ;; *) echo "CI:?" ;; esac ;; in_progress|queued|waiting) echo "CI:⏳" ;; *) echo "CI:?" ;; esac } if [ "$LOCAL_SHA" != "$REMOTE_SHA" ]; then AHEAD_COUNT=$(git rev-list origin/main..HEAD --count 2>/dev/null || echo "?") STATUS=$(get_ci_status "$REMOTE_SHA") echo "${STATUS} +${AHEAD_COUNT}" else get_ci_status "$LOCAL_SHA" fi