From 25c295a81d91613b13d0ff56920010300760dcd2 Mon Sep 17 00:00:00 2001 From: Mikhail Zabaluev Date: Fri, 22 May 2020 01:31:59 +0300 Subject: [PATCH] Added a more elaborate Rust example This example could be used by projects that build Rust end product crates on an OS matrix, but share the cargo cache. To avoid fetching the dependencies from the network in each matrix job in case of a cache miss, a dedicated job pre-populates the cache on Linux, to be reused by the jobs in the matrix. Also demonstrate separate proximate caching of the registry index. --- examples.md | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/examples.md b/examples.md index 5572988..66e27a7 100644 --- a/examples.md +++ b/examples.md @@ -427,6 +427,14 @@ When dependencies are installed later in the workflow, we must specify the same ## Rust - Cargo +### Simple end product build + +If `Cargo.lock` is checked into git, its hash can be used as a key +to cache filesystem state suitable for the build. Use the `--locked` option +with cargo build and test commands to ensure that the state cached at the +post step corresponds to the contents of `Cargo.lock` that were hashed for +the key. + ```yaml - name: Cache cargo dependencies uses: actions/cache@v2 @@ -443,6 +451,91 @@ When dependencies are installed later in the workflow, we must specify the same key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} ``` +### A separate job to fetch and cache the dependencies + +The files cached from `$CARGO_HOME` are platform-independent. +If cargo build/test jobs are run on a matrix and `Cargo.lock` changes often, +it might make sense to populate the cache with the matching state in one job, +then reuse it in the matrix jobs. + +This example also uses a separate cache to avoid expensive syncs with the +`crates.io-index` repository. + +```yaml +jobs: + update-deps: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - id: cargo-deps + name: Cache cargo dependencies + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry/index + ~/.cargo/registry/cache + ~/.cargo/git/db + key: cargo-deps-${{ hashFiles('**/Cargo.lock') }} + + - if: ${{ steps.cargo-deps.outputs.cache-hit != 'true' }} + id: ls-crates-io-index + name: Get head commit hash of crates.io registry index + shell: bash + run: | + commit=$( + git ls-remote --heads https://github.com/rust-lang/crates.io-index.git master | + cut -f 1 + ) + echo "::set-output name=head::$commit" + - if: ${{ steps.cargo-deps.outputs.cache-hit != 'true' }} + name: Cache cargo registry index + uses: actions/cache@v2 + with: + path: ~/.cargo/registry/index + key: cargo-index-${{ steps.ls-crates-io-index.outputs.head }} + restore-keys: cargo-index- + + - if: ${{ steps.cargo-deps.outputs.cache-hit != 'true' }} + name: Fetch dependencies and update registry index + run: cargo fetch --locked + + test: + needs: update-deps + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v2 + + # https://github.com/actions/runner/issues/498 + - if: ${{ runner.os == 'Windows' }} + name: Fix up Cargo.lock hash + shell: powershell + run: | + Get-ChildItem . -Recurse -Filter Cargo.lock | + Foreach-Object { + ((Get-Content $_.FullName) -join "`n") + "`n" | + Set-Content -NoNewline $_.FullName + } + + - name: Restore cargo dependencies + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry/index + ~/.cargo/registry/cache + ~/.cargo/git/db + key: cargo-deps-${{ hashFiles('**/Cargo.lock') }} + + - name: Build and test + uses: actions-rs/cargo@v1 + with: + command: test + args: --locked +``` + ## Scala - SBT ```yaml