ZDDC/zddc/release.sh
ZDDC 2dc9ad240c refactor: distribute via Codeberg release assets, drop the upstream image
Removes the codeberg.org/varasys/zddc-server registry image, which had
no remaining consumer outside this shop. The two chart Dockerfiles
(tnd-zddc-chart) now compile zddc-server from source at build time,
fetching the right tag from a Codeberg release. release-image.sh,
zddc/Containerfile, and zddc/podman-compose.yaml are gone.

Build artifacts (HTML tools + zddc-server binaries) move from
website/releases/ in this repo to Codeberg release assets attached to
git tags. The website at zddc.varasys.io serves them by reverse-
proxying /releases/<tag>/<asset> to the corresponding Codeberg URL,
so consumers (zddc-use, level-2 bootstrap stubs, the chart
Dockerfiles) only ever talk to zddc.varasys.io.

Releases page becomes server-rendered static HTML regenerated on each
build via a single Codeberg API call. A small website/releases/manifest.json
maps <tool>-<channel> → tag for runtime channel resolution by zddc-use
and the level-2 stubs.

Files added:
- shared/publish-codeberg-release.sh — POSIX-sh helper that creates a
  Codeberg release for a tag (sets prerelease flag from tag suffix)
  and uploads/replaces release assets idempotently. Sourced by
  build-lib.sh and zddc/release.sh.
- zddc/release.sh — replaces release-image.sh. Tags + cross-compiles
  binaries via native Go (no podman needed; install Go) + uploads to
  Codeberg release assets. No image build, no registry push.

Files modified:
- shared/build-lib.sh — promote_release tags + uploads via the helper
  for stable AND alpha/beta now (alpha/beta were untagged before).
  update_alpha removed; per-tool build.sh files no longer mirror to
  website/releases/<tool>_alpha.html on plain dev builds.
- build.sh — prefers native go build over the old podman-based
  cross-compile (which is gone with Containerfile). build_releases_index
  queries the Codeberg API once and writes static HTML + manifest.json,
  with graceful fallback when the API is unreachable.
- bootstrap/level2.html.tmpl — fetches manifest.json to resolve
  channel → tag, then fetches the asset from /releases/<tag>/<asset>
  (Caddy proxy). Replaces the old /releases/<tool>_<channel>.html flat
  URL pattern. Operators with curl'd level-2 stubs need to re-issue
  them — this is a breaking change.
- AGENTS.md, CLAUDE.md — rewritten to describe the new flow.
- .gitignore — releases/ artifacts now expected to be on Codeberg, not
  committed locally.

NOT in this commit (deferred until $CODEBERG_TOKEN is provisioned):
- Backfilling existing tags as Codeberg releases.
- Cleanup commit: git rm-ing the existing artifacts in website/releases/.
  Until backfill happens, those files are how operators with old
  bootstrap stubs still get content. Once Codeberg has the assets,
  drop them.
- The Caddy reverse-proxy config on zddc.varasys.io.

Operator-side changes (not in this repo):
- tnd-zddc-chart Dockerfile.prod and Dockerfile (dev) need updating
  to compile from source rather than `FROM codeberg.org/...:stable`.
  Done in a separate commit on that repo.
- Caddyfile rule for the /releases/<tag>/<asset> reverse-proxy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 21:18:26 -05:00

