mirror of
https://github.com/nimbold/Firelink.git
synced 2026-09-09 17:25:42 +00:00
eca4efb1ad
- replace hardcoded make -j2 with dynamic CPU core detection in aria2 build.sh - isolate Aria2 source build cache from prebuilt engine downloads - add atomic cache validation, restoration, and promotion in scripts/engine-aria2-cache.js - add Rust dependency and target caching with Swatinem/rust-cache@v2 - raise Desktop checks timeout to 45 minutes to prevent job aborts - harden temporary directory cleanup on Windows process abort
233 lines
10 KiB
YAML
233 lines
10 KiB
YAML
name: CI
|
|
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches: [main]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
rust-security:
|
|
name: Rust advisory audit
|
|
runs-on: ubuntu-22.04
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
- name: Install locked cargo-audit
|
|
run: cargo install cargo-audit --version 0.22.2 --locked
|
|
- name: Reject vulnerable resolved dependencies
|
|
working-directory: src-tauri
|
|
run: cargo audit
|
|
|
|
frontend:
|
|
name: Frontend checks
|
|
runs-on: ubuntu-22.04
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
submodules: recursive
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 22.12
|
|
cache: npm
|
|
- run: npm ci
|
|
- run: node --test scripts/*.node-test.js
|
|
- run: npm test -- --run
|
|
- run: npm run build
|
|
|
|
desktop:
|
|
name: Desktop checks (${{ matrix.target }})
|
|
timeout-minutes: 45
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: macos-latest
|
|
target: aarch64-apple-darwin
|
|
- os: windows-latest
|
|
target: x86_64-pc-windows-msvc
|
|
- os: ubuntu-22.04
|
|
target: x86_64-unknown-linux-gnu
|
|
runs-on: ${{ matrix.os }}
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
submodules: recursive
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 22.12
|
|
cache: npm
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: ${{ matrix.target }}
|
|
- name: Cache Rust dependencies and build targets
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: src-tauri -> target
|
|
- name: Install Linux dependencies
|
|
if: runner.os == 'Linux'
|
|
run: |
|
|
# The hosted Ubuntu image can expose an unreachable Azure mirror in
|
|
# its apt sources while the public Ubuntu archive is reachable.
|
|
# Normalize every apt source, including the image's mirror list,
|
|
# before refreshing indexes so a transient runner-local mirror does
|
|
# not consume the whole job timeout.
|
|
sudo find /etc/apt -type f \
|
|
-exec sed -i \
|
|
-e 's#http://azure\.archive\.ubuntu\.com#https://archive.ubuntu.com#g' \
|
|
-e 's#https://azure\.archive\.ubuntu\.com#https://archive.ubuntu.com#g' \
|
|
{} +
|
|
sudo env DEBIAN_FRONTEND=noninteractive timeout --foreground --signal=TERM --kill-after=30s 10m apt-get \
|
|
-o Acquire::Retries=3 \
|
|
-o Acquire::http::Timeout=30 \
|
|
-o Acquire::https::Timeout=30 \
|
|
-o DPkg::Lock::Timeout=60 \
|
|
update
|
|
sudo env DEBIAN_FRONTEND=noninteractive timeout --foreground --signal=TERM --kill-after=30s 10m apt-get \
|
|
-o Acquire::Retries=3 \
|
|
-o Acquire::http::Timeout=30 \
|
|
-o Acquire::https::Timeout=30 \
|
|
-o DPkg::Lock::Timeout=60 \
|
|
install -y --no-install-recommends \
|
|
libwebkit2gtk-4.1-dev \
|
|
libappindicator3-dev \
|
|
librsvg2-dev \
|
|
patchelf \
|
|
libdbus-1-dev \
|
|
pkg-config
|
|
- run: npm ci
|
|
- name: Test Rust backend
|
|
if: runner.os != 'Windows'
|
|
working-directory: src-tauri
|
|
run: cargo test --all-targets --target ${{ matrix.target }}
|
|
- name: Test Windows Torrent RPC integration
|
|
if: runner.os == 'Windows'
|
|
working-directory: src-tauri
|
|
run: cargo test --test torrent_rpc --target ${{ matrix.target }} -- --nocapture
|
|
- name: Compile Windows queue-manager integration
|
|
if: runner.os == 'Windows'
|
|
working-directory: src-tauri
|
|
run: cargo test --test queue_manager --no-run --target ${{ matrix.target }}
|
|
- name: Compile Windows Rust library tests
|
|
if: runner.os == 'Windows'
|
|
working-directory: src-tauri
|
|
run: cargo test --lib --no-run --target ${{ matrix.target }}
|
|
- name: Run Windows headless production contracts
|
|
if: runner.os == 'Windows'
|
|
working-directory: src-tauri
|
|
run: cargo test --test production_contract --target ${{ matrix.target }} -- --nocapture
|
|
- name: Verify Windows atomic Torrent storage
|
|
if: runner.os == 'Windows'
|
|
working-directory: src-tauri
|
|
run: cargo test --test atomic_file --target ${{ matrix.target }} -- --nocapture
|
|
- name: Verify Windows Torrent cache safety
|
|
if: runner.os == 'Windows'
|
|
working-directory: src-tauri
|
|
run: cargo test --test torrent_cache --target ${{ matrix.target }} -- --nocapture
|
|
- name: Verify Windows Torrent web-seed normalization
|
|
if: runner.os == 'Windows'
|
|
working-directory: src-tauri
|
|
run: cargo test --test torrent_web_seed --target ${{ matrix.target }} -- --nocapture
|
|
- name: Install Aria2 source build dependencies (Linux)
|
|
if: runner.os == 'Linux'
|
|
run: sudo apt-get install -y autoconf automake libtool gettext autopoint libssl-dev libssh2-1-dev libgcrypt20-dev libc-ares-dev libexpat1-dev libsqlite3-dev zlib1g-dev
|
|
- name: Install Aria2 source build dependencies (Windows)
|
|
id: aria2-msys
|
|
if: runner.os == 'Windows'
|
|
uses: msys2/setup-msys2@v2
|
|
with:
|
|
msystem: MINGW64
|
|
install: >-
|
|
base-devel autoconf automake libtool gettext-devel pkgconf
|
|
mingw-w64-x86_64-gcc mingw-w64-x86_64-pkgconf
|
|
mingw-w64-x86_64-openssl mingw-w64-x86_64-libssh2
|
|
mingw-w64-x86_64-c-ares mingw-w64-x86_64-expat
|
|
mingw-w64-x86_64-sqlite3 mingw-w64-x86_64-zlib
|
|
- name: Fingerprint engine toolchain
|
|
id: engine-toolchain
|
|
if: runner.os != 'macOS'
|
|
env:
|
|
FIRELINK_MSYS2_ROOT: ${{ steps.aria2-msys.outputs.msys2-location }}
|
|
FIRELINK_TARGET_TRIPLE: ${{ matrix.target }}
|
|
run: node scripts/engine-toolchain-fingerprint.js
|
|
- name: Restore verified engine payload cache
|
|
id: engine-cache
|
|
if: runner.os != 'macOS'
|
|
# v4.2.0 pinned to an immutable commit; this cache is an optimization,
|
|
# and a miss always falls back to source provisioning below.
|
|
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
|
|
with:
|
|
path: src-tauri/provisioned-engines/${{ matrix.target }}
|
|
# The target, toolchain fingerprint, lockfiles, provisioning code,
|
|
# payload validators, and runner package lists all invalidate the key.
|
|
key: firelink-engine-payload-v1-${{ matrix.target }}-${{ steps.engine-toolchain.outputs.fingerprint }}-${{ hashFiles('engine-sources.lock.json', 'engines.lock.json', 'scripts/aria2/**', 'scripts/engine-*.js', 'scripts/provision-engines.js', 'scripts/stage-engines.js', 'scripts/verify-binaries.js', 'scripts/aria2-route-contract.js', '.github/workflows/ci.yml', '.github/workflows/release.yml') }}
|
|
- name: Validate restored engine payload
|
|
id: engine-cache-validation
|
|
if: runner.os != 'macOS' && steps.engine-cache.outputs.cache-hit == 'true'
|
|
continue-on-error: true
|
|
env:
|
|
FIRELINK_TARGET_TRIPLE: ${{ matrix.target }}
|
|
FIRELINK_ENGINE_OUTPUT_ROOT: ${{ runner.temp }}/firelink-engine-cache-validation/${{ matrix.target }}
|
|
run: |
|
|
node scripts/stage-engines.js
|
|
node scripts/verify-binaries.js --staged
|
|
- name: Restore verified Aria2 build cache
|
|
id: aria2-cache
|
|
if: >-
|
|
runner.os != 'macOS' &&
|
|
(steps.engine-cache.outputs.cache-hit != 'true' ||
|
|
steps.engine-cache-validation.outcome != 'success')
|
|
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
|
|
with:
|
|
path: src-tauri/provisioned-engines/.aria2-cache/${{ matrix.target }}
|
|
key: firelink-aria2-build-v1-${{ matrix.target }}-${{ steps.engine-toolchain.outputs.aria2-fingerprint }}
|
|
- name: Provision locked engines
|
|
if: >-
|
|
runner.os != 'macOS' &&
|
|
(steps.engine-cache.outputs.cache-hit != 'true' ||
|
|
steps.engine-cache-validation.outcome != 'success')
|
|
env:
|
|
FIRELINK_MSYS2_ROOT: ${{ steps.aria2-msys.outputs.msys2-location }}
|
|
FIRELINK_TOOLCHAIN_FINGERPRINT: ${{ steps.engine-toolchain.outputs.fingerprint }}
|
|
run: node scripts/provision-engines.js --target ${{ matrix.target }}
|
|
- name: Stage and verify engines
|
|
env:
|
|
FIRELINK_ENGINE_OUTPUT_ROOT: ${{ runner.temp }}/firelink-engine-workspace/${{ matrix.target }}/engine-dist
|
|
run: |
|
|
node scripts/stage-engines.js --target ${{ matrix.target }}
|
|
node scripts/verify-binaries.js --staged --target ${{ matrix.target }}
|
|
- name: Run Torrent process smoke
|
|
env:
|
|
FIRELINK_ENGINE_OUTPUT_ROOT: ${{ runner.temp }}/firelink-engine-workspace/${{ matrix.target }}/engine-dist
|
|
run: node scripts/smoke-torrent.js --failure-paths
|
|
- name: Run Aria2 resolver smoke
|
|
env:
|
|
FIRELINK_ENGINE_OUTPUT_ROOT: ${{ runner.temp }}/firelink-engine-workspace/${{ matrix.target }}/engine-dist
|
|
run: node scripts/smoke-aria2-resolver.js
|
|
- name: Run Aria2 normal-transfer smoke
|
|
env:
|
|
FIRELINK_ENGINE_OUTPUT_ROOT: ${{ runner.temp }}/firelink-engine-workspace/${{ matrix.target }}/engine-dist
|
|
run: node scripts/smoke-aria2-transfers.js
|
|
- name: Save verified Aria2 build cache
|
|
if: >-
|
|
runner.os != 'macOS' &&
|
|
github.event_name == 'push' &&
|
|
github.ref == 'refs/heads/main' &&
|
|
steps.aria2-cache.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57
|
|
with:
|
|
path: src-tauri/provisioned-engines/.aria2-cache/${{ matrix.target }}
|
|
key: firelink-aria2-build-v1-${{ matrix.target }}-${{ steps.engine-toolchain.outputs.aria2-fingerprint }}
|
|
- name: Save verified engine payload cache
|
|
if: >-
|
|
runner.os != 'macOS' &&
|
|
github.event_name == 'push' &&
|
|
github.ref == 'refs/heads/main' &&
|
|
steps.engine-cache.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57
|
|
with:
|
|
path: src-tauri/provisioned-engines/${{ matrix.target }}
|
|
key: firelink-engine-payload-v1-${{ matrix.target }}-${{ steps.engine-toolchain.outputs.fingerprint }}-${{ hashFiles('engine-sources.lock.json', 'engines.lock.json', 'scripts/aria2/**', 'scripts/engine-*.js', 'scripts/provision-engines.js', 'scripts/stage-engines.js', 'scripts/verify-binaries.js', 'scripts/aria2-route-contract.js', '.github/workflows/ci.yml', '.github/workflows/release.yml') }}
|