Skip to content

Merge pull request #1839 from kristof-mattei/renovate/lock-file-maint… #3969

Merge pull request #1839 from kristof-mattei/renovate/lock-file-maint…

Merge pull request #1839 from kristof-mattei/renovate/lock-file-maint… #3969

Workflow file for this run

# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Build
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions:
contents: read
checks: write
pull-requests: write
issues: write
packages: write
env:
# set this to true in GitHub variables to enable building the container
# HAS_CONTAINER: true
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
RUSTFLAGS: --deny=warnings
concurrency:
# each new commit to a PR runs this workflow
# so we need to avoid a long running older one from overwriting the "pr-<number>-latest"
group: "${{ github.workflow }} @ ${{ github.ref_name }}"
cancel-in-progress: true
jobs:
repo-has-container:
name: Repo has container?
runs-on: ubuntu-latest
outputs:
has_container: ${{ steps.determine.outputs.has_container }}
steps:
- name: Repo has docker container?
shell: bash
id: determine
run: |
HAS_CONTAINER="${{ vars.HAS_CONTAINER }}"
echo "has_container=${HAS_CONTAINER:-false}" >> ${GITHUB_OUTPUT}
changes:
name: Detect changes
runs-on: ubuntu-latest
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: false
- name: Check if we actually made changes
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
token: ${{ secrets.GITHUB_TOKEN }}
filters: .github/file-filters.yml
calculate-version:
name: Calculate version
runs-on: ubuntu-latest
needs:
- changes
- repo-has-container
outputs:
version: ${{ steps.version.outputs.version }}
if: |
github.event_name == 'pull_request' &&
fromJSON(needs.repo-has-container.outputs.has_container) == true &&
fromJSON(needs.changes.outputs.code) == true
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: false
fetch-depth: 0
- name: Cache dependencies
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
env:
CACHE_NAME: cargo-cache-dependencies
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-cocogitto
restore-keys: |
${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-
${{ runner.os }}-build-${{ env.CACHE_NAME }}-
- name: Set up mold
uses: rui314/setup-mold@e16410e7f8d9e167b74ad5697a9089a35126eb50 # v1
- name: Set up toolchain
shell: bash
run: |
rm ${HOME}/.cargo/bin/cargo-fmt
rm ${HOME}/.cargo/bin/rust-analyzer
rm ${HOME}/.cargo/bin/rustfmt
rustup self update
rustup update
rustup show active-toolchain || rustup toolchain install
rustup show
cargo --version
- name: Get binstall
shell: bash
working-directory: /tmp
run: |
archive="cargo-binstall-x86_64-unknown-linux-musl.tgz"
wget "https://github.com/cargo-bins/cargo-binstall/releases/latest/download/${archive}"
tar -xvf "./${archive}"
rm "./${archive}"
mv ./cargo-binstall ~/.cargo/bin/
- name: Install cocogitto to get the next version number
shell: bash
run: |
cargo binstall --no-confirm cocogitto --target x86_64-unknown-linux-musl --pkg-url "{ repo }/releases/download/{ version }/{ name }-{ version }-{ target }.tar.gz" --bin-dir "{ bin }" --pkg-fmt tgz
- name: Calculate next version
shell: bash
id: version
run: |
VERSION="$(cog bump --auto --dry-run || true)"
if [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "New version: ${VERSION}"
else
VERSION="v$(cog -v get-version)"
echo "No version generated, defaulting to latest tag: ${VERSION}"
fi
# remove v
VERSION="${VERSION//v/}"
# store
echo "version=${VERSION}" >> ${GITHUB_OUTPUT}
cargo-build:
name: Cargo build
runs-on: ubuntu-latest
needs:
- changes
if: |
github.event_name == 'pull_request' &&
fromJSON(needs.changes.outputs.code) == true
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: false
- name: Cache dependencies
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
env:
CACHE_NAME: cargo-cache-dependencies
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-build
restore-keys: |
${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-
${{ runner.os }}-build-${{ env.CACHE_NAME }}-
- name: Set up mold
uses: rui314/setup-mold@e16410e7f8d9e167b74ad5697a9089a35126eb50 # v1
- name: Set up toolchain
shell: bash
run: |
rm ${HOME}/.cargo/bin/cargo-fmt
rm ${HOME}/.cargo/bin/rust-analyzer
rm ${HOME}/.cargo/bin/rustfmt
rustup self update
rustup update
rustup show active-toolchain || rustup toolchain install
rustup show
cargo --version
- name: Build
shell: bash
run: |
cargo build --all-targets --workspace --verbose
cargo-fmt:
name: Cargo fmt
runs-on: ubuntu-latest
needs:
- changes
if: |
github.event_name == 'pull_request' &&
fromJSON(needs.changes.outputs.code) == true
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: false
- name: Cache dependencies
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
env:
CACHE_NAME: cargo-cache-dependencies
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-fmt
restore-keys: |
${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-
${{ runner.os }}-build-${{ env.CACHE_NAME }}-
- name: Set up mold
uses: rui314/setup-mold@e16410e7f8d9e167b74ad5697a9089a35126eb50 # v1
- name: Set up toolchain
shell: bash
run: |
rm ${HOME}/.cargo/bin/cargo-fmt
rm ${HOME}/.cargo/bin/rust-analyzer
rm ${HOME}/.cargo/bin/rustfmt
rustup self update
rustup update
rustup show active-toolchain || rustup toolchain install
rustup show
cargo --version
- name: Install rustfmt
shell: bash
run: |
rustup component add rustfmt
# restore symlinks
rustup update
- name: Check formatting
shell: bash
run: |
cargo fmt --all -- --check --verbose
cargo-test-and-report:
name: Cargo test (and report)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: false
- name: Cache dependencies
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
env:
CACHE_NAME: cargo-cache-dependencies
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-test
restore-keys: |
${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-
${{ runner.os }}-build-${{ env.CACHE_NAME }}-
- name: Set up mold
uses: rui314/setup-mold@e16410e7f8d9e167b74ad5697a9089a35126eb50 # v1
- name: Set up toolchain
shell: bash
run: |
rm ${HOME}/.cargo/bin/cargo-fmt
rm ${HOME}/.cargo/bin/rust-analyzer
rm ${HOME}/.cargo/bin/rustfmt
rustup self update
rustup update
rustup show active-toolchain || rustup toolchain install
rustup show
cargo --version
- name: Install llvm-tools-preview
shell: bash
run: |
rustup component add llvm-tools-preview
# restore symlinks
rustup update
- name: Get binstall
shell: bash
working-directory: /tmp
run: |
archive="cargo-binstall-x86_64-unknown-linux-musl.tgz"
wget "https://github.com/cargo-bins/cargo-binstall/releases/latest/download/${archive}"
tar -xvf "./${archive}"
rm "./${archive}"
mv ./cargo-binstall ~/.cargo/bin/
- name: Install nextest, custom test runner, with native support for junit
shell: bash
run: |
cargo binstall --no-confirm cargo-nextest;
- name: Install grcov
shell: bash
run: |
cargo binstall --no-confirm grcov --pkg-url "{ repo }/releases/download/v{ version }/{ name }-{ target }.tar.bz2" --pkg-fmt tbz2 --bin-dir "{ bin }";
- name: Build with instrumentation support
shell: bash
env:
RUSTFLAGS: "${{ env.RUSTFLAGS }} --allow=warnings -C instrument-coverage"
run: |
cargo build --all-targets --all-features --workspace --verbose
- name: Run nextest
shell: bash
id: tests
env:
RUSTFLAGS: "${{ env.RUSTFLAGS }} --allow=warnings -C instrument-coverage"
LLVM_PROFILE_FILE: "profiling/profile-%p-%m.profraw"
run: |
cargo nextest run --profile ci --no-fail-fast --all-targets --all-features --workspace
continue-on-error: true
- name: Upload test results
uses: EnricoMi/publish-unit-test-result-action@afb2984f4d89672b2f9d9c13ae23d53779671984 # v2.19.0
with:
check_name: Test results
github_token: ${{ secrets.GITHUB_TOKEN }}
junit_files: reports/results.xml
- name: Run grcov
shell: bash
run: |
grcov $(find profiling -name "profile-*.profraw" -print) --source-dir . --binary-path ./target/debug/ --output-type lcov --branch --ignore-not-existing --llvm --keep-only "src/**" --keep-only "tests/**" --output-path ./reports/lcov.info
- name: Upload coverage results (to Codecov.io)
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
with:
disable_search: true
fail_ci_if_error: true
files: reports/lcov.info
plugins: ""
token: ${{ secrets.CODECOV_TOKEN }}
- name: Upload test results to Codecov
uses: codecov/test-results-action@f2dba722c67b86c6caa034178c6e4d35335f6706 # v1.1.0
with:
disable_search: true
fail_ci_if_error: true
files: reports/results.xml
token: ${{ secrets.CODECOV_TOKEN }}
- name: Fail if tests failed
shell: bash
if: |
steps.tests.outcome != 'success'
run: |
# the test reporter we use (or any for that matter)
# all show a report. But we cannot depend on that report because
# we don't know which subsection it belongs in GitHub
# so we explicitly fail this one
# which will fail All Done
exit 1;
cargo-clippy-and-report:
name: Cargo clippy (and report)
runs-on: ubuntu-latest
needs:
- changes
if: |
github.event_name == 'pull_request' &&
fromJSON(needs.changes.outputs.code) == true
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: false
- name: Cache dependencies
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
env:
CACHE_NAME: cargo-cache-dependencies
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-clippy
restore-keys: |
${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-
${{ runner.os }}-build-${{ env.CACHE_NAME }}-
- name: Set up mold
uses: rui314/setup-mold@e16410e7f8d9e167b74ad5697a9089a35126eb50 # v1
- name: Set up toolchain
shell: bash
run: |
rm ${HOME}/.cargo/bin/cargo-fmt
rm ${HOME}/.cargo/bin/rust-analyzer
rm ${HOME}/.cargo/bin/rustfmt
rustup self update
rustup update
rustup show active-toolchain || rustup toolchain install
rustup show
cargo --version
- name: Run Clippy for GitHub Actions report
uses: actions-rs-plus/clippy-check@0d83844d8ff1a67b11d384d9dd6adcdcf142a8a7 # v2.2.1
with:
args: --workspace --all-targets --all-features --no-deps
docker-build:
name: Build Docker container
runs-on: ubuntu-latest
needs:
- calculate-version
# if:
# ... is not needed because calculate-version will not run if we disable building the docker container
env:
APPLICATION_NAME: PLACEHOLDER # overridden in step 'Set application name', this is merely to satisfy the linter
PATH_TO_TAR: PLACEHOLDER # same ^
UNIQUE_TAG: PLACEHOLDER # same ^
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: false
- name: Cache dependencies
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
env:
CACHE_NAME: cargo-cache-dependencies
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-test
restore-keys: |
${{ runner.os }}-build-${{ env.CACHE_NAME }}-${{ hashFiles('Cargo.lock') }}-
${{ runner.os }}-build-${{ env.CACHE_NAME }}-
- name: Set up mold
uses: rui314/setup-mold@e16410e7f8d9e167b74ad5697a9089a35126eb50 # v1
- name: Set up toolchain
shell: bash
run: |
rm ${HOME}/.cargo/bin/cargo-fmt
rm ${HOME}/.cargo/bin/rust-analyzer
rm ${HOME}/.cargo/bin/rustfmt
rustup self update
rustup update
rustup show active-toolchain || rustup toolchain install
rustup show
cargo --version
- name: Get binstall
shell: bash
working-directory: /tmp
run: |
archive="cargo-binstall-x86_64-unknown-linux-musl.tgz"
wget "https://github.com/cargo-bins/cargo-binstall/releases/latest/download/${archive}"
tar -xvf "./${archive}"
rm "./${archive}"
mv ./cargo-binstall ~/.cargo/bin/
- name: Install cargo-edit to do set-version
shell: bash
run: |
cargo binstall cargo-edit
- name: Set the Cargo.toml version before we copy in the data into the Docker container
shell: bash
run: |
cargo set-version ${{ needs.calculate-version.outputs.version }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
# TODO validate no changes between github.event.pull_request.head.sha and the actual current sha (representing the hypothetical merge)
- name: Lowercase the image name
shell: bash
run: |
echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV}
- name: Set Docker tag
shell: bash
run: |
UNIQUE_TAG=pr-${{ github.event.pull_request.base.sha }}-${{ github.event.pull_request.head.sha }}
echo "UNIQUE_TAG=${UNIQUE_TAG##*/}" >> ${GITHUB_ENV}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
id: meta
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=${{ env.UNIQUE_TAG }}
labels: |
org.opencontainers.image.version=pr-${{ github.event.number }}
org.opencontainers.image.source=${{ github.event.pull_request.html_url }}
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set application name
shell: bash
run: |
APPLICATION_NAME=${{ github.repository }}
echo "APPLICATION_NAME=${APPLICATION_NAME##*/}" >> ${GITHUB_ENV}
- name: Build Docker image
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
build-args: |
APPLICATION_NAME=${{ env.APPLICATION_NAME }}
context: .
# this container is THE PR's artifact, and we will re-tag it
# once the PR has been accepted
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-${{ env.APPLICATION_NAME }}
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-${{ env.APPLICATION_NAME }},mode=max
platforms: linux/amd64, linux/arm64
outputs: type=oci,dest=/tmp/${{ env.UNIQUE_TAG }}.tar
- name: Upload artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: container-${{ env.APPLICATION_NAME }}
path: /tmp/${{ env.UNIQUE_TAG }}.tar
if-no-files-found: error
retention-days: 1
docker-publish:
name: Publish Docker container
runs-on: ubuntu-latest
needs:
- docker-build
env:
APPLICATION_NAME: PLACEHOLDER # overridden in step 'Set application name', this is merely to satisfy the linter
UNIQUE_TAG: PLACEHOLDER # same ^
# Check if the event is not triggered by a fork
if: |
github.event.pull_request.head.repo.full_name == github.repository &&
github.event_name == 'pull_request'
steps:
- name: Set up Docker
uses: docker/setup-docker-action@b60f85385d03ac8acfca6d9996982511d8620a19 # v4.3.0
with:
daemon-config: |
{
"features": {
"containerd-snapshotter": true
}
}
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Lowercase the image name
shell: bash
run: |
echo "IMAGE_NAME=${IMAGE_NAME,,}" >> ${GITHUB_ENV}
- name: Set application name
shell: bash
run: |
APPLICATION_NAME=${{ github.repository }}
echo "APPLICATION_NAME=${APPLICATION_NAME##*/}" >> ${GITHUB_ENV}
- name: Set Docker tag (which is also the filename.tar)
shell: bash
run: |
UNIQUE_TAG=pr-${{ github.event.pull_request.base.sha }}-${{ github.event.pull_request.head.sha }}
echo "UNIQUE_TAG=${UNIQUE_TAG##*/}" >> ${GITHUB_ENV}
- name: Extract Docker metadata
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
id: meta
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=pr,suffix=-latest
type=raw,value=${{ env.UNIQUE_TAG }}
- name: Download artifact
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
id: artifact
with:
path: /tmp/container/
name: container-${{ env.APPLICATION_NAME }}
- name: Load images from artifacts
shell: bash
run: |
docker load --input ${{ steps.artifact.outputs.download-path }}/${{ env.UNIQUE_TAG }}.tar
- name: Push image to register
shell: bash
run: |
base_tag=$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:%s ' ${{ env.UNIQUE_TAG }})
docker push ${base_tag}
- name: Set new tags on pushed image
shell: bash
working-directory: /tmp/container/
run: |
new_tags="${{ join(steps.meta.outputs.tags, ' ') }}"
new_tags=$(printf -- '--tag %s ' $new_tags)
base_tag=$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:%s ' ${{ env.UNIQUE_TAG }})
docker buildx imagetools create $new_tags $base_tag
for new_tag in $(echo "${{ join(steps.meta.outputs.tags, ' ') }}"); do
echo "${new_tag}:"
docker buildx imagetools inspect --raw $new_tag
echo "" # newline
done
all-done:
name: All done
# this is the job that should be marked as required on GitHub. It's the only one that'll reliably trigger
# when any upstream fails: success
# when all upstream skips: pass
# when all upstream success: success
# combination of upstream skip and success: success
runs-on: ubuntu-latest
needs:
- calculate-version
- cargo-build
- cargo-fmt
- cargo-clippy-and-report
- cargo-test-and-report
- docker-build
- docker-publish
if: |
always()
steps:
- name: Fail!
shell: bash
if: |
contains(needs.*.result, 'failure') ||
contains(needs.*.result, 'cancelled')
run: |
echo "One / more upstream failed or was cancelled. Failing job..."
exit 1
- name: Success!
shell: bash
run: |
echo "Great success!"