name: Build .deb Package on: push: branches: [master] tags: ["v*"] pull_request: branches: [master] env: CARGO_TERM_COLOR: always jobs: build-and-package: runs-on: linux steps: - name: Install system dependencies run: | sudo apt-get update -qq sudo apt-get install -y --no-install-recommends \ curl pkg-config libssl-dev ca-certificates \ git nodejs npm dpkg-dev python3 - name: Checkout repository run: | # Use Gitea API archive download with token auth # GITHUB_TOKEN may not be injected in linux:host mode; fall back to GITEA_TOKEN TOKEN="${GITHUB_TOKEN:-$GITEA_TOKEN}" curl -sf -H "Authorization: token ${TOKEN}" \ "http://192.168.2.189:3000/api/v1/repos/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz" \ -o repo.tar.gz tar xzf repo.tar.gz --strip-components=1 rm repo.tar.gz - name: Ensure Rust toolchain run: | . "$HOME/.cargo/env" 2>/dev/null || true if ! command -v cargo &>/dev/null; then curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y . "$HOME/.cargo/env" fi echo "Rust: $(cargo --version)" - name: Build Rust backend (release) run: | . "$HOME/.cargo/env" 2>/dev/null || true cargo build --release 2>&1 - name: Run Rust tests run: | . "$HOME/.cargo/env" 2>/dev/null || true cargo test --release 2>&1 || true - name: Strip binaries run: | strip target/release/pm-web strip target/release/pm-worker - name: Install frontend dependencies working-directory: frontend run: npm ci - name: Build frontend working-directory: frontend run: npm run build - 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 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 "Built: ${DEB_NAME}" du -h "${DEB_NAME}" - 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: Create Gitea Release (tags only) if: startsWith(github.ref, 'refs/tags/v') run: | DEB_NAME=$(ls linux-patch-manager_*.deb) VERSION="${{ steps.version.outputs.version }}" TOKEN="${GITHUB_TOKEN:-$GITEA_TOKEN}" REF_NAME="${GITHUB_REF_NAME:-v${VERSION}}" REPO="${GITHUB_REPOSITORY:-echo/linux_patch_manager}" echo "Creating release for tag: ${REF_NAME} repo: ${REPO}" echo "DEB: ${DEB_NAME}" # Create release via Gitea API HTTP_CODE=$(curl -s -o release.json -w "%{http_code}" -X POST \ "http://192.168.2.189:3000/api/v1/repos/${REPO}/releases" \ -H "Authorization: token ${TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"tag_name\": \"${REF_NAME}\", \"title\": \"Release ${VERSION}\", \"body\": \"Automated build from tag ${REF_NAME}.\\n\\n## Installation\\n\\n\\\`\\\`\\\`bash\\nsudo apt install ./linux-patch-manager_${VERSION}-1_amd64.deb\\n\\\`\\\`\\\`\\\"}") echo "Release API HTTP status: ${HTTP_CODE}" cat release.json if [ "${HTTP_CODE}" != "201" ]; then echo "ERROR: Failed to create release (HTTP ${HTTP_CODE})" exit 1 fi # Extract release ID and upload .deb RELEASE_ID=$(python3 -c "import json; print(json.load(open('release.json'))['id'])") echo "Release ID: ${RELEASE_ID}" curl -s -X POST \ "http://192.168.2.189:3000/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets" \ -H "Authorization: token ${TOKEN}" \ -F "attachment=@${DEB_NAME}" \ -F "name=${DEB_NAME}" echo "Release upload complete"