mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-10 02:30:39 +01:00
* Load the Capy crew skills only on Capy machines (GST-1833) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Add changelog entry for Capy-only crew skills (GST-1833) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Move the Capy-only crew tooling into crew/ and run its tests only when needed (GST-1833) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Test that the Capy launch file puts crew/bin on PATH Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Count any ~/.capy as a Capy machine, so a Mac running Capy keeps /captain Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Fix the tests and fixtures that broke when crew tooling moved into crew/ Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Plan every crew test when a pull request's merge-base can't be read Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Add a test that checks each crew-only module left the root tree for crew/ Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Run crew tests on pull requests that change bin/ commands or workflows they drive Review-Finding: p1/specialist-batched#1 reader=testing Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Keep running every crew test on every pull request; the skip comes in a later change Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Keep copied installs and older release bisects working after the crew/ move Setup now copies crew/lib into every host's runtime root beside bin and lib, so Windows installs (which copy instead of linking) can still start gstack-ship-receipt, gstack-pregate and the other commands that import it. The release bisect runs the train-gate script from wherever the checked-out commit has it, so a bisect over commits from before the move still gets a verdict. Review-Finding: p1/outside-voice#1 reader=outside-voice Review-Finding: p1/outside-voice#2 reader=outside-voice Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Say in the changelog that Windows installs keep working after the crew/ move Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Point the harness guide's merge-queue rows at crew/lib/ where those modules moved Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Point the plain-title test at the wave module's new home in crew/ (GST-1833) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
18 lines
1.5 KiB
TypeScript
18 lines
1.5 KiB
TypeScript
/**
|
|
* restamp-release — the precondition of `gstack-restamp --release` (lib/release-stamp.ts, docs/ship-policy.md#release-stamp):
|
|
* a release stamp runs on a clean checkout of origin/<base> under changelog_fragments, so the release PR carries only the stamp.
|
|
*/
|
|
import { spawnSync } from 'node:child_process';
|
|
|
|
const git = (cwd: string, args: string[]) => (spawnSync('git', args, { cwd, encoding: 'utf8', timeout: 60_000 }).stdout ?? '').trim();
|
|
|
|
/** Why a release stamp cannot run here, or null when it can. */
|
|
export function releaseRefusal(repoRoot: string, base: string, baseRef: string | undefined, fragDir: string | null): { message: string; fix?: string } | null {
|
|
if (!fragDir) return { message: '--release needs changelog_fragments in the base policy (a release folds the fragments); nothing written' };
|
|
const tip = git(repoRoot, ['rev-parse', '--verify', '--quiet', `${baseRef ?? `origin/${base}`}^{commit}`]);
|
|
if (!tip || git(repoRoot, ['rev-parse', 'HEAD']) !== tip) return { message: `--release runs on a checkout of origin/${base} (${tip.slice(0, 12) || 'unresolved'}), not on ${git(repoRoot, ['rev-parse', '--short', 'HEAD'])}; nothing written`, fix: `git fetch origin ${base} && git checkout --detach origin/${base}` };
|
|
const dirty = git(repoRoot, ['status', '--porcelain', '--untracked-files=no']);
|
|
if (dirty) return { message: `--release needs a clean checkout; commit or stash: ${dirty.split('\n').slice(0, 5).map(l => l.slice(3)).join(', ')}; nothing written` };
|
|
return null;
|
|
}
|