Files
CIAgent 1a88ab3199
Release / release (push) Successful in 3m45s
CI / python (push) Successful in 1m52s
CI / node (push) Successful in 1m0s
merge: milestone/v0.8-ship-anywhere -> main (v0.8 complete — Ship Anywhere)
The v0.8 milestone: installable on any Debian-based server via docker
(Gitea registry image, honest sandbox degrade), deb (amd64+arm64,
advisory postinst), and arch-aware binary — with release consistency
enforced by pre-commit hooks + Gitea Actions (3-runner fleet on CT 113,
machine-made releases with the full 8-asset matrix + registry image), the
CLI carrying the full suite (guide, channel-aware doctor), and the admin
runbook (deploy/README.md, evidence-backed recipes).

---ci---
phase: 6
milestone: v0.8
status: complete
requirements:
  covered: [REQ-8-001, REQ-8-002, REQ-8-003, REQ-8-004, REQ-8-005]
  partial: []
---/ci---
2026-09-29 16:04:40 +00:00

87 lines
3.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# build-deb.sh — .deb packages for the nextcraft CLI (v0.8 P3, REQ-8-003,
# R-22/R-23). Contents per D-067: the CLI binary + docs ONLY — no systemd
# unit (deploy --service owns unit generation), no proxy fragments; the
# postinst runs an ADVISORY doctor (never fails dpkg; || echo → exit 0).
#
# Usage: scripts/build-deb.sh <tag> <arch> (arch = x64|arm64)
# Output: dist/deb/nextcraft_<ver>_<debarch>.deb (+ .sha256 sidecar)
#
# deb Version = tag minus the leading v (R-22: upstream-version must not
# start with 'v' — the policy-clean form; --nocheck escape hatch noted,
# never needed).
set -euo pipefail
TAG="${1:?usage: build-deb.sh <tag> <arch>}"
ARCH="${2:?usage: build-deb.sh <tag> <arch> (x64|arm64)}"
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
DIST="$ROOT/apps/cli/dist"
case "$ARCH" in
x64) DEB_ARCH="amd64"; BIN_NAME="nextcraft-linux-x64" ;;
arm64) DEB_ARCH="arm64"; BIN_NAME="nextcraft-linux-arm64" ;;
*) echo "unknown arch: $ARCH (x64|arm64)"; exit 1 ;;
esac
VERSION="${TAG#v}"
if [ "$VERSION" = "$TAG" ]; then
echo "warning: tag '$TAG' has no v-prefix; using as-is" >&2
fi
BIN="$DIST/$BIN_NAME"
[ -f "$BIN" ] || { echo "binary missing: $BIN — run build:binary $TAG --arch $ARCH first"; exit 1; }
[ -f "$BIN.sha256" ] || { echo "checksum missing: $BIN.sha256"; exit 1; }
PKGROOT="$(mktemp -d /tmp/nc-deb-XXXXXX)"
OUTDIR="$DIST/deb"
mkdir -p "$PKGROOT/DEBIAN" "$PKGROOT/usr/bin" "$PKGROOT/usr/share/doc/nextcraft" "$OUTDIR"
# -- control (R-22: empty Depends — the CLI is self-contained (SEA embeds
# node); Recommends names the host-side stack deploy wants) ----------
cat > "$PKGROOT/DEBIAN/control" << EOF
Package: nextcraft
Version: $VERSION
Section: utils
Priority: optional
Architecture: $DEB_ARCH
Maintainer: coreci <coreci@git.coreci.dev>
Depends:
Recommends: nodejs, python3, git, util-linux
Description: Nextcraft bootstrap CLI — doctor, verify, guide, deploy
The self-contained nextcraft CLI (node SEA binary). Takes a Debian
server zero -> running: doctor (preflight), verify (health), guide
(offline admin runbook), deploy (single-port stack). The Recommended
packages are the host-side stack the deploy command orchestrates.
Installed-Size: $(du -sk "$PKGROOT" | cut -f1)
EOF
# -- postinst (R-23: advisory doctor, NEVER fails dpkg) --------------------
cat > "$PKGROOT/DEBIAN/postinst" << 'EOF'
#!/bin/sh
# Advisory postinst (D-067): a missing Recommends must not fail the
# install — the doctor output tells the admin what deploy will need.
echo "nextcraft: installed to /usr/bin/nextcraft"
echo "nextcraft: advisory doctor (failures are informational, not dpkg errors):"
/usr/bin/nextcraft doctor || echo "nextcraft: doctor reported failures above — install the Recommends (nodejs python3 git util-linux) before 'nextcraft deploy'"
echo "nextcraft: next steps — 'nextcraft doctor' (after installing Recommends), 'nextcraft guide', 'nextcraft deploy --service'"
exit 0
EOF
chmod 0755 "$PKGROOT/DEBIAN/postinst"
# -- contents ---------------------------------------------------------------
install -m 0755 "$BIN" "$PKGROOT/usr/bin/nextcraft"
# Docs: the admin guide text ships with the package (guide points here too)
cp "$ROOT/README.md" "$PKGROOT/usr/share/doc/nextcraft/README.md" 2>/dev/null || true
if [ -f "$ROOT/deploy/README.md" ]; then
cp "$ROOT/deploy/README.md" "$PKGROOT/usr/share/doc/nextcraft/deploy-guide.md"
fi
# -- build -------------------------------------------------------------------
DEB="$OUTDIR/nextcraft_${VERSION}_${DEB_ARCH}.deb"
dpkg-deb --root-owner-group --build -Zxz "$PKGROOT" "$DEB" >/dev/null
sha256sum "$DEB" | sed "s| $OUTDIR/| |" > "$DEB.sha256"
SIZE="$(stat -c%s "$DEB")"
echo "built $DEB ($((SIZE / 1024 / 1024)) MB, $DEB_ARCH, version $VERSION)"
rm -rf "$PKGROOT"