ci: use separate steps for building and running tests #1206
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: ci | |
| on: | |
| push: | |
| branches: ['**'] | |
| paths: | |
| - "Cargo.*" | |
| - "**/*.rs" | |
| - "crates/*/testdata/**" | |
| - ".github/workflows/ci.yml" | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - "Cargo.*" | |
| - "crates/*/src/**" | |
| jobs: | |
| msrv: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.msrv.outputs.version }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Get the minimum supported rust version (MSRV) | |
| id: msrv | |
| run: | | |
| version=$(sed -rn '/^rust-version\s*=/ s/^.*=\s*"([0-9](\.[0-9]+)+)(.*)/\1/p' Cargo.toml) | |
| if [[ -n ${version} ]]; then | |
| echo "version=${version}" >> $GITHUB_OUTPUT | |
| else | |
| exit 1 | |
| fi | |
| test: | |
| needs: msrv | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| rust-version: ${{ needs.msrv.outputs.version }} | |
| rust: msrv | |
| - os: ubuntu-latest | |
| rust-version: stable | |
| rust: stable | |
| - os: macos-latest | |
| rust-version: stable | |
| rust: stable | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up rust toolchain | |
| uses: dtolnay/rust-toolchain@master | |
| id: rust | |
| with: | |
| toolchain: ${{ matrix.rust-version }} | |
| components: llvm-tools-preview | |
| - name: Install tools on macOS | |
| if: runner.os == 'macOS' | |
| run: | | |
| # install the latest bash release -- macos defaults to an ancient version due to licensing | |
| brew install bash | |
| - name: Restore cache | |
| uses: actions/cache/restore@v4 | |
| id: restore-cache | |
| with: | |
| path: | | |
| ~/.cargo/registry/index | |
| ~/.cargo/registry/cache | |
| ~/.cargo/git/db | |
| target | |
| key: ${{ github.workflow }}-${{ github.job }}-${{ runner.os }}-rust-${{ matrix.rust }}-${{ steps.rust.outputs.cachekey }}-cargo-${{ hashFiles('Cargo.lock') }} | |
| - name: Remove old caches | |
| if: ${{ github.ref_name == 'main' && steps.restore-cache.outputs.cache-hit != 'true' }} | |
| continue-on-error: true | |
| shell: bash | |
| run: | | |
| gh extension install actions/gh-actions-cache | |
| REPO=${{ github.repository }} | |
| BRANCH=${{ github.ref }} | |
| KEY=${{ github.workflow }}-${{ github.job }}-${{ runner.os }}-rust-${{ matrix.rust }}- | |
| # find matching caches | |
| mapfile -t cache_keys < <( gh actions-cache list -R $REPO -B $BRANCH --key $KEY --sort created-at --order desc | cut -f 1 ) | |
| # remove all matching caches | |
| for key in ${cache_keys[@]} | |
| do | |
| gh actions-cache delete $key -R $REPO -B $BRANCH --confirm | |
| done | |
| exit 0 | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Install cargo-llvm-cov | |
| if: ${{ matrix.rust == 'stable' && runner.os == 'Linux' }} | |
| uses: taiki-e/install-action@cargo-llvm-cov | |
| - name: Build tests | |
| run: | | |
| # only collect coverage for the latest rust release on linux | |
| if [[ ${{ matrix.rust }} == 'stable' && ${{ runner.os }} == 'Linux' ]]; then | |
| # set environment variables needed for coverage | |
| source <(cargo llvm-cov show-env --export-prefix) | |
| # remove artifacts that may affect coverage results | |
| cargo llvm-cov clean --workspace | |
| fi | |
| # build tests | |
| cargo build --all-features --workspace --tests | |
| - name: Save cache | |
| if: ${{ github.ref_name == 'main' && steps.restore-cache.outputs.cache-hit != 'true' }} | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry/index | |
| ~/.cargo/registry/cache | |
| ~/.cargo/git/db | |
| target | |
| key: ${{ steps.restore-cache.outputs.cache-primary-key }} | |
| - name: Install grcov | |
| if: ${{ matrix.rust == 'stable' && runner.os == 'Linux' }} | |
| uses: taiki-e/install-action@grcov | |
| - name: Install cargo-nextest | |
| uses: taiki-e/install-action@nextest | |
| - name: Run tests | |
| run: | | |
| # set environment variables needed for coverage | |
| if [[ ${{ matrix.rust }} == 'stable' && ${{ runner.os }} == 'Linux' ]]; then | |
| source <(cargo llvm-cov show-env --export-prefix) | |
| fi | |
| # run tests | |
| cargo nextest run --all-features --workspace --tests | |
| # only collect coverage for the latest rust release on linux | |
| if [[ ${{ matrix.rust }} == 'stable' && ${{ runner.os }} == 'Linux' ]]; then | |
| # make sure all profile data is in the expected directory | |
| find crates -name \*.profraw -exec mv '{}' target/debug/ \; | |
| # process coverage information | |
| grcov . -s . --binary-path target/debug \ | |
| --keep-only "crates/*/src/*" -t lcov --llvm --branch -o lcov.info \ | |
| --excl-line "unreachable!(.*)|grcov-excl-line" \ | |
| --excl-start grcov-excl-start \ | |
| --excl-stop grcov-excl-stop | |
| fi | |
| - name: Upload build artifacts | |
| if: ${{ matrix.rust == 'stable' && runner.os == 'Linux' }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage | |
| path: lcov.info | |
| if-no-files-found: error | |
| retention-days: 3 | |
| coverage: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v4 | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: coverage/lcov.info | |
| fail_ci_if_error: true |