feat: apt-based deployment via Gitea Debian registry
Deklarix now ships as a .deb package instead of a raw binary, matching the enconf-webpanel infrastructure standard: scripts/build.sh assembles a real .deb (systemd unit, env template, postinst/prerm), scripts/release.sh uploads it to Gitea's built-in Debian package registry after a green test run. Target servers add one apt source and get updates via `apt upgrade` from then on. postinst only starts the service once DATABASE_URL is actually set in /etc/deklarix/deklarix.env — the shipped template ships it commented out on purpose, since an uncommented but unfilled placeholder URL is syntactically indistinguishable from a real one and caused exactly that crash-loop during verification. Verified end-to-end against the real test server and Gitea registry: upload -> apt-get update -> apt-cache policy -> apt-get install -> a service that stays down until configured, then runs migrations and serves /health once a real database is set. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,23 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
# Deklarix — Build-Skript (amd64 + arm64)
|
||||
# Deklarix — .deb-Pakete bauen (amd64 + arm64)
|
||||
#
|
||||
# Verwendung:
|
||||
# ./scripts/build.sh [version] # Beide Architekturen
|
||||
# ./scripts/build.sh [version] amd64 # Nur amd64
|
||||
# ./scripts/build.sh [version] arm64 # Nur arm64
|
||||
#
|
||||
# Ausgabe: dist/deklarix_<version>_<arch>
|
||||
#
|
||||
# Release-Prozess:
|
||||
# 1. VERSION erhöhen (Semantic Versioning: MAJOR.MINOR.PATCH)
|
||||
# 2. ./scripts/build.sh <version>
|
||||
# 3. ./scripts/test.sh
|
||||
# 4. git tag v<version> && git push origin v<version>
|
||||
# Ausgabe: dist/deklarix_<version>_<arch>.deb
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
PACKAGING_DIR="$REPO_DIR/packaging"
|
||||
BUILD_DIR="$REPO_DIR/dist/build"
|
||||
VERSION="${1:-0.0.1}"
|
||||
ARCH_FILTER="${2:-both}"
|
||||
|
||||
@@ -26,9 +22,8 @@ log() { echo -e "${GRN}[build]${NC} $*"; }
|
||||
|
||||
export PATH=$PATH:/usr/local/go/bin
|
||||
|
||||
command -v go >/dev/null || { echo "Go nicht gefunden — PATH: $PATH"; exit 1; }
|
||||
|
||||
mkdir -p "$REPO_DIR/dist"
|
||||
command -v go >/dev/null || { echo "Go nicht gefunden — PATH: $PATH"; exit 1; }
|
||||
command -v dpkg-deb >/dev/null || { echo "dpkg-deb nicht gefunden"; exit 1; }
|
||||
|
||||
log "Version: $VERSION | Go: $(go version)"
|
||||
|
||||
@@ -39,14 +34,40 @@ case "$ARCH_FILTER" in
|
||||
*) ARCHS=("amd64" "arm64") ;;
|
||||
esac
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir -p "$REPO_DIR/dist"
|
||||
|
||||
for ARCH in "${ARCHS[@]}"; do
|
||||
OUT="$REPO_DIR/dist/deklarix_${VERSION}_${ARCH}"
|
||||
log "Baue $ARCH → $OUT"
|
||||
GOARCH=$ARCH GOOS=linux go build \
|
||||
-ldflags="-X main.Version=${VERSION} -s -w" \
|
||||
-o "$OUT" \
|
||||
DEB_NAME="deklarix_${VERSION}_${ARCH}"
|
||||
DEB_DIR="$BUILD_DIR/$DEB_NAME"
|
||||
|
||||
log "Baue Binary ($ARCH)..."
|
||||
mkdir -p "$DEB_DIR/DEBIAN" \
|
||||
"$DEB_DIR/usr/bin" \
|
||||
"$DEB_DIR/etc/systemd/system" \
|
||||
"$DEB_DIR/etc/deklarix"
|
||||
CGO_ENABLED=0 GOARCH=$ARCH GOOS=linux go build \
|
||||
-trimpath -ldflags="-X main.Version=${VERSION} -s -w" \
|
||||
-o "$DEB_DIR/usr/bin/deklarix" \
|
||||
./cmd/deklarix/
|
||||
log "$ARCH fertig: $(du -sh "$OUT" | cut -f1)"
|
||||
chmod 755 "$DEB_DIR/usr/bin/deklarix"
|
||||
|
||||
log "Stelle Paket zusammen ($ARCH)..."
|
||||
sed "s/^Version: VERSION/Version: $VERSION/; s/^Architecture: ARCH/Architecture: $ARCH/" \
|
||||
"$PACKAGING_DIR/DEBIAN/control.tmpl" > "$DEB_DIR/DEBIAN/control"
|
||||
cp "$PACKAGING_DIR/DEBIAN/postinst" "$DEB_DIR/DEBIAN/postinst"
|
||||
cp "$PACKAGING_DIR/DEBIAN/prerm" "$DEB_DIR/DEBIAN/prerm"
|
||||
cp "$PACKAGING_DIR/DEBIAN/conffiles" "$DEB_DIR/DEBIAN/conffiles"
|
||||
chmod 755 "$DEB_DIR/DEBIAN/postinst" "$DEB_DIR/DEBIAN/prerm"
|
||||
|
||||
cp "$PACKAGING_DIR/etc/systemd/system/deklarix.service" "$DEB_DIR/etc/systemd/system/"
|
||||
cp "$PACKAGING_DIR/etc/deklarix/deklarix.env.example" "$DEB_DIR/etc/deklarix/"
|
||||
|
||||
dpkg-deb --build --root-owner-group "$DEB_DIR" "$REPO_DIR/dist/$DEB_NAME.deb"
|
||||
|
||||
log "$ARCH fertig: dist/$DEB_NAME.deb ($(du -sh "$REPO_DIR/dist/$DEB_NAME.deb" | cut -f1))"
|
||||
done
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
|
||||
log "Build abgeschlossen ✓"
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
#
|
||||
# Was passiert:
|
||||
# 1. Tests laufen
|
||||
# 2. Build für amd64 + arm64
|
||||
# 3. git tag v<version> wird gesetzt
|
||||
# 4. git push origin main + git push origin v<version>
|
||||
# 2. .deb-Pakete bauen (amd64 + arm64)
|
||||
# 3. Pakete in Giteas Debian-Paketregistrierung hochladen (Kanal "testing")
|
||||
# 4. git tag v<version> wird gesetzt
|
||||
# 5. git push origin main + git push origin v<version>
|
||||
#
|
||||
# Voraussetzungen:
|
||||
# - Sauberer Git-Status (keine uncommitted changes)
|
||||
# - Alle Tests grün
|
||||
# - Alle Tests grün (inkl. DATABASE_URL für die Store-Integrationstests)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -24,8 +25,9 @@ if [[ -z "$VERSION" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GRN='\033[0;32m'; BLD='\033[1m'; NC='\033[0m'
|
||||
log() { echo -e "${GRN}[release]${NC} $*"; }
|
||||
GRN='\033[0;32m'; YLW='\033[0;33m'; BLD='\033[1m'; NC='\033[0m'
|
||||
log() { echo -e "${GRN}[release]${NC} $*"; }
|
||||
warn() { echo -e "${YLW}[release]${NC} $*"; }
|
||||
|
||||
cd "$REPO_DIR"
|
||||
|
||||
@@ -43,9 +45,46 @@ log "Tests laufen..."
|
||||
bash "$REPO_DIR/scripts/test.sh"
|
||||
|
||||
# Build
|
||||
log "Build für alle Architekturen..."
|
||||
log "Pakete bauen..."
|
||||
bash "$REPO_DIR/scripts/build.sh" "$VERSION"
|
||||
|
||||
# ─── apt-Kanal-Modell ────────────────────────────────────────────────────────
|
||||
# Suite = OS-Codename, Komponente = Kanal. Deklarix hat aktuell nur einen
|
||||
# Kanal (testing) — es gibt noch keine Kunden, für die "stable" vom
|
||||
# aktuellen Entwicklungsstand getrennt werden müsste. Sobald das relevant
|
||||
# wird: gleiches Promote-Modell wie enconf-webpanel (release.sh stable).
|
||||
GITEA_URL="https://git.netcell-it.de"
|
||||
GITEA_ORG="projekte"
|
||||
GITEA_CHANNEL="testing"
|
||||
APT_SUITES=(bookworm trixie)
|
||||
|
||||
GITEA_TOKEN="$(git -C "$REPO_DIR" remote get-url origin | grep -oP '://[^:]+:\K[^@]+' 2>/dev/null || echo '')"
|
||||
if [ -z "$GITEA_TOKEN" ]; then
|
||||
echo "FEHLER: Gitea-Token nicht im Git-Remote gefunden."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
upload_deb() {
|
||||
curl -sk -w "%{http_code}" -o /dev/null -X PUT \
|
||||
"$GITEA_URL/api/packages/$GITEA_ORG/debian/pool/$2/$3/upload" \
|
||||
-H "Authorization: token $GITEA_TOKEN" --upload-file "$1" 2>/dev/null
|
||||
}
|
||||
|
||||
log "Pakete → Gitea-Debian-Registry (${APT_SUITES[*]} / $GITEA_CHANNEL)..."
|
||||
for deb in "$REPO_DIR"/dist/deklarix_"${VERSION}"_*.deb; do
|
||||
[ -f "$deb" ] || { echo "FEHLER: kein .deb für Version $VERSION in dist/ gefunden"; exit 1; }
|
||||
b="$(basename "$deb")"
|
||||
for suite in "${APT_SUITES[@]}"; do
|
||||
code=$(upload_deb "$deb" "$suite" "$GITEA_CHANNEL")
|
||||
if [ "$code" = "201" ] || [ "$code" = "409" ]; then
|
||||
log " ✅ $b → $suite/$GITEA_CHANNEL"
|
||||
else
|
||||
echo "FEHLER: Upload $b → $suite/$GITEA_CHANNEL fehlgeschlagen (HTTP $code)"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# Git Tag
|
||||
log "Tag v${VERSION} setzen..."
|
||||
git tag -a "v${VERSION}" -m "Release v${VERSION}"
|
||||
@@ -57,4 +96,5 @@ git push origin "v${VERSION}"
|
||||
|
||||
log ""
|
||||
log "Release v${VERSION} fertig ✓"
|
||||
log "Binaries: dist/deklarix_${VERSION}_amd64 + _arm64"
|
||||
log "Pakete: dist/deklarix_${VERSION}_amd64.deb + _arm64.deb"
|
||||
log "Installation/Update auf Zielservern: apt install/upgrade deklarix"
|
||||
|
||||
Reference in New Issue
Block a user