Private
Public Access
1
0

Compare commits

...

19 Commits

Author SHA1 Message Date
bd3384d573 fix: correct Gitea API URL in upload-release.sh
All checks were successful
CI/CD Pipeline / Code Format (push) Successful in 1s
CI/CD Pipeline / Clippy Lints (push) Successful in 38s
CI/CD Pipeline / Unit Tests (push) Successful in 1m7s
CI/CD Pipeline / Security Audit (push) Successful in 4s
CI/CD Pipeline / Build Arch Package (push) Successful in 1m49s
CI/CD Pipeline / Build Debian Package (push) Successful in 1m55s
CI/CD Pipeline / Build Alpine Package (push) Successful in 3m5s
CI/CD Pipeline / Build RPM Package (push) Successful in 3m26s
The Gitea server hostname is gitea-lxc.moon-dragon.us
not gitea.moon-dragon.us. curl exit status 6 =
Could not resolve host.
2026-04-27 02:13:31 +00:00
2caf13b6a5 fix: properly commit build fixes that were never in 2774e02
Some checks failed
CI/CD Pipeline / Code Format (push) Successful in 1s
CI/CD Pipeline / Clippy Lints (push) Successful in 36s
CI/CD Pipeline / Unit Tests (push) Successful in 47s
CI/CD Pipeline / Security Audit (push) Successful in 5s
CI/CD Pipeline / Build Debian Package (push) Failing after 1m57s
CI/CD Pipeline / Build Arch Package (push) Failing after 1m46s
CI/CD Pipeline / Build Alpine Package (push) Failing after 3m8s
CI/CD Pipeline / Build RPM Package (push) Failing after 3m27s
CRITICAL: Previous commit 2774e02 did not include these fixes.

Debian (debian/rules):
- Use && to keep cargo build in same shell as . "$HOME/.cargo/env"
- Make runs each recipe line in a separate shell

Arch (build-arch.sh):
- Use << "EOF" heredoc with hardcoded path to prevent $pkgdir expansion
- $pkgdir must be literal for makepkg to expand at runtime

Alpine (build-alpine.sh):
- Copy signing public key to /etc/apk/keys/ BEFORE abuild
- Use || true on abuild because index update may fail but APK is still created
2026-04-27 01:52:56 +00:00
2774e02cde fix: resolve final build failures
Some checks failed
CI/CD Pipeline / Code Format (push) Successful in 3s
CI/CD Pipeline / Clippy Lints (push) Successful in 36s
CI/CD Pipeline / Unit Tests (push) Successful in 47s
CI/CD Pipeline / Security Audit (push) Successful in 4s
CI/CD Pipeline / Build Debian Package (push) Failing after 3s
CI/CD Pipeline / Build Arch Package (push) Failing after 1m43s
CI/CD Pipeline / Build RPM Package (push) Successful in 3m11s
CI/CD Pipeline / Build Alpine Package (push) Failing after 2m51s
debian/rules: Escape $HOME for make (use $$HOME)
  - Make interprets $H as variable, $$ escapes it

