Pairs the EGB-713 skew WARNING with a fix path. `secrets upgrade` fast-forwards the tool's own git checkout (git -C "$SCRIPT_DIR" pull --ff-only; never merges or rewrites local commits), reports vOLD -> vNEW, then best-effort re-checks the store's recorded writer-version against the new version so the operator sees whether the nudge is cleared. `secrets upgrade --check` reports availability without pulling. Thin and explicit: no auto-update, no background polling (security tool). Directed errors for not-a-checkout / no-upstream / diverged / offline. cmd_upgrade never calls check_initialized (it's about the tool, not the store); the skew re-check is silent unless a store with a writer-version resolves. Wired into the dispatcher (upgrade) shift; cmd_upgrade "$@") and cmd_help. Tests: test/upgrade.bats (8) run a relocated script copy in a throwaway git repo with a bare upstream, so the real checkout is never touched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
115 lines
3.9 KiB
Bash
115 lines
3.9 KiB
Bash
#!/usr/bin/env bats
|
|
# EGB-716: `secrets upgrade` verb — self-update (git pull --ff-only) + skew re-check.
|
|
#
|
|
# These tests never touch the real tool checkout. Each test relocates a COPY of
|
|
# the script into a throwaway git repo wired to a bare upstream, so $SCRIPT_DIR
|
|
# (computed from BASH_SOURCE) resolves to the fake tool repo and the pull/fetch
|
|
# operate there.
|
|
|
|
load test_helper
|
|
|
|
# Create a fake tool repo at $TOOL (script copy + VERSION), wired to a bare
|
|
# upstream at $TOOL_REMOTE, at version $1. cd's into $TOOL (under $HOME so
|
|
# resolve_store's walk-up stays bounded and never strays to a real store).
|
|
setup_tool_repo() {
|
|
TOOL="$TEST_TMPDIR/tool"
|
|
TOOL_REMOTE="$TEST_TMPDIR/tool-remote.git"
|
|
mkdir -p "$TOOL"
|
|
cp "$SECRETS_BIN" "$TOOL/secrets"
|
|
echo "$1" > "$TOOL/VERSION"
|
|
git -c init.defaultBranch=main init -q "$TOOL"
|
|
git -C "$TOOL" add -A
|
|
git -C "$TOOL" -c user.email=t@t -c user.name=t commit -qm "v$1"
|
|
git -c init.defaultBranch=main init --bare -q "$TOOL_REMOTE"
|
|
git -C "$TOOL" remote add origin "$TOOL_REMOTE"
|
|
git -C "$TOOL" push -q -u origin HEAD:main
|
|
cd "$TOOL"
|
|
}
|
|
|
|
# Publish a newer VERSION to the upstream (as a different clone would).
|
|
advance_tool_remote() {
|
|
local clone="$TEST_TMPDIR/tool-pub"
|
|
rm -rf "$clone"
|
|
git clone -q "$TOOL_REMOTE" "$clone"
|
|
echo "$1" > "$clone/VERSION"
|
|
git -C "$clone" -c user.email=t@t -c user.name=t commit -qam "v$1"
|
|
git -C "$clone" push -q origin HEAD:main
|
|
rm -rf "$clone"
|
|
}
|
|
|
|
@test "upgrade --check reports an available update without changing VERSION (EGB-716)" {
|
|
setup_tool_repo 0.1.0.0
|
|
advance_tool_remote 0.2.0.0
|
|
run "$TOOL/secrets" upgrade --check
|
|
[ "$status" -eq 0 ]
|
|
[[ "$output" == *"Update available"* ]] || false
|
|
[[ "$output" == *"0.1.0.0"* ]] || false
|
|
# --check must not pull: local VERSION is untouched.
|
|
[ "$(cat "$TOOL/VERSION")" = "0.1.0.0" ]
|
|
}
|
|
|
|
@test "upgrade --check is clean when already current (EGB-716)" {
|
|
setup_tool_repo 0.2.0.0
|
|
run "$TOOL/secrets" upgrade --check
|
|
[ "$status" -eq 0 ]
|
|
[[ "$output" == *"up to date"* ]] || false
|
|
}
|
|
|
|
@test "upgrade fast-forwards and reports old -> new (EGB-716)" {
|
|
setup_tool_repo 0.1.0.0
|
|
advance_tool_remote 0.2.0.0
|
|
run "$TOOL/secrets" upgrade
|
|
[ "$status" -eq 0 ]
|
|
[[ "$output" == *"v0.1.0.0 -> v0.2.0.0"* ]] || false
|
|
[ "$(cat "$TOOL/VERSION")" = "0.2.0.0" ]
|
|
}
|
|
|
|
@test "upgrade is a no-op when already at the latest (EGB-716)" {
|
|
setup_tool_repo 0.2.0.0
|
|
run "$TOOL/secrets" upgrade
|
|
[ "$status" -eq 0 ]
|
|
[[ "$output" == *"up to date"* ]] || false
|
|
[ "$(cat "$TOOL/VERSION")" = "0.2.0.0" ]
|
|
}
|
|
|
|
@test "upgrade refuses when the tool dir is not a git checkout (EGB-716)" {
|
|
local d="$HOME/plain-tool"
|
|
mkdir -p "$d"
|
|
cp "$SECRETS_BIN" "$d/secrets"
|
|
echo 0.1.0.0 > "$d/VERSION"
|
|
cd "$d"
|
|
run "$d/secrets" upgrade
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"git checkout"* ]] || false
|
|
}
|
|
|
|
@test "upgrade rejects an unknown flag (EGB-716)" {
|
|
setup_tool_repo 0.1.0.0
|
|
run "$TOOL/secrets" upgrade --bogus
|
|
[ "$status" -eq 1 ]
|
|
[[ "$output" == *"Unknown upgrade flag"* ]] || false
|
|
}
|
|
|
|
@test "upgrade re-checks store skew and confirms the client caught up (EGB-716)" {
|
|
setup_tool_repo 0.1.0.0
|
|
advance_tool_remote 0.9.0.0
|
|
# A store last written by a newer client than our starting version.
|
|
git -c init.defaultBranch=main init -q "$SECRETS_DIR"
|
|
echo 0.8.0.0 > "$SECRETS_DIR/.secrets-writer-version"
|
|
run "$TOOL/secrets" upgrade
|
|
[ "$status" -eq 0 ]
|
|
[[ "$output" == *"v0.1.0.0 -> v0.9.0.0"* ]] || false
|
|
# New client (0.9.0.0) is now ahead of the store's last writer (0.8.0.0).
|
|
[[ "$output" == *"at or ahead"* ]] || false
|
|
}
|
|
|
|
@test "upgrade still notes when the store is ahead of the upgraded client (EGB-716)" {
|
|
setup_tool_repo 0.1.0.0
|
|
advance_tool_remote 0.2.0.0
|
|
git -c init.defaultBranch=main init -q "$SECRETS_DIR"
|
|
echo 0.9.0.0 > "$SECRETS_DIR/.secrets-writer-version"
|
|
run "$TOOL/secrets" upgrade
|
|
[ "$status" -eq 0 ]
|
|
[[ "$output" == *"v0.1.0.0 -> v0.2.0.0"* ]] || false
|
|
[[ "$output" == *"still ahead"* ]] || false
|
|
}
|