Claude Skill

ci

Monitor the CI pipeline for the current branch via a background Monitor script (GitHub or GitLab), reacting to pass, fail, and manual-gate states. Use when the user says 'watch CI', 'monitor the pipeline', 'is CI green', or after pushing a branch or creating a PR/MR.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download domengabrovsek-claude-skills_ci-48da5d0.zip · 4 KB
Part of domengabrovsek/claude — 41 skills

Install

skills CLI npx skills add https://github.com/domengabrovsek/agent-config/tree/main/skills/ci
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install domengabrovsek-claude@llmmart
Git git clone https://github.com/domengabrovsek/agent-config.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole domengabrovsek/claude collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Monitor CI Pipeline

Workflow

why-no-hook: skill workflow guidance; each step requires understanding the surrounding context (repo, task shape, prior state).

  1. Detect VCS platform: .gitlab-ci.yml -> glab, .github/ -> gh (review-time: see section note)
  2. Start a Monitor with the matching script: (review-time: see section note)
    • GitHub: bash scripts/gh-ci-monitor.sh, resolved inside this skill's own directory (review-time: see section note)
    • GitLab: bash scripts/glab-ci-monitor.sh, resolved inside this skill's own directory (review-time: see section note)
    • Use timeout_ms: 1800000, the Monitor maximum of 30 minutes (review-time: see section note)
    • Description: "CI pipeline on
  3. React to Monitor notifications: (review-time: see section note)
    • Monitor expiry before a completed|* status: re-arm the same script, since CI pipelines can outlast 30 minutes. The restarted script re-emits the current status (review-time: see section note)
    • no-runs|<branch>: no CI runs found for this branch - inform the user and stop (review-time: see section note)
    • error|persistent-failure: the monitor script hit 5 consecutive errors - report and stop (review-time: see section note)
    • Status change (e.g., in_progress|null → completed|success): acknowledge briefly (review-time: see section note)
    • Pipeline passes (completed|success): (review-time: see section note)
      • Run ~/.agents/scripts/notify.sh "CI passed - <branch-name>" (review-time: see section note)
      • Report success (review-time: see section note)
    • Pipeline awaiting manual action (completed|manual, GitLab only): (review-time: see section note)
      • All automatic jobs completed; the pipeline is paused on a manual gate and will not progress without user action (review-time: see section note)
      • Run ~/.agents/scripts/notify.sh "CI awaiting manual action - <branch-name>" (review-time: see section note)
      • Report status and stop watching - do NOT trigger the manual job automatically (review-time: see section note)
    • Pipeline fails (completed|failure or any non-success conclusion): (review-time: see section note)
      1. Fetch the job log:
        • GitLab: glab ci trace <job-id> (review-time: see section note)
        • GitHub: gh run view <run-id> --log-failed (review-time: see section note)
      2. Do NOT pipe output through head, tail, grep, or any other command - run the commands directly
      3. Analyze the root cause - identify the specific failure (test, lint, type check, build, coverage, etc.)
      4. Classify the failure as transient or real before proposing any change - transient = infra outage, rate limit, queued/timed-out runner, auth/network flake, registry or dependency propagation delay; real = a test/lint/type/build/coverage failure caused by the code under change. State the classification (review-time: see section note)
      5. If transient: re-run the failed job (gh run rerun <run-id> --failed / glab ci retry <job-id>) and keep monitoring - do NOT edit code for a transient failure. Escalate to the user only if it recurs after a re-run (review-time: see section note)
      6. Run ~/.agents/scripts/notify.sh "CI failed - <failure-summary>"
      7. If real, fix it: make the change, run /verify-done, commit with a descriptive message, push, and keep monitoring (review-time: see section note)
      8. Report what failed and what changed in the same message as the next action (review-time: see section note)

How it works

