#!/usr/bin/env bash set -euo pipefail # Fenris one-command release flow (issue #52). # Builds both packages, signs, uploads to registry, creates release entry, # and attaches artifacts — or in dry-run mode, prints every command. # # Usage: # scripts/release.sh --dry-run # Print commands without executing # scripts/release.sh --publish # Execute the full release flow # # Environment: # GITEA_TOKEN - API token for Gitea registry and release API # PACKAGING_KEY - GPG key UID (default: packaging@bongbetic.com) # # Spec: release-packaging.md §5 # ── Defaults ───────────────────────────────────────────────────────────── DRY_RUN=false PUBLISH=false GITEA_URL="https://git.bongbetic.com" GITEA_OWNER="xavierk" GITEA_REPO="Fenris" PACKAGING_KEY="${PACKAGING_KEY:-packaging@bongbetic.com}" CODENAMES=(bookworm jammy noble) RPM_GROUP="fenris" # ── Parse arguments ────────────────────────────────────────────────────── for arg in "$@"; do case "$arg" in --dry-run) DRY_RUN=true ;; --publish) PUBLISH=true ;; --help|-h) echo "Usage: $0 [--dry-run | --publish]" echo "" echo "Modes:" echo " --dry-run Print commands without executing (default)" echo " --publish Execute the full release flow" echo "" echo "Environment:" echo " GITEA_TOKEN API token for Gitea registry and release API" echo " PACKAGING_KEY GPG key UID (default: packaging@bongbetic.com)" exit 0 ;; *) echo "Unknown argument: $arg" >&2 echo "Usage: $0 [--dry-run | --publish]" >&2 exit 1 ;; esac done if ! $DRY_RUN && ! $PUBLISH; then DRY_RUN=true fi # ── Helpers ────────────────────────────────────────────────────────────── _version() { sed -n 's/^version = "\(.*\)"/\1/p' pyproject.toml } _deb_name() { local ver="$1" echo "fenris_${ver}_amd64.deb" } _rpm_name() { local ver="$1" rel="$2" echo "fenris-${ver}-${rel}.x86_64.rpm" } _run() { if $DRY_RUN; then echo " $*" else eval "$@" fi } # ── Main ───────────────────────────────────────────────────────────────── VERSION=$(_version) REVISION=1 DEB=$(_deb_name "$VERSION") RPM=$(_rpm_name "$VERSION" "$REVISION") echo "=== Fenris Release v${VERSION} ===" echo "" if $DRY_RUN; then echo "[dry-run] Commands below will be executed in --publish mode." echo "" fi # ── Step 1: Build both formats ────────────────────────────────────────── echo "--- Build packages ---" _run "make package" echo "" # ── Step 2: Sign RPM payload ──────────────────────────────────────────── echo "--- Sign RPM payload ---" _run "rpmsign --addsign --define '_gpg_name ${PACKAGING_KEY}' dist/${RPM}" echo "" # ── Step 3: Generate and clearsign SHA256SUMS ──────────────────────────── echo "--- Generate SHA256SUMS ---" _run "cd dist && sha256sum ${DEB} ${RPM} > SHA256SUMS" echo "" echo "--- Clearsign SHA256SUMS ---" _run "gpg --batch --yes --clearsign --local-user ${PACKAGING_KEY} dist/SHA256SUMS" echo "" # ── Step 4: Upload to Gitea package registry ───────────────────────────── echo "--- Upload packages to registry ---" for codename in "${CODENAMES[@]}"; do _run "curl --fail -X PUT -u ${GITEA_OWNER}:\$GITEA_TOKEN -T dist/${DEB} '${GITEA_URL}/api/packages/${GITEA_OWNER}/debian/pool/${codename}/main/upload'" done _run "curl --fail -X PUT -u ${GITEA_OWNER}:\$GITEA_TOKEN -T dist/${RPM} '${GITEA_URL}/api/packages/${GITEA_OWNER}/rpm/${RPM_GROUP}/upload'" echo "" # ── Step 5: Create Gitea release with notes ───────────────────────────── echo "--- Create Gitea release ---" _release_notes="Release v${VERSION} ## Packages Install via apt (Debian/Ubuntu): \`\`\`bash curl --fail -fsSL https://git.bongbetic.com/${GITEA_OWNER}/${GITEA_REPO}/raw/branch/main/packaging/keys/fenris-packaging.asc | sudo gpg --dearmor -o /etc/apt/keyrings/fenris.asc echo \"deb [signed-by=/etc/apt/keyrings/fenris.asc] https://git.bongbetic.com/api/packages/${GITEA_OWNER}/debian bookworm main\" | sudo tee /etc/apt/sources.list.d/fenris.list sudo apt update && sudo apt install fenris \`\`\` Install via dnf (Fedora): \`\`\`bash sudo dnf config-manager --add-repo https://git.bongbetic.com/${GITEA_OWNER}/${GITEA_REPO}/raw/branch/main/packaging/fenris.repo sudo dnf install fenris \`\`\` ## Verification \`\`\`bash rpm -Kv fenris-${VERSION}-1.x86_64.rpm gpg --verify SHA256SUMS.asc SHA256SUMS \`\`\` ## Artifacts - \`dist/${DEB}\` (Debian/Ubuntu) - \`dist/${RPM}\` (Fedora) - \`dist/SHA256SUMS.asc\` (clearsigned checksums) See [docs/install/signing-key-ceremony.md](docs/install/signing-key-ceremony.md) for key ceremony details. See [docs/install/migrate-from-makeinstall.md](docs/install/migrate-from-makeinstall.md) for migration from make install." if $DRY_RUN; then _run "curl --fail -X POST -u ${GITEA_OWNER}:\$GITEA_TOKEN -H 'Content-Type: application/json' -d '{\"tag_name\":\"v${VERSION}\",\"name\":\"v${VERSION}\",\"body\":\"...\"}' '${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases'" else # Create release via Gitea API (creates the tag atomically — no bare tag) RELEASE_RESPONSE=$(curl --fail -s -X POST \ -u "${GITEA_OWNER}:${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ -d "$(jq -n \ --arg tag "v${VERSION}" \ --arg name "v${VERSION}" \ --arg body "$_release_notes" \ '{tag_name: $tag, name: $name, body: $body}')" \ "${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases") RELEASE_ID=$(echo "$RELEASE_RESPONSE" | jq -r '.id') echo " Release created: ${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}/releases/tag/v${VERSION}" fi echo "" # ── Step 6: Attach artifacts to release ────────────────────────────────── echo "--- Attach artifacts to release ---" for artifact in "dist/${DEB}" "dist/${RPM}" "dist/SHA256SUMS.asc"; do _run "curl --fail -X POST -u ${GITEA_OWNER}:\$GITEA_TOKEN -F 'attachment=@${artifact}' '${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/${RELEASE_ID:-0}/assets'" done echo "" # ── Done ───────────────────────────────────────────────────────────────── echo "=== Release v${VERSION} complete ===" echo "" echo "Summary:" echo " Packages: ${DEB}, ${RPM}" echo " Checksums: dist/SHA256SUMS.asc" echo " Registry: deb → bookworm, jammy, noble; rpm → ${RPM_GROUP}" echo " Release: ${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}/releases/tag/v${VERSION}" echo "" echo "Key ceremony: delete the private key after release." echo " See docs/install/signing-key-ceremony.md"