186 lines
6.6 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# release.sh — cut a zddc-server release: tag, compile binaries,
# publish them as assets to a Codeberg release.
#
# Usage:
# sh zddc/release.sh # alpha cut (default), version auto-derived
# sh zddc/release.sh alpha # same
# sh zddc/release.sh beta # beta cut, version auto-derived
# sh zddc/release.sh stable # stable cut, patch++ from latest stable
# sh zddc/release.sh stable 0.1.0 # stable cut, explicit version
#
# What this is NOT: there's no container image build, no registry push.
# Those went away when the upstream codeberg.org/varasys/zddc-server
# image lost its only consumers (tnd-zddc-chart's two Dockerfiles now
# compile from source directly, fetching this Codeberg release tarball
# / binary). See AGENTS.md "Releasing" for the full flow.
#
# Prerequisites:
# - Go 1.24+ on PATH.
# - $CODEBERG_TOKEN exported, scoped to write the VARASYS/ZDDC repo.
# - curl, jq, git.
#
# What it does:
# 1. Determine version per the pre-release semver scheme:
# alpha/beta → next_prerelease (vX.Y.Z-CHANNEL.N from latest stable)
# stable → operator-supplied or patch-bumped from latest stable
# 2. Tag the current commit zddc-server-v<version>.
# 3. Cross-compile binaries (linux/darwin/windows × amd64/arm64)
# into zddc/dist/zddc-server-<os>-<arch>[.exe]. Native Go preferred.
# 4. Upload each binary as an asset to the new Codeberg release.
# 5. Print the operator's next steps (push the tag).
#
# The script does NOT push the tag itself — that's a deliberate `git push`
# you do after reviewing.
set -eu
usage() {
cat >&2 <<'EOF'
usage: release.sh [alpha|beta|stable] [<version>]
alpha (default) cut alpha. Auto-derive version from the latest clean
zddc-server-vX.Y.Z tag plus next-patch + -alpha.N.
beta cut beta. Auto-derive version (vX.Y.Z + -beta.N).
stable cut stable. Without <version>, patch-bump from the
latest clean stable tag. With <version>, use it
verbatim (must be a clean X.Y.Z).
EOF
exit 1
}
CHANNEL="${1:-alpha}"
case "$CHANNEL" in
alpha | beta | stable) ;;
-h | --help) usage ;;
*) echo "error: unknown channel '$CHANNEL'" >&2; usage ;;
esac
EXPLICIT_VERSION="${2:-}"
if [ -n "$EXPLICIT_VERSION" ] && [ "$CHANNEL" != "stable" ]; then
echo "error: an explicit <version> is only valid with the 'stable' channel" >&2
echo " alpha and beta versions are auto-derived." >&2
exit 1
fi
if [ -z "${CODEBERG_TOKEN:-}" ]; then
echo "error: CODEBERG_TOKEN must be exported in the environment" >&2
echo " (Codeberg user → Settings → Applications → generate a token" >&2
echo " with scope sufficient to create releases on VARASYS/ZDDC.)" >&2
exit 1
fi
SCRIPT_DIR=$(cd "$(dirname "$0")/.." && pwd)
TAG_PREFIX="zddc-server-v"
REPO="VARASYS/ZDDC"
# Source build-lib.sh for next_prerelease + _validate_semver. It
# requires root_dir set; pointing at the repo root works.
root_dir="$SCRIPT_DIR"
. "$SCRIPT_DIR/shared/build-lib.sh"
. "$SCRIPT_DIR/shared/publish-codeberg-release.sh"
# --- Determine version -----------------------------------------------------
case "$CHANNEL" in
alpha | beta)
VERSION=$(next_prerelease "$CHANNEL" "$TAG_PREFIX")
;;
stable)
if [ -n "$EXPLICIT_VERSION" ]; then
_validate_semver "$EXPLICIT_VERSION"
VERSION="$EXPLICIT_VERSION"
else
_latest=$(git -C "$SCRIPT_DIR" tag --list "${TAG_PREFIX}*" 2>/dev/null \
| grep -E "^${TAG_PREFIX}[0-9]+\.[0-9]+\.[0-9]+\$" \
| sed "s|^${TAG_PREFIX}||" \
| sort -V \
| tail -1)
[ -n "$_latest" ] || _latest="0.0.0"
_major="${_latest%%.*}"
_rest="${_latest#*.}"
_minor="${_rest%%.*}"
_patch="${_rest#*.}"
VERSION="${_major}.${_minor}.$((_patch + 1))"
fi
;;
esac
GIT_TAG="${TAG_PREFIX}${VERSION}"
echo "=== zddc-server release ==="
echo "Channel: $CHANNEL"
echo "Version: $VERSION"
echo "Git tag: $GIT_TAG"
echo
# --- Tag the commit (idempotent: skip if the tag already points here) -----
if git -C "$SCRIPT_DIR" rev-parse -q --verify "refs/tags/$GIT_TAG" >/dev/null; then
_existing=$(git -C "$SCRIPT_DIR" rev-list -n 1 "$GIT_TAG")
_head=$(git -C "$SCRIPT_DIR" rev-parse HEAD)
if [ "$_existing" != "$_head" ]; then
echo "error: tag $GIT_TAG already exists at $_existing, but HEAD is $_head" >&2
echo " refusing to overwrite. Resolve manually." >&2
exit 1
fi
echo "(tag $GIT_TAG already at HEAD)"
else
git -C "$SCRIPT_DIR" tag "$GIT_TAG"
echo "tagged $GIT_TAG"
fi
# --- Cross-compile binaries (native Go) ------------------------------------
if ! command -v go >/dev/null 2>&1; then
echo "error: go not found on PATH" >&2
echo " (install Go 1.24+, or run this script from inside a Go" >&2
echo " container — there's no podman fallback anymore.)" >&2
exit 1
fi
DIST="$SCRIPT_DIR/zddc/dist"
mkdir -p "$DIST"
echo
echo "=== Cross-compiling ==="
cd "$SCRIPT_DIR/zddc"
LDFLAGS="-s -w -X main.version=${VERSION}"
for target in linux/amd64 darwin/amd64 darwin/arm64 windows/amd64; do
os="${target%/*}"
arch="${target#*/}"
out="zddc-server-${os}-${arch}"
case "$os" in windows) out="${out}.exe" ;; esac
echo " building $out"
CGO_ENABLED=0 GOOS="$os" GOARCH="$arch" \
go build -trimpath -ldflags="$LDFLAGS" -o "$DIST/$out" ./cmd/zddc-server
done
cd "$SCRIPT_DIR"
# --- Publish to Codeberg ---------------------------------------------------
echo
echo "=== Publishing to Codeberg release $GIT_TAG ==="
publish_codeberg_release "$REPO" "$GIT_TAG" \
"$DIST/zddc-server-linux-amd64" \
"$DIST/zddc-server-darwin-amd64" \
"$DIST/zddc-server-darwin-arm64" \
"$DIST/zddc-server-windows-amd64.exe"
echo
echo "=== Done ==="
echo "Release: https://codeberg.org/$REPO/releases/tag/$GIT_TAG"
echo "Git tag: $GIT_TAG (publish with: git push origin $GIT_TAG)"
echo
case "$CHANNEL" in
stable)
echo "Reminder (channel discipline rule 4): freshen alpha + beta now"
echo "so the floating channels resolve to at-least-current code:"
echo " ./freshen-channel zddc-server alpha"
echo " ./freshen-channel zddc-server beta"
;;
beta)
echo "Beta cut. Soak before promoting to stable."
;;
esac
echo
echo "Don't forget to also regenerate the website releases page:"
echo " sh build.sh"
echo " git add website/releases/index.html website/releases/manifest.json"
echo " git commit && git push"