diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index dcfd30a8a..882956122 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -843,10 +843,26 @@ jobs: rustup toolchain list - # The key of this cache includes the version of rustc and Cargo.lock, so the cache has to come - # after the setup of Rust. A new toolchain or a change to the dependencies leads to a new cache; - # until then, the latest cache of the same toolchain serves as the starting point. Before the - # cache is saved, the action removes everything which is no dependency, our own crate among it. + # Without a key of our own, the cache below would start from the latest cache of the same + # toolchain whenever the dependencies change. The action then keeps the old version of each + # updated crate next to its new one: a single update of Tauri let the caches grow by a fifth to + # a third. Also, GitHub dropped the new cache of this job right away, since build_main still + # read its old caches afterwards. Therefore, a hash of Cargo.toml and Cargo.lock goes into the + # key, so that only the very same dependencies restore a cache. The version of our own crate + # stays out of the hash, since every release changes it; in both files, it directly follows the + # name of the crate: + - name: Hash the Rust dependencies + id: rust_dependencies + shell: bash + run: | + hash=$(sed '/^name = "mindwork-ai-studio"/{n;d;}' runtime/Cargo.toml runtime/Cargo.lock | git hash-object --stdin) + echo "hash=${hash}" >> "$GITHUB_OUTPUT" + echo "Hash of the Rust dependencies: '${hash}'" + + # The key of this cache includes the version of rustc and the hash from above, so the cache has + # to come after both steps. A new toolchain or a change to the dependencies leads to a new + # cache, which starts empty. Before the cache is saved, the action removes everything which is + # no dependency, our own crate among it. # Only pushes to main save a cache: pull requests and releases read it alone, so they cannot # crowd out the other caches, since GitHub keeps at most 10 GB of them per repository. # @@ -858,6 +874,7 @@ jobs: uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3 with: workspaces: runtime -> target + key: ${{ steps.rust_dependencies.outputs.hash }} cache-bin: false save-if: ${{ github.ref == 'refs/heads/main' }} @@ -1295,15 +1312,24 @@ jobs: rustup toolchain list + # The same step of the verify job explains why the cache needs this hash: + - name: Hash the Rust dependencies + id: rust_dependencies + shell: bash + run: | + hash=$(sed '/^name = "mindwork-ai-studio"/{n;d;}' runtime/Cargo.toml runtime/Cargo.lock | git hash-object --stdin) + echo "hash=${hash}" >> "$GITHUB_OUTPUT" + echo "Hash of the Rust dependencies: '${hash}'" + # The same step of the verify job explains how this cache works, and why the two jobs keep # separate caches. The action tells the caches apart by the job name and the runner. Both are - # the same for the two macOS builds, and for the two Windows builds as well, so the runtime - # identifier gives each platform a cache of its own: + # the same for the two macOS builds, and for the two Windows builds as well, so the key holds + # the runtime identifier, which gives each platform a cache of its own, next to the hash: - name: Cache Rust uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3 with: workspaces: runtime -> target - key: ${{ matrix.dotnet_runtime }} + key: ${{ matrix.dotnet_runtime }}-${{ steps.rust_dependencies.outputs.hash }} cache-bin: false save-if: ${{ github.ref == 'refs/heads/main' }}