Skip to content

chore: add npm run fallow:ci script with --changed-since scoping#48

Merged
ethanj merged 2 commits intomainfrom
chore/local-fallow-ci-parity
Apr 29, 2026
Merged

chore: add npm run fallow:ci script with --changed-since scoping#48
ethanj merged 2 commits intomainfrom
chore/local-fallow-ci-parity

Conversation

@ethanj
Copy link
Copy Markdown
Contributor

@ethanj ethanj commented Apr 29, 2026

What

Adds npm run fallow:ci (backed by scripts/fallow-ci.sh) that runs fallow with the same --changed-since <PR-base-sha> scoping the GitHub Action uses, so contributors can catch most CI fallow findings before pushing.

```bash
npm run fallow:ci

→ fetches origin/main, computes merge-base, runs:

npx fallow --root . --format human --changed-since

```

Why

Over the last batch of PRs (#44/#45/#47) we hit four rounds of fallow CI failures that local `npx fallow` ran clean for. Investigation: CI passes `--changed-since ` (auto-detected by `fallow-rs/fallow@v2`), and that scoping matters for which clones get reported. Local invocations without it analyze the whole tree at slightly different sensitivity.

Honest caveat (documented in CONTRIBUTING.md)

Even with this script, there's a residual parity gap: empirically, fallow 2.42.0's clone detector sometimes returns different results across platforms (CI Linux x64 vs developer macOS arm64) on the same commit, same flags, same fallow version, fresh `npm ci`, clean cache. I couldn't fully reverse-engineer it. The script catches most of what CI flags; when CI flags a clone you can't reproduce locally, dedupe by intent and re-push.

Test plan

  • `npm run fallow:ci` runs cleanly on this branch
  • `npx tsc --noEmit` clean
  • `npm test` — 575 pass / 3 skipped
  • `npx fallow` — 0 issues above threshold

ethanj added 2 commits April 28, 2026 18:55
CI's codebase-health job runs fallow with `--changed-since <PR-base-sha>`,
which scopes findings to the diff. The plain `npx fallow` command runs
project-wide, which sometimes behaves differently than the CI invocation
and lets dupes through that CI later catches.

Add `scripts/fallow-ci.sh` (wired up as `npm run fallow:ci`) that fetches
origin/main, computes the merge-base with HEAD, and runs fallow with the
same `--changed-since` scoping CI uses.

Honest documentation in CONTRIBUTING.md: the script catches most issues
locally, but there's an empirically observed platform gap where fallow's
clone detector returns different results on Linux x64 (CI) vs macOS
arm64 (local). When CI flags something you can't reproduce locally,
dedupe by intent and re-push.
…eam/main

Two issues codex flagged on PR #48:

1. The unreachable-fallback bug. `BASE_SHA=$(git merge-base ...)` runs
   under set -e, so a non-zero exit from git merge-base would terminate
   the script before the empty-string fallback ran. Added `|| true` to
   the command substitution so the fallback path is reachable.

2. Fork-aware base resolution. CONTRIBUTING.md describes a fork-and-PR
   workflow where `origin` is the contributor's fork. CI compares against
   atomicmemory/main, but `git merge-base origin/main HEAD` on a fork
   would compare against the fork's main, which can drift from canonical.
   The script now prefers `upstream/main` when an `upstream` remote
   exists, falls back to `origin/main` otherwise. Documented the
   `git remote add upstream ...` setup step in CONTRIBUTING.md.
@ethanj ethanj merged commit ad8da7e into main Apr 29, 2026
3 checks passed
@ethanj ethanj deleted the chore/local-fallow-ci-parity branch April 29, 2026 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant