All checks were successful
CI/CD Pipeline / Code Format (push) Successful in 1s
CI/CD Pipeline / Clippy Lints (push) Successful in 48s
CI/CD Pipeline / All Unit Tests (push) Successful in 1m22s
CI/CD Pipeline / Security Audit (push) Successful in 5s
CI/CD Pipeline / Enrollment Tests (push) Successful in 1m54s
CI/CD Pipeline / Verify Enrollment CLI Flag (push) Successful in 1m31s
CI/CD Pipeline / Build RPM Package (push) Successful in 2m36s
CI/CD Pipeline / Build Debian Package (Ubuntu 22.04) (push) Successful in 2m44s
CI/CD Pipeline / Build Arch Package (push) Successful in 2m54s
CI/CD Pipeline / Build Alpine Package (push) Successful in 3m43s
CI/CD Pipeline / Build Debian Package (push) Successful in 2m5s
Root causes of ALL Alpine build failures: 1. ci.yml: Verify Alpine package step was TRUNCATED at line 339 - missing closing quote, then clause, fi, and entire upload step. This caused YAML parse failure every run. 2. build-alpine.sh: Copy path was /home/builduser/packages/home/x86_64/ but abuild outputs to /home/builduser/packages/builduser/x86_64/. The find fallback caught stale packages from previous builds. Fixes: - Complete the Verify Alpine package step with proper if/fi - Add Upload to Gitea Release step for Alpine (was completely missing) - Fix abuild output path in build-alpine.sh
168 lines
6.1 KiB
Bash
168 lines
6.1 KiB
Bash
#!/bin/sh
|
|
# Build Alpine Package (.apk)
|
|
# Run on: Alpine Linux 3.18+
|
|
# Designed for native Gitea Actions runner execution
|
|
|
|
set -e
|
|
|
|
echo "=== Linux Patch API - Alpine Build Script ==="
|
|
echo ""
|
|
|
|
# Source cargo environment (for rustup-installed toolchain in CI)
|
|
if [ -f "$HOME/.cargo/env" ]; then
|
|
. "$HOME/.cargo/env"
|
|
fi
|
|
|
|
# Check if running on Alpine
|
|
if ! command -v abuild &> /dev/null; then
|
|
echo "Installing Alpine build tools..."
|
|
apk add --no-cache alpine-sdk rust cargo openssl-dev openrc git abuild gcc
|
|
fi
|
|
|
|
# Generate abuild signing keys
|
|
echo "Generating abuild signing keys..."
|
|
apk add --no-cache abuild
|
|
abuild-keygen -a -n 2>&1 | tee /tmp/keygen.log
|
|
KEYFILE=$(ls /root/.abuild/*.rsa 2>/dev/null | head -1)
|
|
if [ -z "$KEYFILE" ]; then
|
|
KEYFILE=$(ls /root/.abuild/-*.rsa 2>/dev/null | head -1)
|
|
fi
|
|
echo "Found key: $KEYFILE"
|
|
echo "PACKAGER_PRIVKEY=\"$KEYFILE\"" > /etc/abuild.conf
|
|
cat /etc/abuild.conf
|
|
|
|
# Setup build environment
|
|
echo "Setting up build environment..."
|
|
export CBUILDROOT=$(pwd)/.abuild
|
|
mkdir -p "$CBUILDROOT"
|
|
|
|
# Build release binary
|
|
if [ -z "$SKIP_CARGO_BUILD" ]; then
|
|
echo "Building release binary..."
|
|
cargo build --release --target x86_64-unknown-linux-musl
|
|
else
|
|
echo "Skipping cargo build (SKIP_CARGO_BUILD is set)"
|
|
fi
|
|
|
|
# Get version from Cargo.toml
|
|
VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*=.*"\([^"]*\)".*/\1/')
|
|
|
|
# Create package directory structure
|
|
PKGDIR=$(pwd)/apk-package
|
|
rm -rf "$PKGDIR"
|
|
mkdir -p "$PKGDIR"/usr/bin
|
|
mkdir -p "$PKGDIR"/etc/linux_patch_api/certs
|
|
mkdir -p "$PKGDIR"/etc/init.d
|
|
mkdir -p "$PKGDIR"/var/lib/linux_patch_api
|
|
mkdir -p "$PKGDIR"/var/log/linux_patch_api
|
|
|
|
# Copy binary
|
|
chmod 755 target/x86_64-unknown-linux-musl/release/linux-patch-api
|
|
cp target/x86_64-unknown-linux-musl/release/linux-patch-api "$PKGDIR"/usr/bin/
|
|
|
|
# Copy OpenRC init script
|
|
cp configs/linux-patch-api-openrc "$PKGDIR"/etc/init.d/linux-patch-api
|
|
chmod 755 "$PKGDIR"/etc/init.d/linux-patch-api
|
|
|
|
# Copy example configs (as .example files - install script creates live configs)
|
|
cp configs/config.yaml.example "$PKGDIR"/etc/linux_patch_api/config.yaml.example
|
|
cp configs/whitelist.yaml.example "$PKGDIR"/etc/linux_patch_api/whitelist.yaml.example
|
|
|
|
# Prepare workspace for abuild
|
|
WORKSPACE_DIR=/home/builduser/repo
|
|
rm -rf "$WORKSPACE_DIR"
|
|
mkdir -p "$WORKSPACE_DIR"
|
|
|
|
# Copy package directory to workspace
|
|
cp -r "$PKGDIR" "$WORKSPACE_DIR"/apk-package
|
|
|
|
# Copy install scripts to workspace (must be co-located with APKBUILD)
|
|
# Alpine abuild requires SEPARATE files with valid suffixes:
|
|
# pkgname.pre-install, pkgname.post-install, pkgname.pre-deinstall, pkgname.post-deinstall
|
|
cp configs/linux-patch-api.pre-install "$WORKSPACE_DIR"/linux-patch-api.pre-install
|
|
cp configs/linux-patch-api.post-install "$WORKSPACE_DIR"/linux-patch-api.post-install
|
|
cp configs/linux-patch-api.pre-deinstall "$WORKSPACE_DIR"/linux-patch-api.pre-deinstall
|
|
cp configs/linux-patch-api.post-deinstall "$WORKSPACE_DIR"/linux-patch-api.post-deinstall
|
|
|
|
# Create APKBUILD in workspace directory (co-located with install scripts)
|
|
echo "Creating APKBUILD..."
|
|
cat > "$WORKSPACE_DIR"/APKBUILD << EOF
|
|
pkgname=linux-patch-api
|
|
pkgver=${VERSION}
|
|
pkgrel=1
|
|
pkgdesc="Secure remote package management API for Linux systems"
|
|
url="https://gitea.moon-dragon.us/echo/linux_patch_api"
|
|
arch="x86_64"
|
|
license="MIT"
|
|
makedepends=""
|
|
depends="openrc"
|
|
install="linux-patch-api.pre-install linux-patch-api.post-install linux-patch-api.pre-deinstall linux-patch-api.post-deinstall"
|
|
subpackages=""
|
|
source=""
|
|
|
|
package() {
|
|
install -d "\$pkgdir"/usr/bin
|
|
install -d "\$pkgdir"/etc/linux_patch_api/certs
|
|
install -d "\$pkgdir"/etc/init.d
|
|
install -d "\$pkgdir"/var/lib/linux_patch_api
|
|
install -d "\$pkgdir"/var/log/linux_patch_api
|
|
|
|
install -Dm755 "\$startdir"/apk-package/usr/bin/linux-patch-api "\$pkgdir"/usr/bin/linux-patch-api
|
|
install -Dm755 "\$startdir"/apk-package/etc/init.d/linux-patch-api "\$pkgdir"/etc/init.d/linux-patch-api
|
|
install -Dm644 "\$startdir"/apk-package/etc/linux_patch_api/config.yaml.example "\$pkgdir"/etc/linux_patch_api/config.yaml.example
|
|
install -Dm644 "\$startdir"/apk-package/etc/linux_patch_api/whitelist.yaml.example "\$pkgdir"/etc/linux_patch_api/whitelist.yaml.example
|
|
}
|
|
EOF
|
|
|
|
# Build APK package
|
|
echo "Building APK package..."
|
|
|
|
# For CI environments where we may run as root or as a build user
|
|
if [ "$(id -u)" = "0" ]; then
|
|
echo "Running as root - creating build user for abuild..."
|
|
adduser -D -s /bin/sh builduser 2>/dev/null || true
|
|
addgroup builduser abuild 2>/dev/null || usermod -aG abuild builduser
|
|
|
|
# Set ownership of workspace
|
|
chown -R builduser:builduser "$WORKSPACE_DIR"
|
|
|
|
# Set up builduser home directory for abuild
|
|
mkdir -p /home/builduser/.abuild
|
|
cp /root/.abuild/* /home/builduser/.abuild/ 2>/dev/null || true
|
|
chown -R builduser:builduser /home/builduser/.abuild
|
|
|
|
KEYFILE=$(ls /home/builduser/.abuild/*.rsa 2>/dev/null | head -1)
|
|
if [ -z "$KEYFILE" ]; then
|
|
KEYFILE=$(ls /home/builduser/.abuild/-*.rsa 2>/dev/null | head -1)
|
|
fi
|
|
|
|
echo "Key file: $KEYFILE"
|
|
echo "PACKAGER_PRIVKEY=\"$KEYFILE\"" > /home/builduser/.abuild/abuild.conf
|
|
chown builduser:builduser /home/builduser/.abuild/abuild.conf
|
|
|
|
# Install public key BEFORE abuild (fixes UNTRUSTED signature)
|
|
cp /home/builduser/.abuild/*.rsa.pub /etc/apk/keys/ 2>/dev/null || true
|
|
|
|
# Run abuild as builduser in workspace directory
|
|
su - builduser -c "cd $WORKSPACE_DIR && abuild checksum && abuild -d"
|
|
|
|
# Copy APK from builduser packages to releases
|
|
# Note: abuild outputs to /home/builduser/packages/builduser/x86_64/ not /home/builduser/packages/home/x86_64/
|
|
mkdir -p releases
|
|
cp /home/builduser/packages/builduser/x86_64/*.apk releases/ 2>/dev/null || find /home/builduser/packages -name "*.apk" -exec cp {} releases/ \; 2>/dev/null || true
|
|
else
|
|
cd "$WORKSPACE_DIR"
|
|
abuild checksum
|
|
abuild -r
|
|
cd -
|
|
mkdir -p releases
|
|
cp ~/packages/x86_64/*.apk releases/ 2>/dev/null || cp ~/packages/*.apk releases/ 2>/dev/null || true
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Build Complete ==="
|
|
echo "Package: releases/linux-patch-api-*.apk"
|
|
echo ""
|
|
echo "Install with:"
|
|
echo " sudo apk add ./releases/linux-patch-api-*.apk"
|