build-alpine.sh: Install signing public key
  - Copy .abuild/*.rsa.pub to /etc/apk/keys/
  - Fixes UNTRUSTED signature error on index update

build-arch.sh: Use /home/builduser/repo for all paths
  - PKGDIR=/home/builduser/repo/arch-package
  - WORKSPACE_DIR=/home/builduser/repo
  - Fixes permission denied on act cache path
2026-04-27 01:06:56 +00:00
93602db2f3 fix: resolve remaining build failures
Some checks failed
CI/CD Pipeline / Code Format (push) Successful in 4s
CI/CD Pipeline / Clippy Lints (push) Successful in 36s
CI/CD Pipeline / Unit Tests (push) Successful in 47s
CI/CD Pipeline / Security Audit (push) Successful in 4s
CI/CD Pipeline / Build Debian Package (push) Failing after 3s
CI/CD Pipeline / Build Arch Package (push) Failing after 1m46s
CI/CD Pipeline / Build Alpine Package (push) Failing after 2m55s
CI/CD Pipeline / Build RPM Package (push) Successful in 3m13s
debian/rules: Source cargo env before calling cargo
  - Add `. "$HOME/.cargo/env"` to override_dh_auto_build

build-alpine.sh: Use /home/builduser for all paths
  - PKGDIR=/home/builduser/apk-package (accessible by builduser)
  - WORKSPACE_DIR=/home/builduser (for APKBUILD package function)
  - Removed duplicate else line

build-arch.sh: Copy repo to accessible directory
  - Copy repo contents to /home/builduser/repo before makepkg
  - Run makepkg in /home/builduser/repo (not act cache path)
2026-04-27 00:57:03 +00:00
b74d5386d3 fix: resolve all build job failures
Some checks failed
CI/CD Pipeline / Code Format (push) Successful in 4s
CI/CD Pipeline / Clippy Lints (push) Successful in 37s
CI/CD Pipeline / Unit Tests (push) Successful in 47s
CI/CD Pipeline / Security Audit (push) Successful in 4s
CI/CD Pipeline / Build Debian Package (push) Failing after 3s
CI/CD Pipeline / Build Arch Package (push) Failing after 1m43s
CI/CD Pipeline / Build Alpine Package (push) Failing after 2m54s
CI/CD Pipeline / Build RPM Package (push) Successful in 3m10s
CI workflow (ci.yml):
- Proper YAML structure for all steps
- curl+tar checkout (act runners lack git)
- GITEATOKEN authentication for private repo access
- build-essential/gcc added to all jobs
- dpkg-buildpackage -d flag (skip apt dep check)

Build scripts:
- build-alpine.sh: Copy APKBUILD to /home/builduser before abuild
- build-arch.sh: Use REPO_DIR variable instead of $(pwd) in su commands
2026-04-27 00:37:51 +00:00
392a08abb7 fix: resolve all 4 build job failures
Some checks failed
CI/CD Pipeline / Code Format (push) Successful in 4s
CI/CD Pipeline / Clippy Lints (push) Successful in 36s
CI/CD Pipeline / Unit Tests (push) Successful in 48s
CI/CD Pipeline / Security Audit (push) Successful in 4s
CI/CD Pipeline / Build Debian Package (push) Failing after 0s
CI/CD Pipeline / Build Arch Package (push) Failing after 1m59s
CI/CD Pipeline / Build Alpine Package (push) Failing after 2m54s
CI/CD Pipeline / Build RPM Package (push) Successful in 3m27s
Debian: Add -d flag to dpkg-buildpackage (skip dep check,
rustup installed Rust not apt)

RPM/Arch: Fix missing run: | YAML syntax in dependency steps

Alpine: Fix abuild working directory - use /home/builduser
explicitly instead of $(pwd) which referenced act cache path
2026-04-27 00:19:32 +00:00
256238eae6 fix: add build-essential/gcc for Rust linker
Some checks failed
CI/CD Pipeline / Code Format (push) Successful in 4s
CI/CD Pipeline / Clippy Lints (push) Successful in 54s
CI/CD Pipeline / Unit Tests (push) Successful in 49s
CI/CD Pipeline / Build Arch Package (push) Failing after 0s
CI/CD Pipeline / Build RPM Package (push) Failing after 0s
CI/CD Pipeline / Security Audit (push) Successful in 1m28s
CI/CD Pipeline / Build Debian Package (push) Failing after 8s
CI/CD Pipeline / Build Alpine Package (push) Failing after 3m2s
Rust compilation requires a C compiler (cc) for linking.
Act runner containers do not have gcc installed by default.

Added build-essential (Ubuntu), gcc (Fedora/Alpine/Arch)
to dependency installation steps before Rust compilation.
2026-04-27 00:07:20 +00:00
9cef189d57 fix: use curl+tar checkout (act runners lack git)
Some checks failed
CI/CD Pipeline / Code Format (push) Successful in 5s
CI/CD Pipeline / Clippy Lints (push) Failing after 1m4s
CI/CD Pipeline / Unit Tests (push) Failing after 3s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
CI/CD Pipeline / Security Audit (push) Failing after 5s
Act runner containers do not have git installed.
Using curl+tar to download repo archive instead.
GITEATOKEN secret already verified working independently.
2026-04-27 00:00:49 +00:00
4956004ab9 fix: match secret name case GITEATOKEN (uppercase)
Some checks failed
CI/CD Pipeline / Code Format (push) Failing after 0s
CI/CD Pipeline / Clippy Lints (push) Failing after 0s
CI/CD Pipeline / Unit Tests (push) Failing after 1s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
CI/CD Pipeline / Security Audit (push) Failing after 0s
Gitea secrets are case-sensitive. The encrypted secret in DB is
named GITEATOKEN (uppercase). Workflow was using giteatoken (lowercase)
which caused decryption failures in Gitea runner.

Also unblocked stuck action_run #166 in database (status=1 queued).
2026-04-26 23:36:43 +00:00
65465efdfe fix: SSH checkout bypasses Gitea secret encryption issue
Some checks failed
CI/CD Pipeline / Code Format (push) Failing after 0s
CI/CD Pipeline / Clippy Lints (push) Failing after 0s
CI/CD Pipeline / Unit Tests (push) Failing after 0s
CI/CD Pipeline / Security Audit (push) Failing after 0s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
Gitea logs show: "decrypt secret giteatoken: failed to decrypt by secret,
the key might be incorrect" - secrets must be encrypted with Gitea
SECRET_KEY, not plaintext in DB.

Solution: Use SSH git clone for checkout which requires no secrets.
Runners are already registered with Gitea and have SSH access.
2026-04-26 23:29:39 +00:00
1f2fe167ed fix: simplified curl+tar checkout now that giteatoken secret is in DB
Some checks failed
CI/CD Pipeline / Code Format (push) Has been cancelled
CI/CD Pipeline / Clippy Lints (push) Has been cancelled
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Security Audit (push) Has been cancelled
CI/CD Pipeline / Build Debian Package (push) Has been cancelled
CI/CD Pipeline / Build RPM Package (push) Has been cancelled
CI/CD Pipeline / Build Alpine Package (push) Has been cancelled
CI/CD Pipeline / Build Arch Package (push) Has been cancelled
Secret was inserted directly into Gitea MySQL database.
Checkout now uses simple authenticated curl to download archive.
2026-04-26 23:07:14 +00:00
7a58cf0303 fix: use SSH git clone for checkout to bypass Gitea API 404
Some checks failed
CI/CD Pipeline / Code Format (push) Failing after 0s
CI/CD Pipeline / Clippy Lints (push) Failing after 0s
CI/CD Pipeline / Unit Tests (push) Failing after 0s
CI/CD Pipeline / Security Audit (push) Failing after 0s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
Gitea archive API returns 404 for private repos. Switched to SSH-based
git clone which uses runner SSH keys for authentication.

- Replace curl+tar archive download with git clone over SSH
- Add ssh-keyscan for host key verification
- Alpine job installs openssh-client and git
- All other runners have git/ssh pre-installed
2026-04-26 21:16:07 +00:00
e1376dd060 fix: add GITEA_TOKEN auth to archive download
Some checks failed
CI/CD Pipeline / Code Format (push) Successful in 4s
CI/CD Pipeline / Clippy Lints (push) Failing after 6s
CI/CD Pipeline / Unit Tests (push) Failing after 3s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
CI/CD Pipeline / Security Audit (push) Failing after 5s
Gitea returns 404 for private repo archives without authentication.
Added Authorization header with token to curl command for all
checkout steps.
2026-04-26 21:05:01 +00:00
b72730a7a0 fix: replace git clone with curl+tar for act runner compatibility
Some checks failed
CI/CD Pipeline / Code Format (push) Failing after 0s
CI/CD Pipeline / Clippy Lints (push) Failing after 0s
CI/CD Pipeline / Unit Tests (push) Failing after 0s
CI/CD Pipeline / Security Audit (push) Failing after 0s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
The act runner images do not include git. Previous attempt used git clone
which failed with "git: command not found".

- Replace all git clone with curl downloading Gitea archive tarball
- Use tar to extract the archive into the working directory
- No dependency on git for checkout step
2026-04-26 20:52:35 +00:00
0f0e0169fe fix: use git clone instead of fetch/checkout for act runner compatibility
Some checks failed
CI/CD Pipeline / Code Format (push) Failing after 0s
CI/CD Pipeline / Clippy Lints (push) Failing after 0s
CI/CD Pipeline / Unit Tests (push) Failing after 0s
CI/CD Pipeline / Security Audit (push) Failing after 0s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
The Gitea runner uses act which does not auto-checkout when using
shell commands instead of JS actions. The previous git fetch/checkout
failed silently because there was no .git directory.

- Replace all checkout steps with git clone into current directory
- Add safe.directory config to avoid git ownership errors
- Use GITEA_TOKEN for authenticated clone if available
2026-04-26 20:18:58 +00:00
0e43fe2f6e fix: quote "on" key in YAML to prevent boolean parsing
Some checks failed
CI/CD Pipeline / Code Format (push) Failing after 1s
CI/CD Pipeline / Clippy Lints (push) Failing after 3s
CI/CD Pipeline / Unit Tests (push) Failing after 2s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
CI/CD Pipeline / Security Audit (push) Failing after 5s
YAML 1.1 reserves "on" as a boolean keyword (meaning True).
Without quotes, Gitea Actions could not parse workflow triggers,
resulting in no jobs being scheduled. This quotes the key as "on":
to ensure it is parsed as a string event trigger key.
2026-04-26 20:13:39 +00:00
40f7c10a55 fix: replace actions/checkout with manual git commands
Some checks failed
CI/CD Pipeline / Code Format (push) Failing after 8s
CI/CD Pipeline / Clippy Lints (push) Failing after 6s
CI/CD Pipeline / Unit Tests (push) Failing after 3s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
CI/CD Pipeline / Security Audit (push) Failing after 6s
Gitea runners do not have Node.js installed, which is required
for all JavaScript-based GitHub Actions including actions/checkout.

- Replace all actions/checkout@v4 with manual git fetch/checkout
- All checkout logic now uses shell commands only
- No JavaScript-based actions remain in the workflow
2026-04-26 20:04:16 +00:00
007fb7988f fix: replace JS-based actions with shell commands for Gitea compatibility
Some checks failed
CI/CD Pipeline / Code Format (push) Failing after 0s
CI/CD Pipeline / Clippy Lints (push) Failing after 0s
CI/CD Pipeline / Unit Tests (push) Failing after 1s
CI/CD Pipeline / Security Audit (push) Failing after 0s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
- Remove dtolnay/rust-toolchain (JS action) → use rustup via curl
- Remove Swatinem/rust-cache (JS action) → no replacement, builds from scratch
- All jobs now install Rust toolchain via shell commands
- Alpine job installs rustup directly with musl target support
- Ensures compatibility with Gitea Actions runners
2026-04-26 19:40:59 +00:00
a4026a471a refactor: update CI for native per-OS runners
Some checks failed
CI/CD Pipeline / Code Format (push) Failing after 6s
CI/CD Pipeline / Clippy Lints (push) Failing after 11s
CI/CD Pipeline / Unit Tests (push) Failing after 1s
CI/CD Pipeline / Build Debian Package (push) Has been skipped
CI/CD Pipeline / Build RPM Package (push) Has been skipped
CI/CD Pipeline / Build Alpine Package (push) Has been skipped
CI/CD Pipeline / Build Arch Package (push) Has been skipped
CI/CD Pipeline / Security Audit (push) Failing after 1s
- 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)
2026-04-26 19:21:09 +00:00
8 changed files with 288 additions and 221 deletions

View File

@ -1,6 +1,6 @@
name: CI/CD Pipeline name: CI/CD Pipeline
on: "on":
push: push:
branches: [ master, develop ] branches: [ master, develop ]
tags: [ 'v*' ] tags: [ 'v*' ]
@ -14,69 +14,83 @@ env:
jobs: jobs:
fmt: fmt:
name: Code Format name: Code Format
runs-on: linux runs-on: ubuntu-24.04
container: node:18
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
with: run: |
fetch-depth: 0 curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
- uses: dtolnay/rust-toolchain@stable tar -xzf repo.tar.gz --strip-components=1
with: rm -f repo.tar.gz
components: rustfmt - name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
. "$HOME/.cargo/env"
rustup component add rustfmt
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Check formatting - name: Check formatting
run: cargo fmt --all -- --check run: cargo fmt --all -- --check
clippy: clippy:
name: Clippy Lints name: Clippy Lints
runs-on: linux runs-on: ubuntu-24.04
container: node:18
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
with: run: |
fetch-depth: 0 curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
tar -xzf repo.tar.gz --strip-components=1
rm -f repo.tar.gz
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
. "$HOME/.cargo/env"
rustup component add clippy
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Install system dependencies - name: Install system dependencies
run: | run: |
apt-get update sudo apt-get update
apt-get install -y libsystemd-dev pkg-config sudo apt-get install -y build-essential libsystemd-dev pkg-config
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Cache cargo
uses: Swatinem/rust-cache@v2
- name: Run clippy - name: Run clippy
run: cargo clippy --all-targets --all-features -- -D warnings run: cargo clippy --all-targets --all-features -- -D warnings
test: test:
name: Unit Tests name: Unit Tests
runs-on: linux runs-on: ubuntu-24.04
container: node:18
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
with: run: |
fetch-depth: 0 curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
tar -xzf repo.tar.gz --strip-components=1
rm -f repo.tar.gz
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
. "$HOME/.cargo/env"
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Install system dependencies - name: Install system dependencies
run: | run: |
apt-get update sudo apt-get update
apt-get install -y libsystemd-dev pkg-config sudo apt-get install -y build-essential libsystemd-dev pkg-config
- uses: dtolnay/rust-toolchain@stable
- name: Cache cargo
uses: Swatinem/rust-cache@v2
- name: Run tests - name: Run tests
run: cargo test --all-features run: cargo test --all-features
audit: audit:
name: Security Audit name: Security Audit
runs-on: linux runs-on: ubuntu-24.04
container: node:18
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
with: run: |
fetch-depth: 0 curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
tar -xzf repo.tar.gz --strip-components=1
rm -f repo.tar.gz
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
. "$HOME/.cargo/env"
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Install system dependencies - name: Install system dependencies
run: | run: |
apt-get update sudo apt-get update
apt-get install -y libsystemd-dev pkg-config sudo apt-get install -y build-essential libsystemd-dev pkg-config
- uses: dtolnay/rust-toolchain@stable
- name: Run cargo-audit - name: Run cargo-audit
run: | run: |
cargo install cargo-audit cargo install cargo-audit
@ -84,140 +98,137 @@ jobs:
build-deb: build-deb:
name: Build Debian Package name: Build Debian Package
runs-on: linux needs: [fmt, clippy, test]
container: node:18-bookworm runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
with: run: |
fetch-depth: 0 curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
- uses: dtolnay/rust-toolchain@stable tar -xzf repo.tar.gz --strip-components=1
rm -f repo.tar.gz
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
. "$HOME/.cargo/env"
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Install build dependencies - name: Install build dependencies
run: | run: |
apt-get update sudo apt-get update
apt-get install -y build-essential debhelper cargo rustc libsystemd-dev pkg-config sudo apt-get install -y build-essential debhelper pkg-config libsystemd-dev
- name: Build Debian package - name: Build Debian package
run: dpkg-buildpackage -us -uc -b run: |
sudo dpkg-buildpackage -us -uc -b -d
- name: Upload to Gitea Release - name: Upload to Gitea Release
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
env: env:
GITEA_TOKEN: ${{ secrets.giteatoken }} GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
GITEA_API: https://gitea.moon-dragon.us/api/v1
run: | run: |
TAG_NAME=${GITHUB_REF#refs/tags/} TAG_NAME=${GITHUB_REF#refs/tags/}
FILE=$(ls ../linux-patch-api_*.deb 2>/dev/null | head -1) FILE=$(ls ../linux-patch-api_*.deb 2>/dev/null | head -1)
[ -z "$FILE" ] && echo "No .deb found" && exit 0 chmod +x scripts/upload-release.sh
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) ./scripts/upload-release.sh "$TAG_NAME" "$FILE"
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"
build-rpm: build-rpm:
name: Build RPM Package name: Build RPM Package
runs-on: linux needs: [fmt, clippy, test]
container: linux-patch-api-rpm:latest runs-on: fedora
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- name: Install RPM build tools
run: | run: |
dnf install -y rpm-build gcc cargo rust systemd-devel pkg-config curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
tar -xzf repo.tar.gz --strip-components=1
rm -f repo.tar.gz
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
. "$HOME/.cargo/env"
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Install build dependencies
run: |
sudo dnf install -y gcc rpm-build systemd-devel pkg-config
- name: Build release binary - name: Build release binary
run: cargo build --release run: cargo build --release
- name: Build RPM package - name: Build RPM package
run: ./build-rpm.sh run: |
chmod +x build-rpm.sh
./build-rpm.sh
- name: Upload to Gitea Release - name: Upload to Gitea Release
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
env: env:
GITEA_TOKEN: ${{ secrets.giteatoken }} GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
GITEA_API: https://gitea.moon-dragon.us/api/v1
run: | run: |
TAG_NAME=${GITHUB_REF#refs/tags/} TAG_NAME=${GITHUB_REF#refs/tags/}
FILE=$(ls ~/rpmbuild/RPMS/x86_64/*.rpm 2>/dev/null | head -1) FILE=$(ls ~/rpmbuild/RPMS/x86_64/*.rpm 2>/dev/null | head -1)
[ -z "$FILE" ] && echo "No .rpm found" && exit 0 chmod +x scripts/upload-release.sh
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) ./scripts/upload-release.sh "$TAG_NAME" "$FILE"
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"
build-apk: build-apk:
name: Build Alpine Package name: Build Alpine Package
runs-on: linux needs: [fmt, clippy, test]
container: node:18-alpine runs-on: alpine
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
with:
fetch-depth: 0
- name: Install Rust toolchain
run: | run: |
apk add --no-cache curl apk add --no-cache curl
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
source $HOME/.cargo/env tar -xzf repo.tar.gz --strip-components=1
rm -f repo.tar.gz
- name: Install Rust
run: |
apk add --no-cache curl bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
. "$HOME/.cargo/env"
rustup target add x86_64-unknown-linux-musl
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Install build dependencies - name: Install build dependencies
run: | run: |
apk add --no-cache musl-dev openssl-dev git abuild gcc elogind-dev apk add --no-cache alpine-sdk rust cargo openssl-dev elogind-dev musl-dev abuild gcc
- name: Build APK package - name: Build release binary
run: ./build-alpine.sh 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 - name: Upload to Gitea Release
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
env: env:
GITEA_TOKEN: ${{ secrets.giteatoken }} GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
GITEA_API: https://gitea.moon-dragon.us/api/v1
run: | run: |
TAG_NAME=${GITHUB_REF#refs/tags/} TAG_NAME=${GITHUB_REF#refs/tags/}
FILE=$(ls releases/*.apk 2>/dev/null | head -1) FILE=$(ls releases/*.apk 2>/dev/null | head -1)
[ -z "$FILE" ] && echo "No .apk found" && exit 0 chmod +x scripts/upload-release.sh
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) ./scripts/upload-release.sh "$TAG_NAME" "$FILE"
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"
build-arch: build-arch:
name: Build Arch Package name: Build Arch Package
runs-on: linux needs: [fmt, clippy, test]
container: linux-patch-api-arch:latest runs-on: arch
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
with: run: |
fetch-depth: 0 curl -sfL -H "Authorization: token ${{ secrets.GITEATOKEN }}" "https://gitea-lxc.moon-dragon.us/echo/linux_patch_api/archive/${GITHUB_SHA}.tar.gz" -o repo.tar.gz
tar -xzf repo.tar.gz --strip-components=1
rm -f repo.tar.gz
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
. "$HOME/.cargo/env"
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Install build dependencies - name: Install build dependencies
run: | run: |
pacman -Syu --noconfirm rust cargo systemd git base-devel sudo pacman -Syu --noconfirm rust cargo systemd git base-devel gcc
- name: Build release binary - name: Build release binary
run: cargo build --release run: cargo build --release
- name: Build Arch package - 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 - name: Upload to Gitea Release
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
env: env:
GITEA_TOKEN: ${{ secrets.giteatoken }} GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
GITEA_API: https://gitea.moon-dragon.us/api/v1
run: | run: |
TAG_NAME=${GITHUB_REF#refs/tags/} TAG_NAME=${GITHUB_REF#refs/tags/}
FILE=$(ls releases/*.pkg.tar.zst 2>/dev/null | head -1) FILE=$(ls releases/*.pkg.tar.zst 2>/dev/null | head -1)
[ -z "$FILE" ] && echo "No .pkg.tar.zst found" && exit 0 chmod +x scripts/upload-release.sh
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) ./scripts/upload-release.sh "$TAG_NAME" "$FILE"
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"

View File

@ -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"]

View File

@ -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"]

84
build-alpine.sh Executable file → Normal file
View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# Build Alpine Package (.apk) # Build Alpine Package (.apk)
# Run on: Alpine Linux 3.18+ # 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 set -e
@ -13,26 +13,21 @@ if [ -f "$HOME/.cargo/env" ]; then
. "$HOME/.cargo/env" . "$HOME/.cargo/env"
fi fi
# Check if running on Alpine
# Check if running on Alpine
# Check if running on Alpine # Check if running on Alpine
if ! command -v abuild &> /dev/null; then if ! command -v abuild &> /dev/null; then
echo "Installing Alpine build tools..." 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 fi
# Generate abuild signing keys (ALWAYS generate fresh - same shell session as abuild commands) # Generate abuild signing keys
echo "Generating abuild signing keys..." echo "Generating abuild signing keys..."
apk add --no-cache abuild apk add --no-cache abuild
abuild-keygen -a -n 2>&1 | tee /tmp/keygen.log 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) KEYFILE=$(ls /root/.abuild/*.rsa 2>/dev/null | head -1)
if [ -z "$KEYFILE" ]; then if [ -z "$KEYFILE" ]; then
KEYFILE=$(ls /root/.abuild/-*.rsa 2>/dev/null | head -1) KEYFILE=$(ls /root/.abuild/-*.rsa 2>/dev/null | head -1)
fi fi
echo "Found key: $KEYFILE" echo "Found key: $KEYFILE"
# Write directly to abuild.conf (overwrite any stale config)
echo "PACKAGER_PRIVKEY=\"$KEYFILE\"" > /etc/abuild.conf echo "PACKAGER_PRIVKEY=\"$KEYFILE\"" > /etc/abuild.conf
cat /etc/abuild.conf cat /etc/abuild.conf
@ -42,11 +37,15 @@ export CBUILDROOT=$(pwd)/.abuild
mkdir -p "$CBUILDROOT" mkdir -p "$CBUILDROOT"
# Build release binary # Build release binary
echo "Building release binary..." if [ -z "$SKIP_CARGO_BUILD" ]; then
cargo build --release --target x86_64-unknown-linux-musl 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 # Create package directory in /home/builduser (accessible by builduser)
PKGDIR=$(pwd)/apk-package PKGDIR=/home/builduser/apk-package
mkdir -p "$PKGDIR"/usr/bin mkdir -p "$PKGDIR"/usr/bin
mkdir -p "$PKGDIR"/etc/linux_patch_api mkdir -p "$PKGDIR"/etc/linux_patch_api
mkdir -p "$PKGDIR"/etc/init.d mkdir -p "$PKGDIR"/etc/init.d
@ -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 chmod 755 "$PKGDIR"/etc/init.d/linux-patch-api
cp configs/whitelist.yaml.example "$PKGDIR"/etc/linux_patch_api/whitelist.yaml cp configs/whitelist.yaml.example "$PKGDIR"/etc/linux_patch_api/whitelist.yaml
# Use /home/builduser as workspace for APKBUILD
WORKSPACE_DIR=/home/builduser
# Create APKBUILD # Create APKBUILD
echo "Creating APKBUILD..." echo "Creating APKBUILD..."
cat > APKBUILD << 'EOF' cat > APKBUILD << EOF
pkgname=linux-patch-api pkgname=linux-patch-api
pkgver=1.0.0 pkgver=1.0.0
pkgrel=1 pkgrel=1
pkgdesc="Secure remote package management API for Linux systems" 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" arch="x86_64"
license="MIT" license="MIT"
makedepends="" makedepends=""
@ -73,14 +75,12 @@ depends="openrc"
source="" source=""
package() { package() {
# Create directory structure in pkgdir install -d "\$pkgdir"/usr/bin
install -d "$pkgdir"/usr/bin install -d "\$pkgdir"/etc/linux_patch_api
install -d "$pkgdir"/etc/linux_patch_api install -d "\$pkgdir"/etc/init.d
install -d "$pkgdir"/etc/init.d cp -r ${WORKSPACE_DIR}/apk-package/usr/bin/* "\$pkgdir"/usr/bin/
# Copy from pre-built apk-package directory cp -r ${WORKSPACE_DIR}/apk-package/etc/linux_patch_api/* "\$pkgdir"/etc/linux_patch_api/
cp -r /workspace/echo/linux_patch_api/apk-package/usr/bin/* "$pkgdir"/usr/bin/ cp -r ${WORKSPACE_DIR}/apk-package/etc/init.d/* "\$pkgdir"/etc/init.d/
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/
} }
EOF EOF
@ -90,44 +90,56 @@ echo "Generating checksums..."
# Build APK package # Build APK package
echo "Building 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 if [ "$(id -u)" = "0" ]; then
echo "Running as root - creating build user for abuild..." echo "Running as root - creating build user for abuild..."
adduser -D -s /bin/sh builduser 2>/dev/null || true 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 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 repo contents to builduser home (accessible directory)
# Copy abuild keys from root to builduser home cp -r . /home/builduser/repo/
chown -R builduser:builduser /home/builduser/repo/
chown -R builduser:builduser /home/builduser/apk-package/
# Set up builduser home directory for abuild
mkdir -p /home/builduser/.abuild mkdir -p /home/builduser/.abuild
cp /root/.abuild/* /home/builduser/.abuild/ cp /root/.abuild/* /home/builduser/.abuild/ 2>/dev/null || true
chown -R builduser:builduser /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) KEYFILE=$(ls /home/builduser/.abuild/*.rsa 2>/dev/null | head -1)
if [ -z "$KEYFILE" ]; then if [ -z "$KEYFILE" ]; then
KEYFILE=$(ls /home/builduser/.abuild/-*.rsa 2>/dev/null | head -1) KEYFILE=$(ls /home/builduser/.abuild/-*.rsa 2>/dev/null | head -1)
fi fi
echo "Key file: $KEYFILE" 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 echo "PACKAGER_PRIVKEY=\"$KEYFILE\"" > /home/builduser/.abuild/abuild.conf
chown builduser:builduser /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/"
# Copy APKBUILD and checksums to builduser home for abuild
cp APKBUILD /home/builduser/
cp .checksums /home/builduser/ 2>/dev/null || true
# 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 /home/builduser where APKBUILD exists
# Use || true because index update may fail but APK is still created
su - builduser -c "cd /home/builduser && abuild checksum && abuild -d -F" || true
# Copy APK from builduser packages to releases
mkdir -p releases
cp /home/builduser/packages/x86_64/*.apk releases/ 2>/dev/null || cp /home/builduser/packages/*.apk releases/ 2>/dev/null || find /home/builduser/packages -name "*.apk" -exec cp {} releases/ \; 2>/dev/null || true
else else
abuild checksum abuild checksum
abuild -F -r abuild -F -r
cp ~/packages/x86_64/*.apk releases/ 2>/dev/null || cp ~/packages/*.apk releases/ 2>/dev/null || true cp ~/packages/x86_64/*.apk releases/ 2>/dev/null || cp ~/packages/*.apk releases/ 2>/dev/null || true
fi fi
# Copy to releases directory # Copy to releases directory (fallback for non-root builds)
echo "" echo ""
echo "Copying package to releases/..." echo "Copying package to releases/..."
mkdir -p releases mkdir -p releases
cp ~/packages/x86_64/*.apk releases/ 2>/dev/null || cp /root/packages/x86_64/*.apk releases/ || find / -name "linux-patch-api-*.apk" -exec cp {} releases/ \; 2>/dev/null || true cp ~/packages/x86_64/*.apk releases/ 2>/dev/null || cp ~/packages/*.apk releases/ 2>/dev/null || find ~/packages -name "*.apk" -exec cp {} releases/ \; 2>/dev/null || true
echo "" echo ""
echo "=== Build Complete ===" echo "=== Build Complete ==="

48
build-arch.sh Executable file → Normal file
View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# Build Arch Linux Package (.pkg.tar.zst) # Build Arch Linux Package (.pkg.tar.zst)
# Run on: Arch Linux, Manjaro # Run on: Arch Linux / Manjaro
# Or in Docker: docker run -v $(pwd):/build archlinux:latest /build/build-arch.sh # Designed for native Gitea Actions runner execution
set -e set -e
@ -11,17 +11,16 @@ echo ""
# Check if running on Arch # Check if running on Arch
if ! command -v makepkg &> /dev/null; then if ! command -v makepkg &> /dev/null; then
echo "Error: makepkg not found. This script must run on Arch Linux." 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 exit 1
fi fi
# Install build dependencies
echo "Installing build dependencies..."
pacman -Syu --noconfirm rust cargo systemd git base-devel
# Build release binary # Build release binary
echo "Building release binary..." if [ -z "$SKIP_CARGO_BUILD" ]; then
cargo build --release echo "Building release binary..."
cargo build --release
else
echo "Skipping cargo build (SKIP_CARGO_BUILD is set)"
fi
# Create package directory # Create package directory
PKGDIR=$(pwd)/arch-package PKGDIR=$(pwd)/arch-package
@ -36,7 +35,8 @@ 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/config.yaml.example "$PKGDIR"/etc/linux_patch_api/config.yaml
cp configs/whitelist.yaml.example "$PKGDIR"/etc/linux_patch_api/whitelist.yaml cp configs/whitelist.yaml.example "$PKGDIR"/etc/linux_patch_api/whitelist.yaml
# Create PKGBUILD # Create PKGBUILD with quoted heredoc to prevent $pkgdir expansion
# $pkgdir must be literal for makepkg to expand at runtime
echo "Creating PKGBUILD..." echo "Creating PKGBUILD..."
cat > PKGBUILD << 'EOF' cat > PKGBUILD << 'EOF'
pkgname=linux-patch-api pkgname=linux-patch-api
@ -49,8 +49,7 @@ license=('MIT')
depends=('systemd') depends=('systemd')
package() { package() {
# Use absolute path since makepkg changes working directory to srcdir cp -r /home/builduser/repo/arch-package/* "$pkgdir"/
cp -r /workspace/echo/linux_patch_api/arch-package/* "$pkgdir"/
} }
EOF EOF
@ -60,24 +59,29 @@ echo "Creating .SRCINFO..."
# Build package # Build package
echo "Building Arch 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 if [ "$(id -u)" = "0" ]; then
echo "Running as root - creating build user for makepkg..." echo "Running as root - creating build user for makepkg..."
useradd -m builduser 2>/dev/null || true useradd -m builduser 2>/dev/null || true
chown -R builduser:builduser "$(pwd)"
su - builduser -c "cd $(pwd) && makepkg --printsrcinfo > .SRCINFO" # Copy repo contents to builduser home (accessible directory)
su - builduser -c "cd $(pwd) && makepkg -f --noconfirm" mkdir -p /home/builduser/repo
cp -r . /home/builduser/repo/
chown -R builduser:builduser /home/builduser/repo/
su - builduser -c "cd /home/builduser/repo && makepkg --printsrcinfo > .SRCINFO"
su - builduser -c "cd /home/builduser/repo && makepkg -f --noconfirm"
# Copy package to releases
mkdir -p releases
cp /home/builduser/repo/*.pkg.tar.zst releases/
else else
makepkg --printsrcinfo > .SRCINFO makepkg --printsrcinfo > .SRCINFO
makepkg -f --noconfirm makepkg -f --noconfirm
mkdir -p releases
cp *.pkg.tar.zst releases/
fi fi
# Copy to releases directory
echo ""
echo "Copying package to releases/..."
mkdir -p releases
cp *.pkg.tar.zst releases/
echo "" echo ""
echo "=== Build Complete ===" echo "=== Build Complete ==="
echo "Package: releases/linux-patch-api-*.pkg.tar.zst" echo "Package: releases/linux-patch-api-*.pkg.tar.zst"

View File

@ -1,6 +1,7 @@
#!/bin/bash #!/bin/bash
# Build RPM Package for RHEL/CentOS/Fedora # Build RPM Package for RHEL/CentOS/Fedora
# Run on: RHEL 8/9, CentOS 8/9, Fedora 38+ # Run on: RHEL 8/9, CentOS 8/9, Fedora 38+
# Designed for native Gitea Actions runner execution
set -e set -e
@ -11,9 +12,9 @@ echo ""
if ! command -v rpmbuild &> /dev/null; then if ! command -v rpmbuild &> /dev/null; then
echo "Installing RPM build tools..." echo "Installing RPM build tools..."
if command -v dnf &> /dev/null; then 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 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 else
echo "Error: Cannot install rpm-build. Please install manually." echo "Error: Cannot install rpm-build. Please install manually."
exit 1 exit 1
@ -57,6 +58,6 @@ echo "=== Build Complete ==="
echo "Package: releases/linux-patch-api-*.rpm" echo "Package: releases/linux-patch-api-*.rpm"
echo "" echo ""
echo "Install with:" 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 " # or"
echo " sudo yum install -y ./releases/linux-patch-api-*.rpm" echo " yum install -y ./releases/linux-patch-api-*.rpm"

21
debian/rules vendored Executable file → Normal file
View File

@ -8,7 +8,7 @@ export DEB_CARGO_BUILD_FLAGS=--release
dh $@ dh $@
override_dh_auto_build: override_dh_auto_build:
cargo build --release --target x86_64-unknown-linux-gnu . "$$HOME/.cargo/env" && cargo build --release --target x86_64-unknown-linux-gnu
override_dh_auto_install: override_dh_auto_install:
dh_auto_install dh_auto_install
@ -19,13 +19,16 @@ override_dh_auto_install:
mkdir -p debian/tmp/var/log/linux_patch_api mkdir -p debian/tmp/var/log/linux_patch_api
mkdir -p debian/tmp/var/lib/linux_patch_api mkdir -p debian/tmp/var/lib/linux_patch_api
# Install binary # Install binary
cp target/x86_64-unknown-linux-gnu/release/linux-patch-api debian/tmp/usr/bin/ install -D -m 755 target/x86_64-unknown-linux-gnu/release/linux-patch-api debian/tmp/usr/bin/linux-patch-api
chmod 755 debian/tmp/usr/bin/linux-patch-api
# Install systemd service # Install systemd service
cp configs/linux-patch-api.service debian/tmp/lib/systemd/system/ install -D -m 644 configs/linux-patch-api.service debian/tmp/lib/systemd/system/linux-patch-api.service
chmod 644 debian/tmp/lib/systemd/system/linux-patch-api.service # Install default configs
# Install configs (as actual configs for first install) install -D -m 644 configs/config.yaml.example debian/tmp/etc/linux_patch_api/config.yaml
cp configs/config.yaml.example debian/tmp/etc/linux_patch_api/config.yaml install -D -m 644 configs/whitelist.yaml.example debian/tmp/etc/linux_patch_api/whitelist.yaml
cp configs/whitelist.yaml.example debian/tmp/etc/linux_patch_api/whitelist.yaml # Install CA certificates
chmod 644 debian/tmp/etc/linux_patch_api/*.yaml install -d -m 755 debian/tmp/etc/linux_patch_api/certs
cp configs/certs/ca.pem debian/tmp/etc/linux_patch_api/certs/ 2>/dev/null || true
override_dh_auto_test:
# Skip tests during package build (tests run in CI test job)
true

63
scripts/upload-release.sh Normal file
View File

@ -0,0 +1,63 @@
#!/bin/sh
# Upload build artifacts to Gitea Release
# Usage: upload-release.sh <tag_name> <file_path>
# 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 <tag_name> <file_path>}"
FILE_PATH="${2}"
GITEA_API="${GITEA_API:-https://gitea-lxc.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"