Files
unraid-podman/scripts/release.sh
T
maggesandClaude Sonnet 5 d931d8e9e9
Build Packages / Build .txz packages (push) Successful in 8m36s
Lint / ShellCheck (push) Successful in 10s
Lint / Validate .plg XML (push) Successful in 12s
Lint / EditorConfig (push) Successful in 6s
Release / Build release packages (push) Successful in 7m50s
Release / Publish Gitea Release (push) Failing after 6s
release: v0.1.5
Fixes a real bug in scripts/release.sh's per-package entity matching
found while cutting this release: "podman"'s own glob also matched
podman-compose's file (podman is a literal prefix of podman-compose),
and find | head -n1's unsorted output order let podman-compose's
package silently win the "podman" entity on this run. Now explicitly
skips any match that actually belongs to a different, more specific
component name also in the COMPONENTS list.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 21:53:59 +00:00

177 lines
7.6 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# scripts/release.sh
#
# Cuts a release of the plugin itself:
# 1. Bumps the &version; entity in plugin/podman.plg to <new-version>.
# 2. Builds all eleven packages (scripts/build-packages.sh) unless
# SKIP_BUILD=1 is set (useful when CI already built them in a prior job
# and only wants this script to do the .plg/CHANGELOG bookkeeping).
# 3. Verifies + consolidates checksums (scripts/checksums.sh).
# 4. Rewrites the per-package <!ENTITY ..._txz_version/_txz_file/_txz_md5>
# entities in plugin/podman.plg from the freshly built dist/*.txz.md5
# sidecar files, and the &baseURL; entity to point at the GitHub
# Release that will hold these assets.
# 5. Moves CHANGELOG.md's [Unreleased] section under a new dated heading.
#
# This script deliberately does NOT `git commit`, `git tag`, or `gh release
# create` — it only prepares files. Committing/tagging/publishing is left to
# the caller (locally) or to .github/workflows/release.yml (in CI), so a
# human always reviews the diff before anything becomes public. See
# docs/ARCHITECTURE.md section 13 (Updates).
#
# Usage:
# scripts/release.sh <new-version> # e.g. scripts/release.sh 0.2.0
#
# Env vars:
# SKIP_BUILD=1 Skip scripts/build-packages.sh (assume dist/ already built)
# =============================================================================
set -eu
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PLG_FILE="$REPO_ROOT/plugin/podman.plg"
CHANGELOG_FILE="$REPO_ROOT/CHANGELOG.md"
DIST_DIR="$REPO_ROOT/dist"
NEW_VERSION="${1:-}"
if [ -z "$NEW_VERSION" ]; then
echo "usage: $0 <new-version>" >&2
exit 1
fi
if ! [[ "$NEW_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "!! <new-version> must be plain SemVer (X.Y.Z), got: $NEW_VERSION" >&2
exit 1
fi
# The release tag/URL this release's assets will be published under. This
# project is hosted on a self-hosted Gitea instance (git.mp-mueller.de),
# not GitHub — REPO_SLUG/RELEASE_HOST are overridable via env vars for a
# future move, but default to where this repo actually lives today. Must
# match plugin/podman.plg's &baseURL; entity exactly (see that file).
RELEASE_TAG="v$NEW_VERSION"
REPO_SLUG="${GITEA_REPOSITORY:-${GITHUB_REPOSITORY:-magges/unraid-podman}}"
RELEASE_HOST="${RELEASE_HOST:-git.mp-mueller.de}"
RELEASE_BASE_URL="https://$RELEASE_HOST/$REPO_SLUG/releases/download/$RELEASE_TAG"
# Component name -> the entity name prefix used in podman.plg. Must match
# plugin/podman.plg's <!ENTITY NAME_txz_...> declarations exactly.
# catatonit, nftables, and podman-compose are vendored runtime
# dependencies (not built from source, see their own packages/*/README.md)
# and unraid-podman is the plugin's own scaffolding package (see
# packages/unraid-podman/README.md), not an upstream component, but all
# four are released and entity-updated exactly like the seven upstream ones.
COMPONENTS=(podman conmon crun netavark aardvark-dns passt fuse-overlayfs catatonit nftables podman-compose unraid-podman)
echo "==> Releasing unraid-podman plugin v$NEW_VERSION (packages tag: $RELEASE_TAG)"
# --- 1. Build ----------------------------------------------------------------
if [ "${SKIP_BUILD:-0}" != "1" ]; then
echo "==> Building all packages"
"$REPO_ROOT/scripts/build-packages.sh"
else
echo "==> SKIP_BUILD=1, assuming $DIST_DIR is already populated"
fi
"$REPO_ROOT/scripts/checksums.sh" "$DIST_DIR"
# --- 2. Update plugin version entity ------------------------------------------
echo "==> Setting <!ENTITY version> to $NEW_VERSION in $PLG_FILE"
sed -i -E "s|(<!ENTITY version[[:space:]]+\")[^\"]*(\">)|\1${NEW_VERSION}\2|" "$PLG_FILE"
sed -i -E "s|(<!ENTITY baseURL[[:space:]]+\")[^\"]*(\">)|\1${RELEASE_BASE_URL}\2|" "$PLG_FILE"
# --- 3. Update per-package entities from dist/*.txz.md5 -----------------------
for name in "${COMPONENTS[@]}"; do
# dist/ contains files like podman-6.0.1-x86_64-1_unraidpodman.txz — find
# the one for this component (there should be exactly one per release).
# NOT `find ... | head -n1`: "podman"'s own glob (podman-*-*-*.txz) also
# matches podman-compose's file (podman-compose-*-*-*.txz), since
# "podman" is a literal prefix of "podman-compose" — find's output order
# is filesystem-dependent, not sorted, so head -n1 silently picked
# podman-compose's package for the "podman" entity on one real run,
# publishing a release whose podman.plg pointed at the wrong .txz for
# the actual podman package entirely. Explicitly skip any match that
# actually belongs to a DIFFERENT, more specific name also in
# COMPONENTS (i.e. itself prefixed by another component's name).
txz_path=""
for candidate in "$DIST_DIR"/"${name}"-*-*-*.txz; do
[ -e "$candidate" ] || continue
base=$(basename "$candidate")
belongs_to_other=0
for other in "${COMPONENTS[@]}"; do
if [ "$other" != "$name" ] && [ "${base#"$other"-}" != "$base" ]; then
belongs_to_other=1
break
fi
done
if [ "$belongs_to_other" -eq 0 ]; then
txz_path="$candidate"
break
fi
done
if [ -z "$txz_path" ]; then
echo "!! No built .txz found for component '$name' in $DIST_DIR" >&2
echo "!! Did scripts/build-packages.sh run successfully for it?" >&2
exit 1
fi
txz_file=$(basename "$txz_path")
md5_path="$txz_path.md5"
if [ ! -f "$md5_path" ]; then
echo "!! Missing $md5_path" >&2
exit 1
fi
md5=$(awk '{print $1}' "$md5_path")
# Component version is everything between "<name>-" and the next "-<arch>-"
# e.g. "podman-6.0.1-x86_64-1_unraidpodman.txz" -> "6.0.1"
txz_version=$(echo "$txz_file" | sed -E "s/^${name}-(.+)-[^-]+-[0-9]+[^-]*\.txz\$/\1/")
entity_prefix=$(echo "$name" | tr '-' '_')
echo "==> [$name] $txz_file (md5=$md5)"
sed -i -E "s|(<!ENTITY ${entity_prefix}_txz_version[[:space:]]+\")[^\"]*(\">)|\1${txz_version}\2|" "$PLG_FILE"
sed -i -E "s|(<!ENTITY ${entity_prefix}_txz_file[[:space:]]+\")[^\"]*(\">)|\1${txz_file}\2|" "$PLG_FILE"
sed -i -E "s|(<!ENTITY ${entity_prefix}_txz_md5[[:space:]]+\")[^\"]*(\">)|\1${md5}\2|" "$PLG_FILE"
done
# --- 4. Update CHANGELOG.md ---------------------------------------------------
# Pure awk (no python/perl dependency — this script also has to run inside
# the minimal Slackware build container, see .github/workflows/release.yml):
# inserts a fresh "## [<version>] - <date>" heading right after the existing
# "## [Unreleased]" marker, leaving [Unreleased] itself empty and at the top
# for the next round of changes.
echo "==> Moving CHANGELOG.md [Unreleased] section under [$NEW_VERSION]"
TODAY=$(date -u +%Y-%m-%d)
if ! grep -q '^## \[Unreleased\]$' "$CHANGELOG_FILE"; then
echo "!! No '## [Unreleased]' heading found in $CHANGELOG_FILE" >&2
exit 1
fi
awk -v ver="$NEW_VERSION" -v date="$TODAY" '
!done && $0 == "## [Unreleased]" {
print $0
print ""
print "## [" ver "] - " date
done = 1
next
}
{ print $0 }
' "$CHANGELOG_FILE" > "$CHANGELOG_FILE.tmp"
mv "$CHANGELOG_FILE.tmp" "$CHANGELOG_FILE"
echo
echo "==> Release preparation complete for v$NEW_VERSION."
echo "==> Review the diff, then:"
echo " git add plugin/podman.plg CHANGELOG.md"
echo " git commit -m \"release: v$NEW_VERSION\""
echo " git tag $RELEASE_TAG"
echo " git push && git push origin $RELEASE_TAG"
echo "==> .github/workflows/release.yml (softprops/action-gh-release) only"
echo "==> knows how to publish to GitHub — this repo lives on Gitea"
echo "==> ($RELEASE_HOST), so for now, publish the Gitea Release and attach"
echo "==> dist/*.txz + CHECKSUMS.* + the updated podman.plg to it by hand"
echo "==> (or via the Gitea API) after pushing the tag."