From 0ebf4bd849840a7c20bbd2c1063e65ee53a0c7be Mon Sep 17 00:00:00 2001 From: garrytan Date: Thu, 29 Oct 2026 05:38:39 +0000 Subject: [PATCH] test(land): keeps the base's four-part package.json (#3557) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- CHANGELOG.md | 2 +- test/ship-queue-land.test.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 048a4deff..370cb89b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ ### Tests - `test/changelog-fragments.test.ts`: blob-only reads and refusals, bump precedence, fold order with a legacy section, the restamp fold and its tree receipt, an edited fold refused. -- `test/ship-queue-land.test.ts` (bare origin and a gh shim): happy path; two PRs from one base without a collision; a legacy stamp plus a dependency edit; a title-derived entry; a product conflict; the lock and `--break-lock`; the base moving during CI; a foreign push never overwritten; a missing receipt; drift, `--repair` and the lock release; the census; a receipt that fails #3567's depth check refuses. +- `test/ship-queue-land.test.ts` (bare origin and a gh shim): happy path; two PRs from one base without a collision; a legacy stamp plus a dependency edit; a title-derived entry; a product conflict; the lock and `--break-lock`; the base moving during CI; a foreign push never overwritten; a missing receipt; drift, `--repair` and the lock release; the census; a receipt that fails #3567's depth check refuses; a base with a four-part package.json in `stamp_files` lands four parts (#3557), gstack's own shape stays three. - `test/version-gate-fragments.test.ts`: fragment heads, premature version changes, a bot author, an advanced base, an invalid fragment, the stamp commit's effective bump, and the workflow's missing path filter. - `test/restamp-command-boundary.test.ts`: the hook reads its counter from `GSTACK_RESTAMP_BASE_SHA`, not the branch. diff --git a/test/ship-queue-land.test.ts b/test/ship-queue-land.test.ts index 335a19f58..3773239ec 100644 --- a/test/ship-queue-land.test.ts +++ b/test/ship-queue-land.test.ts @@ -246,6 +246,32 @@ describe('land: lock, races and refusals', () => { }, 90_000); }); +describe('land: the base\'s manifest part count', () => { + test('a repo whose base holds a four-part package.json listed in stamp_files lands four parts (gbrain#7878 wrote three)', () => { + const fx = setup({ ...POLICY, stamp_files: ['VERSION', 'package.json', 'CHANGELOG.md', 'changelog.d/*.md'], stamp_patterns: ['"version": "{version}"'] }); + const { repo } = fx; + repo.git('checkout', '-q', 'main'); + const pkg = JSON.parse(readFile(repo, 'package.json')); + fs.writeFileSync(path.join(repo.work, 'package.json'), JSON.stringify({ ...pkg, version: '1.2.3.0' }, null, 2) + '\n'); + fs.rmSync(path.join(repo.work, 'package-lock.json')); + repo.git('add', '-A'); repo.git('commit', '-q', '-m', 'four-part manifest'); repo.git('push', '-q', 'origin', 'main'); + openPr(fx, '21'); + expect(land(fx, ['--pr', '21']).status).toBe(EXIT.ok); + const merged = land(fx, ['--pr', '21']); + expect(merged.status, merged.err).toBe(EXIT.ok); + expect(JSON.parse(show(fx, 'origin/main:package.json')).version).toBe('1.2.4.0'); + expect(show(fx, 'origin/main:VERSION')).toBe('1.2.4.0'); + }, 90_000); + + test('control: gstack\'s shape (a three-part manifest outside stamp_files) stays three parts', () => { + const fx = setup(); + openPr(fx, '22'); + land(fx, ['--pr', '22']); + expect(land(fx, ['--pr', '22']).status).toBe(EXIT.ok); + expect(JSON.parse(show(fx, 'origin/main:package.json')).version).toBe('1.2.4'); + }, 90_000); +}); + describe('resolveReleaseConflicts', () => { test('a manifest whose version conflicts keeps the clean dependency edit and takes the base version; a real dependency conflict stays a conflict', () => { const fx = setup();