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>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-29 08:41:58 +00:00
1 parent d053d1d54d
commit 0ebf4bd849
2 files changed
+27 -1

No files matched your search

+1 -1
View File
@@ -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.
+26
View File
@@ -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();