Add reproducible build system, native Unraid plugin, and WebUI
Build Packages / Build .txz packages (push) Failing after 9s
Lint / ShellCheck (push) Failing after 43s
Lint / Validate .plg XML (push) Successful in 10s
Lint / EditorConfig (push) Failing after 6s

- versions.env pins podman, conmon, crun, netavark, aardvark-dns, passt,
  and fuse-overlayfs to verified upstream source checksums; SlackBuild
  recipes, scripts/build-packages.sh, checksums.sh, release.sh, and
  update-versions.sh implement the reproducible pipeline; GitHub Actions
  workflows build in a Slackware container and publish releases without
  committing any binaries.

- plugin/podman.plg installs/updates/removes all eight packages (the
  seven components plus the plugin's own unraid-podman scaffolding
  package) via upgradepkg, using the official Unraid array-event hook
  mechanism (event/disks_mounted, event/stopping) instead of editing
  /boot/config/go. rc.podman and the sbin/ helper scripts implement
  storage creation, config seeding/sync, preflight checks, autostart
  with per-container Safe-Mode, and package verify/update/rollback.

- webui/plugins/podman implements the Dashboard, Containers, Pods,
  Images, Volumes, Networks, Logs, Terminal, Compose, and Settings
  panels against the approved mockup (webui/mockups/prototype.html),
  talking to podman system service exclusively via PodmanClient.php
  (libpod REST API over the Unix socket), with two documented
  exceptions: Terminal's one-shot exec model and Compose's use of the
  podman compose CLI, since libpod has no REST equivalent for either.

- docs/ARCHITECTURE.md and docs/ROADMAP.md record the design decisions
  and honest current status (syntax-checked, unit- and
  integration-tested against fake sockets/servers; not yet run against
  a real Unraid/Podman/Slackware system).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 10:51:14 +00:00
co-authored by Claude Sonnet 5
parent 58ffc0c226
commit e2fefcdf9c
124 changed files with 9611 additions and 0 deletions
+146
View File
@@ -0,0 +1,146 @@
#!/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 seven 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 GitHub Release tag/URL this release's assets will be published under.
# Must match whatever .github/workflows/release.yml actually creates the
# release as (tag "v<version>") — see that workflow for the release job.
RELEASE_TAG="v$NEW_VERSION"
REPO_SLUG="${GITHUB_REPOSITORY:-OWNER/unraid-podman}"
RELEASE_BASE_URL="https://github.com/$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.
# unraid-podman is the plugin's own scaffolding package (see
# packages/unraid-podman/README.md), not an upstream component, but it's
# released and entity-updated exactly like the other seven.
COMPONENTS=(podman conmon crun netavark aardvark-dns passt fuse-overlayfs 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).
txz_path=$(find "$DIST_DIR" -maxdepth 1 -name "${name}-*-*-*.txz" | head -n1)
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 "==> Pushing the tag triggers .github/workflows/release.yml, which"
echo "==> rebuilds artifacts in CI (for reproducibility/provenance) and"
echo "==> publishes the GitHub Release with dist/*.txz + CHECKSUMS.* + the"
echo "==> updated podman.plg attached."