mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-07 17:28:23 +01:00
* feat(release): versions at release under merge: direct (gstack-release-stamp open, restamp --release, land --pin on release/<version>; GSTA-258 L2 PR 2) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(release): commit only the stamped files, leave no local release branch, reopen replaces the branch; regenerate doctor anchors Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(release): land a release head only on the main it was stamped on Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(release): review round — refresh notes before the release freeze check, check manifest/lockfile/CHANGELOG headings and every release output, branch names the stamped version, reuse an open release PR; restamp stays under 800 lines Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(release): round 2 — a deleted release output is refused, a release that merged onto a moved main is reported, branch-name test Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(release): released CHANGELOG sections must stay byte-identical, rerun land checks the stamped base, --bump refused with --release, open ignores fork PRs Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(release): name the release PR where docs said versions are set at every merge Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(release): a release that deletes a release output is refused by name, before the release tool runs Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(land): the release rerun reads the pin's parent after fetching the pin; tests for the rerun, the released-section guard and the fork filter Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(release): a release may not delete a release output; the release land rerun reads the pin's parent after fetching Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(release): drop the ship-policy.md re-audit sentences (docs risk accepted by GSTA-258; they go into the follow-up) 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;
|
|
}
|