fix(windows): gstack-ship-receipt starts gstack-session-kind through Git Bash (#3541)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-11-01 21:30:48 +00:00
1 parent 5225e35cc6
commit f396bd5ca8
3 files changed
+24 -1

No files matched your search

+2 -1
View File
@@ -37,6 +37,7 @@ import * as path from 'node:path';
import { EXIT, exitTableHelp, type ShipReceipt } from '../lib/headless-artifacts';
import { resultLine, resultLineWithDocs } from '../lib/result-codes';
import { versionAtRef } from '../lib/restamp';
import { runScriptSync } from '../lib/script-invocation';
import { readPregateFile, verifyPregate } from '../lib/pregate/index';
import { isUnavailable, loadPolicyFromBase, matchesAny, policyUnavailableLine, resolveBaseBranch, runningGstackVersion, stampFilesInTree, validatePolicy, type ShipPolicy } from '../lib/ship-policy';
import { approvalForReceipt } from '../lib/approval-citations';
@@ -179,7 +180,7 @@ function cmdWrite(rest: string[], json: boolean): number {
const tree = receiptFile ? JSON.parse(fs.readFileSync(receiptFile, 'utf8')) : null;
let sessionKind = flag(rest, '--session-kind') ?? process.env.GSTACK_SESSION_KIND;
if (!sessionKind) {
const r = spawnSync(path.join(path.dirname(Bun.fileURLToPath(import.meta.url)), 'gstack-session-kind'), [], { encoding: 'utf8', timeout: 15_000 });
const r = runScriptSync(path.join(path.dirname(Bun.fileURLToPath(import.meta.url)), 'gstack-session-kind'), [], { encoding: 'utf8', timeout: 15_000 });
sessionKind = r.status === 0 ? r.stdout.trim() || undefined : undefined;
}
let pregate: PregateField | undefined;
@@ -0,0 +1,7 @@
**`gstack-ship-receipt write` records the session kind on Windows.** Without `--session-kind` or `GSTACK_SESSION_KIND`, it asks the `gstack-session-kind` bash helper. It used to spawn that helper by path, which never starts on Windows, so every /ship receipt there carried no `session_kind`. It now starts the helper through `lib/script-invocation.ts`, which uses Git Bash on Windows. This is the /ship half of #3541.
### Fixed
- **`bin/gstack-ship-receipt`** starts `gstack-session-kind` with `runScriptSync`.
### Tests
- `test/gstack-ship-receipt.test.ts`: a receipt written without a session kind takes it from `gstack-session-kind`.
+15
View File
@@ -72,6 +72,21 @@ describe('gstack-ship-receipt write', () => {
expect(rewritten).toContain('## Summary');
});
test('without --session-kind or GSTACK_SESSION_KIND, session_kind comes from gstack-session-kind (#3541)', () => {
const repo = fixture();
makePr(repo, 'pr-a', { expects: '1.2.4.0' });
expect(restamp(repo, ['--version', '1.2.4.0']).status).toBe(EXIT.ok);
repo.git('commit', '-qam', 'stamp');
const body = path.join(repo.root, 'body.md');
fs.writeFileSync(body, '## Summary\n\nProse.\n');
const env = { GSTACK_SESSION_KIND: '' };
const kind = runBin(repo, 'gstack-session-kind', [], env);
expect(kind.status, kind.err).toBe(0);
const w = runBin(repo, 'gstack-ship-receipt', ['write', '--pr', '44', '--base', 'main', '--body', body, '--json'], env);
expect(w.status, w.err).toBe(EXIT.ok);
expect(JSON.parse(w.out).session_kind).toBe(kind.out.trim());
});
test('refuses an invalid receipt before writing (RECEIPT_INVALID) and a non-integer --pr', () => {
const repo = fixture();
const body = path.join(repo.root, 'body.md');