--ci records an upgrade no room could take (master between releases, its VERSION already on canary) as SKIP instead of failing every commit; its report can never stand in for a release's. --still-current accepts a report only for these exact bytes, passed, from exactly what canary and stable serve now. update_canary.sh takes one through RELEASE_GATE_REPORT_PASSED, so Preview's publish job needs the key and not Docker. Co-Authored-By: Claude Opus 5.5 <[email protected]>
124 lines
4.7 KiB
Bash
Executable File
124 lines
4.7 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$ROOT"
|
|
|
|
source "$ROOT/tools/release-lib.sh"
|
|
|
|
# The version is always said out loud.
|
|
#
|
|
# With only three parts there was one obvious next number. With four
|
|
# 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 [[ $# -lt 1 || $# -gt 2 ]]; then
|
|
current="$(release_channel_version canary || true)"
|
|
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
|
|
IFS='.' read -r major minor patch maintenance <<< "$current"
|
|
echo " $0 ${major}.${minor}.${patch}.$(( ${maintenance:-0} + 1 )) a maintenance release" >&2
|
|
echo " $0 ${major}.${minor}.$(( patch + 1 )) the next feature release" >&2
|
|
fi
|
|
exit 2
|
|
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"
|
|
|
|
# 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")"
|
|
|
|
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
|
|
|
|
# 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}')"
|
|
|
|
# RELEASE_GATE_REPORT_PASSED=REPORT relies on a gate already run on this
|
|
# file instead — Preview's gate job, which has Docker, where the publish
|
|
# job has the key and no Docker. The report is only accepted if it is a
|
|
# pass for exactly these bytes, from exactly what canary and stable serve
|
|
# now; anything else and nothing is published.
|
|
if [[ -n "${RELEASE_GATE_REPORT_PASSED:-}" ]]; then
|
|
"$ROOT/tools/release-gate.sh" --still-current "$RELEASE_GATE_REPORT_PASSED" "$package_path"
|
|
else
|
|
"$ROOT/tools/release-gate.sh" "$package_path" ${RELEASE_GATE_FROM:-}
|
|
fi
|
|
|
|
# Checked again after the gate, which takes long enough for somebody else
|
|
# to have published in the meantime — or for the file to have changed.
|
|
release_check_new_version "$version"
|
|
|
|
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"
|
|
|
|
echo
|
|
echo "Publishing canary manifest..."
|
|
release_publish_manifest canary "$version" "$hash"
|
|
|
|
echo "$RELEASE_URL/canary/latest.deb -> $package_name"
|
|
|
|
echo
|
|
echo "Checking what a classroom will see..."
|
|
release_verify_channel canary "$version"
|
|
echo " stable is still on $(release_channel_version stable || echo unknown)"
|
|
|
|
echo
|
|
echo "Published Ekklesia Classroom $version to CANARY"
|
|
echo "$RELEASE_URL/canary/manifest.json"
|