Implement XBPS proof of concept (issue #83)
Prove signed XBPS installation and immediate updates through Gitea. Changes: - Add scripts/xbps-publish.sh for automated XBPS publication - Add Makefile targets: package-xbps, sign-xbps, xbps-publish - Add docs/spec/xbps-proof-results.md with acceptance criteria results - Add docs/adr/0008-native-void-support.md (architecture decision) - Add docs/spec/native-void-support.md (feature specification) - Add docs/spec/native-void-tickets.md (implementation tickets) Proof results: - Raw URL delivery verified (no LFS indirection) - Signing key handling established (SSH RSA via xbps-rindex) - Install and update flow demonstrated (v0.3.5 → v0.3.6) - Cache behavior documented (6-hour max-age, -S flag for immediate discovery) - Publication mechanism documented and automated - Failure recovery demonstrated (git revert) Repository: https://git.bongbetic.com/xavierk/Fenris-xbps Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
co-authored by
CommandCodeBot
parent
ed61c4e1ec
commit
985efed906
Executable
+170
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Fenris XBPS publication script (issue #83).
|
||||
# Builds, signs, and publishes XBPS packages to the Fenris-xbps repository.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/xbps-publish.sh --dry-run # Print commands without executing
|
||||
# scripts/xbps-publish.sh --publish # Execute the full publication flow
|
||||
#
|
||||
# Environment:
|
||||
# XBPS_SIGNING_KEY - Path to SSH RSA private key for XBPS signing
|
||||
# (default: ~/.ssh/id_rsa)
|
||||
# SIGNED_BY - Signature identity string
|
||||
# (default: "Fenris Packaging <packaging@bongbetic.com>")
|
||||
#
|
||||
# Spec: native-void-support.md, ADR 0008
|
||||
|
||||
# ── Defaults ─────────────────────────────────────────────────────────────
|
||||
|
||||
DRY_RUN=false
|
||||
PUBLISH=false
|
||||
GITEA_URL="https://git.bongbetic.com"
|
||||
GITEA_OWNER="xavierk"
|
||||
GITEA_REPO="Fenris-xbps"
|
||||
GITEA_BRANCH="stable"
|
||||
ARCH="x86_64"
|
||||
XBPS_SIGNING_KEY="${XBPS_SIGNING_KEY:-$HOME/.ssh/id_rsa}"
|
||||
SIGNED_BY="${SIGNED_BY:-Fenris Packaging <packaging@bongbetic.com>}"
|
||||
|
||||
# ── 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 publication flow"
|
||||
echo ""
|
||||
echo "Environment:"
|
||||
echo " XBPS_SIGNING_KEY Path to SSH RSA private key (default: ~/.ssh/id_rsa)"
|
||||
echo " SIGNED_BY Signature identity (default: Fenris Packaging <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
|
||||
}
|
||||
|
||||
_run() {
|
||||
if $DRY_RUN; then
|
||||
echo " $*"
|
||||
else
|
||||
eval "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Pre-flight checks ───────────────────────────────────────────────────
|
||||
|
||||
if [[ ! -f "$XBPS_SIGNING_KEY" ]]; then
|
||||
echo "ERROR: Signing key not found at $XBPS_SIGNING_KEY" >&2
|
||||
echo "Generate one with: ssh-keygen -t rsa -b 3072 -f $XBPS_SIGNING_KEY" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for tool in xbps-create xbps-rindex git; do
|
||||
if ! command -v "$tool" &>/dev/null; then
|
||||
echo "ERROR: Required tool not found: $tool" >&2
|
||||
exit 1
|
||||
done
|
||||
done
|
||||
|
||||
# ── Main ─────────────────────────────────────────────────────────────────
|
||||
|
||||
VERSION=$(_version)
|
||||
REVISION=1
|
||||
PKGVER="fenris-${VERSION}_${REVISION}"
|
||||
XBPS_FILE="${PKGVER}.${ARCH}.xbps"
|
||||
|
||||
echo "=== Fenris XBPS Publication v${VERSION} ==="
|
||||
echo ""
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo "[dry-run] Commands below will be executed in --publish mode."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# ── Step 1: Build XBPS package ───────────────────────────────────────────
|
||||
|
||||
echo "--- Build XBPS package ---"
|
||||
_run "make stage"
|
||||
_run "xbps-create -A ${ARCH} -n ${PKGVER} -s 'Fenris NVMe wear monitor' -S 'NVMe wear monitor with persistent TUI' -m 'Fenris Packaging <packaging@bongbetic.com>' -H 'https://git.bongbetic.com/xavierk/Fenris' -l 'MIT' build/stage"
|
||||
echo ""
|
||||
|
||||
# ── Step 2: Sign package ─────────────────────────────────────────────────
|
||||
|
||||
echo "--- Sign XBPS package ---"
|
||||
_run "xbps-rindex --sign-pkg --privkey ${XBPS_SIGNING_KEY} ${XBPS_FILE}"
|
||||
echo ""
|
||||
|
||||
# ── Step 3: Clone/update distribution repository ─────────────────────────
|
||||
|
||||
echo "--- Prepare distribution repository ---"
|
||||
WORK_DIR=$(mktemp -d)
|
||||
_run "git clone ${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}.git ${WORK_DIR}"
|
||||
_run "cd ${WORK_DIR} && git checkout ${GITEA_BRANCH}"
|
||||
_run "mkdir -p ${WORK_DIR}/${ARCH}"
|
||||
echo ""
|
||||
|
||||
# ── Step 4: Copy artifacts and update index ──────────────────────────────
|
||||
|
||||
echo "--- Update repository index ---"
|
||||
_run "cp ${XBPS_FILE} ${XBPS_FILE}.sig2 ${WORK_DIR}/${ARCH}/"
|
||||
_run "cd ${WORK_DIR} && xbps-rindex --add ${ARCH}/${XBPS_FILE}"
|
||||
_run "cd ${WORK_DIR} && xbps-rindex --sign --privkey ${XBPS_SIGNING_KEY} --signedby '${SIGNED_BY}' ${ARCH}"
|
||||
echo ""
|
||||
|
||||
# ── Step 5: Commit and push ──────────────────────────────────────────────
|
||||
|
||||
echo "--- Commit and push ---"
|
||||
_run "cd ${WORK_DIR} && git add -A"
|
||||
_run "cd ${WORK_DIR} && git commit -m 'Release fenris ${VERSION}'"
|
||||
_run "cd ${WORK_DIR} && git push origin ${GITEA_BRANCH}"
|
||||
echo ""
|
||||
|
||||
# ── Step 6: Verify publication ───────────────────────────────────────────
|
||||
|
||||
echo "--- Verify publication ---"
|
||||
RAW_URL="${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}/raw/branch/${GITEA_BRANCH}/${ARCH}/x86_64-repodata"
|
||||
_run "curl -sI '${RAW_URL}' | head -5"
|
||||
echo ""
|
||||
|
||||
# ── Cleanup ──────────────────────────────────────────────────────────────
|
||||
|
||||
if $PUBLISH; then
|
||||
rm -rf "${WORK_DIR}"
|
||||
fi
|
||||
|
||||
# ── Done ─────────────────────────────────────────────────────────────────
|
||||
|
||||
echo "=== XBPS Publication v${VERSION} complete ==="
|
||||
echo ""
|
||||
echo "Summary:"
|
||||
echo " Package: ${XBPS_FILE}"
|
||||
echo " Repository: ${GITEA_URL}/${GITEA_OWNER}/${GITEA_REPO}"
|
||||
echo " Branch: ${GITEA_BRANCH}"
|
||||
echo " Repository URL: https://git.bongbetic.com/${GITEA_OWNER}/${GITEA_REPO}/raw/branch/${GITEA_BRANCH}/${ARCH}"
|
||||
echo ""
|
||||
echo "Client installation:"
|
||||
echo " sudo xbps-install -S https://git.bongbetic.com/${GITEA_OWNER}/${GITEA_REPO}/raw/branch/${GITEA_BRANCH}/${ARCH}"
|
||||
echo ""
|
||||
echo "Key ceremony: delete the private key after publication."
|
||||
echo " See docs/install/signing-key-ceremony.md"
|
||||
Reference in New Issue
Block a user