name: Build .deb Package on: push: branches: [master] tags: ["v*"] pull_request: branches: [master] env: CARGO_TERM_COLOR: always jobs: # --------------------------------------------------------------------------- # Job 1: Rust Backend - Build + Test # --------------------------------------------------------------------------- build-backend: runs-on: ubuntu-latest container: image: ubuntu:24.04 steps: - name: Checkout uses: actions/checkout@v4 - name: Install build dependencies run: | apt-get update -qq apt-get install -y --no-install-recommends \ curl pkg-config libssl-dev ca-certificates # Install Rust toolchain curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y . "$HOME/.cargo/env" rustup default stable echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Cache Cargo registry uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git target key: cargo-${{ hashFiles('Cargo.lock') }} restore-keys: cargo- - name: Build (release) run: | . "$HOME/.cargo/env" cargo build --release - name: Run Rust tests run: | . "$HOME/.cargo/env" cargo test --release - name: Strip binaries run: | strip target/release/pm-web strip target/release/pm-worker - name: Upload backend artifacts uses: actions/upload-artifact@v3 with: name: backend-binaries path: | target/release/pm-web target/release/pm-worker # --------------------------------------------------------------------------- # Job 2: Frontend - Build # --------------------------------------------------------------------------- build-frontend: runs-on: ubuntu-latest container: image: node:20-bookworm steps: - name: Checkout uses: actions/checkout@v4 - name: Install dependencies working-directory: frontend run: npm ci - name: Build frontend working-directory: frontend run: npm run build - name: Upload frontend artifacts uses: actions/upload-artifact@v3 with: name: frontend-dist path: frontend/dist/ # --------------------------------------------------------------------------- # Job 3: Package .deb # --------------------------------------------------------------------------- build-deb: needs: [build-backend, build-frontend] runs-on: ubuntu-latest container: image: ubuntu:24.04 steps: - name: Checkout uses: actions/checkout@v4 - name: Install packaging tools run: | apt-get update -qq apt-get install -y --no-install-recommends dpkg-dev curl ca-certificates - name: Download backend artifacts uses: actions/download-artifact@v3 with: name: backend-binaries path: target/release/ - name: Download frontend artifacts uses: actions/download-artifact@v3 with: name: frontend-dist path: frontend/dist/ - name: Make binaries executable run: chmod 755 target/release/pm-web target/release/pm-worker - name: Determine version id: version run: | if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then VERSION="${GITHUB_REF#refs/tags/v}" else VERSION="1.0.0-dev.$(date +%Y%m%d%H%M)" fi echo "version=${VERSION}" >> "$GITHUB_OUTPUT" echo "Building version: ${VERSION}" - name: Assemble .deb package run: | VERSION="${{ steps.version.outputs.version }}" BUILD_DIR="package-build" mkdir -p "${BUILD_DIR}/DEBIAN" mkdir -p "${BUILD_DIR}/usr/local/bin" mkdir -p "${BUILD_DIR}/usr/share/patch-manager/frontend" mkdir -p "${BUILD_DIR}/usr/share/patch-manager/migrations" mkdir -p "${BUILD_DIR}/lib/systemd/system" # Binaries cp target/release/pm-web "${BUILD_DIR}/usr/local/bin/pm-web" cp target/release/pm-worker "${BUILD_DIR}/usr/local/bin/pm-worker" cp scripts/backup.sh "${BUILD_DIR}/usr/local/bin/backup.sh" chmod 755 "${BUILD_DIR}/usr/local/bin/pm-web" chmod 755 "${BUILD_DIR}/usr/local/bin/pm-worker" chmod 700 "${BUILD_DIR}/usr/local/bin/backup.sh" # Frontend cp -r frontend/dist/* "${BUILD_DIR}/usr/share/patch-manager/frontend/" # Config + migrations cp config/config.example.toml "${BUILD_DIR}/usr/share/patch-manager/config.example.toml" cp migrations/*.sql "${BUILD_DIR}/usr/share/patch-manager/migrations/" # Systemd units cp systemd/patch-manager-web.service "${BUILD_DIR}/lib/systemd/system/" cp systemd/patch-manager-worker.service "${BUILD_DIR}/lib/systemd/system/" cp systemd/patch-manager.target "${BUILD_DIR}/lib/systemd/system/" # DEBIAN control scripts cp debian/postinst "${BUILD_DIR}/DEBIAN/postinst" cp debian/prerm "${BUILD_DIR}/DEBIAN/prerm" cp debian/postrm "${BUILD_DIR}/DEBIAN/postrm" chmod 755 "${BUILD_DIR}/DEBIAN/postinst" "${BUILD_DIR}/DEBIAN/prerm" "${BUILD_DIR}/DEBIAN/postrm" # Generate control file with computed version and size INSTALLED_SIZE=$(du -sk "${BUILD_DIR}" | cut -f1) cat > "${BUILD_DIR}/DEBIAN/control" < Installed-Size: ${INSTALLED_SIZE} Depends: postgresql-16, libssl3, libc6 (>= 2.39) Recommends: postgresql-client-16 Suggests: gpg Section: admin Priority: optional Description: Enterprise Linux Patch Management System Linux Patch Manager is a secure, web-based management interface for controlling patching and updates on Linux servers and workstations. CTRL # Build .deb DEB_NAME="linux-patch-manager_${VERSION}-1_amd64.deb" dpkg-deb --build "${BUILD_DIR}" "${DEB_NAME}" echo "deb_name=${DEB_NAME}" >> "$GITHUB_OUTPUT" - name: Verify package run: | DEB_NAME=$(ls linux-patch-manager_*.deb) echo "=== Package Info ===" dpkg-deb --info "${DEB_NAME}" echo "=== Package Size ===" du -h "${DEB_NAME}" - name: Upload .deb artifact uses: actions/upload-artifact@v3 with: name: deb-package path: linux-patch-manager_*.deb - name: Create Gitea Release if: startsWith(github.ref, 'refs/tags/v') run: | DEB_NAME=$(ls linux-patch-manager_*.deb) VERSION="${{ steps.version.outputs.version }}" # Use Gitea API to create release and upload asset curl -s -X POST \ "${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases" \ -H "Authorization: token ${GITHUB_TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"tag_name\": \"${GITHUB_REF_NAME}\", \"title\": \"Release ${VERSION}\", \"body\": \"Automated build from tag ${GITHUB_REF_NAME}.\"}" \ -o release.json # Extract release ID RELEASE_ID=$(python3 -c "import json; print(json.load(open('release.json'))['id'])") # Upload .deb as release asset curl -s -X POST \ "${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets" \ -H "Authorization: token ${GITHUB_TOKEN}" \ -F "attachment=@${DEB_NAME}" \ -F "name=${DEB_NAME}"