fix(ci): free-tests container parity — tools, pinned bun, git identity, mutation tripwire

- Dockerfile.ci: add python3 (gstack-jsonl-merge/brain-sync/detach shell out
  to it), file (skill-validation's binary check), poppler-utils (make-pdf
  e2e gates hard-require pdftotext/pdffonts/pdfinfo), fonts-noto-color-emoji
  (emoji render gate, mirrors make-pdf-gate.yml). Fix the bun pin: the
  bun.sh installer ignores a BUN_VERSION env var, so the old form silently
  installed latest on every rebuild (observed 1.3.13/1.3.14 drift vs the
  1.3.10 devs run locally); pass the version as the positional arg.
- free-tests.yml: git identity + safe.directory for the git-exercising
  tests (container checkout is owned by a different uid than runner);
  post-loop tree-mutation tripwire that names a tracked-file-mutating test
  instead of letting downstream collateral confuse the report; skip the
  documented variants-retry-after timing flake.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-15 08:40:27 -07:00
co-authored by Claude Fable 5
parent 8f048370a4
commit 96423aff76
2 changed files with 38 additions and 4 deletions
+23
View File
@@ -83,6 +83,17 @@ jobs:
echo "TMPDIR=/home/runner/.cache"
} >> "$GITHUB_ENV"
# Several test files exercise real git operations (gstack-artifacts-init,
# session-update-autostash, team-mode, brain-sync) and bins that read the
# current branch (gstack-decision-search). The container checkout is owned
# by a different uid than `runner`, so git needs safe.directory, and
# commit-making tests need an identity.
- name: Git identity for git-exercising tests
run: |
git config --global user.email "ci@gstack.invalid"
git config --global user.name "gstack CI"
git config --global --add safe.directory '*'
# Same restore rationale as evals.yml: recursive copy beats symlink
# (realpath escapes workspace) and hardlink (cross-device overlay-fs).
- name: Restore deps
@@ -132,6 +143,7 @@ jobs:
[browse/test/terminal-agent-integration.test.ts]="real PTY round-trip; container TTY semantics differ"
[browse/test/xvfb.test.ts]="tests xvfb management; container has no X server to manage"
[browse/test/security-audit-r2.test.ts]="one behavioral tmpdir-allowlist test breaks under this job's TMPDIR override (bun temp-dir workaround above)"
[design/test/variants-retry-after.test.ts]="known timing flake, tracked in TODOS.md (HTTP-date Retry-After rounding)"
)
FILES=$(bun run scripts/test-free-shards.ts --list | grep -E '^ (browse/|test/|make-pdf/|design/)' | sed 's/^ //')
TOTAL=$(echo "$FILES" | wc -l | tr -d ' ')
@@ -153,6 +165,17 @@ jobs:
fi
done
echo "Skipped $SKIPPED container-incompatible files (reasons above)."
# Tree-mutation tripwire: a test that rewrites tracked files poisons
# every later file in the loop with confusing failures (observed:
# gstack-config's skill_prefix auto-relink patched 52 SKILL.md names,
# failing five unrelated suites downstream). Name the real culprit.
MUTATED=$(git status --porcelain --untracked-files=no)
if [ -n "$MUTATED" ]; then
echo ""
echo "A test mutated tracked files in the working tree — later failures may be collateral:"
echo "$MUTATED"
FAILED="$FAILED [tree-mutation]"
fi
if [ -n "$FAILED" ]; then
echo ""
echo "Failed files:$FAILED"