Skip to content

Commit 923b692

Browse files
committed
fix: self-update checksum verification
1 parent 86fff6d commit 923b692

4 files changed

Lines changed: 114 additions & 3 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ jobs:
6868
tar -czf "dist/${ARCHIVE}" \
6969
updates README.md SPEC.md LICENSE CHANGELOG.md CONTRIBUTING.md CODE_OF_CONDUCT.md SECURITY.md
7070
71-
sha256sum dist/* > dist/SHA256SUMS
71+
(cd dist && sha256sum updates "${ARCHIVE}" > SHA256SUMS)
7272
7373
- name: Create GitHub Release
7474
uses: softprops/action-gh-release@v2

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
77

88
## [Unreleased]
99

10+
## [0.8.1] - 2026-01-30
11+
12+
### Fixed
13+
14+
- Self-update now accepts checksum entries that include a path prefix (e.g. `dist/updates`).
15+
- Release `SHA256SUMS` now uses basenames (enables self-update from `v0.8.0`).
16+
1017
## [0.8.0] - 2026-01-30
1118

1219
### Added

tests/test_cli.sh

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,108 @@ grep -q "^GIT_TERMINAL_PROMPT=0 git -C ${omz_dir} pull --ff-only$" "$CALL_LOG"
227227
grep -q "^GIT_TERMINAL_PROMPT=0 git -C ${omz_dir}/custom/plugins/zsh-autosuggestions pull --ff-only$" "$CALL_LOG"
228228
grep -q "^GIT_TERMINAL_PROMPT=0 git -C ${omz_dir}/custom/themes/powerlevel10k pull --ff-only$" "$CALL_LOG"
229229

230+
echo "Test: self-update accepts checksum paths (dist/updates)"
231+
self_update_home="${tmp_dir}/home-self-update"
232+
mkdir -p "$self_update_home"
233+
234+
self_update_bin="${tmp_dir}/self-update-bin"
235+
mkdir -p "$self_update_bin"
236+
237+
self_update_fixtures="${tmp_dir}/self-update-fixtures"
238+
mkdir -p "$self_update_fixtures"
239+
240+
self_update_old="${self_update_bin}/updates"
241+
self_update_new="${self_update_fixtures}/updates.new"
242+
243+
mk_versioned_copy() {
244+
local src="$1"
245+
local dest="$2"
246+
local ver="$3"
247+
local tmp="${dest}.tmp"
248+
249+
awk -v ver="$ver" '
250+
BEGIN { done = 0 }
251+
{
252+
if (done == 0 && $0 ~ /^UPDATES_VERSION="/) {
253+
print "UPDATES_VERSION=\"" ver "\""
254+
done = 1
255+
next
256+
}
257+
print
258+
}
259+
' "$src" >"$tmp"
260+
mv "$tmp" "$dest"
261+
chmod +x "$dest"
262+
}
263+
264+
mk_versioned_copy "$SCRIPT" "$self_update_old" "0.0.1"
265+
mk_versioned_copy "$SCRIPT" "$self_update_new" "0.0.2"
266+
267+
sha256_file() {
268+
local f="$1"
269+
if command -v sha256sum >/dev/null 2>&1; then
270+
sha256sum "$f" | awk '{print $1}'
271+
return 0
272+
fi
273+
if command -v shasum >/dev/null 2>&1; then
274+
shasum -a 256 "$f" | awk '{print $1}'
275+
return 0
276+
fi
277+
echo "No sha256 tool available (sha256sum/shasum)" >&2
278+
return 1
279+
}
280+
281+
sha="$(sha256_file "$self_update_new")"
282+
printf '%s dist/updates\n' "$sha" >"${self_update_fixtures}/SHA256SUMS"
283+
284+
export SELF_UPDATE_FIXTURES="$self_update_fixtures"
285+
# shellcheck disable=SC2016
286+
write_stub curl '
287+
out=""
288+
url=""
289+
while [ $# -gt 0 ]; do
290+
case "$1" in
291+
-o)
292+
out="${2:-}"
293+
shift 2
294+
;;
295+
http*://*)
296+
url="$1"
297+
shift
298+
;;
299+
*)
300+
shift
301+
;;
302+
esac
303+
done
304+
305+
case "$url" in
306+
*/releases/latest)
307+
echo "{\"tag_name\":\"v0.0.2\"}"
308+
;;
309+
*/updates)
310+
cp "${SELF_UPDATE_FIXTURES}/updates.new" "$out"
311+
;;
312+
*/SHA256SUMS)
313+
cp "${SELF_UPDATE_FIXTURES}/SHA256SUMS" "$out"
314+
;;
315+
*)
316+
echo "curl stub: unexpected url: $url" >&2
317+
exit 1
318+
;;
319+
esac
320+
'
321+
322+
# Ensure self-update isn't skipped due to our git stub always succeeding.
323+
write_stub git 'exit 1'
324+
325+
out="$(UPDATES_SELF_UPDATE=1 CI="" UPDATES_SELF_UPDATE_REPO=fake/repo HOME="$self_update_home" "$self_update_old" --only brew --no-emoji --no-color 2>&1)"
326+
echo "$out" | grep -q 'updates: self-update available (0.0.1 -> 0.0.2)'
327+
echo "$out" | grep -q 'updates: updated to 0.0.2; restarting'
328+
329+
if [ "$("$self_update_old" --version)" != "0.0.2" ]; then
330+
echo "Expected self-update to replace the installed script" >&2
331+
exit 1
332+
fi
333+
230334
echo "All tests passed."

updates

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
set -o pipefail
44

5-
UPDATES_VERSION="0.8.0"
5+
UPDATES_VERSION="0.8.1"
66

77
SCRIPT_NAME="$(basename "$0")"
88

@@ -424,7 +424,7 @@ maybe_self_update() {
424424
fi
425425

426426
local expected=""
427-
expected="$(awk '$2=="updates"{print $1; exit}' "$tmp_sums" 2>/dev/null || true)"
427+
expected="$(awk '$2 ~ /(^|\/)updates$/{print $1; exit}' "$tmp_sums" 2>/dev/null || true)"
428428
if [ -z "$expected" ]; then
429429
warn "updates: self-update checksum missing; continuing"
430430
rm -rf "$tmp_dir"

0 commit comments

Comments
 (0)