From 3d61fc637bde38373b5fa218b432c3a3e185bf48 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Mon, 28 Sep 2026 23:26:24 +0200 Subject: [PATCH] ci(release): reuse cached builds from main The release job never hit a cache: its rust-cache key contained the job name, tags cannot restore caches of earlier tags, and rpmbuild rebuilt the whole workspace under its own compiler flags. CI on main now saves shared debug and release caches that the release workflow restores. Quality gates and the package build run in parallel, and the GitHub release is created once both pass. The RPM spec skips its cargo build when the caller passes --define "prebuilt 1". --- .github/workflows/ci.yml | 40 +++++++++++++ .github/workflows/release.yml | 93 ++++++++++++++++++++++++------- packaging/proton-drive-linux.spec | 6 ++ 3 files changed, 118 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f55195..249d9e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,8 +32,14 @@ jobs: with: toolchain: '1.96' components: rustfmt, clippy + cache: false + # Tags can only restore caches saved on main, so only main saves one. The + # release workflow restores this key for its quality gates. - uses: swatinem/rust-cache@v2 + with: + shared-key: debug + save-if: ${{ github.ref == 'refs/heads/main' }} - name: Formatting run: cargo fmt --all -- --check @@ -57,3 +63,37 @@ jobs: # Real Proton credentials and /dev/fuse deliberately do not run on pull # requests. Follow docs/TESTING.md on a dedicated test-account runner. + + # Keeps the release-profile dependencies cached on main, where the release + # workflow can restore them; a tag cannot reuse the caches of earlier tags. + release-cache: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v7 + + - name: Install native dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + pkg-config \ + libfuse3-dev \ + libgtk-4-dev \ + libadwaita-1-dev \ + libwebkitgtk-6.0-dev \ + libsecret-1-dev \ + libdbus-1-dev + + - name: Install minimum supported Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: '1.96' + cache: false + + - uses: swatinem/rust-cache@v2 + with: + shared-key: release + + - name: Release build + run: cargo build --release --locked diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 272991e..b369e10 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,8 +10,60 @@ permissions: contents: write jobs: + checks: + name: Release quality gates + runs-on: ubuntu-24.04 + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + pkg-config \ + libfuse3-dev \ + libgtk-4-dev \ + libadwaita-1-dev \ + libwebkitgtk-6.0-dev \ + libsecret-1-dev \ + libdbus-1-dev + + - name: Set up Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: '1.96' + components: rustfmt, clippy + cache: false + + # A tag can read the caches of main but its own caches are useless to the next + # tag, so this only restores what CI saved on main. + - name: Cache Cargo target + uses: swatinem/rust-cache@v2 + with: + shared-key: debug + save-if: false + + - name: Verify tag and manifest versions + if: startsWith(github.ref, 'refs/tags/') + shell: bash + run: | + tag_version="${GITHUB_REF_NAME#v}" + manifest_version="$(sed -n 's/^version = "\([^"]*\)"/\1/p' Cargo.toml | head -n1)" + pkgbuild_version="$(sed -n 's/^pkgver=//p' packaging/PKGBUILD | head -n1)" + test "$tag_version" = "$manifest_version" + test "$tag_version" = "$pkgbuild_version" + + - name: Release quality gates + run: | + cargo fmt --all -- --check + cargo clippy --workspace --all-targets -- -D warnings + cargo test --workspace --locked + scripts/fuse-acceptance.sh --offline-only + build-release: - name: Build and Release + name: Build packages runs-on: ubuntu-24.04 environment: 'rpm signing' @@ -38,27 +90,14 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: '1.96' - components: rustfmt, clippy + cache: false + # Restores the release-profile dependencies that CI builds on main. - name: Cache Cargo target uses: swatinem/rust-cache@v2 - - - name: Verify tag and manifest versions - if: startsWith(github.ref, 'refs/tags/') - shell: bash - run: | - tag_version="${GITHUB_REF_NAME#v}" - manifest_version="$(sed -n 's/^version = "\([^"]*\)"/\1/p' Cargo.toml | head -n1)" - pkgbuild_version="$(sed -n 's/^pkgver=//p' packaging/PKGBUILD | head -n1)" - test "$tag_version" = "$manifest_version" - test "$tag_version" = "$pkgbuild_version" - - - name: Release quality gates - run: | - cargo fmt --all -- --check - cargo clippy --workspace --all-targets -- -D warnings - cargo test --workspace --locked - scripts/fuse-acceptance.sh --offline-only + with: + shared-key: release + save-if: false - name: Build release binaries run: | @@ -152,6 +191,7 @@ jobs: --define "_topdir $PWD/rpmbuild" \ --define "_sourcedir $PWD" \ --define "git_dir $PWD" \ + --define "prebuilt 1" \ --define "version ${RPM_VERSION}" \ --define "_dbpath $PWD/rpmbuild/db" \ packaging/proton-drive-linux.spec @@ -190,8 +230,19 @@ jobs: *.rpm if-no-files-found: error + publish: + name: Create GitHub Release + needs: [checks, build-release] + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-24.04 + + steps: + - name: Download packages + uses: actions/download-artifact@v8 + with: + name: proton-drive-linux-builds + - name: Create GitHub Release - if: startsWith(github.ref, 'refs/tags/') uses: softprops/action-gh-release@v3 with: files: | @@ -205,7 +256,7 @@ jobs: aur: name: Publish AUR packages - needs: build-release + needs: publish if: startsWith(github.ref, 'refs/tags/') uses: ./.github/workflows/aur.yml with: diff --git a/packaging/proton-drive-linux.spec b/packaging/proton-drive-linux.spec index d3cb598..be2460d 100644 --- a/packaging/proton-drive-linux.spec +++ b/packaging/proton-drive-linux.spec @@ -60,12 +60,18 @@ test -n "%{?git_dir}" || (echo 'Pass --define "git_dir $PWD" from the repo root' test -f %{git_dir}/Cargo.toml cp -a %{git_dir}/LICENSE . %build +# The release workflow has already built target/release and passes --define "prebuilt 1". +# rpmbuild exports its own compiler flags, which would make cargo rebuild everything. +%if 0%{?prebuilt} +test -x %{git_dir}/target/release/pdfs +%else cd %{git_dir} cargo build --release --locked \ --bin pdfs \ --bin pdfs-tray \ --bin pdfs-app \ --bin pdfs-prompt +%endif %install rel=%{git_dir}/target/release