mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-03 15:27:56 +01:00
fix(merge e85005482): targeted classes since the read accept an empty range; the wave's receipt tests pass main's targeted record
- lib/ship-receipt-depth.ts targetedClassesSince (main, GST-986) reads the range from the commit the targeted reader read to HEAD through headInputs, which since #3795 runs gstack-diff-scope's BASE_CONTAINS_HEAD check. When the reader read HEAD itself the range is empty, diff-scope reported base_contains_head, and every write with --review-targeted was refused (the product patch matched). It now passes merged=true (--merged), which skips only that check; an ancestor check already guards the range. - test/review-exclude.test.ts and test/review-targeted.test.ts: since #3887 write refuses a money head with no targeted record and requires the record's head, so the wave's two writes that must succeed pass one, as main's own tests do (targetedAtHead in test/ship-receipt-depth.test.ts).
This commit is contained in:
1 parent
feeec2e760
commit
d0c6089f82
3 files changed
+4
-3
No files matched your search
@@ -295,7 +295,7 @@ export function bindShippedReceipt(root: string, baseRef: string, body: string,
|
||||
*/
|
||||
export function targetedClassesSince(root: string, from: string, head: string): readonly TargetedClass[] | null {
|
||||
if (!git(root, ['merge-base', '--is-ancestor', from, head]).ok) return null;
|
||||
const at = headInputs(root, from, head);
|
||||
const at = headInputs(root, from, head, undefined, true);
|
||||
let gateTagged: number | null = 0;
|
||||
if (gateScanNeeded(at.c.paths, at.c.root)) {
|
||||
const g = runScriptSync(path.join(BIN_DIR, 'gstack-gate-diff'), [from], { cwd: root, encoding: 'utf8', timeout: 120_000, maxBuffer: 16 * 1024 * 1024 });
|
||||
|
||||
@@ -253,6 +253,7 @@ describe('the receipt binds the selection the reviewers read', () => {
|
||||
const receiptIn = (body: string) => extractReceipt(fs.readFileSync(body, 'utf8')).receipt!;
|
||||
const writeReceipt = (repo: FixtureRepo, body: string, extra: string[]) =>
|
||||
runBin(repo, 'gstack-ship-receipt', ['write', '--pr', '7', '--base', 'main', '--version', '1.0.0', '--session-kind', 'unattended', '--body', body, ...extra]);
|
||||
const targetedAtHead = (repo: FixtureRepo) => ['--review-targeted', JSON.stringify({ classes: ['money', 'gate', 'auth', 'secret'], rules: 'r', brief_sha: 'a'.repeat(64), status: 'done', findings: 0, raised_by: 'targeted', head: repo.git('rev-parse', 'HEAD') })];
|
||||
// Value: protects=a docs-only range whose only file sits under a base pattern and carries a gate tag binds the same selection at
|
||||
// plan and receipt write, so the receipt can be written; fails_when=receiptReviewAtHead skips the gate scan when the paths are
|
||||
// docs-class and excludes the file the plan kept as gate-tagged (/ship review of #3852, red-team#1: digests 652d0aa8 vs
|
||||
@@ -291,7 +292,7 @@ describe('the receipt binds the selection the reviewers read', () => {
|
||||
expect(missing.err).toContain(`field=review_exclude expected=${digest} recorded=none source=origin/main@`);
|
||||
expect(missing.err).toContain('gstack-review-dispatch verify --ledger <ledger>');
|
||||
expect(fs.existsSync(body)).toBe(false);
|
||||
expect(writeReceipt(repo, body, ['--review-exclude', digest!]).status).toBe(EXIT.ok);
|
||||
expect(writeReceipt(repo, body, ['--review-exclude', digest!, ...targetedAtHead(repo)]).status).toBe(EXIT.ok);
|
||||
expect(receiptIn(body).review_exclude).toMatchObject({ digest, excluded: EXCLUDED.length, kept: KEPT.length });
|
||||
|
||||
onBase(repo, { 'docs/other.md': '# other\n' });
|
||||
|
||||
@@ -376,7 +376,7 @@ describe('the /ship commands carry the targeted record to the receipt (GST-464)'
|
||||
fs.writeFileSync(exclude, '*.log');
|
||||
expect(spawnSync('bash', ['-c', entry!], { cwd: repo.work, encoding: 'utf8', timeout: 10_000 }).status).toBe(0);
|
||||
expect(fs.readFileSync(exclude, 'utf8').split('\n')).toEqual(expect.arrayContaining(['*.log', '/.gstack/tmp/']));
|
||||
fs.writeFileSync(path.join(repo.work, recordPath!), JSON.stringify({ classes: ['money'], rules: TARGETED_RULES, brief_sha: targetedBriefSha(), status: 'done', findings: 0, raised_by: 'targeted' }) + '\n');
|
||||
fs.writeFileSync(path.join(repo.work, recordPath!), JSON.stringify({ classes: ['money'], rules: TARGETED_RULES, brief_sha: targetedBriefSha(), status: 'done', findings: 0, raised_by: 'targeted', head: repo.git('rev-parse', 'HEAD') }) + '\n');
|
||||
const args = expand();
|
||||
expect(args).toEqual(['--review-targeted', `@${recordPath}`]);
|
||||
expect(repo.git('ls-files', '--others', '--exclude-standard')).toBe('');
|
||||
|
||||
Reference in new issue
Block a user