test(scripts): cover the dry-run/apply mutation boundary of apply-repo-settings - #128
Merged
Merged
Conversation
…o-settings Adds test/apply-repo-settings.test.mjs, a hermetic Node test that runs scripts/apply-repo-settings.sh against a fake `gh` on PATH. The stub answers the repository-settings contract's read endpoints from temporary JSON fixtures and records every mutating call instead of making one, so the test needs no network, no credential, and no real repository. The fixtures are derived from organization/contracts/repository-settings/v1.json itself, so a contract change cannot silently turn the "already conformant" case into a drift case. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UigLsmd17TVDuaaSN4yfdU
Real `gh api` sends POST whenever a request body is supplied (--input, -f/--raw-field, -F/--field), so the harness's old rule — mutation only on an explicit non-GET -X — let a dry-run regression mutate GitHub while the boundary test still passed. The fake gh now derives the effective method the way gh does: an explicit -X/--method wins, otherwise a request body makes it a POST, otherwise GET. Every effective non-GET call is recorded to the mutations log instead of being answered from a fixture, so the existing dry-run assertions (empty mutations log) actually bind. A fourth case pins the derivation itself for both the --input and the -f form. No production code changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UigLsmd17TVDuaaSN4yfdU
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
scripts/apply-repo-settings.shis dry-run by default and mutates GitHub onlywith
--apply(ADR-0040). Nothing pinned that boundary, so a refactor couldhave made the default invocation write to a repository with no test failing.
Adds
test/apply-repo-settings.test.mjs, a hermetic Node test that runs thereal script against a fake
ghplaced onPATH. The stub answers thecontract's read endpoints from temporary JSON fixtures and records every
mutating call instead of making one; an endpoint the script was not expected
to reach fails loudly rather than returning an empty body that would look like
conformance. No network, no credential, no real repository.
Three cases, all on one representative repository-object drift path
(
.repository.delete_branch_on_merge), scoped to the command contract with--no-rulesets:WOULD PATCH …and1 change(s) planned, andthe call log contains no
-X PATCH|PUT|POST|DELETEand the mutation log isempty;
--applyrecords exactly one mutation —PATCH repos/<repo>with body{"delete_branch_on_merge": true}— and reports1 change(s) applied;already matches the repository settings contractand mutates nothing, in both modes.Fixtures are derived from
organization/contracts/repository-settings/v1.jsonitself, so a contractchange cannot silently turn the conformant case into a drift case. No
production code changed.
Risk tier
Risk tier: 1 — test-only change; no production script, workflow, policy, or
contract file is touched.
Docs housekeeping
No docs touched — this change adds a single test file.
Verification
node scripts/check-docs.mjsgreen (run as part ofnpm run verify):npm run verifygreen (exit 0) —check:docs,check:organization,check:scripts(ok bash_syntax: 6/6), andnpm test:The three new cases are picked up by the existing
node --test test/*.test.mjssignal:
restored with no diff:
plan()forced to rungh apiregardless of--apply→ case 1 fails(
# pass 2 / # fail 1).cases 2 and 3 fail (
# pass 1 / # fail 2)..agents/skills/frostyard-docs-site/scaffold/nottouched.
.github/workflows/is touched.