release_manifest_version ueberlebt ein fehlendes Manifest

feat/versandtakt
nexxo 2026-08-04 15:06:12 +02:00
parent 63328d44d4
commit 4b2c2cd315
2 changed files with 25 additions and 1 deletions

View File

@ -38,8 +38,17 @@ release_manifest_commit() {
# failed in between leaves a newer number on disk than is serving. Deciding
# "is there something newer" against the file would then offer nothing, because
# the checkout already claims to be the version it never finished installing.
#
# `|| true` at the end, same idiom as release_version()'s `|| echo '0.0.0'`:
# guarantee a zero exit status regardless of what happened upstream. Without
# it, a missing manifest — an ordinary state before the first install — makes
# `sed` exit 2, `pipefail` carries that out of the pipeline, and the caller's
# `DEPLOYED_VERSION="$(release_manifest_version)"` is a bare assignment: under
# `set -e` that ends the agent on every tick, before it ever writes a status.
# Empty output either way, so the caller's existing fallback to
# release_version() still fires exactly as before.
release_manifest_version() {
sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$MANIFEST_FILE" 2>/dev/null | head -1
sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$MANIFEST_FILE" 2>/dev/null | head -1 || true
}
# release_version_gt A B — true when A is strictly a higher version than B.

View File

@ -115,6 +115,21 @@ it('answers with nothing, and cleanly, when there are no releases yet', function
->and(trim($process->getOutput()))->toBe('[0]');
});
it('survives a missing manifest instead of taking the agent down with it', function () {
// Kein storage/app/deployment.json in diesem Wegwerf-Repo — der Zustand
// eines frischen Checkouts vor der ersten Installation. `sed` auf einer
// fehlenden Datei liefert Status 2; die Zeile, die diese Funktion in
// update-agent.sh tatsaechlich verbraucht — eine reine Zuweisung,
// `DEPLOYED_VERSION="$(release_manifest_version)"` — reicht diesen
// Status unter `pipefail` an `set -e` weiter. Ohne Absicherung stirbt der
// Agent bei JEDEM Tick, bevor er je eine Statusdatei schreibt — dieselbe
// Fehlerklasse wie bei sync_vpn_certificate und einem fehlenden `.env`.
$process = runRelease('DEPLOYED_VERSION="$(release_manifest_version)"; echo "[$?][$DEPLOYED_VERSION]"');
expect($process->getExitCode())->toBe(0)
->and(trim($process->getOutput()))->toBe('[0][]');
});
it('orders by version, not alphabetically', function () {
// v1.10.0 is newer than v1.9.0 and sorts earlier as a string. Getting this
// wrong means a server sitting on 1.9.0 is told it is current.