The monitor scripts poll CI status every 30 seconds but only emit a line when the status changes. This means:

  • Zero token cost while the pipeline is running and status hasn't changed (review-time: see section note)
  • Claude reacts within ~30s of a status change (vs up to 2 min with /loop) (review-time: see section note)
  • No CronDelete cleanup needed - the script exits on terminal state, ending the Monitor (review-time: see section note)
  • If gh/glab fails 5 times in a row (auth expired, network down), the script exits with an error notification (review-time: see section note)

Important: Non-interactive commands only

These commands require a TTY and will NOT work - never use them:

  • glab ci view (interactive TUI) (review-time: see section note)
  • gh run watch (interactive watcher) (review-time: see section note)
  • Any command with --web flag (opens browser) (review-time: see section note)

Safe commands to use:

  • glab ci status, glab ci list, glab ci trace <job-id> (review-time: see section note)
  • gh pr checks, gh run list, gh run view <run-id> --log-failed (review-time: see section note)

Guardrails

  • After 3 consecutive failures on the same issue, stop and escalate - something structural is wrong (review-time: see section note)
  • Never weaken tests, skip linting, or lower coverage thresholds to make CI pass (review-time: see section note)
  • Never use --no-verify or skip hooks (review-time: see section note)
  • A failure unrelated to your changes (flaky test, infra issue) is transient: re-run it per step e, and do not edit code for it (review-time: see section note)
