Releases: VERSION + automatic patch tags + promote; updater installs newer versions (node-26#49)
Tag release / tag (push) Successful in 8s
CI / lint (push) Successful in 8s
CI / test-op25 (push) Successful in 16s
CI / test (push) Successful in 49s
Build edge-node / build (push) Successful in 1m2s

VERSION holds MAJOR.MINOR (1.1), edited by hand. Every push to main is
tagged vMAJOR.MINOR.PATCH by the "Tag release" workflow, with PATCH counted
as an integer by scripts/next-version.sh. "Promote release" moves the major
tag (v1) to a tested release and refuses to move it backwards.

drb-update.sh: a newer release on the node's channel is now a reason to
update by itself. REF=latest follows the highest vX.Y.Z tag (test nodes);
REF=v1 follows the promoted tag (customer nodes). Versions compare per
field as integers (1.10.0 > 1.9.3, never string or float order). It never
downgrades, and an untagged target still needs a request. After an update
it writes DRB_VERSION to .env; the edge node reports it in checkin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Logan Cusano
2026-11-09 00:34:50 -05:00
co-authored by Claude Opus 5.5
parent 6330609a75
commit 5549736706
8 changed files with 234 additions and 9 deletions
+39
View File
@@ -0,0 +1,39 @@
name: Promote release
# node-26#49: move the major tag (v1) to a tested release. Customer nodes
# (updater REF=v1) install it on their next timer run, because its version is
# numerically higher than what they run. Never moves it backwards.
on:
workflow_dispatch:
inputs:
version:
description: "Release to promote, e.g. 1.1.3 (must already be tagged v1.1.3)"
required: true
jobs:
promote:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Move the major tag
env:
VERSION: ${{ inputs.version }}
run: |
[[ "$VERSION" =~ ^([0-9]+)\.[0-9]+\.[0-9]+$ ]] || { echo "version must be MAJOR.MINOR.PATCH, got '$VERSION'"; exit 1; }
MAJOR="${BASH_REMATCH[1]}"
git fetch --force --tags origin
git rev-parse -q --verify "refs/tags/v$VERSION" >/dev/null || { echo "tag v$VERSION does not exist"; exit 1; }
# Refuse to go backwards: compare with the release v$MAJOR points at now.
CUR="$(git tag --points-at "v$MAJOR" 2>/dev/null | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
| sed 's/^v//' | sort -t. -k1,1n -k2,2n -k3,3n | tail -1 || true)"
if [ -n "$CUR" ]; then
HIGHEST="$(printf '%s\n%s\n' "$CUR" "$VERSION" | sort -t. -k1,1n -k2,2n -k3,3n | tail -1)"
[ "$HIGHEST" = "$VERSION" ] || { echo "v$MAJOR is at $CUR, newer than $VERSION — refusing to roll back here"; exit 1; }
fi
git tag -f "v$MAJOR" "v$VERSION^{commit}"
git push --force origin "refs/tags/v$MAJOR"
echo "v$MAJOR -> $VERSION (was ${CUR:-untagged})"
+31
View File
@@ -0,0 +1,31 @@
name: Tag release
# node-26#49: every push to main is a release, vMAJOR.MINOR.PATCH (see
# scripts/next-version.sh). Test nodes (updater REF=latest) install the
# highest tag on their next timer run; customer nodes (REF=v1) wait for the
# Promote workflow.
on:
push:
branches: [main]
concurrency:
group: version-tag
cancel-in-progress: false
jobs:
tag:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Tag this commit
run: |
git fetch --force --tags origin
TAG="$(bash scripts/next-version.sh)"
if [ -z "$TAG" ]; then echo "already tagged"; exit 0; fi
git tag "$TAG"
git push origin "refs/tags/$TAG"
echo "released $TAG"