Files
archy/scripts/create-release.sh
T

71 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Build unsigned pending artifacts from an already reviewed, versioned,
# annotated source tag. Never change source after recording BUILD-INFO.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
if [ "${1:-}" = --backend-only ]; then
[ "$#" = 2 ] && [[ "$2" =~ ^[0-9a-f]{64}$ ]] || { echo 'Exact Cargo.lock SHA256 required' >&2; exit 1; }
cd "$PROJECT_ROOT/core"
[ -f Cargo.lock ] && [ ! -L Cargo.lock ] || exit 1
ACTUAL=$(sha256sum Cargo.lock)
[ "${ACTUAL%% *}" = "$2" ] || { echo 'Cargo.lock mismatch' >&2; exit 1; }
exec cargo build --release -p archipelago --locked --offline
fi
VERSION="${1:-}"
[ "$#" -gt 0 ] && shift
DRY_RUN='' APPLICATION_ONLY=0
while [ "$#" -gt 0 ]; do
case "$1" in
--dry-run) DRY_RUN=--dry-run ;;
--application-only) APPLICATION_ONLY=1 ;;
*) echo "Usage: $0 VERSION [--application-only] [--dry-run]" >&2; exit 1 ;;
esac
shift
done
[[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]] \
|| { echo 'Invalid release version' >&2; exit 1; }
[ "${SKIP_RELEASE_TESTS:-0}" = 0 ] || { echo 'Release gate bypass is forbidden' >&2; exit 1; }
SOURCE_COMMIT=$(python3 "$SCRIPT_DIR/release_payload.py" source --version "$VERSION")
OS_PLAN=${ARCHIPELAGO_OS_RELEASE_PLAN:-}
if [ "$APPLICATION_ONLY" = 1 ]; then
[ -z "$OS_PLAN" ] || { echo 'Application-only release must not carry an OS plan' >&2; exit 1; }
else
[ -n "$OS_PLAN" ] && [ -f "$OS_PLAN" ] && [ ! -L "$OS_PLAN" ] || {
echo 'Set ARCHIPELAGO_OS_RELEASE_PLAN to the reviewed exact OS transaction JSON' >&2; exit 1;
}
OS_PLAN=$(realpath "$OS_PLAN")
fi
PENDING="$PROJECT_ROOT/releases/pending/v$VERSION/manifest.json"
ARTIFACTS="$PROJECT_ROOT/releases/v$VERSION"
[ ! -e "$PENDING" ] && [ ! -e "$ARTIFACTS" ] || { echo 'Existing candidate retained; use its verification/signing steps rather than rebuilding over it' >&2; exit 1; }
if [ "$DRY_RUN" = --dry-run ]; then
echo "Build backend/UI/AIUI/radio from $SOURCE_COMMIT; stage unsigned $PENDING."
echo 'Run under flock /tmp/opencode/release-heavy.lock. Source/tag creation and signing are separate operator steps.'
exit 0
fi
cd "$PROJECT_ROOT"
bash tests/release/run.sh
python3 scripts/release_payload.py companion
(cd core && cargo build --release -p archipelago --locked --offline)
(cd neode-ui && npm ci && npm run build)
python3 scripts/release_payload.py ui web/dist/neode-ui --commit "$SOURCE_COMMIT"
(cd reticulum-daemon && ./build.sh)
test "$SOURCE_COMMIT" = "$(python3 scripts/release_payload.py source --version "$VERSION")"
mkdir -p "$(dirname "$PENDING")" "$ARTIFACTS"
manifest_args=(--version "$VERSION" --output "$PENDING")
if [ "$APPLICATION_ONLY" = 1 ]; then
manifest_args+=(--application-only)
else
install -m 0644 "$OS_PLAN" "$ARTIFACTS/os-update-plan.json"
manifest_args+=(--os-plan "$ARTIFACTS/os-update-plan.json")
fi
bash scripts/create-release-manifest.sh "${manifest_args[@]}"
install -m 0755 core/target/release/archipelago "$ARTIFACTS/archipelago"
install -m 0644 "/tmp/archipelago-frontend-$VERSION.tar.gz" "$ARTIFACTS/archipelago-frontend-$VERSION.tar.gz"
bash scripts/check-release-manifest.sh "$PENDING"
echo "Unsigned candidate staged from $SOURCE_COMMIT; no commit, tag, signature or feed promotion performed."
echo "Operator signing command (inputs now exist): bash scripts/sign-manifest.sh '$PENDING'"