#!/bin/bash # ============================================================================= # scripts/release.sh # # Cuts a release of the plugin itself: # 1. Bumps the &version; entity in plugin/podman.plg to . # 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 # 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 # 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 " >&2 exit 1 fi if ! [[ "$NEW_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "!! 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 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 to $NEW_VERSION in $PLG_FILE" sed -i -E "s|()|\1${NEW_VERSION}\2|" "$PLG_FILE" sed -i -E "s|()|\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 "-" and the next "--" # 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|()|\1${txz_version}\2|" "$PLG_FILE" sed -i -E "s|()|\1${txz_file}\2|" "$PLG_FILE" sed -i -E "s|()|\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 "## [] - " 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."