mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-31 14:06:50 +01:00
v1.91.118.0 test: held-install recovery fixture no longer assumes the checkout has no local main (#3237)
* test: held-install recovery fixture no longer assumes the checkout has no local main actions/checkout leaves push runs on a local main branch, so the fixture's clone already had main and 'checkout --orphan main' failed. Build the root commit on an orphan held-fixture branch and push HEAD:refs/heads/main; add a regression covering a source on main and a detached source with no branch. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.118.0 test: held-install recovery fixture no longer assumes the checkout has no local main 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>
This commit is contained in:
1 parent
82530ac143
commit
a6eb647328
5 files changed
+36
-8
No files matched your search
@@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## [1.91.118.0] - 2026-10-17
|
||||
|
||||
**Free Tests is green on pushes to main again.** Since v1.91.106.0, every push to main failed `test/held-install-recovery.test.ts`, while pull request runs passed.
|
||||
|
||||
### Fixed
|
||||
- **The held-install recovery fixture no longer assumes the checkout has no `main` branch.** On a push, `actions/checkout` leaves the checkout on a local `main`, so the fixture's clone already had `main` and `git checkout --orphan main` failed with `a branch named 'main' already exists`. Pull request runs check out a detached merge ref and never hit it. The fixture now builds on its own orphan branch and pushes `HEAD:refs/heads/main`, and a new test builds it from a source on `main` and from a detached source with no branch.
|
||||
|
||||
### If you…
|
||||
- **…write a test fixture that clones this repository:** don't create a branch with a fixed name such as `main` in the clone. Push runs and pull request runs leave different local branches behind.
|
||||
|
||||
## [1.91.117.0] - 2026-10-17
|
||||
|
||||
**Pregate understands bats repositories and says why a fingerprint failed, `gstack-doctor` lists rescued edits and pasted skill lists, oversized SKILL.md files can no longer grow, and hosts without plan mode drop the plan-mode preamble.** The last PR of the 2026-10-15 fix wave (`docs/designs/FIX_WAVE_2026_10_15.md`, PR 5), built after #3190.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# gstack digest v1.91.117.0 — regenerate/re-copy after upgrading gstack
|
||||
# gstack digest v1.91.118.0 — regenerate/re-copy after upgrading gstack
|
||||
|
||||
Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed
|
||||
for agent hosts without a full skill install. The full skills add workflows,
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gstack",
|
||||
"version": "1.91.117",
|
||||
"version": "1.91.118",
|
||||
"description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
|
||||
@@ -36,15 +36,16 @@ const CONFLICT_LINE = 'THROTTLE_SECONDS=3600 # 1 hour';
|
||||
* install sits one commit behind it, at the same tree without
|
||||
* bin/gstack-ff-update (an install that predates it), with VERSION 1.91.101.0.
|
||||
*/
|
||||
function makeFixture() {
|
||||
function makeFixture(source = ROOT) {
|
||||
const base = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-held-')));
|
||||
bases.push(base);
|
||||
const origin = path.join(base, 'origin.git');
|
||||
const work = path.join(base, 'work');
|
||||
execFileSync('git', ['clone', '-q', '--shared', ROOT, work], { timeout: 60_000 });
|
||||
execFileSync('git', ['clone', '-q', '--shared', source, work], { timeout: 60_000 });
|
||||
// A root commit of this tree: the checkout may be shallow, and a bare
|
||||
// origin refuses a shallow push.
|
||||
git(work, 'checkout', '-q', '--orphan', 'main');
|
||||
// origin refuses a shallow push. The clone already has a local main when
|
||||
// the source is on main (actions/checkout runs `checkout -B main` on a push).
|
||||
git(work, 'checkout', '-q', '--orphan', 'held-fixture');
|
||||
fs.writeFileSync(path.join(work, 'VERSION'), '1.91.101.0\n');
|
||||
fs.rmSync(path.join(work, 'bin', 'gstack-ff-update'), { force: true });
|
||||
git(work, 'add', '-A');
|
||||
@@ -59,7 +60,7 @@ function makeFixture() {
|
||||
git(work, 'commit', '-q', '-m', 'the fixed release');
|
||||
const fixed = git(work, 'rev-parse', 'HEAD');
|
||||
execFileSync('git', ['init', '-q', '--bare', '-b', 'main', origin], { timeout: 60_000 });
|
||||
git(work, 'push', '-q', origin, 'main');
|
||||
git(work, 'push', '-q', origin, 'HEAD:refs/heads/main');
|
||||
return { base, origin, held, fixed };
|
||||
}
|
||||
type Fx = ReturnType<typeof makeFixture>;
|
||||
@@ -126,6 +127,23 @@ describe.skipIf(process.platform === 'win32')('held-install recovery (Git Bash f
|
||||
expect(form('recovery-powershell')).toContain('d=$(mktemp -d)');
|
||||
});
|
||||
|
||||
for (const checkout of ['on main', 'detached with no branch'] as const) {
|
||||
test(`the fixture builds from a source checkout ${checkout}`, () => {
|
||||
const src = path.join(fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-held-src-'))), 'src');
|
||||
bases.push(path.dirname(src));
|
||||
execFileSync('git', ['clone', '-q', '--shared', ROOT, src], { timeout: 60_000 });
|
||||
if (checkout === 'on main') git(src, 'checkout', '-q', '-B', 'main');
|
||||
else {
|
||||
git(src, 'checkout', '-q', '--detach');
|
||||
for (const b of git(src, 'for-each-ref', '--format=%(refname:short)', 'refs/heads').split('\n').filter(Boolean)) git(src, 'branch', '-q', '-D', b);
|
||||
}
|
||||
const fx = makeFixture(src);
|
||||
expect(git(fx.origin, 'rev-parse', 'refs/heads/main')).toBe(fx.fixed);
|
||||
expect(git(fx.origin, 'rev-parse', `${fx.fixed}^`)).toBe(fx.held);
|
||||
expect(git(fx.origin, 'rev-list', '--max-parents=0', fx.fixed)).toBe(fx.held);
|
||||
}, 60_000);
|
||||
}
|
||||
|
||||
for (const state of ['clean', 'dirty', 'unmerged'] as const) {
|
||||
test(`a ${state} prefix-mode install reaches the fixed release; a planted symlink is never followed`, async () => {
|
||||
const fx = makeFixture();
|
||||
|
||||
Reference in new issue
Block a user