Skip to content
Merged
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: 5 additions & 5 deletions .claude/skills/codetrial-contribute/collaboration.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ triage's outdated ones.
## Make CI green before asking for review

"Before asking someone to review, you MUST resolve any regressions flagged by
GitHub Actions." (#256, #260). Open the failing `gates (<lane>)` job, not
`check` (`.claude/skills/codetrial-verify/ci-failure.sh <pr>` names the failed
gates and whether `main` fails them too), and rerun that lane with
`./scripts/test.sh <lane>`
([codetrial-verify](../codetrial-verify/SKILL.md) describes the lanes). A bad
GitHub Actions." (#256, #260). Open the failing job, not `check`
([codetrial-verify](../codetrial-verify/SKILL.md) says which one, and
`.claude/skills/codetrial-verify/ci-failure.sh <pr>` names the failed gates and
whether `main` fails them too), and rerun a failing lane with
`./scripts/test.sh <lane>`. A bad
commit message skips the rest of the portable lane, so fix the messages
first.

Expand Down
6 changes: 3 additions & 3 deletions .claude/skills/codetrial-triage/pulls.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,9 @@ last; a stale base is a rebase request; one `main` shares, or an environment
limit, is the maintainer's. The sweep's `status` lists them (`failing:` in
`why`), and `ci-failure.sh` in
[codetrial-verify](../codetrial-verify/SKILL.md#failed-github-actions-checks)
tells those cases apart for one PR in one call. Read the failing
`gates (<lane>)` job, not `check` or `mutation`, which only collect results ([codetrial-verify](../codetrial-verify/SKILL.md)
describes the lanes). A failing commit-message check skips the rest of the
tells those cases apart for one PR in one call. Read the failing job that
[codetrial-verify](../codetrial-verify/SKILL.md) names, not `check`, which only
collects results. A failing commit-message check skips the rest of the
portable lane, so name it first. A second PR
from the same author for the same change supersedes the first or is superseded
by it; report which in the sweep output and leave the
Expand Down
20 changes: 10 additions & 10 deletions .claude/skills/codetrial-verify/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ make check # every gate, plus a live Gemini credential check

CI runs one `gates (<lane>)` job per lane in parallel: `gates (rust)`,
`gates (portable)` and `gates (browser)`. The `check` job only collects their
results and `mutation` does the same for the mutant shards, so neither log
says what failed: open the failing lane, or the failing `mutants` shard when
`mutation` is the red one. On a pull request the portable lane
checks the commit messages first, and a bad message skips the rest of that
lane only. A gate names its lane where it is declared, one naming none is
portable, and a test proves the three lanes together cover the full run.
results and the mutation jobs', so its log does not say what failed: open the
failing lane, or, when every lane is green, the failing `plan-mutants` job or
`mutants` shard. On a pull request the portable lane checks the commit
messages first, and a bad message skips the rest of that lane only. A gate
names its lane where it is declared, one naming none is portable, and a test
proves the three lanes together cover the full run.
Reproduce a failure with the same lane locally.

`scripts/test.sh` is a list of named gates that all run before it reports, so
Expand Down Expand Up @@ -130,7 +130,7 @@ regression check in the existing lane.

## Failed GitHub Actions checks

The lanes and the aggregate `check` and `mutation` jobs are described above;
The lanes and the aggregate `check` job are described above;
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
telling a stale base, a regression, a race and an environment limit apart is in
[collaboration.md](../codetrial-contribute/collaboration.md#make-ci-green-before-asking-for-review);
reading the job log, and why it is `--log`, is the recipe in
Expand All @@ -152,9 +152,9 @@ locally with the same head. A `cargo-audit` failure on a PR whose base predates
the advisory fix is a stale base, answered by a rebase (#334), not a code
change; `stale_base` (defined in the script's header) says exactly that, and
the PR sweep lists such a PR in `rebase` on its own. The aggregate `check` job
only collects the lanes, so its entry points at the failing `gates (<lane>)`
one. A check outside Actions has only its link, and `held` checks have no log
until a maintainer approves the run.
only collects results, so its entry points at the failing job it collected,
as in the lanes section above. A check outside Actions has only its link, and
`held` checks have no log until a maintainer approves the run.

The raw calls behind it, when one answer needs checking:

Expand Down
10 changes: 5 additions & 5 deletions .claude/skills/codetrial-verify/ci-failure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,11 @@ failing=$(printf '%s\n' "$checks" | jq -r "$defs"'.[] | select(failed)
| if $read then . else .gates = null | .errors = null | .excerpt = null end'
done | jq -s .)

# The check job only collects the lanes, so it says nothing of its own. A
# failing check outside Actions (cubic) has no gates to read, so a rebase is not
# known to clear it, and it rules a stale base out. Each gate that reads data
# from outside the tree maps to the files whose change would make the failure
# the PR's own; a gate added here needs nothing else.
# The check job only collects the lanes and the mutation jobs, so it says
# nothing of its own. A failing check outside Actions (cubic) has no gates to
# read, so a rebase is not known to clear it, and it rules a stale base out.
# Each gate that reads data from outside the tree maps to the files whose change
# would make the failure the PR's own; a gate added here needs nothing else.
printf '%s\n' "$checks" | jq --argjson failing "$failing" --arg head "$head" \
--argjson pr "$pr" --argjson meta "$meta" --argjson jobs "$main_jobs" \
"$defs"'
Expand Down
4 changes: 2 additions & 2 deletions .claude/skills/codetrial-verify/review.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ report what it reports. For each area, look for:
- Ordering. A resume racing the message it replays, a check then an act across
an await, a message handled before the state it assumes.
- Tests. A new branch no test reaches; a surviving mutant in code the diff adds
(CI's mutation job names them, as on #262; it is skipped when the diff
(CI's `mutants` shards name them, as on #262; it is skipped when the diff
changes no Rust, so `web/` code has no mutation evidence and each new branch
needs a test that reaches it); a browser test of the shapes
[SKILL.md](SKILL.md) says reviewers reject (Writing a test).
Expand Down Expand Up @@ -200,7 +200,7 @@ Past about 500 changed lines, or when several reviewers are run, split them
by lens rather than by file, each reading the whole diff for one thing: the
specification checklist; the owners in step 2; trust boundaries, workflows and
what reaches a log or a public thread; failure paths and boundaries; tests,
including what CI's mutation job says survived; and comments and messages
including what CI's `mutants` shards say survived; and comments and messages
against the register in
[codetrial-conventions](../codetrial-conventions/SKILL.md). A reviewer handed a
lens reports only that lens, so silence on the others is not a pass.
Expand Down
27 changes: 27 additions & 0 deletions .github/actions/chromium/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Install Chromium
description: Restore Playwright's Chromium and install its system libraries.

# The browser binary, not the npm package. package-lock.json pins the
# playwright version, and the version is what decides which build of Chromium
# lands in this directory. Needs `npm ci` first, since it runs that playwright.
#
# The install is one command on a cache hit too: it then only installs the
# system libraries, which are not in the cached directory. Without it the
# browser suites skip themselves and the gate passes while testing nothing.
outputs:
key:
description: The exact key, for the step that saves the browser.
value: ${{ steps.restore.outputs.cache-primary-key }}
cache-hit:
description: Whether the exact key was restored.
value: ${{ steps.restore.outputs.cache-hit }}
runs:
using: composite
steps:
- id: restore
uses: actions/cache/restore@v6
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
- shell: sh
run: npx playwright install --with-deps chromium
31 changes: 31 additions & 0 deletions .github/actions/restore-vendor/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Restore vendored bytes
description: Restore the web/vendor tree the portable lane saves.

# One definition of the key for every job that reads this cache: the gate
# lanes, the mutation shards, the release legs and the avatar check.
#
# Keyed on the whole tree, not on SHA256SUMS alone. The cached path holds the
# committed vendor files as well as the fetched ones, so a key that only reads
# the pins is unchanged when a committed file is edited: the restore then puts
# the old bytes back over the edit and verify-vendor passes on content the pull
# request does not contain. Hashing the tree costs a re-fetch when a README
# under web/vendor changes, which is the cheaper side of that trade.
#
# At restore time the directory holds only checked-out files, so the key is a
# function of the commit. No restore-keys: a stale entry here is 24 MB of bytes
# that fail their hash.
outputs:
key:
description: The exact key, for the step that saves the tree.
value: ${{ steps.restore.outputs.cache-primary-key }}
cache-hit:
description: Whether the exact key was restored.
value: ${{ steps.restore.outputs.cache-hit }}
runs:
using: composite
steps:
- id: restore
uses: actions/cache/restore@v6
with:
path: web/vendor
key: vendor-${{ hashFiles('web/vendor/**') }}
55 changes: 0 additions & 55 deletions .github/workflows/avatar.yml

This file was deleted.

Loading