Files (claude)
  • scripts
    • gh-ci-monitor.sh 2.5 KB
      #!/usr/bin/env bash
      # Monitor GitHub CI status for the current branch.
      # Uses `gh pr checks` to aggregate ALL checks for the PR.
      # Falls back to `gh run list` (all runs, not just one) when no PR exists.
      # Emits a line to stdout ONLY when status changes.
      # Exits when the pipeline reaches a terminal state.
      set -uo pipefail
      # Note: no -e - gh pr checks uses non-standard exit codes (8 = pending)
      # that would terminate the script under errexit
      
      branch=$(git branch --show-current)
      pr_number=$(gh pr view --json number --jq '.number' 2>/dev/null) || pr_number=""
      prev=""
      error_count=0
      
      while true; do
        if [ -n "$pr_number" ]; then
          # Primary path: aggregate all PR checks via gh pr checks
          gh pr checks "$pr_number" >/dev/null 2>&1
          ec=$?
          case $ec in
            0) cur="completed|success" ;;
            1) cur="completed|failure" ;;
            8) cur="in_progress|null" ;;
            *) cur="error|exit-$ec" ;;
          esac
        else
          # Fallback: no PR yet - check ALL runs for the branch, not just one
          lines=$(gh run list --branch "$branch" --json status,conclusion \
            --jq '.[] | "\(.status)|\(.conclusion)"' 2>/dev/null) || lines=""
      
          if [ -z "$lines" ]; then
            echo "no-runs|$branch"
            exit 0
          fi
      
          # Aggregate: any in_progress → in_progress; any failure → failure; all success → success
          has_pending=false
          has_failure=false
          all_completed=true
      
          while IFS='|' read -r status conclusion; do
            if [ "$status" != "completed" ]; then
              all_completed=false
              has_pending=true
            elif [ "$conclusion" != "success" ] && [ "$conclusion" != "skipped" ]; then
              has_failure=true
            fi
          done <<< "$lines"
      
          if [ "$all_completed" = true ] && [ "$has_failure" = true ]; then
            cur="completed|failure"
          elif [ "$all_completed" = true ]; then
            cur="completed|success"
          elif [ "$has_pending" = true ]; then
            cur="in_progress|null"
          else
            cur="error|unknown"
          fi
      
          # Re-check for PR in case it was created after push
          pr_number=$(gh pr view --json number --jq '.number' 2>/dev/null) || pr_number=""
        fi
      
        # Track consecutive errors
        if [[ "$cur" == error* ]]; then
          error_count=$((error_count + 1))
          if [ "$error_count" -ge 5 ]; then
            echo "error|persistent-failure"
            exit 1
          fi
        else
          error_count=0
        fi
      
        if [ "$cur" != "$prev" ]; then
          echo "$cur"
          prev="$cur"
          # Exit on any completed status regardless of conclusion
          if [[ "$cur" == completed\|* ]]; then
            exit 0
          fi
        fi
      
        sleep 30
      done
      
    • glab-ci-monitor.sh 1.7 KB
      #!/usr/bin/env bash
      # Monitor GitLab CI status for the current branch.
      # Emits a line to stdout ONLY when status changes.
      # Exits when the pipeline reaches a terminal state.
      set -euo pipefail
      
      prev_state=""
      prev_first=""
      error_count=0
      
      while true; do
        raw=$(glab ci status 2>/dev/null) || raw=""
      
        if [ -z "$raw" ]; then
          error_count=$((error_count + 1))
          if [ "$error_count" -ge 5 ]; then
            echo "error|persistent-failure"
            exit 1
          fi
          sleep 30
          continue
        fi
        error_count=0
      
        # Source of truth: the trailing "Pipeline state: <state>" line.
        # `glab ci status` lists jobs above it; the first job line can be a
        # `manual`/`skipped` outlier that does not reflect overall progress.
        # Take the LAST match via awk's END block (no SIGPIPE risk under
        # pipefail) and strip the label prefix so we tolerate extra fields.
        state_line=$(awk '/^Pipeline state:/ { line = $0 } END { print line }' <<<"$raw")
        state="${state_line##*: }"
        first="${raw%%$'\n'*}"
      
        if [ "$first" != "$prev_first" ]; then
          echo "$first"
          prev_first="$first"
        fi
      
        if [ "$state" != "$prev_state" ] && [ -n "$state" ]; then
          case "$state" in
            success|failed|canceled|skipped|manual)
              # Terminal from the monitor's POV: nothing more will happen
              # automatically. `manual` means all automatic jobs completed and
              # the pipeline is paused on a manual gate awaiting human action,
              # so treat it as semi-done and stop watching.
              # Emit a structured marker so the consumer can branch on outcome
              # without re-parsing glab's free-form job lines. Mirrors the
              # `completed|<conclusion>` contract of gh-ci-monitor.sh.
              echo "completed|$state"
              exit 0
              ;;
          esac
          prev_state="$state"
        fi
      
        sleep 30
      done
      
  • SKILL.md 5.5 KB
    ---
    name: ci
    description: "Monitor the CI pipeline for the current branch via a background Monitor script (GitHub or GitLab), reacting to pass, fail, and manual-gate states. Use when the user says 'watch CI', 'monitor the pipeline', 'is CI green', or after pushing a branch or creating a PR/MR."
    ---
    
    # Monitor CI Pipeline
    
    ## Workflow
    
    **why-no-hook:** skill workflow guidance; each step requires understanding the surrounding context (repo, task shape, prior state).
    
    1. **Detect VCS platform**: `.gitlab-ci.yml` -> glab, `.github/` -> gh `(review-time: see section note)`
    2. **Start a Monitor** with the matching script: `(review-time: see section note)`
       - GitHub: `bash scripts/gh-ci-monitor.sh`, resolved inside this skill's own directory `(review-time: see section note)`
       - GitLab: `bash scripts/glab-ci-monitor.sh`, resolved inside this skill's own directory `(review-time: see section note)`
       - Use `timeout_ms: 1800000`, the Monitor maximum of 30 minutes `(review-time: see section note)`
       - Description: "CI pipeline on <branch-name>" `(review-time: see section note)`
    3. **React to Monitor notifications**: `(review-time: see section note)`
       - Monitor expiry before a `completed|*` status: re-arm the same script, since CI pipelines can outlast 30 minutes. The restarted script re-emits the current status `(review-time: see section note)`
       - `no-runs|<branch>`: no CI runs found for this branch - inform the user and stop `(review-time: see section note)`
       - `error|persistent-failure`: the monitor script hit 5 consecutive errors - report and stop `(review-time: see section note)`
       - Status change (e.g., `in_progress|null` → `completed|success`): acknowledge briefly `(review-time: see section note)`
       - **Pipeline passes** (`completed|success`): `(review-time: see section note)`
         - Run `~/.agents/scripts/notify.sh "CI passed - <branch-name>"` `(review-time: see section note)`
         - Report success `(review-time: see section note)`
       - **Pipeline awaiting manual action** (`completed|manual`, GitLab only): `(review-time: see section note)`
         - All automatic jobs completed; the pipeline is paused on a manual gate and will not progress without user action `(review-time: see section note)`
         - Run `~/.agents/scripts/notify.sh "CI awaiting manual action - <branch-name>"` `(review-time: see section note)`
         - Report status and stop watching - do NOT trigger the manual job automatically `(review-time: see section note)`
       - **Pipeline fails** (`completed|failure` or any non-success conclusion): `(review-time: see section note)`
         a. Fetch the job log:
            - GitLab: `glab ci trace <job-id>` `(review-time: see section note)`
            - GitHub: `gh run view <run-id> --log-failed` `(review-time: see section note)`
         b. Do NOT pipe output through head, tail, grep, or any other command - run the commands directly
         c. Analyze the root cause - identify the specific failure (test, lint, type check, build, coverage, etc.)
         d. **Classify the failure as transient or real before proposing any change** - transient = infra outage, rate limit, queued/timed-out runner, auth/network flake, registry or dependency propagation delay; real = a test/lint/type/build/coverage failure caused by the code under change. State the classification `(review-time: see section note)`
         e. **If transient**: re-run the failed job (`gh run rerun <run-id> --failed` / `glab ci retry <job-id>`) and keep monitoring - do NOT edit code for a transient failure. Escalate to the user only if it recurs after a re-run `(review-time: see section note)`
         f. Run `~/.agents/scripts/notify.sh "CI failed - <failure-summary>"`
         g. **If real, fix it**: make the change, run `/verify-done`, commit with a descriptive message, push, and keep monitoring `(review-time: see section note)`
         h. Report what failed and what changed in the same message as the next action `(review-time: see section note)`
    
    ## How it works
    
    The monitor scripts poll CI status every 30 seconds but only emit a line when the status **changes**. This means:
    
    - Zero token cost while the pipeline is running and status hasn't changed `(review-time: see section note)`
    - Claude reacts within ~30s of a status change (vs up to 2 min with /loop) `(review-time: see section note)`
    - No CronDelete cleanup needed - the script exits on terminal state, ending the Monitor `(review-time: see section note)`
    - If `gh`/`glab` fails 5 times in a row (auth expired, network down), the script exits with an error notification `(review-time: see section note)`
    
    ## Important: Non-interactive commands only
    
    These commands require a TTY and will NOT work - never use them:
    
    - `glab ci view` (interactive TUI) `(review-time: see section note)`
    - `gh run watch` (interactive watcher) `(review-time: see section note)`
    - Any command with `--web` flag (opens browser) `(review-time: see section note)`
    
    Safe commands to use:
    
    - `glab ci status`, `glab ci list`, `glab ci trace <job-id>` `(review-time: see section note)`
    - `gh pr checks`, `gh run list`, `gh run view <run-id> --log-failed` `(review-time: see section note)`
    
    ## Guardrails
    
    - After 3 consecutive failures on the **same issue**, stop and escalate - something structural is wrong `(review-time: see section note)`
    - Never weaken tests, skip linting, or lower coverage thresholds to make CI pass `(review-time: see section note)`
    - Never use `--no-verify` or skip hooks `(review-time: see section note)`
    - A failure unrelated to your changes (flaky test, infra issue) is transient: re-run it per step e, and do not edit code for it `(review-time: see section note)`
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related