Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a3b299b116 | |||
| 2d33973b5f | |||
| 6ddb511cb0 | |||
| cc21868b6c | |||
| 32803ff27c | |||
| 0bca0c7784 | |||
| 2ac40076f5 | |||
| 4375f915ca |
195
.github/workflows/ci.yml
vendored
195
.github/workflows/ci.yml
vendored
@ -9,8 +9,15 @@ on:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUST_BACKTRACE: 1
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
# ── Quality Gates (GitHub-hosted, all triggers) ──────────────────────────
|
||||
|
||||
fmt:
|
||||
name: Rust Format
|
||||
runs-on: ubuntu-latest
|
||||
@ -68,24 +75,18 @@ jobs:
|
||||
- run: cargo test --test enrollment_test
|
||||
- run: cargo test --test enrollment_e2e
|
||||
|
||||
build-deb:
|
||||
name: Build & Release
|
||||
needs: [fmt, clippy, test, enrollment-tests]
|
||||
# ── Release Preparation (tag push only) ───────────────────────────────────
|
||||
|
||||
prepare-release:
|
||||
name: Prepare Release
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [fmt, clippy, test, enrollment-tests, audit]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: Install system dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y build-essential libsystemd-dev pkg-config libssl-dev dpkg-dev
|
||||
- name: Build .deb package
|
||||
run: |
|
||||
. "$HOME/.cargo/env"
|
||||
sudo env "PATH=$PATH" dpkg-buildpackage -us -uc -b -d
|
||||
- name: Generate release notes
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
id: release_notes
|
||||
run: |
|
||||
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
||||
@ -97,9 +98,173 @@ jobs:
|
||||
echo "notes<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$NOTES" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
- name: Upload to GitHub Release
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body: ${{ steps.release_notes.outputs.notes }}
|
||||
files: ../linux-patch-api_*.deb
|
||||
|
||||
# ── Build Jobs (tag push only, self-hosted runners) ───────────────────────
|
||||
|
||||
build-deb-u2404:
|
||||
name: Build .deb (Ubuntu 24.04)
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [fmt, clippy, test, enrollment-tests, audit, prepare-release]
|
||||
runs-on: [self-hosted, linux, ubuntu-24.04]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install system dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y build-essential libsystemd-dev pkg-config libssl-dev
|
||||
- name: Add Rust to PATH
|
||||
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
- name: Build .deb package
|
||||
run: chmod +x scripts/build-package.sh && scripts/build-package.sh
|
||||
- name: Rename package with distro suffix
|
||||
run: |
|
||||
FILE=$(ls linux-patch-api_*_amd64.deb 2>/dev/null | head -1)
|
||||
if [ -n "$FILE" ]; then
|
||||
mv "$FILE" "$(echo "$FILE" | sed 's/_amd64/_u2404_amd64/')"
|
||||
fi
|
||||
- name: Upload to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: linux-patch-api_*_u2404_amd64.deb
|
||||
|
||||
build-deb-u2204:
|
||||
name: Build .deb (Ubuntu 22.04)
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [fmt, clippy, test, enrollment-tests, audit, prepare-release]
|
||||
runs-on: [self-hosted, linux, ubuntu-22.04]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install system dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y build-essential libsystemd-dev pkg-config libssl-dev
|
||||
- name: Add Rust to PATH
|
||||
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
- name: Build .deb package
|
||||
run: chmod +x scripts/build-package.sh && scripts/build-package.sh
|
||||
- name: Rename package with distro suffix
|
||||
run: |
|
||||
FILE=$(ls linux-patch-api_*_amd64.deb 2>/dev/null | head -1)
|
||||
if [ -n "$FILE" ]; then
|
||||
mv "$FILE" "$(echo "$FILE" | sed 's/_amd64/_u2204_amd64/')"
|
||||
fi
|
||||
- name: Upload to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: linux-patch-api_*_u2204_amd64.deb
|
||||
|
||||
build-deb-debian13:
|
||||
name: Build .deb (Debian 13)
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [fmt, clippy, test, enrollment-tests, audit, prepare-release]
|
||||
runs-on: [self-hosted, linux, debian-13]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install system dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y build-essential libsystemd-dev pkg-config libssl-dev
|
||||
- name: Add Rust to PATH
|
||||
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
- name: Build .deb package
|
||||
run: chmod +x scripts/build-package.sh && scripts/build-package.sh
|
||||
- name: Rename package with distro suffix
|
||||
run: |
|
||||
FILE=$(ls linux-patch-api_*_amd64.deb 2>/dev/null | head -1)
|
||||
if [ -n "$FILE" ]; then
|
||||
mv "$FILE" "$(echo "$FILE" | sed 's/_amd64/_debian13_amd64/')"
|
||||
fi
|
||||
- name: Upload to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: linux-patch-api_*_debian13_amd64.deb
|
||||
|
||||
build-rpm-fedora:
|
||||
name: Build .rpm (Fedora)
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [fmt, clippy, test, enrollment-tests, audit, prepare-release]
|
||||
runs-on: [self-hosted, linux, fedora]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install system dependencies
|
||||
run: sudo dnf install -y systemd-devel openssl-devel pkg-config gcc make
|
||||
- name: Add Rust to PATH
|
||||
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
- name: Build release binary
|
||||
run: cargo build --release
|
||||
- name: Build RPM package
|
||||
run: chmod +x build-rpm.sh && SKIP_CARGO_BUILD=1 sudo -E ./build-rpm.sh
|
||||
- name: Upload to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: releases/linux-patch-api-*.rpm
|
||||
|
||||
build-rpm-almalinux:
|
||||
name: Build .rpm (AlmaLinux 10)
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [fmt, clippy, test, enrollment-tests, audit, prepare-release]
|
||||
runs-on: [self-hosted, linux, almalinux-10]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install system dependencies
|
||||
run: sudo dnf install -y systemd-devel openssl-devel pkg-config gcc make
|
||||
- name: Add Rust to PATH
|
||||
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
- name: Build release binary
|
||||
run: cargo build --release
|
||||
- name: Build RPM package
|
||||
run: chmod +x build-rpm.sh && SKIP_CARGO_BUILD=1 sudo -E ./build-rpm.sh
|
||||
- name: Upload to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: releases/linux-patch-api-*.rpm
|
||||
|
||||
build-arch:
|
||||
name: Build .pkg.tar.zst (Arch Linux)
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [fmt, clippy, test, enrollment-tests, audit, prepare-release]
|
||||
runs-on: [self-hosted, linux, arch]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install system dependencies
|
||||
run: sudo pacman -Syu --noconfirm systemd openssl pkg-config gcc
|
||||
- name: Add Rust to PATH
|
||||
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
- name: Build release binary
|
||||
run: cargo build --release
|
||||
- name: Build Arch package
|
||||
run: chmod +x build-arch.sh && SKIP_CARGO_BUILD=1 ./build-arch.sh
|
||||
- name: Upload to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: releases/*.pkg.tar.zst
|
||||
|
||||
build-alpine:
|
||||
name: Build .apk (Alpine)
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [fmt, clippy, test, enrollment-tests, audit, prepare-release]
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: alpine:latest
|
||||
steps:
|
||||
- name: Install prerequisites for actions/checkout
|
||||
run: apk add --no-cache bash git curl tar
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Alpine build dependencies
|
||||
run: apk add --no-cache gcc musl-dev openssl-dev openssl elogind-dev alpine-sdk abuild
|
||||
- name: Install Rust via rustup
|
||||
run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
- name: Add Rust to PATH
|
||||
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
- name: Add musl target
|
||||
run: rustup target add x86_64-unknown-linux-musl
|
||||
- name: Build release binary (musl target)
|
||||
run: cargo build --release --target x86_64-unknown-linux-musl
|
||||
- name: Generate abuild signing keys
|
||||
run: abuild-keygen -a -n
|
||||
- name: Build Alpine package
|
||||
run: |
|
||||
chmod +x build-alpine.sh
|
||||
SKIP_CARGO_BUILD=1 ./build-alpine.sh
|
||||
- name: Upload to GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: releases/linux-patch-api-*.apk
|
||||
|
||||
2
debian/control
vendored
2
debian/control
vendored
@ -14,6 +14,8 @@ Vcs-Browser: https://gitea.moon-dragon.us/echo/linux_patch_api
|
||||
|
||||
Package: linux-patch-api
|
||||
Architecture: amd64
|
||||
Version: 1.2.0-1
|
||||
Installed-Size: 0
|
||||
Depends: systemd,
|
||||
libsystemd0,
|
||||
${shlibs:Depends},
|
||||
|
||||
2
debian/rules
vendored
Executable file → Normal file
2
debian/rules
vendored
Executable file → Normal file
@ -8,7 +8,7 @@ export DEB_CARGO_BUILD_FLAGS=--release
|
||||
dh $@
|
||||
|
||||
override_dh_auto_build:
|
||||
. "$$HOME/.cargo/env" && cargo build --release --target x86_64-unknown-linux-gnu
|
||||
cargo build --release --target x86_64-unknown-linux-gnu
|
||||
|
||||
override_dh_auto_install:
|
||||
dh_auto_install
|
||||
|
||||
147
scripts/build-package.sh
Normal file
147
scripts/build-package.sh
Normal file
@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# Linux Patch API — Build .deb Package for Ubuntu 24.04
|
||||
# =============================================================================
|
||||
# Produces: linux-patch-api_<version>-1_amd64.deb
|
||||
# Prerequisites:
|
||||
# - Rust toolchain (cargo, rustc >= 1.75)
|
||||
# - dpkg-deb
|
||||
# =============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
|
||||
|
||||
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
VERSION="1.2.0"
|
||||
RELEASE="1"
|
||||
PKG_NAME="linux-patch-api"
|
||||
DEB_NAME="${PKG_NAME}_${VERSION}-${RELEASE}_amd64.deb"
|
||||
BUILD_DIR="${PROJECT_ROOT}/package-build"
|
||||
|
||||
info "=== Linux Patch API — Package Build ==="
|
||||
info "Version: ${VERSION}-${RELEASE}"
|
||||
info "Target: Ubuntu 24.04 (noble) amd64"
|
||||
echo
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 1. Build Rust binary (release mode)
|
||||
# ---------------------------------------------------------------------------
|
||||
info "Step 1/4: Building Rust binary (release mode)..."
|
||||
cd "${PROJECT_ROOT}"
|
||||
cargo build --release 2>&1 | tail -5
|
||||
|
||||
# Verify binary exists
|
||||
[[ -f "${PROJECT_ROOT}/target/release/linux-patch-api" ]] || error "linux-patch-api not found in target/release/"
|
||||
info "Rust binary built successfully."
|
||||
|
||||
# Strip debug symbols for smaller package
|
||||
strip "${PROJECT_ROOT}/target/release/linux-patch-api" 2>/dev/null || warn "strip failed (may already be stripped)"
|
||||
info "Binary stripped."
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 2. Assemble package directory structure
|
||||
# ---------------------------------------------------------------------------
|
||||
info "Step 2/4: Assembling package structure..."
|
||||
rm -rf "${BUILD_DIR}"
|
||||
mkdir -p "${BUILD_DIR}/DEBIAN"
|
||||
mkdir -p "${BUILD_DIR}/usr/bin"
|
||||
mkdir -p "${BUILD_DIR}/etc/linux_patch_api"
|
||||
mkdir -p "${BUILD_DIR}/etc/linux_patch_api/certs"
|
||||
mkdir -p "${BUILD_DIR}/lib/systemd/system"
|
||||
mkdir -p "${BUILD_DIR}/var/log/linux_patch_api"
|
||||
mkdir -p "${BUILD_DIR}/var/lib/linux_patch_api"
|
||||
|
||||
# Binary
|
||||
cp "${PROJECT_ROOT}/target/release/linux-patch-api" "${BUILD_DIR}/usr/bin/linux-patch-api"
|
||||
chmod 755 "${BUILD_DIR}/usr/bin/linux-patch-api"
|
||||
|
||||
# Systemd service
|
||||
cp "${PROJECT_ROOT}/configs/linux-patch-api.service" "${BUILD_DIR}/lib/systemd/system/"
|
||||
|
||||
# Configuration files (live configs for admin editing)
|
||||
cp "${PROJECT_ROOT}/configs/config.yaml.example" "${BUILD_DIR}/etc/linux_patch_api/config.yaml"
|
||||
cp "${PROJECT_ROOT}/configs/whitelist.yaml.example" "${BUILD_DIR}/etc/linux_patch_api/whitelist.yaml"
|
||||
|
||||
# Example config files (referenced by postinst for first-run setup)
|
||||
cp "${PROJECT_ROOT}/configs/config.yaml.example" "${BUILD_DIR}/etc/linux_patch_api/config.yaml.example"
|
||||
cp "${PROJECT_ROOT}/configs/whitelist.yaml.example" "${BUILD_DIR}/etc/linux_patch_api/whitelist.yaml.example"
|
||||
|
||||
# Calculate installed size BEFORE generating control file
|
||||
INSTALLED_SIZE=$(du -sk "${BUILD_DIR}" | cut -f1)
|
||||
|
||||
# Generate DEBIAN/control from scratch for dpkg-deb --build
|
||||
# (debian/control uses dpkg-buildpackage substitution variables like
|
||||
# ${shlibs:Depends} that dpkg-deb cannot resolve)
|
||||
cat > "${BUILD_DIR}/DEBIAN/control" <<EOF
|
||||
Package: linux-patch-api
|
||||
Version: ${VERSION}-${RELEASE}
|
||||
Architecture: amd64
|
||||
Maintainer: Echo <echo@moon-dragon.us>
|
||||
Installed-Size: ${INSTALLED_SIZE}
|
||||
Depends: systemd, libsystemd0
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Homepage: https://github.com/Draco-Lunaris/Linux-Patch-Api
|
||||
Description: Secure remote package management API for Linux systems
|
||||
Linux Patch API provides a secure, mTLS-authenticated REST API for
|
||||
remote package management operations including package installation
|
||||
and removal, security patch application, system health monitoring,
|
||||
and job queue management with WebSocket status streaming.
|
||||
EOF
|
||||
|
||||
# Conffiles
|
||||
cat > "${BUILD_DIR}/DEBIAN/conffiles" << 'EOF'
|
||||
/etc/linux_patch_api/config.yaml
|
||||
/etc/linux_patch_api/whitelist.yaml
|
||||
EOF
|
||||
|
||||
# Maintainer scripts
|
||||
cp "${PROJECT_ROOT}/debian/postinst" "${BUILD_DIR}/DEBIAN/postinst"
|
||||
cp "${PROJECT_ROOT}/debian/prerm" "${BUILD_DIR}/DEBIAN/prerm"
|
||||
cp "${PROJECT_ROOT}/debian/postrm" "${BUILD_DIR}/DEBIAN/postrm"
|
||||
chmod 755 "${BUILD_DIR}/DEBIAN/postinst" "${BUILD_DIR}/DEBIAN/prerm" "${BUILD_DIR}/DEBIAN/postrm"
|
||||
|
||||
info "Package structure assembled (${INSTALLED_SIZE} KB)."
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 3. Build .deb package
|
||||
# ---------------------------------------------------------------------------
|
||||
info "Step 3/4: Building .deb package..."
|
||||
dpkg-deb --build "${BUILD_DIR}" "${PROJECT_ROOT}/${DEB_NAME}"
|
||||
info ".deb package created: ${DEB_NAME}"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 4. Verify and summarize
|
||||
# ---------------------------------------------------------------------------
|
||||
info "Step 4/4: Verifying package..."
|
||||
dpkg-deb --info "${PROJECT_ROOT}/${DEB_NAME}"
|
||||
echo
|
||||
dpkg-deb --contents "${PROJECT_ROOT}/${DEB_NAME}" | head -20 || true
|
||||
echo
|
||||
|
||||
PKG_SIZE=$(du -h "${PROJECT_ROOT}/${DEB_NAME}" | cut -f1)
|
||||
|
||||
info "=== Package Build Complete ==="
|
||||
info "Package: ${DEB_NAME}"
|
||||
info "Size: ${PKG_SIZE}"
|
||||
echo
|
||||
echo -e "${CYAN}Installation instructions:${NC}"
|
||||
echo " 1. Copy ${DEB_NAME} to the target Ubuntu 24.04 host"
|
||||
echo " 2. Install: sudo dpkg -i ${DEB_NAME}"
|
||||
echo " 3. Or with auto-deps: sudo apt install ./${DEB_NAME}"
|
||||
echo " 4. Configure: /etc/linux_patch_api/config.yaml"
|
||||
echo " 5. Start: systemctl enable --now linux-patch-api.service"
|
||||
echo
|
||||
|
||||
# Cleanup build directory
|
||||
rm -rf "${BUILD_DIR}"
|
||||
info "Build directory cleaned up."
|
||||
Reference in New Issue
Block a user