diff --git a/.gitea/actions/setup/action.yml b/.gitea/actions/setup/action.yml index cc3cb6b..2317dd8 100644 --- a/.gitea/actions/setup/action.yml +++ b/.gitea/actions/setup/action.yml @@ -1,27 +1,69 @@ name: Rust plugin toolchain -description: Native checks and optional Windows GNU cross-compilation in Node's Debian container +description: >- + Native checks and optional Windows GNU cross-compilation in Node's Debian + container. Restores the Rust toolchain, Cargo registry, and the caller's + build directories from the runner cache, and saves them after the job. inputs: windows: description: Install the Windows cross compiler default: "false" + cache-name: + description: Distinguishes build-directory caches of different jobs + required: true + target-paths: + description: Build directories to cache, one per line, relative to the workspace + default: target runs: using: composite steps: + - name: Cache keys + id: keys + shell: bash + run: | + # A new ISO week starts fresh caches, so stale build output cannot grow forever + # and the stable toolchain is refreshed regularly. + echo "week=$(date -u +%G-%V)" >> "$GITHUB_OUTPUT" + - name: Restore Rust toolchain and Cargo registry + uses: https://github.com/actions/cache@v4 + with: + path: | + .cargo-ci/bin + .cargo-ci/registry/index + .cargo-ci/registry/cache + .cargo-ci/git/db + .rustup-ci + key: rust-${{ inputs.windows }}-${{ steps.keys.outputs.week }}-${{ hashFiles('Cargo.lock', 'plugins/*/plugin/Cargo.lock', 'tools/editor-check/Cargo.lock') }} + restore-keys: | + rust-${{ inputs.windows }}-${{ steps.keys.outputs.week }}- + - name: Restore build directories + uses: https://github.com/actions/cache@v4 + with: + path: ${{ inputs.target-paths }} + # One entry per job, week, and dependency set: compiled dependencies are + # reused, and only this repository's crates rebuild on each push. + key: build-${{ inputs.cache-name }}-${{ steps.keys.outputs.week }}-${{ hashFiles('Cargo.lock', 'plugins/*/plugin/Cargo.lock', 'tools/editor-check/Cargo.lock') }} + restore-keys: | + build-${{ inputs.cache-name }}-${{ steps.keys.outputs.week }}- - name: Install build prerequisites shell: bash run: | apt-get update apt-get install -y --no-install-recommends python3 curl ca-certificates pkg-config libgl1-mesa-dev libx11-dev libxcursor-dev libx11-xcb-dev libxcb1-dev libxcb-dri2-0-dev libxcb-icccm4-dev libxkbcommon-x11-dev + if [ "${{ inputs.windows }}" = "true" ]; then + apt-get install -y --no-install-recommends gcc-mingw-w64-x86-64 + fi - name: Install Rust shell: bash run: | - curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs -o /tmp/rustup-init.sh - sh /tmp/rustup-init.sh -y --profile minimal --default-toolchain stable + if [ ! -x "$CARGO_HOME/bin/rustup" ]; then + curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs -o /tmp/rustup-init.sh + sh /tmp/rustup-init.sh -y --profile minimal --default-toolchain none --no-modify-path + fi echo "$CARGO_HOME/bin" >> "$GITHUB_PATH" - "$CARGO_HOME/bin/rustup" component add rustfmt clippy - - name: Install Windows target - if: inputs.windows == 'true' - shell: bash - run: | - apt-get install -y --no-install-recommends gcc-mingw-w64-x86-64 - rustup target add x86_64-pc-windows-gnu + # No-op when the restored toolchain is already current. + "$CARGO_HOME/bin/rustup" toolchain install stable --profile minimal -c rustfmt -c clippy + "$CARGO_HOME/bin/rustup" default stable + if [ "${{ inputs.windows }}" = "true" ]; then + "$CARGO_HOME/bin/rustup" target add x86_64-pc-windows-gnu + fi + "$CARGO_HOME/bin/rustc" --version diff --git a/.gitea/workflows/check.yml b/.gitea/workflows/check.yml index 36c7c3b..afa031a 100644 --- a/.gitea/workflows/check.yml +++ b/.gitea/workflows/check.yml @@ -10,7 +10,10 @@ permissions: env: CARGO_HOME: ${{ gitea.workspace }}/.cargo-ci + RUSTUP_HOME: ${{ gitea.workspace }}/.rustup-ci CARGO_TERM_COLOR: always + # Incremental data is not reused between CI runs; it only inflates the cache. + CARGO_INCREMENTAL: "0" jobs: check: @@ -26,6 +29,11 @@ jobs: token: ${{ secrets.GITEA_TOKEN }} persist-credentials: false - uses: ./.gitea/actions/setup + with: + cache-name: check-${{ matrix.plugin }} + target-paths: | + target + plugins/${{ matrix.plugin }}/plugin/target - run: python3 -m unittest discover -s scripts/tests -v - run: python3 scripts/check-plugin.py --plugin "${{ matrix.plugin }}" @@ -38,6 +46,9 @@ jobs: token: ${{ secrets.GITEA_TOKEN }} persist-credentials: false - uses: ./.gitea/actions/setup + with: + cache-name: previews + target-paths: tools/editor-check/target - run: | cargo fmt --all -- --check cargo fmt --manifest-path tools/editor-check/Cargo.toml -- --check @@ -65,6 +76,8 @@ jobs: - uses: ./.gitea/actions/setup with: windows: "true" + cache-name: windows-preview + target-paths: target/windows - run: | python3 scripts/build-plugin.py --plugin rivet --target x86_64-pc-windows-gnu python3 scripts/build-plugin.py --plugin patina --target x86_64-pc-windows-gnu diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index d499f1a..57d5903 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -8,7 +8,9 @@ permissions: env: CARGO_HOME: ${{ gitea.workspace }}/.cargo-ci + RUSTUP_HOME: ${{ gitea.workspace }}/.rustup-ci CARGO_TERM_COLOR: always + CARGO_INCREMENTAL: "0" RELEASE_REF: ${{ gitea.ref }} jobs: @@ -44,6 +46,10 @@ jobs: - uses: ./.gitea/actions/setup with: windows: "true" + # CARGO_TARGET_DIR holds both the native checks and the Windows build. + # Kept apart from branch builds; a release never reuses preview output. + cache-name: release-${{ needs.plan.outputs.plugin }} + target-paths: target/windows - run: | python3 -m unittest discover -s scripts/tests -v python3 scripts/check-plugin.py --plugin "$PLUGIN" diff --git a/docs/releases.md b/docs/releases.md index 4fe90e0..5779a2a 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -64,6 +64,24 @@ Node runtime, and a local composite action installs Rust and build dependencies. Windows binaries are cross-compiled with MinGW; no Windows runner or Linux release binary is required. +### Build cache + +Every Rust job restores two caches through the runner's cache server +(`actions/cache@v4`, run from the setup composite action): + +- **Toolchain:** rustup's stable toolchain, Cargo's binaries, and the registry and + git sources, keyed by ISO week, Windows target, and all three `Cargo.lock` files. +- **Build directories:** each job's target directories (check per plugin, + previews, Windows preview, release per plugin), keyed the same way. + +A new week or a changed lockfile starts a fresh entry, so stale build output does +not accumulate and the stable toolchain refreshes weekly. Within a week, pushes +reuse compiled dependencies and rebuild only this repository's crates. Release +jobs use their own entries and never reuse branch build output. A cache miss only +costs time. The runner's cache server must be enabled (`cache.enabled` in +`act_runner`'s config, the default) and must support post steps of actions +inside composite actions (current `act_runner` releases do). + The workflows use explicit action URLs and the v3-compatible artifact protocol. Only the publish job requests `contents: write`. It authenticates against the same Gitea instance using the automatic `secrets.GITEA_TOKEN`; no personal access