fix(ci): assert the focused path's shard shape in the workflow contract

The workflow contract pinned the focused path by literal: the job name
`Test (changed packages)`, the unsharded
`list "$TEST_BASE_REF" "$TEST_HEAD_REF"` call, and a single
`go test -timeout=15m` line standing in for internal/app's package-level
headroom. Sharding the job changed all three literals, so `Test (workflow
and release contracts)` failed on this branch even though every shard
selection test passed.

Each invariant the contract guarded still holds, so the assertions are
updated to the new shape rather than relaxed:

- the focused job must still exist, now as the matrix job, named the way
  the contract already names `Test (race: ${{ matrix.shard }})`;
- package selection must still derive from the authoritative synthetic
  merge base/head, now with an explicit shard argument, so pointing it at
  any other ref still fails the contract;
- internal/app's headroom is asserted through the process-isolating
  helper and the per-shard budgets, mirroring the assertions already
  applied to test-race. That is stronger than the old single -timeout: it
  pins the mechanism that keeps the suite inside its budget rather than
  the number alone. release-scripts membership is asserted too, because
  its dedicated job only runs at full-suite or release-sensitive scope,
  so losing it here would silently stop testing test/scripts changes.

The shard comparisons in the focused job are quoted so that job reads
verbatim like test-race's.

Ablating the implementation one change at a time turns the contract red
in all five cases: removing the app helper call, dropping release-scripts
from the matrix, selecting from HEAD~1, collapsing the matrix back to a
single unsharded job, and dropping the cli/smoke timeout budget.
This commit is contained in:
chichuan
2026-08-15 22:58:30 +08:00
parent 308e71c783
commit c4f2ab631b
2 changed files with 30 additions and 8 deletions
+4 -4
View File
@@ -612,7 +612,7 @@ jobs:
exit 1
}
done
if [ "$TEST_SHARD" = app ]; then
if [ "$TEST_SHARD" = "app" ]; then
# A single long-lived app test process retains every constructed
# command tree in framework registries. Isolate Schema assembly and
# bounded name ranges so each process releases that state on exit.
@@ -620,7 +620,7 @@ jobs:
./scripts/ci/run-app-race-tests.sh run "${packages[0]}"
exit 0
fi
if [ "$TEST_SHARD" = release-scripts ]; then
if [ "$TEST_SHARD" = "release-scripts" ]; then
# Mirror the dedicated release-contract job: these suites shell out
# to archive tooling and are not race-instrumented there.
go test -v -count=1 -timeout=10m "${packages[@]}"
@@ -629,8 +629,8 @@ jobs:
# cli/smoke own heavy NewRootCommand / Schema assembly under -race;
# give them a dedicated package timeout on slower hosted runners.
timeout_budget=12m
if [ "$TEST_SHARD" = cli ] ||
[ "$TEST_SHARD" = smoke ]; then
if [ "$TEST_SHARD" = "cli" ] ||
[ "$TEST_SHARD" = "smoke" ]; then
timeout_budget=15m
fi
go test -v -race -count=1 -timeout="$timeout_budget" "${packages[@]}"
+26 -4
View File
@@ -1151,13 +1151,13 @@ func TestChangelogPRFastPathWorkflowContract(t *testing.T) {
"filename.startsWith('pkg/cmdutil/')",
"filename === 'skills_embed.go'",
"filename.startsWith('test/mock_mcp/')",
"name: Test (changed packages)",
`name: "Test (focused: ${{ matrix.shard }})"`,
"changed-test-packages.sh",
"Verify authoritative synthetic merge",
`test "$(git rev-parse HEAD^1)" = "$PR_BASE_SHA"`,
`test "$(git rev-parse HEAD^2)" = "$PR_HEAD_SHA"`,
`echo "TEST_HEAD_REF=$(git rev-parse HEAD)"`,
"list \"$TEST_BASE_REF\" \"$TEST_HEAD_REF\"",
`list-shard "$TEST_SHARD" "$TEST_BASE_REF" "$TEST_HEAD_REF"`,
"needs.lint.outputs.full_suite != 'true'",
`name: "Test (race: ${{ matrix.shard }})"`,
"name: Test (workflow and release contracts)",
@@ -1217,8 +1217,30 @@ func TestChangelogPRFastPathWorkflowContract(t *testing.T) {
if !strings.Contains(focusedJob, "timeout-minutes: 20") {
t.Error("focused test job must allow the scoped race suite up to 20 minutes")
}
if !strings.Contains(focusedJob, `go test -v -race -count=1 -timeout=15m "${packages[@]}"`) {
t.Error("focused race tests must retain enough package-level time for internal/app")
// The focused path fans the impacted set across the same shards as test-race
// and runs each shard the way test-race runs it, so no single job carries
// internal/app together with its reverse dependencies. internal/app keeps its
// package-level headroom through the process-isolating helper instead of one
// long -timeout, which is strictly stronger: every process releases the
// framework registries it populated. release-scripts is asserted because its
// dedicated job only runs at full-suite or release-sensitive scope, so losing
// it here would silently stop testing test/scripts changes.
for _, want := range []string{
`if [ "$TEST_SHARD" = "app" ]; then`,
`test "${#packages[@]}" -eq 1`,
`./scripts/ci/run-app-race-tests.sh run "${packages[0]}"`,
`if [ "$TEST_SHARD" = "release-scripts" ]; then`,
`go test -v -count=1 -timeout=10m "${packages[@]}"`,
"timeout_budget=12m",
`if [ "$TEST_SHARD" = "cli" ] ||`,
`[ "$TEST_SHARD" = "smoke" ]; then`,
"timeout_budget=15m",
`go test -v -race -count=1 -timeout="$timeout_budget" "${packages[@]}"`,
"- release-scripts",
} {
if !strings.Contains(focusedJob, want) {
t.Errorf("focused test job missing shard contract %q", want)
}
}
raceStart := focusedEnd