Skip to content

fix(ci): stop version-guard demanding a bump for byte-neutral src/ changes - #111

Merged
sweetrb merged 1 commit into
mainfrom
fix-version-guard-byte-neutral-src
Jul 30, 2026
Merged

fix(ci): stop version-guard demanding a bump for byte-neutral src/ changes#111
sweetrb merged 1 commit into
mainfrom
fix-version-guard-byte-neutral-src

Conversation

@sweetrb

@sweetrb sweetrb commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Problem

version-guard's shipped-bytes detector matched every non-test file under src/:

grep -E '^(src/.*|requirements\.txt|build/.*)$'

But TypeScript under src/ is not a shipped file — it reaches users only after esbuild inlines it into build/index.js. So a comment-, formatting- or type-only edit that leaves the committed bundle byte-identical was hard-blocked by require-version-bump, leaving two bad options: publish a release of literally nothing, or don't write the comment.

apple-photos-mcp#58 hit exactly this — docs plus a code comment, bundle byte-identical, guard red.

Fix

src/**/*.ts becomes a first-cause detector that implies a bump only when build/** changed too.

The exemption is sound rather than merely convenient. ci.yml has a "Verify committed build/ matches source" step that rebuilds and requires git diff --quiet build/, and it runs in the test job — whose test (22) / test (24) contexts are required by branch protection. So at merge time an unchanged build/ provably matches src/: a src edit that did change the bundle cannot merge without the rebuilt bundle, and build/** then catches it. (That coupling is now stated in the workflow's header comment, and conformance-check.sh already asserts both the step and the contexts.)

Unconditional detectors are unchanged: build/**, requirements.txt, and any non-.ts file under src/ — which is precisely what package.json files[] ships verbatim (the *_reader.py sidecars in numbers/photos). The rule is written fail-safe: only .ts is treated as bundle-only, so a new file type added under src/ defaults to requiring a bump rather than silently escaping the guard. __tests__/__mocks__ paths are excluded there too, since no repo ships them.

Verification

Detector logic exercised against 13 scenarios:

Changed files Verdict
CHANGELOG.md CLAUDE.md src/index.ts (photos#58) exempt
docs-only, test-only, .github/, lockfile-only exempt
src/index.ts + build/index.js bump
build/index.js only bump
requirements.txt bump
src/utils/photos_reader.py, src/utils/numbers_reader.py bump
hypothetical src/data/table.json, src/x.applescript bump

YAML parses; format:check clean.

Scope

.github/ only — does not ship, so no version bump. The file stays byte-identical across all four repos (conformance-check.sh IDENTICAL set); this same commit lands in each.

…anges

The shipped-bytes detector matched every non-test file under src/, but
TypeScript there is not shipped: it reaches users only after esbuild inlines
it into build/index.js. A comment-, formatting- or type-only edit that leaves
the committed bundle byte-identical was therefore hard-blocked by
require-version-bump, leaving two bad options — publish a release of literally
nothing, or do not write the comment. apple-photos-mcp#58 (docs + a code
comment, bundle byte-identical) hit exactly this.

src/**/*.ts is now a first-cause detector that implies a bump only when
build/** changed too. The exemption is sound rather than convenient: ci.yml
has a "Verify committed build/ matches source" step that rebuilds and requires
`git diff --quiet build/`, and it lives in the `test` job whose test (22) /
test (24) contexts are required by branch protection. So at merge time an
unchanged build/ provably matches src/ — a src edit that DID change the bundle
cannot merge without the rebuilt bundle, which build/** then catches.

Everything else stays an unconditional detector: build/**, requirements.txt,
and any non-.ts file under src/ — which is what package.json files[] ships
verbatim (the *_reader.py sidecars in numbers/photos). The rule is written
fail-safe: only .ts is treated as bundle-only, so a new file type added under
src/ defaults to requiring a bump rather than silently escaping the guard.
__tests__/__mocks__ paths are excluded from that detector too, since no repo
ships them.

Verified against 13 scenarios (photos#58 shape, docs-only, test-only,
lockfile-only, src+build, build-only, requirements.txt, both .py sidecars, and
hypothetical src/*.json / *.applescript additions).

The file stays byte-identical across all four repos (conformance-check.sh);
this same commit lands in each. .github/ does not ship, so no version bump.
@sweetrb
sweetrb merged commit 8e15d69 into main Jul 30, 2026
8 checks passed
@sweetrb
sweetrb deleted the fix-version-guard-byte-neutral-src branch July 30, 2026 11:40
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