Hook tests cannot detect drift in Flutter's own SDK launchers (#678) - #683
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
WalkthroughAdds a real Flutter SDK pre-commit integration test with disposable SDK safeguards, linked worktree fixtures, isolated Git execution, and a recording Git shim. The test validates commit success, hook liveness, SDK cache and version-file preservation, framework revision integrity, and Git environment isolation. CI adds path detection and an uncached SDK job. Documentation defines execution and coverage boundaries. Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.githooks/tests/test-pre-commit-real-sdk.sh:
- Around line 421-425: Resolve the overridable HOOK to an absolute path before
the executable check and symlink creation. Update the setup flow around HOOK so
both the -x validation and ln -sf use that absolute value, preserving the
existing validation and reporting behavior.
- Around line 202-216: Extend refuse_if_shared in
.githooks/tests/test-pre-commit-real-sdk.sh to inspect versions/* under both
configured FVM_CACHE_PATH and legacy FVM_HOME, while preserving the existing
hard-coded checks and refusal behavior. Update the matching shared-SDK refusal
list in docs/TESTING.md at line 77 to document these configured cache paths.
In @.github/workflows/flutter-ci.yml:
- Around line 122-127: Add an explicit timeout-minutes value to the
hook-real-sdk job definition, alongside its existing name, needs, if, and
runs-on settings. Choose a bounded duration consistent with the workflow’s
documented timeout scenario, while preserving the job’s current execution
behavior.
- Around line 24-35: Add workflow-level least-privilege settings before the jobs
declaration in the Flutter CI workflow: grant only contents read access and
configure concurrency using the workflow/ref group, cancelling in-progress runs
for pull requests. Keep the existing android-build-changes and hook-real-sdk job
behavior unchanged.
- Around line 155-163: Update the Flutter action configuration for the real-SDK
pre-commit coverage job to install a git-backed checkout instead of the stable
3.44.1 release archive, and change the run block to set sdk from FLUTTER_ROOT.
Preserve REQUIRE_REAL_SDK and the existing test invocation so
.githooks/tests/test-pre-commit-real-sdk.sh can resolve the SDK repository and
git revision.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: fa7dfdb2-8818-4cfa-b544-a8a503823e76
📒 Files selected for processing (4)
.githooks/tests/test-pre-commit-real-sdk.sh.github/workflows/flutter-ci.ymlNOTES.mddocs/TESTING.md
…en HOOK absolute (#678) refuse_if_shared only enumerated the two default FVM roots (~/fvm, ~/.fvm was not even covered) and the hook's system fallbacks, so a shared SDK under a configured FVM_CACHE_PATH (or legacy FVM_HOME) cache could be designated as JEEVES_REAL_SDK and corrupted. Enumerate the configured caches' versions/* too, and add the ~/.fvm/versions default. Verified: a git-checkout SDK reachable only via FVM_CACHE_PATH / FVM_HOME is now refused. Also resolve an overridden HOOK to an absolute path before symlinking it into .git/hooks/pre-commit: git resolves a hook symlink against the hooks dir, not this script's cwd, so a relative teeth-proof HOOK installed a dangling link git silently ignored, surfacing later as a bogus 'Flutter block never ran'. Re: #683 (comment) Re: #683 (comment) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…timeout (#678) The Flutter workflow declared no permissions, so every job (including the new detector and hook-real-sdk jobs) ran with the broad default token scope (zizmor excessive-permissions). Every job only reads the repo, so grant contents: read once at the workflow level. Add a concurrency group that cancels superseded PR runs — the real-SDK job downloads a full uncached SDK, so a stale run is expensive — while leaving main pushes to finish. Bound hook-real-sdk with timeout-minutes: 30 (well above its ~2-minute observed runtime) so a hang cannot hold a runner for the 360-minute default and the exit-trap-can't-repair window stays small. Re: #683 (comment) Re: #683 (comment) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Review comments addressed. I triaged all 5 CodeRabbit comments on PR #683, fixing four (broadening |
|
No changes needed. |
…cannot-detect-drift-in-flutter-s-own-sd # Conflicts: # NOTES.md
|
Merge conflicts resolved. Merged |
|
Merge gate: NOT-READY — one true blocker, plus cleanups that can ride the same fixup. The substance is good and I want this. Teeth verified from source, not assumed: with Safety is right too: the hard-refuse at Blocker — shellcheck will red CI, and it is invisible today
It is green right now only because Cleanups worth folding into the same push
Two plan-level citations ( CodeRabbit is a genuine clean pass (range |
…DK check Blocker: the cleanup() body carries `# shellcheck disable=SC2317`, but shellcheck >=0.11 reclassifies a trap-only (never-directly-invoked) function as SC2329, which the SC2317 disable no longer covers. --severity=style treats info as fatal, so the 'Infra & hooks' sweep would red for every PR touching .githooks/ or backend/ the moment the runner image bumps shellcheck. Disable both codes. Cleanups on the real-SDK check, all in-scope for #678's new files: - Fail CLOSED when `git rev-parse --local-env-vars` fails or answers empty (was swallowed with `|| true`): otherwise the leak assertion iterates over nothing and the job greens vacuously. Mirrors the hook (pre-commit:191-199). - Resolve HOOK to an absolute path BEFORE the -x check, so validation and the symlink use the same resolved path (the resolve-first half of the earlier CodeRabbit request). - Soften the header's 'Measured … byte-compare red' teeth-proof line to describe the mechanism and require running the teeth-proof, rather than asserting a measurement not evidenced in the PR. - Record the measured wall-clock in the workflow (hook-real-sdk ~1m33s vs analyze ~5m29s -> adds ~0 to PR wall-clock), replacing the resolved TODO (AC #5). - Add the two provenance citations a future reader will want: shared.sh's own $FLUTTER_ROOT/.git bail, and the test_ops_author_chain_race_postgres.py skip-locally/fail-in-CI precedent premise_unmet() mirrors. Re: #683 (comment) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Re: #683 (comment) All addressed in Blocker — SC2329. Cleanups:
Optional citations added: Scope stayed two files. shellcheck |
|
Review comments addressed. Addressed the |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/flutter-ci.yml:
- Around line 133-135: Update the workflow comment near the hook-only runtime
calculation to document both paths: when analyze runs, hook-real-sdk finishes
within its window and adds negligible wall-clock time; when only hook files
change and analyze is skipped, hook-real-sdk can extend PR wall-clock by its own
runtime.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: baa276d6-2158-4203-8da5-298ef6cb19a2
📒 Files selected for processing (2)
.githooks/tests/test-pre-commit-real-sdk.sh.github/workflows/flutter-ci.yml
) The cost comment claimed ~0 PR wall-clock unconditionally, but `analyze` is gated on `app` and is skipped for hook-only changes while `hook-real-sdk` still runs (gated on `app || hook`). In that case this job is on the critical path and can extend wall-clock by its own runtime. Document both paths. Re: #683 (comment) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Review comments addressed. CI on |
|
No changes needed. |
Summary
.githooks/tests/test-pre-commit-real-sdk.sh, an additive real-SDK check that closes the blind spot in the existing stub suite: the stubs hand-model the SDK's self-resolution and go red against the unfixed hook, but cannot notice the real Flutter SDK changing how it resolves its own revision — a future release could quietly break the Pre-commit hook leaks GIT_* into Flutter tooling, corrupting the FVM SDK in worktrees #644 protection while the stubs stay green.git commit— the exact Pre-commit hook leaks GIT_* into Flutter tooling, corrupting the FVM SDK in worktrees #644 configuration — using a minimal generated fixture package (build_runnerpinned to the versionapp/pubspec.lockresolves).bin/cache/flutter.version.jsonsurvives byte-for-byte (catching deletion and mutation), that itsframeworkRevisionstill matches the SDK's owngit rev-parse HEAD, and — via a non-interposinggit-shim — that at least one SDK-targetedgit -C "$FLUTTER_ROOT" rev-parse HEADcall actually happened, so it reds if a future SDK stops resolving through that channel.JEEVES_REAL_SDK, hard-refuse the FVM store and the hook's shared fallbacks (~/fvm/versions/*,~/development/flutter,~/flutter,/opt/flutter), trap-repair the disposable SDK on exit, skip loudly (exit 0) when none is designated, but fail rather than skip under CI (REQUIRE_REAL_SDK=1).Running build_runneroutput appeared) so a mis-staged fixture that tripspre-commit's^app/gate cannot make every survival assertion pass trivially..github/workflows/flutter-ci.ymlas a parallelhook-real-sdkjob withcache: false(a corrupted SDK saved and restored later is exactly the hazard this catches), split the path filter so a hook-only change runs only this job whileapp/**still runs analyze/build, and expand the triggers to cover the hook, this check, and the workflow file itself.docs/TESTING.md, plus three agent-instinct corrections inNOTES.md.Test plan
HOOKpointed at a deliberately-unfixed copy of the hook against a disposable SDK — the byte-compare must go red and the commit must be rejected.JEEVES_REAL_SDKdesignated, and hard-fails underREQUIRE_REAL_SDK=1.JEEVES_REAL_SDKpointing at~/fvm/versions/*,/opt/flutter, or another shared fallback.hook-real-sdkCI job runs on a hook-only change (and that analyze/android-build stay skipped), and runs on anapp/**change.flutter.version.jsonis intact after a run (trap-repair fired) and the shell-lint sweep covers the new script.🤖 Generated with Claude Code
Closes #678