From 9a81f5cd8dcfb81de5e65a99999f22a0895b5213 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 30 Nov 2025 10:56:57 -0600 Subject: [PATCH 1/5] ci: reduce GitHub Actions costs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add concurrency groups to cancel in-progress runs on new commits - Switch Test, Clippy, six-peer tests from freenet-default-runner to ubuntu-latest - Remove redundant cancel-workflow-action steps (native concurrency handles this) - Reduce six_peer_regression timeout from 120m to 30m - Skip cross-compile on PRs (only run on main/tags) Estimated savings: ~50% reduction in CI costs by using standard runners instead of larger runners, and avoiding duplicate work. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/ci.yml | 42 ++++++++--------------------- .github/workflows/cross-compile.yml | 3 +-- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9f7167a9f..0f4d830de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,22 +6,22 @@ on: pull_request: merge_group: +# Cancel in-progress runs when a new commit is pushed to the same branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test_all: name: Test - runs-on: freenet-default-runner + runs-on: ubuntu-latest env: FREENET_LOG: error CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.12.1 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@stable @@ -49,7 +49,7 @@ jobs: # TODO: Re-enable when ubertest is stable - currently failing if: false - runs-on: freenet-default-runner + runs-on: ubuntu-latest env: FREENET_LOG: error @@ -57,11 +57,6 @@ jobs: UBERTEST_PEER_COUNT: 6 # Fewer peers for faster CI steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.12.1 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@stable @@ -87,18 +82,13 @@ jobs: six_peer_regression: name: six-peer-regression needs: test_all - runs-on: freenet-default-runner - timeout-minutes: 120 + runs-on: ubuntu-latest + timeout-minutes: 30 env: FREENET_LOG: error steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.12.1 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v6 with: fetch-depth: 0 @@ -133,18 +123,13 @@ jobs: six_peer_connection_cap: name: six-peer-connection-cap needs: test_all - runs-on: freenet-default-runner + runs-on: ubuntu-latest env: FREENET_LOG: error CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.12.1 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@stable @@ -166,18 +151,13 @@ jobs: clippy_check: name: Clippy - runs-on: freenet-default-runner + runs-on: ubuntu-latest env: FREENET_LOG: error CARGO_TARGET_DIR: ${{ github.workspace }}/target steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.12.1 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@stable diff --git a/.github/workflows/cross-compile.yml b/.github/workflows/cross-compile.yml index 86296e090..77584a738 100644 --- a/.github/workflows/cross-compile.yml +++ b/.github/workflows/cross-compile.yml @@ -2,8 +2,7 @@ name: Build and Cross-Compile on: workflow_dispatch: - pull_request: - merge_group: + # Skip PRs - only build on main and releases to reduce CI costs push: branches: [main] tags: ['v*'] From 47d829c805e29d7fd71a2d052448976c36c3507d Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 30 Nov 2025 11:25:52 -0600 Subject: [PATCH 2/5] ci: use self-hosted runner (nova) for CI jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nova has 128GB RAM and fast network, configured with mold linker and sccache for fast builds. Eliminates GitHub Actions billing entirely. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f4d830de..037137fef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: test_all: name: Test - runs-on: ubuntu-latest + runs-on: self-hosted env: FREENET_LOG: error @@ -49,7 +49,7 @@ jobs: # TODO: Re-enable when ubertest is stable - currently failing if: false - runs-on: ubuntu-latest + runs-on: self-hosted env: FREENET_LOG: error @@ -82,7 +82,7 @@ jobs: six_peer_regression: name: six-peer-regression needs: test_all - runs-on: ubuntu-latest + runs-on: self-hosted timeout-minutes: 30 env: @@ -123,7 +123,7 @@ jobs: six_peer_connection_cap: name: six-peer-connection-cap needs: test_all - runs-on: ubuntu-latest + runs-on: self-hosted env: FREENET_LOG: error @@ -151,7 +151,7 @@ jobs: clippy_check: name: Clippy - runs-on: ubuntu-latest + runs-on: self-hosted env: FREENET_LOG: error @@ -183,7 +183,7 @@ jobs: fmt_check: name: Fmt - runs-on: ubuntu-latest + runs-on: self-hosted steps: - uses: actions/checkout@v6 @@ -199,7 +199,7 @@ jobs: conventional_commits: name: Conventional Commits - runs-on: ubuntu-latest + runs-on: self-hosted if: github.event_name == 'pull_request' steps: @@ -234,7 +234,7 @@ jobs: claude-ci-analysis: name: Claude CI Analysis - runs-on: ubuntu-latest + runs-on: self-hosted needs: [test_all, clippy_check, fmt_check] if: failure() && contains(github.event.pull_request.labels.*.name, 'claude-debug') From 366b90c01b53fca20c75363121f137750a4f8b84 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 30 Nov 2025 12:32:42 -0600 Subject: [PATCH 3/5] ci: reorder jobs for faster fail-fast on single runner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Jobs now run in order from fastest to slowest: 1. Conventional Commits (~5s) 2. Fmt (~10s) 3. Clippy (~3-5min) 4. Test (~10-15min) 5. six-peer tests (after Test) This ensures simple issues like formatting or commit messages fail immediately rather than waiting for long builds. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/ci.yml | 171 +++++++++++++++++++-------------------- 1 file changed, 84 insertions(+), 87 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 037137fef..fd7ac57ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,9 +12,60 @@ concurrency: cancel-in-progress: true jobs: - test_all: - name: Test + # Fast checks first - fail fast on simple issues + # Order: fastest to slowest for single-runner efficiency + conventional_commits: + name: Conventional Commits + runs-on: self-hosted + if: github.event_name == 'pull_request' + + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Check PR title follows Conventional Commits + uses: amannn/action-semantic-pull-request@v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + types: | + feat + fix + docs + style + refactor + perf + test + build + ci + chore + revert + requireScope: false + subjectPattern: ^(?![A-Z]).+$ + subjectPatternError: | + The subject "{subject}" found in the pull request title "{title}" + didn't match the configured pattern. Please ensure that the subject + doesn't start with an uppercase character. + + fmt_check: + name: Fmt + runs-on: self-hosted + + steps: + - uses: actions/checkout@v6 + + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + components: rustfmt + + - name: Check code formatting + run: cargo fmt -- --check + + clippy_check: + name: Clippy runs-on: self-hosted env: @@ -27,34 +78,30 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: toolchain: stable + components: clippy targets: wasm32-unknown-unknown - uses: Swatinem/rust-cache@v2 - if: success() || steps.test.conclusion == 'failure' with: save-if: ${{ github.ref == 'refs/heads/main' }} - name: Build run: | - cargo build --locked - export PATH="$PWD/target/debug:$PATH" - make -C apps/freenet-ping -f run-ping.mk build - - - name: Test - run: cargo test --workspace --no-default-features --features trace,websocket,redb + cargo build --locked --bin fdev --manifest-path ../../crates/fdev/Cargo.toml + export PATH="$PWD/../../target/debug:$PATH" + make -f run-ping.mk build + working-directory: apps/freenet-ping - ubertest: - name: Ubertest - needs: test_all - # TODO: Re-enable when ubertest is stable - currently failing - if: false + - name: clippy + run: cargo clippy -- -D warnings + test_all: + name: Test runs-on: self-hosted env: FREENET_LOG: error CARGO_TARGET_DIR: ${{ github.workspace }}/target - UBERTEST_PEER_COUNT: 6 # Fewer peers for faster CI steps: - uses: actions/checkout@v6 @@ -67,17 +114,16 @@ jobs: - uses: Swatinem/rust-cache@v2 if: success() || steps.test.conclusion == 'failure' with: - save-if: false - - - name: Install riverctl - run: cargo install riverctl + save-if: ${{ github.ref == 'refs/heads/main' }} - name: Build - run: cargo build --locked + run: | + cargo build --locked + export PATH="$PWD/target/debug:$PATH" + make -C apps/freenet-ping -f run-ping.mk build - - name: Run Ubertest - run: cargo test --test ubertest --no-default-features --features trace,websocket,redb - working-directory: crates/core + - name: Test + run: cargo test --workspace --no-default-features --features trace,websocket,redb six_peer_regression: name: six-peer-regression @@ -148,14 +194,17 @@ jobs: --features trace,websocket,redb,test-network -- connection_cap_respected --nocapture - clippy_check: - name: Clippy - + ubertest: + name: Ubertest + needs: test_all + # TODO: Re-enable when ubertest is stable - currently failing + if: false runs-on: self-hosted env: FREENET_LOG: error CARGO_TARGET_DIR: ${{ github.workspace }}/target + UBERTEST_PEER_COUNT: 6 # Fewer peers for faster CI steps: - uses: actions/checkout@v6 @@ -163,77 +212,25 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: toolchain: stable - components: clippy targets: wasm32-unknown-unknown - uses: Swatinem/rust-cache@v2 + if: success() || steps.test.conclusion == 'failure' with: - save-if: ${{ github.ref == 'refs/heads/main' }} - - - name: Build - run: | - cargo build --locked --bin fdev --manifest-path ../../crates/fdev/Cargo.toml - export PATH="$PWD/../../target/debug:$PATH" - make -f run-ping.mk build - working-directory: apps/freenet-ping - - - name: clippy - run: cargo clippy -- -D warnings - - fmt_check: - name: Fmt - - runs-on: self-hosted - - steps: - - uses: actions/checkout@v6 - - - uses: dtolnay/rust-toolchain@stable - with: - toolchain: stable - components: rustfmt - - - name: Check code formatting - run: cargo fmt -- --check - - conventional_commits: - name: Conventional Commits + save-if: false - runs-on: self-hosted - if: github.event_name == 'pull_request' + - name: Install riverctl + run: cargo install riverctl - steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 0 + - name: Build + run: cargo build --locked - - name: Check PR title follows Conventional Commits - uses: amannn/action-semantic-pull-request@v6 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - types: | - feat - fix - docs - style - refactor - perf - test - build - ci - chore - revert - requireScope: false - subjectPattern: ^(?![A-Z]).+$ - subjectPatternError: | - The subject "{subject}" found in the pull request title "{title}" - didn't match the configured pattern. Please ensure that the subject - doesn't start with an uppercase character. + - name: Run Ubertest + run: cargo test --test ubertest --no-default-features --features trace,websocket,redb + working-directory: crates/core claude-ci-analysis: name: Claude CI Analysis - runs-on: self-hosted needs: [test_all, clippy_check, fmt_check] if: failure() && contains(github.event.pull_request.labels.*.name, 'claude-debug') From 71b1dd269178ad0af73da7d468838871bc7ee5c8 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 30 Nov 2025 12:34:50 -0600 Subject: [PATCH 4/5] ci: enforce sequential job execution for fail-fast on single runner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add `needs` dependencies to chain jobs in order of execution time: 1. Conventional Commits (fastest, ~5s) 2. Fmt (needs Conventional Commits, ~10s) 3. Clippy (needs Fmt, ~3-5min) 4. Test (needs Clippy, ~10-15min) 5. six-peer tests (needs Test) With a single self-hosted runner, this ensures faster checks run first and fail fast, avoiding wasted time on slow tests when simple checks would fail anyway. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd7ac57ac..4a0ff63b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,8 @@ jobs: fmt_check: name: Fmt runs-on: self-hosted + needs: conventional_commits + if: always() && (needs.conventional_commits.result == 'success' || needs.conventional_commits.result == 'skipped') steps: - uses: actions/checkout@v6 @@ -67,6 +69,7 @@ jobs: clippy_check: name: Clippy runs-on: self-hosted + needs: fmt_check env: FREENET_LOG: error @@ -98,6 +101,7 @@ jobs: test_all: name: Test runs-on: self-hosted + needs: clippy_check env: FREENET_LOG: error From 3102413991d9869ca64ad2a74f8b0cc1a0e8c196 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 30 Nov 2025 13:40:10 -0600 Subject: [PATCH 5/5] ci: add cleanup step for test temp directories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove /tmp/freenet and /tmp/freenet-* directories before running tests to prevent permission denied errors when the self-hosted runner user cannot access directories created by other users. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a0ff63b9..a0f25ef59 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -126,6 +126,12 @@ jobs: export PATH="$PWD/target/debug:$PATH" make -C apps/freenet-ping -f run-ping.mk build + - name: Clean test directories + run: | + # Remove freenet test directories from /tmp to avoid permission issues + # when tests create directories with different user ownership + rm -rf /tmp/freenet /tmp/freenet-* 2>/dev/null || true + - name: Test run: cargo test --workspace --no-default-features --features trace,websocket,redb