fix: the file the gate passed is the file published, and stable takes only the approved one
tools/release-gate.sh is the one gate: a fresh install, and the upgrade from what canary and stable serve, each on a room of that channel, plus any older release rooms are still on (RELEASE_GATE_FROM). The releases it upgrades from are fetched over HTTPS and checked against their manifests, so it needs no credential and a CI runner can run it. update_canary.sh VERSION PACKAGE gates and publishes that file without rebuilding it, since a second build is a second, untested file; the hash is taken before the gate and checked after it. update_stable.sh VERSION SHA256 refuses anything but the file that was approved. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6c04f743ed
commit
a9700536bf
+46
-36
@@ -12,9 +12,12 @@ source "$ROOT/tools/release-lib.sh"
|
||||
# there are two — 0.2.6 is followed by 0.2.6.1 if it is a fix and by
|
||||
# 0.2.7 if it is not — and which one a release is, is a decision about
|
||||
# what is in it, not arithmetic.
|
||||
if [[ $# -ne 1 ]]; then
|
||||
if [[ $# -lt 1 || $# -gt 2 ]]; then
|
||||
current="$(release_channel_version canary || true)"
|
||||
echo "Usage: $0 VERSION" >&2
|
||||
echo "Usage: $0 VERSION [PACKAGE.deb]" >&2
|
||||
echo >&2
|
||||
echo "With PACKAGE.deb, that file is gated and published and nothing is" >&2
|
||||
echo "built, so the file that was tested is the file that is published." >&2
|
||||
echo >&2
|
||||
echo "Canary is on ${current:-an unknown version}. Name the release, for example:" >&2
|
||||
if [[ -n "$current" ]] && release_version_valid "$current"; then
|
||||
@@ -28,62 +31,69 @@ fi
|
||||
version="$1"
|
||||
package_name="$(release_package_name "$version")"
|
||||
package_path="$ROOT/dist/$package_name"
|
||||
prebuilt="${2:-}"
|
||||
|
||||
echo "Current canary: $(release_channel_version canary || echo unknown)"
|
||||
echo "New canary: $version"
|
||||
echo
|
||||
|
||||
# RELEASE_GATE_FROM="0.2.2" adds the upgrade from an older release that
|
||||
# rooms are still on to the gate, beside canary's and stable's own.
|
||||
#
|
||||
# Before anything is built: a version that has been published, or that
|
||||
# would not be newer than everything that has been, stops here.
|
||||
release_check_new_version "$version"
|
||||
|
||||
"$ROOT/tools/build-release.sh" "$version"
|
||||
# ONE FILE, FROM THE GATE TO THE ROOM.
|
||||
#
|
||||
# Given a package, that package is what is gated and published, and
|
||||
# nothing is rebuilt: a build is not byte-for-byte repeatable, so a second
|
||||
# build is a second, untested file. Without one, it is built here.
|
||||
if [[ -n "$prebuilt" ]]; then
|
||||
package_path="$(realpath "$prebuilt")"
|
||||
|
||||
# Validate the exact artifact that will be published. If a previous canary is
|
||||
# available locally, exercise the real upgrade path as well as a fresh install.
|
||||
validation_args=("$package_path")
|
||||
|
||||
if [[ -f "$RELEASE_LOCAL/canary/manifest.json" ]]; then
|
||||
previous_package_name="$(python3 -c \
|
||||
'import json, sys; print(json.load(open(sys.argv[1]))["package"].rsplit("/", 1)[-1])' \
|
||||
"$RELEASE_LOCAL/canary/manifest.json")"
|
||||
previous_package="$RELEASE_LOCAL/packages/$previous_package_name"
|
||||
|
||||
if [[ -f "$previous_package" && "$previous_package" != "$package_path" ]]; then
|
||||
validation_args+=("$previous_package")
|
||||
if [[ "$(basename "$package_path")" != "$package_name" ]]; then
|
||||
echo "$prebuilt is not named $package_name." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$(release_package_version "$package_path")" != "$version" ]]; then
|
||||
echo "$prebuilt says it is $(release_package_version "$package_path"), not $version." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Publishing the package already built: $package_path"
|
||||
else
|
||||
"$ROOT/tools/build-release.sh" "$version"
|
||||
fi
|
||||
|
||||
"$ROOT/tools/validate-trixie-release.sh" "${validation_args[@]}"
|
||||
# A fresh install, and the upgrade from whatever canary and stable serve
|
||||
# today, each on a room of that channel. Every canary is a stable release
|
||||
# in waiting, and the desktops are not on the previous canary: they are on
|
||||
# whatever stable names, which can be several releases back (0.2.2 under
|
||||
# 0.2.6.1). A package that upgrades the laptop and breaks the desktops has
|
||||
# to fail here, not on a Sunday. See tools/release-gate.sh.
|
||||
hash="$(sha256sum "$package_path" | awk '{print $1}')"
|
||||
|
||||
# And the stable rooms' own path, on the same file. Every canary is a
|
||||
# stable release in waiting, and the desktops are not on the previous
|
||||
# canary: they are on whatever stable names, which can be several
|
||||
# releases back (0.2.2 under 0.2.6.1). A package that upgrades the
|
||||
# laptop and breaks the desktops has to fail here, not on a Sunday.
|
||||
if [[ -f "$RELEASE_LOCAL/stable/manifest.json" ]]; then
|
||||
stable_package_name="$(python3 -c \
|
||||
'import json, sys; print(json.load(open(sys.argv[1]))["package"].rsplit("/", 1)[-1])' \
|
||||
"$RELEASE_LOCAL/stable/manifest.json")"
|
||||
stable_package="$RELEASE_LOCAL/packages/$stable_package_name"
|
||||
|
||||
if [[ -f "$stable_package" && "$stable_package" != "${validation_args[1]:-}" ]]; then
|
||||
echo
|
||||
echo "Rehearsing the stable rooms' upgrade from $stable_package_name"
|
||||
VALIDATION_CHANNEL=stable \
|
||||
"$ROOT/tools/validate-trixie-release.sh" "$package_path" "$stable_package"
|
||||
fi
|
||||
fi
|
||||
"$ROOT/tools/release-gate.sh" "$package_path" ${RELEASE_GATE_FROM:-}
|
||||
|
||||
# Checked again after the gate, which takes long enough for somebody else
|
||||
# to have published in the meantime.
|
||||
# to have published in the meantime — or for the file to have changed.
|
||||
release_check_new_version "$version"
|
||||
|
||||
hash="$(sha256sum "$package_path" | awk '{print $1}')"
|
||||
if [[ "$(sha256sum "$package_path" | awk '{print $1}')" != "$hash" ]]; then
|
||||
echo "$package_path changed while it was being gated. Nothing was published." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$RELEASE_LOCAL/packages"
|
||||
cp -n "$package_path" "$RELEASE_LOCAL/packages/$package_name"
|
||||
|
||||
if [[ "$(sha256sum "$RELEASE_LOCAL/packages/$package_name" | awk '{print $1}')" != "$hash" ]]; then
|
||||
echo "$RELEASE_LOCAL/packages/$package_name is not the file that passed the gate." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Publishing package..."
|
||||
release_upload_package "$RELEASE_LOCAL/packages/$package_name"
|
||||
|
||||
Reference in New Issue
Block a user