mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-08 17:58:13 +01:00
fix(releases): the upgrade skill's ahead-of-stable exit works in depth-1 clones; update-check keeps its cache identity on the pre-release fallback
/ship second-pass review of 73e278d4 (GSTA-98, PR #3429):
- gstack-upgrade/SKILL.md.tmpl: README installs are depth-1 clones, where
origin/stable never connects to HEAD, so the AHEAD_OF_STABLE shortcut now
also fires when HEAD is not behind stable and stable's VERSION is not
higher than the installed one (the order bin/gstack-upgrade uses). The
fence prints the channel helper's warnings instead of discarding them, and
a 'fetching origin/stable failed' line is a STOP. Prose trimmed to stay
under the skill size budget. New behavioral test runs the Step 4 fence on
a depth-1 install past the release (AHEAD_OF_STABLE, nothing moved) and on
one behind it (goes on to the fast-forward).
- bin/gstack-update-check: the no-stable fallback keeps #stable in the
cache identity (so the outcome replays within its TTL instead of two
ls-remote calls per skill start), triggers only when ls-remote answered
with no such branch (a failed ls-remote stays CHECK_FAILED on stable), and
the branch-pinned URL derives from REMOTE_RAW_BASE so tests stay offline.
- scripts/release-cut.ts: a cancelled check run is red; the previous-release
lookups check .ok before using git output. docs/releases.md says which
pushes get no main-backstop check run at all.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
73e278d4a6
commit
964481a42e
7 files changed
+98
-46
No files matched your search
+14
-15
@@ -135,16 +135,18 @@ is saved in a rescue ref instead of being left as conflict markers:
|
||||
cd -- "${INSTALL_DIR:?INSTALL_DIR is not set: re-run Step 2 and substitute the printed path}" || exit 1
|
||||
{ [ -f VERSION ] && [ -f setup ] && [ -f bin/gstack-config ] && _p=$(git rev-parse --show-prefix 2>/dev/null) && [ -z "$_p" ] && [ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true ]; } || { echo "ERROR: $INSTALL_DIR is not a gstack checkout; nothing was changed. Re-run Step 2." >&2; exit 1; }
|
||||
git fetch origin
|
||||
# Channel ref (docs/releases.md): origin/stable for a team install, else origin/main.
|
||||
UPSTREAM_REF=$(bash bin/gstack-update-channel.sh --fetch-ref 2>/dev/null) || UPSTREAM_REF=origin/main
|
||||
# Channel ref (docs/releases.md): origin/stable for a team install, else origin/main
|
||||
_CH=$(bash bin/gstack-update-channel.sh --fetch-ref 2>&1) || _CH=origin/main
|
||||
echo "$_CH"; UPSTREAM_REF=$(printf '%s\n' "$_CH" | tail -1)
|
||||
echo "UPSTREAM_REF=${UPSTREAM_REF:=origin/main}"
|
||||
# Same pre-advance check as the auto-updater: the incoming release's Bun floor,
|
||||
# judged by bash whatever this tool shell is (zsh does not word-split).
|
||||
HOLD=$(UPSTREAM_REF="$UPSTREAM_REF" bash -c '. bin/gstack-bun-version.sh && gstack_bun_incoming_hold . "$UPSTREAM_REF"' 2>/dev/null) && { case "$HOLD" in bun-version-unreadable*) echo "BUN_VERSION_UNREADABLE: $HOLD; nothing was changed" >&2 ;; *) echo "BUN_TOO_OLD: $HOLD; nothing was changed" >&2 ;; esac; exit 1; }
|
||||
PRE_UPGRADE_COMMIT=$(git rev-parse HEAD)
|
||||
echo "PRE_UPGRADE_COMMIT=$PRE_UPGRADE_COMMIT"
|
||||
# A team install past the release waits for stable; nothing moves back.
|
||||
if [ "$UPSTREAM_REF" = origin/stable ] && [ "$(git rev-parse origin/stable)" != "$PRE_UPGRADE_COMMIT" ] && git merge-base --is-ancestor origin/stable HEAD; then echo "AHEAD_OF_STABLE"; exit 0; fi
|
||||
# Past the release (by ancestry, or by VERSION in a depth-1 clone): wait for stable; nothing moves back.
|
||||
if [ "$UPSTREAM_REF" = origin/stable ] && [ "$(git rev-parse origin/stable)" != "$PRE_UPGRADE_COMMIT" ] && ! git merge-base --is-ancestor HEAD origin/stable 2>/dev/null \
|
||||
&& { git merge-base --is-ancestor origin/stable HEAD 2>/dev/null || [ "$(printf '%s\n%s\n' "$(git show origin/stable:VERSION)" "$(cat VERSION)" | sort -V | tail -1)" = "$(cat VERSION)" ]; }; then echo "AHEAD_OF_STABLE"; exit 0; fi
|
||||
FF=$(bash bin/gstack-ff-update . "$UPSTREAM_REF"); FF_RC=$?
|
||||
echo "$FF"
|
||||
case "$FF_RC" in
|
||||
@@ -169,7 +171,7 @@ their conflicting local edits were saved there and relay the `Inspect`,
|
||||
checkout with `git apply -3`, never `stash apply` in the install;
|
||||
`unmerged=1` means the rescue needs manual resolution).
|
||||
On `FF_STOPPED`, STOP and relay the reason: nothing was changed.
|
||||
On `AHEAD_OF_STABLE`, STOP: the checkout is already past the weekly release, so nothing changes until the next cut (`gstack-config set update_channel main` follows every merge).
|
||||
On `AHEAD_OF_STABLE`, STOP: the checkout is already past the weekly release, so nothing changes until the next cut (`gstack-config set update_channel main` follows every merge). On a `fetching origin/stable failed` line above, STOP and relay it; nothing was changed.
|
||||
`ff-busy` means another gstack update is running (retry in a minute);
|
||||
`autostash-unrecoverable` names what is in the way (an untracked file the
|
||||
release adds, or another git command); `index-unreadable` means the checkout's
|
||||
@@ -307,10 +309,9 @@ fi
|
||||
|
||||
### Step 4.8: Stop any stale daemon (unconditional)
|
||||
|
||||
A browse daemon started before the upgrade keeps serving the OLD binary's code
|
||||
until it is stopped — it survives `git reset --hard` and `./setup` because the
|
||||
running process holds the old executable. Always run this step, using
|
||||
the install directory detected in Step 2.
|
||||
A browse daemon started before the upgrade keeps running the old binary (the
|
||||
reset and `./setup` do not stop it), so always run this step with the install
|
||||
directory from Step 2.
|
||||
|
||||
```bash
|
||||
INSTALL_DIR_PLACEHOLDER="<install dir from Step 2>"
|
||||
@@ -335,8 +336,7 @@ else
|
||||
fi
|
||||
```
|
||||
|
||||
Replace `<install dir from Step 2>` with the actual install directory before
|
||||
running. Interpret the `DAEMON_CHECK` result:
|
||||
Substitute the install directory from Step 2, then act on `DAEMON_CHECK`:
|
||||
|
||||
1. **`stale-responsive` + `DAEMON_STOPPED=yes`:** Tell the user "Stopped the
|
||||
old browse daemon (binary {OLD_HASH} → {NEW_HASH}). The next browse command
|
||||
@@ -347,7 +347,7 @@ running. Interpret the `DAEMON_CHECK` result:
|
||||
busy right now. When it finishes, stop it with `browse stop` — or force it
|
||||
immediately with `browse --force-restart stop` (loses that session's
|
||||
tabs/cookies/logins)."
|
||||
3. **`none` / `dead` / `current`:** Nothing to do — say nothing.
|
||||
3. **`none` / `dead` / `current`:** say nothing.
|
||||
|
||||
### Step 5: Write marker + clear cache
|
||||
|
||||
@@ -361,7 +361,7 @@ rm -f "$GSTACK_STATE_ROOT"/update-snoozed
|
||||
|
||||
### Step 6: Show What's New
|
||||
|
||||
Read `$INSTALL_DIR/CHANGELOG.md`. Find all version entries between the old version and the new version. Summarize as 5-7 bullets grouped by theme. Don't overwhelm — focus on user-facing changes. Skip internal refactors unless they're significant.
|
||||
Read `$INSTALL_DIR/CHANGELOG.md`. Find all version entries between the old version and the new version. Summarize as 5-7 bullets grouped by theme, user-facing changes first.
|
||||
|
||||
Four fields: summarize `git -C "$INSTALL_DIR" log --oneline <PRE_UPGRADE_COMMIT>..HEAD` (≤7 bullets) as "gstack v{old}, main at {sha}".
|
||||
|
||||
@@ -379,7 +379,7 @@ Happy shipping!
|
||||
|
||||
### Step 7: Continue
|
||||
|
||||
After showing What's New, continue with whatever skill the user originally invoked. The upgrade is done — no further action needed.
|
||||
Continue with the skill the user originally invoked; the upgrade is done.
|
||||
|
||||
---
|
||||
|
||||
@@ -392,7 +392,6 @@ When invoked directly as `/gstack-upgrade` (not from a preamble):
|
||||
~/.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \
|
||||
.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || true
|
||||
```
|
||||
Use the output to determine if an upgrade is available.
|
||||
|
||||
2. If `UPGRADE_AVAILABLE` (three or four fields): follow Steps 2-6 above.
|
||||
|
||||
|
||||
@@ -141,16 +141,18 @@ is saved in a rescue ref instead of being left as conflict markers:
|
||||
cd -- "${INSTALL_DIR:?INSTALL_DIR is not set: re-run Step 2 and substitute the printed path}" || exit 1
|
||||
{ [ -f VERSION ] && [ -f setup ] && [ -f bin/gstack-config ] && _p=$(git rev-parse --show-prefix 2>/dev/null) && [ -z "$_p" ] && [ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true ]; } || { echo "ERROR: $INSTALL_DIR is not a gstack checkout; nothing was changed. Re-run Step 2." >&2; exit 1; }
|
||||
git fetch origin
|
||||
# Channel ref (docs/releases.md): origin/stable for a team install, else origin/main.
|
||||
UPSTREAM_REF=$(bash bin/gstack-update-channel.sh --fetch-ref 2>/dev/null) || UPSTREAM_REF=origin/main
|
||||
# Channel ref (docs/releases.md): origin/stable for a team install, else origin/main
|
||||
_CH=$(bash bin/gstack-update-channel.sh --fetch-ref 2>&1) || _CH=origin/main
|
||||
echo "$_CH"; UPSTREAM_REF=$(printf '%s\n' "$_CH" | tail -1)
|
||||
echo "UPSTREAM_REF=${UPSTREAM_REF:=origin/main}"
|
||||
# Same pre-advance check as the auto-updater: the incoming release's Bun floor,
|
||||
# judged by bash whatever this tool shell is (zsh does not word-split).
|
||||
HOLD=$(UPSTREAM_REF="$UPSTREAM_REF" bash -c '. bin/gstack-bun-version.sh && gstack_bun_incoming_hold . "$UPSTREAM_REF"' 2>/dev/null) && { case "$HOLD" in bun-version-unreadable*) echo "BUN_VERSION_UNREADABLE: $HOLD; nothing was changed" >&2 ;; *) echo "BUN_TOO_OLD: $HOLD; nothing was changed" >&2 ;; esac; exit 1; }
|
||||
PRE_UPGRADE_COMMIT=$(git rev-parse HEAD)
|
||||
echo "PRE_UPGRADE_COMMIT=$PRE_UPGRADE_COMMIT"
|
||||
# A team install past the release waits for stable; nothing moves back.
|
||||
if [ "$UPSTREAM_REF" = origin/stable ] && [ "$(git rev-parse origin/stable)" != "$PRE_UPGRADE_COMMIT" ] && git merge-base --is-ancestor origin/stable HEAD; then echo "AHEAD_OF_STABLE"; exit 0; fi
|
||||
# Past the release (by ancestry, or by VERSION in a depth-1 clone): wait for stable; nothing moves back.
|
||||
if [ "$UPSTREAM_REF" = origin/stable ] && [ "$(git rev-parse origin/stable)" != "$PRE_UPGRADE_COMMIT" ] && ! git merge-base --is-ancestor HEAD origin/stable 2>/dev/null \
|
||||
&& { git merge-base --is-ancestor origin/stable HEAD 2>/dev/null || [ "$(printf '%s\n%s\n' "$(git show origin/stable:VERSION)" "$(cat VERSION)" | sort -V | tail -1)" = "$(cat VERSION)" ]; }; then echo "AHEAD_OF_STABLE"; exit 0; fi
|
||||
FF=$(bash bin/gstack-ff-update . "$UPSTREAM_REF"); FF_RC=$?
|
||||
echo "$FF"
|
||||
case "$FF_RC" in
|
||||
@@ -175,7 +177,7 @@ their conflicting local edits were saved there and relay the `Inspect`,
|
||||
checkout with `git apply -3`, never `stash apply` in the install;
|
||||
`unmerged=1` means the rescue needs manual resolution).
|
||||
On `FF_STOPPED`, STOP and relay the reason: nothing was changed.
|
||||
On `AHEAD_OF_STABLE`, STOP: the checkout is already past the weekly release, so nothing changes until the next cut (`gstack-config set update_channel main` follows every merge).
|
||||
On `AHEAD_OF_STABLE`, STOP: the checkout is already past the weekly release, so nothing changes until the next cut (`gstack-config set update_channel main` follows every merge). On a `fetching origin/stable failed` line above, STOP and relay it; nothing was changed.
|
||||
`ff-busy` means another gstack update is running (retry in a minute);
|
||||
`autostash-unrecoverable` names what is in the way (an untracked file the
|
||||
release adds, or another git command); `index-unreadable` means the checkout's
|
||||
@@ -313,10 +315,9 @@ fi
|
||||
|
||||
### Step 4.8: Stop any stale daemon (unconditional)
|
||||
|
||||
A browse daemon started before the upgrade keeps serving the OLD binary's code
|
||||
until it is stopped — it survives `git reset --hard` and `./setup` because the
|
||||
running process holds the old executable. Always run this step, using
|
||||
the install directory detected in Step 2.
|
||||
A browse daemon started before the upgrade keeps running the old binary (the
|
||||
reset and `./setup` do not stop it), so always run this step with the install
|
||||
directory from Step 2.
|
||||
|
||||
```bash
|
||||
INSTALL_DIR_PLACEHOLDER="<install dir from Step 2>"
|
||||
@@ -341,8 +342,7 @@ else
|
||||
fi
|
||||
```
|
||||
|
||||
Replace `<install dir from Step 2>` with the actual install directory before
|
||||
running. Interpret the `DAEMON_CHECK` result:
|
||||
Substitute the install directory from Step 2, then act on `DAEMON_CHECK`:
|
||||
|
||||
1. **`stale-responsive` + `DAEMON_STOPPED=yes`:** Tell the user "Stopped the
|
||||
old browse daemon (binary {OLD_HASH} → {NEW_HASH}). The next browse command
|
||||
@@ -353,7 +353,7 @@ running. Interpret the `DAEMON_CHECK` result:
|
||||
busy right now. When it finishes, stop it with `browse stop` — or force it
|
||||
immediately with `browse --force-restart stop` (loses that session's
|
||||
tabs/cookies/logins)."
|
||||
3. **`none` / `dead` / `current`:** Nothing to do — say nothing.
|
||||
3. **`none` / `dead` / `current`:** say nothing.
|
||||
|
||||
### Step 5: Write marker + clear cache
|
||||
|
||||
@@ -367,7 +367,7 @@ rm -f "$GSTACK_STATE_ROOT"/update-snoozed
|
||||
|
||||
### Step 6: Show What's New
|
||||
|
||||
Read `$INSTALL_DIR/CHANGELOG.md`. Find all version entries between the old version and the new version. Summarize as 5-7 bullets grouped by theme. Don't overwhelm — focus on user-facing changes. Skip internal refactors unless they're significant.
|
||||
Read `$INSTALL_DIR/CHANGELOG.md`. Find all version entries between the old version and the new version. Summarize as 5-7 bullets grouped by theme, user-facing changes first.
|
||||
|
||||
Four fields: summarize `git -C "$INSTALL_DIR" log --oneline <PRE_UPGRADE_COMMIT>..HEAD` (≤7 bullets) as "gstack v{old}, main at {sha}".
|
||||
|
||||
@@ -385,7 +385,7 @@ Happy shipping!
|
||||
|
||||
### Step 7: Continue
|
||||
|
||||
After showing What's New, continue with whatever skill the user originally invoked. The upgrade is done — no further action needed.
|
||||
Continue with the skill the user originally invoked; the upgrade is done.
|
||||
|
||||
---
|
||||
|
||||
@@ -398,7 +398,6 @@ When invoked directly as `/gstack-upgrade` (not from a preamble):
|
||||
~/.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || \
|
||||
.claude/skills/gstack/bin/gstack-update-check --force 2>/dev/null || true
|
||||
```
|
||||
Use the output to determine if an upgrade is available.
|
||||
|
||||
2. If `UPGRADE_AVAILABLE` (three or four fields): follow Steps 2-6 above.
|
||||
|
||||
|
||||
Reference in new issue
Block a user