From d6748fa2617369084b2afcec17aeee0521f8408e Mon Sep 17 00:00:00 2001 From: Echo Date: Sun, 26 Apr 2026 19:21:09 +0000 Subject: [PATCH] refactor: update CI for native per-OS runners - Replace generic "linux" runner label with dedicated per-OS labels (ubuntu-24.04, fedora, alpine, arch) - Remove all container declarations (native runner execution) - Add build gate dependencies: build jobs need fmt+clippy+test - Extract release upload logic into reusable scripts/upload-release.sh - Fix build-alpine.sh: remove hardcoded container paths, add SKIP_CARGO_BUILD support - Fix build-arch.sh: remove hardcoded container paths, add SKIP_CARGO_BUILD support - Fix build-rpm.sh: remove sudo, native runner compatible - Remove Dockerfile.rpm and Dockerfile.arch (no longer needed) - Add sudo to Ubuntu/Fedora/Arch package installs for safety - Add nodejs to Alpine deps for Gitea Actions compatibility - Make upload-release.sh POSIX sh compatible (Alpine) - Fix curl -sf to curl -s in upload-release.sh (404 on new releases) --- .gitea/workflows/ci.yml | 140 +++++++++++++++----------------------- Dockerfile.arch | 13 ---- Dockerfile.rpm | 14 ---- build-alpine.sh | 53 +++++++-------- build-arch.sh | 27 ++++---- build-rpm.sh | 9 +-- scripts/upload-release.sh | 63 +++++++++++++++++ 7 files changed, 161 insertions(+), 158 deletions(-) delete mode 100644 Dockerfile.arch delete mode 100644 Dockerfile.rpm mode change 100755 => 100644 build-alpine.sh mode change 100755 => 100644 build-arch.sh create mode 100755 scripts/upload-release.sh diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index a17871f..b3c584f 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -14,8 +14,7 @@ env: jobs: fmt: name: Code Format - runs-on: linux - container: node:18 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: @@ -28,16 +27,15 @@ jobs: clippy: name: Clippy Lints - runs-on: linux - container: node:18 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install system dependencies run: | - apt-get update - apt-get install -y libsystemd-dev pkg-config + sudo apt-get update + sudo apt-get install -y libsystemd-dev pkg-config - uses: dtolnay/rust-toolchain@stable with: components: clippy @@ -48,16 +46,15 @@ jobs: test: name: Unit Tests - runs-on: linux - container: node:18 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install system dependencies run: | - apt-get update - apt-get install -y libsystemd-dev pkg-config + sudo apt-get update + sudo apt-get install -y libsystemd-dev pkg-config - uses: dtolnay/rust-toolchain@stable - name: Cache cargo uses: Swatinem/rust-cache@v2 @@ -66,17 +63,18 @@ jobs: audit: name: Security Audit - runs-on: linux - container: node:18 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install system dependencies run: | - apt-get update - apt-get install -y libsystemd-dev pkg-config + sudo apt-get update + sudo apt-get install -y libsystemd-dev pkg-config - uses: dtolnay/rust-toolchain@stable + - name: Cache cargo + uses: Swatinem/rust-cache@v2 - name: Run cargo-audit run: | cargo install cargo-audit @@ -84,140 +82,114 @@ jobs: build-deb: name: Build Debian Package - runs-on: linux - container: node:18-bookworm + needs: [fmt, clippy, test] + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: dtolnay/rust-toolchain@stable + - name: Cache cargo + uses: Swatinem/rust-cache@v2 - name: Install build dependencies run: | - apt-get update - apt-get install -y build-essential debhelper cargo rustc libsystemd-dev pkg-config + sudo apt-get update + sudo apt-get install -y build-essential debhelper pkg-config libsystemd-dev - name: Build Debian package - run: dpkg-buildpackage -us -uc -b + run: sudo dpkg-buildpackage -us -uc -b - name: Upload to Gitea Release if: startsWith(github.ref, 'refs/tags/') env: GITEA_TOKEN: ${{ secrets.giteatoken }} - GITEA_API: https://gitea.moon-dragon.us/api/v1 run: | TAG_NAME=${GITHUB_REF#refs/tags/} FILE=$(ls ../linux-patch-api_*.deb 2>/dev/null | head -1) - [ -z "$FILE" ] && echo "No .deb found" && exit 0 - RELEASE_ID=$(curl -s -H "Authorization: token $GITEA_TOKEN" "$GITEA_API/repos/echo/linux_patch_api/releases/tags/$TAG_NAME" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) - if [ -z "$RELEASE_ID" ]; then - RESPONSE=$(curl -s -X POST -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d "{\"tag_name\": \"$TAG_NAME\", \"name\": \"$TAG_NAME\"}" "$GITEA_API/repos/echo/linux_patch_api/releases") - RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) - fi - UPLOAD_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X POST -H "Authorization: token $GITEA_TOKEN" -F "attachment=@$FILE" "$GITEA_API/repos/echo/linux_patch_api/releases/$RELEASE_ID/assets?name=$(basename $FILE)") - HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2) - if [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "200" ]; then echo "Upload failed $HTTP_CODE" && exit 1; fi - echo "Successfully uploaded $FILE" + chmod +x scripts/upload-release.sh + ./scripts/upload-release.sh "$TAG_NAME" "$FILE" build-rpm: name: Build RPM Package - runs-on: linux - container: linux-patch-api-rpm:latest + needs: [fmt, clippy, test] + runs-on: fedora steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: dtolnay/rust-toolchain@stable - - name: Install RPM build tools - run: | - dnf install -y rpm-build gcc cargo rust systemd-devel pkg-config + - name: Cache cargo + uses: Swatinem/rust-cache@v2 + - name: Install build dependencies + run: sudo dnf install -y rpm-build gcc systemd-devel pkg-config - name: Build release binary run: cargo build --release - name: Build RPM package - run: ./build-rpm.sh + run: | + chmod +x build-rpm.sh + ./build-rpm.sh - name: Upload to Gitea Release if: startsWith(github.ref, 'refs/tags/') env: GITEA_TOKEN: ${{ secrets.giteatoken }} - GITEA_API: https://gitea.moon-dragon.us/api/v1 run: | TAG_NAME=${GITHUB_REF#refs/tags/} FILE=$(ls ~/rpmbuild/RPMS/x86_64/*.rpm 2>/dev/null | head -1) - [ -z "$FILE" ] && echo "No .rpm found" && exit 0 - RELEASE_ID=$(curl -s -H "Authorization: token $GITEA_TOKEN" "$GITEA_API/repos/echo/linux_patch_api/releases/tags/$TAG_NAME" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) - if [ -z "$RELEASE_ID" ]; then - RESPONSE=$(curl -s -X POST -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d "{\"tag_name\": \"$TAG_NAME\", \"name\": \"$TAG_NAME\"}" "$GITEA_API/repos/echo/linux_patch_api/releases") - RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) - fi - UPLOAD_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X POST -H "Authorization: token $GITEA_TOKEN" -F "attachment=@$FILE" "$GITEA_API/repos/echo/linux_patch_api/releases/$RELEASE_ID/assets?name=$(basename $FILE)") - HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2) - if [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "200" ]; then echo "Upload failed $HTTP_CODE" && exit 1; fi - echo "Successfully uploaded $FILE" + chmod +x scripts/upload-release.sh + ./scripts/upload-release.sh "$TAG_NAME" "$FILE" build-apk: name: Build Alpine Package - runs-on: linux - container: node:18-alpine + needs: [fmt, clippy, test] + runs-on: alpine steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Install Rust toolchain - run: | - apk add --no-cache curl - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable - source $HOME/.cargo/env + - name: Cache cargo + uses: Swatinem/rust-cache@v2 - name: Install build dependencies run: | - apk add --no-cache musl-dev openssl-dev git abuild gcc elogind-dev - - name: Build APK package - run: ./build-alpine.sh + apk add --no-cache alpine-sdk rust cargo openssl-dev elogind-dev musl-dev git abuild gcc bash curl nodejs + - name: Build release binary + run: cargo build --release --target x86_64-unknown-linux-musl + - name: Build Alpine package + run: | + chmod +x build-alpine.sh + SKIP_CARGO_BUILD=1 ./build-alpine.sh - name: Upload to Gitea Release if: startsWith(github.ref, 'refs/tags/') env: GITEA_TOKEN: ${{ secrets.giteatoken }} - GITEA_API: https://gitea.moon-dragon.us/api/v1 run: | TAG_NAME=${GITHUB_REF#refs/tags/} FILE=$(ls releases/*.apk 2>/dev/null | head -1) - [ -z "$FILE" ] && echo "No .apk found" && exit 0 - RELEASE_ID=$(curl -s -H "Authorization: token $GITEA_TOKEN" "$GITEA_API/repos/echo/linux_patch_api/releases/tags/$TAG_NAME" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) - if [ -z "$RELEASE_ID" ]; then - RESPONSE=$(curl -s -X POST -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d "{\"tag_name\": \"$TAG_NAME\", \"name\": \"$TAG_NAME\"}" "$GITEA_API/repos/echo/linux_patch_api/releases") - RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) - fi - UPLOAD_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X POST -H "Authorization: token $GITEA_TOKEN" -F "attachment=@$FILE" "$GITEA_API/repos/echo/linux_patch_api/releases/$RELEASE_ID/assets?name=$(basename $FILE)") - HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2) - if [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "200" ]; then echo "Upload failed $HTTP_CODE" && exit 1; fi - echo "Successfully uploaded $FILE" + chmod +x scripts/upload-release.sh + ./scripts/upload-release.sh "$TAG_NAME" "$FILE" build-arch: name: Build Arch Package - runs-on: linux - container: linux-patch-api-arch:latest + needs: [fmt, clippy, test] + runs-on: arch steps: - uses: actions/checkout@v4 with: fetch-depth: 0 + - uses: dtolnay/rust-toolchain@stable + - name: Cache cargo + uses: Swatinem/rust-cache@v2 - name: Install build dependencies - run: | - pacman -Syu --noconfirm rust cargo systemd git base-devel + run: sudo pacman -Syu --noconfirm rust cargo systemd git base-devel - name: Build release binary run: cargo build --release - name: Build Arch package - run: ./build-arch.sh + run: | + chmod +x build-arch.sh + SKIP_CARGO_BUILD=1 ./build-arch.sh - name: Upload to Gitea Release if: startsWith(github.ref, 'refs/tags/') env: GITEA_TOKEN: ${{ secrets.giteatoken }} - GITEA_API: https://gitea.moon-dragon.us/api/v1 run: | TAG_NAME=${GITHUB_REF#refs/tags/} FILE=$(ls releases/*.pkg.tar.zst 2>/dev/null | head -1) - [ -z "$FILE" ] && echo "No .pkg.tar.zst found" && exit 0 - RELEASE_ID=$(curl -s -H "Authorization: token $GITEA_TOKEN" "$GITEA_API/repos/echo/linux_patch_api/releases/tags/$TAG_NAME" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) - if [ -z "$RELEASE_ID" ]; then - RESPONSE=$(curl -s -X POST -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d "{\"tag_name\": \"$TAG_NAME\", \"name\": \"$TAG_NAME\"}" "$GITEA_API/repos/echo/linux_patch_api/releases") - RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) - fi - UPLOAD_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X POST -H "Authorization: token $GITEA_TOKEN" -F "attachment=@$FILE" "$GITEA_API/repos/echo/linux_patch_api/releases/$RELEASE_ID/assets?name=$(basename $FILE)") - HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2) - if [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "200" ]; then echo "Upload failed $HTTP_CODE" && exit 1; fi - echo "Successfully uploaded $FILE" + chmod +x scripts/upload-release.sh + ./scripts/upload-release.sh "$TAG_NAME" "$FILE" diff --git a/Dockerfile.arch b/Dockerfile.arch deleted file mode 100644 index 9b2419b..0000000 --- a/Dockerfile.arch +++ /dev/null @@ -1,13 +0,0 @@ -# Arch Linux container with Node.js for GitHub Actions support -# Used for Arch package builds in CI/CD -FROM archlinux:latest - -# Update system and install Node.js (required for GitHub Actions JavaScript-based actions) -RUN pacman -Syu --noconfirm nodejs npm && \ - pacman -Scc --noconfirm - -# Verify node is available -RUN node --version - -# Default command (not used in CI, but good for testing) -CMD ["/bin/bash"] diff --git a/Dockerfile.rpm b/Dockerfile.rpm deleted file mode 100644 index 79d5c94..0000000 --- a/Dockerfile.rpm +++ /dev/null @@ -1,14 +0,0 @@ -# Fedora container with Node.js for GitHub Actions support -# Used for RPM package builds in CI/CD -FROM fedora:latest - -# Install Node.js (required for GitHub Actions JavaScript-based actions) -# Also install dnf-plugins-core for potential multiarch support -RUN dnf install -y nodejs dnf-plugins-core && \ - dnf clean all - -# Verify node is available -RUN node --version - -# Default command (not used in CI, but good for testing) -CMD ["/bin/bash"] diff --git a/build-alpine.sh b/build-alpine.sh old mode 100755 new mode 100644 index 4740e06..66b9d40 --- a/build-alpine.sh +++ b/build-alpine.sh @@ -1,7 +1,7 @@ #!/bin/sh # Build Alpine Package (.apk) # Run on: Alpine Linux 3.18+ -# Or in Docker: docker run -v $(pwd):/build alpine:latest /build/build-alpine.sh +# Designed for native Gitea Actions runner execution set -e @@ -13,26 +13,21 @@ if [ -f "$HOME/.cargo/env" ]; then . "$HOME/.cargo/env" fi -# Check if running on Alpine - -# Check if running on Alpine # 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 + apk add --no-cache alpine-sdk rust cargo openssl-dev openrc git abuild gcc fi -# Generate abuild signing keys (ALWAYS generate fresh - same shell session as abuild commands) +# Generate abuild signing keys echo "Generating abuild signing keys..." apk add --no-cache abuild abuild-keygen -a -n 2>&1 | tee /tmp/keygen.log -# Find the actual key file (handles missing username prefix) 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" -# Write directly to abuild.conf (overwrite any stale config) echo "PACKAGER_PRIVKEY=\"$KEYFILE\"" > /etc/abuild.conf cat /etc/abuild.conf @@ -42,8 +37,12 @@ export CBUILDROOT=$(pwd)/.abuild mkdir -p "$CBUILDROOT" # Build release binary -echo "Building release binary..." -cargo build --release --target x86_64-unknown-linux-musl +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 # Create package directory PKGDIR=$(pwd)/apk-package @@ -58,14 +57,17 @@ cp configs/linux-patch-api-openrc "$PKGDIR"/etc/init.d/linux-patch-api chmod 755 "$PKGDIR"/etc/init.d/linux-patch-api cp configs/whitelist.yaml.example "$PKGDIR"/etc/linux_patch_api/whitelist.yaml +# Determine workspace path for APKBUILD +WORKSPACE_DIR=$(pwd) + # Create APKBUILD echo "Creating APKBUILD..." -cat > APKBUILD << 'EOF' +cat > APKBUILD << EOF pkgname=linux-patch-api pkgver=1.0.0 pkgrel=1 pkgdesc="Secure remote package management API for Linux systems" -url="https://gitea.internal/linux-patch-api" +url="https://gitea.moon-dragon.us/echo/linux_patch_api" arch="x86_64" license="MIT" makedepends="" @@ -73,14 +75,12 @@ depends="openrc" source="" package() { - # Create directory structure in pkgdir - install -d "$pkgdir"/usr/bin - install -d "$pkgdir"/etc/linux_patch_api - install -d "$pkgdir"/etc/init.d - # Copy from pre-built apk-package directory - cp -r /workspace/echo/linux_patch_api/apk-package/usr/bin/* "$pkgdir"/usr/bin/ - cp -r /workspace/echo/linux_patch_api/apk-package/etc/linux_patch_api/* "$pkgdir"/etc/linux_patch_api/ - cp -r /workspace/echo/linux_patch_api/apk-package/etc/init.d/* "$pkgdir"/etc/init.d/ + install -d "\$pkgdir"/usr/bin + install -d "\$pkgdir"/etc/linux_patch_api + install -d "\$pkgdir"/etc/init.d + cp -r ${WORKSPACE_DIR}/apk-package/usr/bin/* "\$pkgdir"/usr/bin/ + cp -r ${WORKSPACE_DIR}/apk-package/etc/linux_patch_api/* "\$pkgdir"/etc/linux_patch_api/ + cp -r ${WORKSPACE_DIR}/apk-package/etc/init.d/* "\$pkgdir"/etc/init.d/ } EOF @@ -90,30 +90,23 @@ echo "Generating checksums..." # Build APK package echo "Building APK package..." -# For CI/container environments where we run as root, create a build user +# 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 - # CRITICAL: Add builduser to abuild group (required for apk install permissions) addgroup builduser abuild 2>/dev/null || usermod -aG abuild builduser chown -R builduser:builduser "$(pwd)" chown -R builduser:builduser /root/packages 2>/dev/null || true - # Copy abuild keys from root to builduser home mkdir -p /home/builduser/.abuild cp /root/.abuild/* /home/builduser/.abuild/ chown -R builduser:builduser /home/builduser/.abuild - - # Find the actual key file + 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 "Key file exists: $(test -f "$KEYFILE" && echo YES || echo NO)" - - # CRITICAL: Write to builduser's PERSONAL abuild.conf (~/.abuild/abuild.conf) - # abuild reads this when running as builduser - standard behavior, no shell quoting issues! echo "PACKAGER_PRIVKEY=\"$KEYFILE\"" > /home/builduser/.abuild/abuild.conf chown builduser:builduser /home/builduser/.abuild/abuild.conf su - builduser -c "cd $(pwd) && abuild checksum && abuild -d -F && cp /home/builduser/packages/x86_64/*.apk ./releases/ 2>/dev/null || cp /home/builduser/packages/*.apk ./releases/ 2>/dev/null || ls -la /home/builduser/packages/" diff --git a/build-arch.sh b/build-arch.sh old mode 100755 new mode 100644 index f4fca2c..1bba214 --- a/build-arch.sh +++ b/build-arch.sh @@ -1,7 +1,7 @@ #!/bin/bash # Build Arch Linux Package (.pkg.tar.zst) -# Run on: Arch Linux, Manjaro -# Or in Docker: docker run -v $(pwd):/build archlinux:latest /build/build-arch.sh +# Run on: Arch Linux / Manjaro +# Designed for native Gitea Actions runner execution set -e @@ -11,17 +11,16 @@ echo "" # Check if running on Arch if ! command -v makepkg &> /dev/null; then echo "Error: makepkg not found. This script must run on Arch Linux." - echo "Or use Docker: docker run -v \$(pwd):/build archlinux:latest /build/build-arch.sh" exit 1 fi -# Install build dependencies -echo "Installing build dependencies..." -pacman -Syu --noconfirm rust cargo systemd git base-devel - # Build release binary -echo "Building release binary..." -cargo build --release +if [ -z "$SKIP_CARGO_BUILD" ]; then + echo "Building release binary..." + cargo build --release +else + echo "Skipping cargo build (SKIP_CARGO_BUILD is set)" +fi # Create package directory PKGDIR=$(pwd)/arch-package @@ -36,9 +35,12 @@ cp configs/linux-patch-api.service "$PKGDIR"/usr/lib/systemd/system/ cp configs/config.yaml.example "$PKGDIR"/etc/linux_patch_api/config.yaml cp configs/whitelist.yaml.example "$PKGDIR"/etc/linux_patch_api/whitelist.yaml +# Determine workspace path for PKGBUILD +WORKSPACE_DIR=$(pwd) + # Create PKGBUILD echo "Creating PKGBUILD..." -cat > PKGBUILD << 'EOF' +cat > PKGBUILD << EOF pkgname=linux-patch-api pkgver=1.0.0 pkgrel=1 @@ -49,8 +51,7 @@ license=('MIT') depends=('systemd') package() { - # Use absolute path since makepkg changes working directory to srcdir - cp -r /workspace/echo/linux_patch_api/arch-package/* "$pkgdir"/ + cp -r ${WORKSPACE_DIR}/arch-package/* "$pkgdir"/ } EOF @@ -60,7 +61,7 @@ echo "Creating .SRCINFO..." # Build package echo "Building Arch package..." -# For CI/container environments where we run as root, create a build user +# For CI environments where we may run as root if [ "$(id -u)" = "0" ]; then echo "Running as root - creating build user for makepkg..." useradd -m builduser 2>/dev/null || true diff --git a/build-rpm.sh b/build-rpm.sh index 26f0ea1..3e2196b 100755 --- a/build-rpm.sh +++ b/build-rpm.sh @@ -1,6 +1,7 @@ #!/bin/bash # Build RPM Package for RHEL/CentOS/Fedora # Run on: RHEL 8/9, CentOS 8/9, Fedora 38+ +# Designed for native Gitea Actions runner execution set -e @@ -11,9 +12,9 @@ echo "" if ! command -v rpmbuild &> /dev/null; then echo "Installing RPM build tools..." if command -v dnf &> /dev/null; then - sudo dnf install -y rpm-build cargo rust gcc systemd-devel + dnf install -y rpm-build cargo rust gcc systemd-devel elif command -v yum &> /dev/null; then - sudo yum install -y rpm-build cargo rust gcc systemd-devel + yum install -y rpm-build cargo rust gcc systemd-devel else echo "Error: Cannot install rpm-build. Please install manually." exit 1 @@ -57,6 +58,6 @@ echo "=== Build Complete ===" echo "Package: releases/linux-patch-api-*.rpm" echo "" echo "Install with:" -echo " sudo dnf install -y ./releases/linux-patch-api-*.rpm" +echo " dnf install -y ./releases/linux-patch-api-*.rpm" echo " # or" -echo " sudo yum install -y ./releases/linux-patch-api-*.rpm" +echo " yum install -y ./releases/linux-patch-api-*.rpm" diff --git a/scripts/upload-release.sh b/scripts/upload-release.sh new file mode 100755 index 0000000..dbc776d --- /dev/null +++ b/scripts/upload-release.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# Upload build artifacts to Gitea Release +# Usage: upload-release.sh +# Example: upload-release.sh v1.0.0 "../linux-patch-api_1.0.0-1_amd64.deb" +# +# Required environment variables: +# GITEA_TOKEN - API token with repo access +# GITEA_API - Gitea API base URL (default: https://gitea.moon-dragon.us/api/v1) + +set -e + +TAG_NAME="${1:?Usage: upload-release.sh }" +FILE_PATH="${2}" + +GITEA_API="${GITEA_API:-https://gitea.moon-dragon.us/api/v1}" +REPO="echo/linux_patch_api" + +if [ -z "$GITEA_TOKEN" ]; then + echo "Error: GITEA_TOKEN environment variable not set" + exit 1 +fi + +if [ -z "$FILE_PATH" ] || [ ! -f "$FILE_PATH" ]; then + echo "No file found at '$FILE_PATH'" + echo "Skipping upload." + exit 0 +fi + +echo "Uploading $(basename "$FILE_PATH") for release $TAG_NAME..." + +# Try to find existing release (do not use -f flag since 404 is expected for new releases) +RELEASE_ID=$(curl -s -H "Authorization: token $GITEA_TOKEN" "$GITEA_API/repos/$REPO/releases/tags/$TAG_NAME" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) + +# Create release if it doesn't exist +if [ -z "$RELEASE_ID" ]; then + echo "Creating new release for tag $TAG_NAME..." + RESPONSE=$(curl -s -X POST \ + -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\": \"$TAG_NAME\", \"name\": \"$TAG_NAME\"}" \ + "$GITEA_API/repos/$REPO/releases") + RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) +fi + +if [ -z "$RELEASE_ID" ]; then + echo "Error: Could not create or find release for tag $TAG_NAME" + exit 1 +fi + +# Upload the asset +UPLOAD_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X POST \ + -H "Authorization: token $GITEA_TOKEN" \ + -F "attachment=@$FILE_PATH" \ + "$GITEA_API/repos/$REPO/releases/$RELEASE_ID/assets?name=$(basename "$FILE_PATH")") + +HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2) +if [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "200" ]; then + echo "Upload failed with HTTP code $HTTP_CODE" + echo "$UPLOAD_RESPONSE" + exit 1 +fi + +echo "Successfully uploaded $(basename "$FILE_PATH") to release $TAG_NAME"