release: v1.5.0-alpha + version hygiene fixes
Versioning was drifting on three axes — fixed all of them: 1. Cargo.toml → 1.5.0-alpha (was 1.5.0). User wants `-alpha` suffix on every pre-stable release; this is the current state of main. 2. neode-ui/package.json was still 1.3.5 — brought in line. 3. /opt/archipelago/build-info.txt was stale on .198 (1.3.4) and .253 (1.3.5), absent on .116/.228. That file OVERRIDES the binary's CARGO_PKG_VERSION for the UI sidebar, which is why .198/.253 kept showing old versions even with fresh binaries. scripts/deploy-to-target.sh now writes build-info.txt on every deploy, reading the version straight from Cargo.toml — so the sidebar can never drift from the binary again. Release artifacts + manifest: - releases/v1.5.0-alpha/archipelago (40M, sha in manifest) - releases/v1.5.0-alpha/archipelago-frontend-1.5.0-alpha.tar.gz (51M) - releases/manifest.json bumped with full 7-line changelog covering FIPS-first routing, Settings toggle, transitive federation, cancel button, transport badges, peer listener, and the build-info fix. - scripts/check-release-manifest.sh — new pre-publish guard. Refuses to pass if: Cargo.toml ≠ manifest version, changelog is empty (release notes are mandatory), or any component's sha256/size doesn't match the file on disk. Run locally or from CI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2
core/Cargo.lock
generated
2
core/Cargo.lock
generated
@@ -80,7 +80,7 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "archipelago"
|
||||
version = "1.5.0"
|
||||
version = "1.5.0-alpha"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"archipelago-container",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "archipelago"
|
||||
version = "1.5.0"
|
||||
version = "1.5.0-alpha"
|
||||
edition = "2021"
|
||||
description = "Archipelago Bitcoin Node OS - Native backend"
|
||||
authors = ["Archipelago Team"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "neode-ui",
|
||||
"private": true,
|
||||
"version": "1.3.5",
|
||||
"version": "1.5.0-alpha",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "./start-dev.sh",
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
{
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.0-alpha",
|
||||
"release_date": "2026-04-19",
|
||||
"changelog": [
|
||||
"FIPS mesh transport integrated (github.com/jmcorgan/fips): preferred over Tor for peer traffic",
|
||||
"Seed-derived FIPS identity via HKDF label archipelago/fips/secp256k1/v1",
|
||||
"Federation invites carry an optional fips_npub so peers can reach each other via FIPS",
|
||||
"Network tab surfaces FIPS daemon version + copyable npub; Home shows FIPS status line",
|
||||
"WiFi SSID now shown on Network tab when connected (was N/A)"
|
||||
"FIPS-first transport for federation, messaging, peer linking, and file sharing — Tor stays as automatic fallback",
|
||||
"Per-service transport preference Settings card (Auto / FIPS / Tor) per node-to-node surface",
|
||||
"Transport badge (FIPS / TOR / LAN / MESH) on every federated node card, reflecting the transport actually used on the last reach",
|
||||
"Transitive federation — accepting one peer automatically learns their trusted peers (one hop) so subsequent syncs go over FIPS directly",
|
||||
"Cancel button for outbound pending peer requests: withdraws locally and notifies the recipient to drop their inbound row",
|
||||
"Dedicated FIPS peer listener bound to fips0 ULA on port 5679 with a path whitelist (only signed endpoints are reachable from the mesh)",
|
||||
"Deploy script now writes /opt/archipelago/build-info.txt on every deploy so the UI sidebar version never drifts from the binary again"
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"name": "archipelago",
|
||||
"current_version": "1.3.5",
|
||||
"new_version": "1.4.0",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.4.0/archipelago",
|
||||
"sha256": "f42b03622ea47b953f5961a364cdfd1c354f21456dff7ec26594af4150c4976d",
|
||||
"size_bytes": 37714624
|
||||
"current_version": "1.4.0",
|
||||
"new_version": "1.5.0-alpha",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.5.0-alpha/archipelago",
|
||||
"sha256": "b7527e53b373aba05013b35750f890e5f98c91be542cbe406fa55216cb6a6acc",
|
||||
"size_bytes": 40020488
|
||||
},
|
||||
{
|
||||
"name": "archipelago-frontend-1.4.0.tar.gz",
|
||||
"current_version": "1.3.5",
|
||||
"new_version": "1.4.0",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.4.0/archipelago-frontend-1.4.0.tar.gz",
|
||||
"sha256": "100388985b98ab1adab191a23dd7a197f9a6c45c743da39f9df99d0213880086",
|
||||
"size_bytes": 76984287
|
||||
"name": "archipelago-frontend-1.5.0-alpha.tar.gz",
|
||||
"current_version": "1.4.0",
|
||||
"new_version": "1.5.0-alpha",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.5.0-alpha/archipelago-frontend-1.5.0-alpha.tar.gz",
|
||||
"sha256": "83fbacf3b0ba237cd78cc0be798f7d74d8aea5d62110a1eb6ecdc56f77cf505e",
|
||||
"size_bytes": 53359792
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
BIN
releases/v1.5.0-alpha/archipelago
Executable file
BIN
releases/v1.5.0-alpha/archipelago
Executable file
Binary file not shown.
BIN
releases/v1.5.0-alpha/archipelago-frontend-1.5.0-alpha.tar.gz
Normal file
BIN
releases/v1.5.0-alpha/archipelago-frontend-1.5.0-alpha.tar.gz
Normal file
Binary file not shown.
78
scripts/check-release-manifest.sh
Executable file
78
scripts/check-release-manifest.sh
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
# Validate releases/manifest.json:
|
||||
# - version matches core/archipelago/Cargo.toml
|
||||
# - changelog is non-empty (release notes are mandatory per product policy)
|
||||
# - every component's download_url exists on disk and matches sha256/size
|
||||
#
|
||||
# Run on every push from CI, and also locally before publishing a release:
|
||||
# scripts/check-release-manifest.sh
|
||||
#
|
||||
# Exits non-zero on any mismatch so the release process fails loud.
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
MANIFEST="$REPO_ROOT/releases/manifest.json"
|
||||
|
||||
if [ ! -f "$MANIFEST" ]; then
|
||||
echo "❌ releases/manifest.json missing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fail() { echo "❌ $*"; exit 1; }
|
||||
ok() { echo "✅ $*"; }
|
||||
|
||||
MANIFEST_VERSION=$(python3 -c "import json; print(json.load(open('$MANIFEST'))['version'])")
|
||||
CARGO_VERSION=$(grep '^version' "$REPO_ROOT/core/archipelago/Cargo.toml" | head -1 | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
|
||||
if [ "$MANIFEST_VERSION" != "$CARGO_VERSION" ]; then
|
||||
fail "manifest version ($MANIFEST_VERSION) ≠ Cargo.toml ($CARGO_VERSION)"
|
||||
fi
|
||||
ok "version matches: $MANIFEST_VERSION"
|
||||
|
||||
# Release notes mandatory — ships stuff nobody can read otherwise.
|
||||
CHANGELOG_COUNT=$(python3 -c "import json; print(len(json.load(open('$MANIFEST'))['changelog']))")
|
||||
if [ "$CHANGELOG_COUNT" -eq 0 ]; then
|
||||
fail "changelog is empty — every release MUST have release notes"
|
||||
fi
|
||||
ok "changelog has $CHANGELOG_COUNT lines"
|
||||
|
||||
# Each component: the artifact on disk under releases/v<version>/ must match
|
||||
# the declared sha256 and size_bytes.
|
||||
VERSION_DIR="$REPO_ROOT/releases/v${MANIFEST_VERSION}"
|
||||
if [ ! -d "$VERSION_DIR" ]; then
|
||||
fail "releases/v${MANIFEST_VERSION}/ missing — artifacts not staged"
|
||||
fi
|
||||
|
||||
COMPONENT_COUNT=$(python3 -c "import json; print(len(json.load(open('$MANIFEST'))['components']))")
|
||||
for i in $(seq 0 $((COMPONENT_COUNT - 1))); do
|
||||
NAME=$(python3 -c "import json; print(json.load(open('$MANIFEST'))['components'][$i]['name'])")
|
||||
DECLARED_SHA=$(python3 -c "import json; print(json.load(open('$MANIFEST'))['components'][$i]['sha256'])")
|
||||
DECLARED_SIZE=$(python3 -c "import json; print(json.load(open('$MANIFEST'))['components'][$i]['size_bytes'])")
|
||||
|
||||
# Component names other than exactly "archipelago" are the tarball's
|
||||
# filename; use as-is. The bare "archipelago" component maps to the
|
||||
# binary file literally named `archipelago`.
|
||||
FILE="$VERSION_DIR/$NAME"
|
||||
if [ "$NAME" = "archipelago" ]; then
|
||||
FILE="$VERSION_DIR/archipelago"
|
||||
fi
|
||||
|
||||
if [ ! -f "$FILE" ]; then
|
||||
fail "component '$NAME' file missing at $FILE"
|
||||
fi
|
||||
|
||||
ACTUAL_SHA=$(sha256sum "$FILE" | awk '{print $1}')
|
||||
ACTUAL_SIZE=$(stat -c%s "$FILE")
|
||||
|
||||
if [ "$ACTUAL_SHA" != "$DECLARED_SHA" ]; then
|
||||
fail "component '$NAME' sha256 mismatch (declared=$DECLARED_SHA actual=$ACTUAL_SHA)"
|
||||
fi
|
||||
if [ "$ACTUAL_SIZE" != "$DECLARED_SIZE" ]; then
|
||||
fail "component '$NAME' size mismatch (declared=$DECLARED_SIZE actual=$ACTUAL_SIZE)"
|
||||
fi
|
||||
ok "component '$NAME': sha256 + size match on-disk artifact"
|
||||
done
|
||||
|
||||
echo
|
||||
ok "releases/manifest.json passes all checks — safe to publish v${MANIFEST_VERSION}"
|
||||
@@ -923,6 +923,19 @@ PYEOF
|
||||
}
|
||||
MANIFEST_EOF
|
||||
|
||||
# Write build-info.txt — this is what the UI sidebar reads for the
|
||||
# displayed version (overrides the binary's CARGO_PKG_VERSION). Keeping
|
||||
# it synced with Cargo.toml on every deploy prevents the 1.3.x drift
|
||||
# we saw on .198/.253 where stale build-info survived across upgrades.
|
||||
DEPLOY_PKG_VERSION=$(grep '^version' "$PROJECT_DIR/core/archipelago/Cargo.toml" | head -1 | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
ssh $SSH_OPTS "$TARGET_HOST" "sudo tee /opt/archipelago/build-info.txt > /dev/null" << BUILDINFO_EOF
|
||||
version=$DEPLOY_PKG_VERSION
|
||||
build=$DEPLOY_TS
|
||||
commit=$DEPLOY_COMMIT
|
||||
date=$DEPLOY_TS
|
||||
type=deployed
|
||||
BUILDINFO_EOF
|
||||
|
||||
# Ensure NTP and swap are configured (prevents OOM kills and clock drift)
|
||||
progress "Ensuring NTP + swap"
|
||||
ssh $SSH_OPTS "$TARGET_HOST" '
|
||||
|
||||
Reference in New Issue
Block a user