Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .claude/skills/ci/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Monitor GitHub Actions CI across both repos after a push. Always run in backgrou
- `/ci` — monitor the most recent CI run on both repos for the current branch
- `/ci pgxntool-test` — monitor pgxntool-test only
- `/ci pgxntool` — monitor pgxntool only
- `/ci <branch> <pgxntool-sha> <pgxntool-test-sha>` — monitor specific push SHAs (most reliable)
- `/ci both <branch> <pgxntool-test-sha> <pgxntool-sha>` — monitor specific push SHAs (most reliable)

## Workflow

Expand All @@ -41,9 +41,11 @@ When pushing to both repos, always pass the SHAs to avoid a race condition where

> **Race condition note**: `gh run list --branch` returns the most recent run on
> that branch — if two pushes happen close together (e.g. two sessions pushing
> in parallel), it may pick up the wrong run. Passing `--commit SHA` targets the
> exact push and avoids this. When SHA is unavailable, always verify the
> `=== BRANCHES: ===` line in the output matches the code you pushed.
> in parallel), it may pick up the wrong run. Passing the `sha1`/`sha2`
> positional arguments above lets the script resolve the run via `gh run list
> --commit` internally, targeting the exact push and avoiding this — the
> script itself has no `--commit` flag. When SHA is unavailable, always verify
> the `=== BRANCHES: ===` line in the output matches the code you pushed.

**Always use `run_in_background: true`.**

Expand Down
11 changes: 11 additions & 0 deletions .claude/skills/ci/scripts/monitor-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@

set -euo pipefail

# Purely positional args, no flags (see the header comment above) - catch a
# "--commit SHA"-style invocation here instead of letting it silently
# misparse into REPOS="--commit" (falls through to the "both" default) with
# the SHA itself landing in BRANCH, which then polls a nonexistent branch
# until timeout.
if [[ "${1:-}" == --* ]]; then
echo "monitor-ci.sh takes positional args, not flags: [repos] [branch] [sha_pgxntool_test] [sha_pgxntool]" >&2
echo "Got '$1' where 'repos' was expected. See the /ci skill's Usage section." >&2
exit 64
fi

REPOS="${1:-both}"
BRANCH="${2:-$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")}"
SHA_TEST="${3:-}"
Expand Down
12 changes: 7 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ convention in `../ai/CLAUDE.md`:
for each repo — do not monitor them sequentially.
- Always use the `/ci` skill (`bash .claude/skills/ci/scripts/monitor-ci.sh`)
rather than raw `gh run`/`gh pr checks` calls — it derives the owner from
the current repo and monitors both. Pass the exact push SHA when
available — `gh run list --branch` has a race condition: if two pushes
land close together on the same branch (e.g., two Claude sessions pushing
in parallel), `--branch` may pick up the wrong run. `--commit SHA` targets
the exact push and avoids this.
the current repo and monitors both. Pass the exact push SHA(s) as
positional arguments when available (see the `/ci` skill for exact
usage — the script takes `[repos] [branch] [sha_pgxntool_test]
[sha_pgxntool]`, not a `--commit` flag) — `gh run list --branch` has a
race condition: if two pushes land close together on the same branch
(e.g., two Claude sessions pushing in parallel), `--branch` may pick up
the wrong run. An exact SHA targets the push directly and avoids this.
- **After every monitor run, check the `=== BRANCHES: pgxntool=X
pgxntool-test=Y ===` line** to verify the right code is under test. If the
branches don't match what you pushed, cancel the run and re-trigger.
Expand Down
Loading