mirror of
https://github.com/dani-garcia/vaultwarden.wiki.git
synced 2026-11-14 00:46:05 +02:00
Speed up the Build workflow
- Pass the MariaDB client library to mysqlclient-sys through its environment variables, so a cached build no longer recompiles mysqlclient-sys, diesel and diesel_migrations in every MySQL build. - Split each channel into two parallel jobs, keeping the required check names through a result job per channel. - Drop the sqlite,mysql,postgresql,enable_mimalloc test: enable_mimalloc is still tested on and off. - Only save caches on main, so pull requests and branches no longer push main's caches out of the 10 GB limit.
This commit is contained in:
1 file changed
+95
-29
+95
-29
@@ -40,24 +40,53 @@ defaults:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build and Test ${{ matrix.channel }}
|
name: Build and Test ${{ matrix.channel }} (part ${{ matrix.part }})
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
timeout-minutes: 120
|
timeout-minutes: 120
|
||||||
# Make warnings errors, this is to prevent warnings slipping through.
|
# Make warnings errors, this is to prevent warnings slipping through.
|
||||||
# This is done globally to prevent rebuilds when the RUSTFLAGS env variable changes.
|
# This is done globally to prevent rebuilds when the RUSTFLAGS env variable changes.
|
||||||
env:
|
env:
|
||||||
RUSTFLAGS: "-Dwarnings"
|
RUSTFLAGS: "-Dwarnings"
|
||||||
|
# Which parts passed, read by the `result` job below. Matrix jobs combine their outputs.
|
||||||
|
outputs:
|
||||||
|
rust-toolchain-1: ${{ steps.passed.outputs.rust-toolchain-1 }}
|
||||||
|
rust-toolchain-2: ${{ steps.passed.outputs.rust-toolchain-2 }}
|
||||||
|
msrv-1: ${{ steps.passed.outputs.msrv-1 }}
|
||||||
|
msrv-2: ${{ steps.passed.outputs.msrv-2 }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
channel:
|
channel:
|
||||||
- "rust-toolchain" # The version defined in rust-toolchain
|
- "rust-toolchain" # The version defined in rust-toolchain
|
||||||
- "msrv" # The supported MSRV
|
- "msrv" # The supported MSRV
|
||||||
|
# Each step builds the whole vaultwarden crate again, so the steps are split over two jobs of
|
||||||
|
# about the same length that run in parallel.
|
||||||
|
part:
|
||||||
|
- 1 # Several backends together, and the lints
|
||||||
|
- 2 # One backend at a time
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
- name: "Install dependencies Ubuntu"
|
- name: "Install dependencies Ubuntu"
|
||||||
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends openssl build-essential libmariadb-dev-compat libpq-dev libssl-dev pkg-config
|
run: |
|
||||||
|
# Separate commands, so a failing update fails the step. The image already has Oracle's MySQL client
|
||||||
|
# library, so a skipped install would otherwise go unnoticed and build against that one.
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --no-install-recommends openssl build-essential libmariadb-dev-compat libpq-dev libssl-dev pkg-config
|
||||||
|
|
||||||
|
# Pass the MariaDB client library to mysqlclient-sys through its environment variables.
|
||||||
|
# When it finds the library with pkg-config, its build script makes cargo rerun it whenever
|
||||||
|
# anything in the library directory changes, and the install above changes that directory on
|
||||||
|
# every run. So every MySQL build recompiled mysqlclient-sys, diesel and diesel_migrations,
|
||||||
|
# even with a cached build. Cargo compares environment variables by their value instead.
|
||||||
|
lib_dir="$(pkg-config --variable=libdir mysqlclient)"
|
||||||
|
version="$(pkg-config --modversion mysqlclient)"
|
||||||
|
{
|
||||||
|
echo "MYSQLCLIENT_NO_PKG_CONFIG=1"
|
||||||
|
echo "LIBMARIADB_NO_PKG_CONFIG=1"
|
||||||
|
echo "MYSQLCLIENT_LIB_DIR=${lib_dir}"
|
||||||
|
echo "MYSQLCLIENT_VERSION=${version}"
|
||||||
|
} | tee -a "${GITHUB_ENV}"
|
||||||
# End Install dependencies
|
# End Install dependencies
|
||||||
|
|
||||||
# Checkout the repo
|
# Checkout the repo
|
||||||
@@ -119,50 +148,50 @@ jobs:
|
|||||||
# Like changing the build host from Ubuntu 20.04 to 22.04 for example.
|
# Like changing the build host from Ubuntu 20.04 to 22.04 for example.
|
||||||
# Only update when really needed! Use a <year>.<month>[.<inc>] format.
|
# Only update when really needed! Use a <year>.<month>[.<inc>] format.
|
||||||
prefix-key: "v2025.09-rust"
|
prefix-key: "v2025.09-rust"
|
||||||
|
# The two parts build the dependencies with different features, so each has its own cache.
|
||||||
|
key: part-${{ matrix.part }}
|
||||||
|
# Only main saves caches. The repository can keep 10 GB of caches, and the ones saved by pull
|
||||||
|
# requests and other branches were mostly copies of main's that pushed other caches out.
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
# End Enable Rust Caching
|
# End Enable Rust Caching
|
||||||
|
|
||||||
# Run cargo tests
|
# Run cargo tests
|
||||||
# First test all features together, afterwards test them separately.
|
# Part 1 tests several features together, part 2 tests each database backend on its own.
|
||||||
|
# enable_mimalloc only selects the allocator, so it is tested on and off, not with every combination.
|
||||||
- name: "test features: sqlite,mysql,postgresql,enable_mimalloc,s3"
|
- name: "test features: sqlite,mysql,postgresql,enable_mimalloc,s3"
|
||||||
id: test_sqlite_mysql_postgresql_mimalloc_s3
|
id: test_sqlite_mysql_postgresql_mimalloc_s3
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() && matrix.part == 1 }}
|
||||||
run: |
|
run: |
|
||||||
cargo test --profile ci --features sqlite,mysql,postgresql,enable_mimalloc,s3
|
cargo test --profile ci --features sqlite,mysql,postgresql,enable_mimalloc,s3
|
||||||
|
|
||||||
- name: "test features: sqlite,mysql,postgresql,enable_mimalloc"
|
|
||||||
id: test_sqlite_mysql_postgresql_mimalloc
|
|
||||||
if: ${{ !cancelled() }}
|
|
||||||
run: |
|
|
||||||
cargo test --profile ci --features sqlite,mysql,postgresql,enable_mimalloc
|
|
||||||
|
|
||||||
- name: "test features: sqlite,mysql,postgresql"
|
- name: "test features: sqlite,mysql,postgresql"
|
||||||
id: test_sqlite_mysql_postgresql
|
id: test_sqlite_mysql_postgresql
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() && matrix.part == 1 }}
|
||||||
run: |
|
run: |
|
||||||
cargo test --profile ci --features sqlite,mysql,postgresql
|
cargo test --profile ci --features sqlite,mysql,postgresql
|
||||||
|
|
||||||
- name: "test features: sqlite"
|
- name: "test features: sqlite"
|
||||||
id: test_sqlite
|
id: test_sqlite
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() && matrix.part == 2 }}
|
||||||
run: |
|
run: |
|
||||||
cargo test --profile ci --features sqlite
|
cargo test --profile ci --features sqlite
|
||||||
|
|
||||||
- name: "test features: mysql"
|
- name: "test features: mysql"
|
||||||
id: test_mysql
|
id: test_mysql
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() && matrix.part == 2 }}
|
||||||
run: |
|
run: |
|
||||||
cargo test --profile ci --features mysql
|
cargo test --profile ci --features mysql
|
||||||
|
|
||||||
- name: "test features: postgresql"
|
- name: "test features: postgresql"
|
||||||
id: test_postgresql
|
id: test_postgresql
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() && matrix.part == 2 }}
|
||||||
run: |
|
run: |
|
||||||
cargo test --profile ci --features postgresql
|
cargo test --profile ci --features postgresql
|
||||||
|
|
||||||
# The test seeder only exists with this feature, which no release build has
|
# The test seeder only exists with this feature, which no release build has
|
||||||
- name: "test features: sqlite,unsafe_test_mode"
|
- name: "test features: sqlite,unsafe_test_mode"
|
||||||
id: test_unsafe_test_mode
|
id: test_unsafe_test_mode
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() && matrix.part == 2 }}
|
||||||
run: |
|
run: |
|
||||||
cargo test --profile ci --features sqlite,unsafe_test_mode
|
cargo test --profile ci --features sqlite,unsafe_test_mode
|
||||||
# End Run cargo tests
|
# End Run cargo tests
|
||||||
@@ -171,13 +200,13 @@ jobs:
|
|||||||
# Run cargo clippy, and fail on warnings
|
# Run cargo clippy, and fail on warnings
|
||||||
- name: "clippy features: sqlite,mysql,postgresql,enable_mimalloc,s3"
|
- name: "clippy features: sqlite,mysql,postgresql,enable_mimalloc,s3"
|
||||||
id: clippy
|
id: clippy
|
||||||
if: ${{ !cancelled() && matrix.channel == 'rust-toolchain' }}
|
if: ${{ !cancelled() && matrix.channel == 'rust-toolchain' && matrix.part == 1 }}
|
||||||
run: |
|
run: |
|
||||||
cargo clippy --profile ci --features sqlite,mysql,postgresql,enable_mimalloc,s3
|
cargo clippy --profile ci --features sqlite,mysql,postgresql,enable_mimalloc,s3
|
||||||
|
|
||||||
- name: "clippy features: sqlite,unsafe_test_mode"
|
- name: "clippy features: sqlite,unsafe_test_mode"
|
||||||
id: clippy_unsafe_test_mode
|
id: clippy_unsafe_test_mode
|
||||||
if: ${{ !cancelled() && matrix.channel == 'rust-toolchain' }}
|
if: ${{ !cancelled() && matrix.channel == 'rust-toolchain' && matrix.part == 1 }}
|
||||||
run: |
|
run: |
|
||||||
cargo clippy --profile ci --features sqlite,unsafe_test_mode
|
cargo clippy --profile ci --features sqlite,unsafe_test_mode
|
||||||
# End Run cargo clippy
|
# End Run cargo clippy
|
||||||
@@ -186,7 +215,7 @@ jobs:
|
|||||||
# Run cargo fmt (Only run on rust-toolchain defined version)
|
# Run cargo fmt (Only run on rust-toolchain defined version)
|
||||||
- name: "check formatting"
|
- name: "check formatting"
|
||||||
id: formatting
|
id: formatting
|
||||||
if: ${{ !cancelled() && matrix.channel == 'rust-toolchain' }}
|
if: ${{ !cancelled() && matrix.channel == 'rust-toolchain' && matrix.part == 1 }}
|
||||||
run: |
|
run: |
|
||||||
cargo fmt --all -- --check
|
cargo fmt --all -- --check
|
||||||
# End Run cargo fmt
|
# End Run cargo fmt
|
||||||
@@ -198,7 +227,6 @@ jobs:
|
|||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
env:
|
env:
|
||||||
TEST_DB_M_S3: ${{ steps.test_sqlite_mysql_postgresql_mimalloc_s3.outcome }}
|
TEST_DB_M_S3: ${{ steps.test_sqlite_mysql_postgresql_mimalloc_s3.outcome }}
|
||||||
TEST_DB_M: ${{ steps.test_sqlite_mysql_postgresql_mimalloc.outcome }}
|
|
||||||
TEST_DB: ${{ steps.test_sqlite_mysql_postgresql.outcome }}
|
TEST_DB: ${{ steps.test_sqlite_mysql_postgresql.outcome }}
|
||||||
TEST_SQLITE: ${{ steps.test_sqlite.outcome }}
|
TEST_SQLITE: ${{ steps.test_sqlite.outcome }}
|
||||||
TEST_MYSQL: ${{ steps.test_mysql.outcome }}
|
TEST_MYSQL: ${{ steps.test_mysql.outcome }}
|
||||||
@@ -208,20 +236,25 @@ jobs:
|
|||||||
CLIPPY_UNSAFE_TEST_MODE: ${{ steps.clippy_unsafe_test_mode.outcome }}
|
CLIPPY_UNSAFE_TEST_MODE: ${{ steps.clippy_unsafe_test_mode.outcome }}
|
||||||
FMT: ${{ steps.formatting.outcome }}
|
FMT: ${{ steps.formatting.outcome }}
|
||||||
run: |
|
run: |
|
||||||
|
# Only list the checks this part runs
|
||||||
|
row() {
|
||||||
|
if [[ "${2}" != "skipped" ]]; then
|
||||||
|
echo "|${1}|${2}|" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
echo "### :x: Checks Failed!" >> "${GITHUB_STEP_SUMMARY}"
|
echo "### :x: Checks Failed!" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
echo "" >> "${GITHUB_STEP_SUMMARY}"
|
echo "" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
echo "|Job|Status|" >> "${GITHUB_STEP_SUMMARY}"
|
echo "|Job|Status|" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
echo "|---|------|" >> "${GITHUB_STEP_SUMMARY}"
|
echo "|---|------|" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
echo "|test (sqlite,mysql,postgresql,enable_mimalloc,s3)|${TEST_DB_M_S3}|" >> "${GITHUB_STEP_SUMMARY}"
|
row "test (sqlite,mysql,postgresql,enable_mimalloc,s3)" "${TEST_DB_M_S3}"
|
||||||
echo "|test (sqlite,mysql,postgresql,enable_mimalloc)|${TEST_DB_M}|" >> "${GITHUB_STEP_SUMMARY}"
|
row "test (sqlite,mysql,postgresql)" "${TEST_DB}"
|
||||||
echo "|test (sqlite,mysql,postgresql)|${TEST_DB}|" >> "${GITHUB_STEP_SUMMARY}"
|
row "test (sqlite)" "${TEST_SQLITE}"
|
||||||
echo "|test (sqlite)|${TEST_SQLITE}|" >> "${GITHUB_STEP_SUMMARY}"
|
row "test (mysql)" "${TEST_MYSQL}"
|
||||||
echo "|test (mysql)|${TEST_MYSQL}|" >> "${GITHUB_STEP_SUMMARY}"
|
row "test (postgresql)" "${TEST_POSTGRESQL}"
|
||||||
echo "|test (postgresql)|${TEST_POSTGRESQL}|" >> "${GITHUB_STEP_SUMMARY}"
|
row "test (sqlite,unsafe_test_mode)" "${TEST_UNSAFE_TEST_MODE}"
|
||||||
echo "|test (sqlite,unsafe_test_mode)|${TEST_UNSAFE_TEST_MODE}|" >> "${GITHUB_STEP_SUMMARY}"
|
row "clippy (sqlite,mysql,postgresql,enable_mimalloc,s3)" "${CLIPPY}"
|
||||||
echo "|clippy (sqlite,mysql,postgresql,enable_mimalloc,s3)|${CLIPPY}|" >> "${GITHUB_STEP_SUMMARY}"
|
row "clippy (sqlite,unsafe_test_mode)" "${CLIPPY_UNSAFE_TEST_MODE}"
|
||||||
echo "|clippy (sqlite,unsafe_test_mode)|${CLIPPY_UNSAFE_TEST_MODE}|" >> "${GITHUB_STEP_SUMMARY}"
|
row "fmt" "${FMT}"
|
||||||
echo "|fmt|${FMT}|" >> "${GITHUB_STEP_SUMMARY}"
|
|
||||||
echo "" >> "${GITHUB_STEP_SUMMARY}"
|
echo "" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
echo "Please check the failed jobs and fix where needed." >> "${GITHUB_STEP_SUMMARY}"
|
echo "Please check the failed jobs and fix where needed." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
echo "" >> "${GITHUB_STEP_SUMMARY}"
|
echo "" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
@@ -231,7 +264,40 @@ jobs:
|
|||||||
# Check for any previous failures, if there are stop, else continue.
|
# Check for any previous failures, if there are stop, else continue.
|
||||||
# This is useful so all test/clippy/fmt actions are done, and they can all be addressed
|
# This is useful so all test/clippy/fmt actions are done, and they can all be addressed
|
||||||
- name: "All checks passed"
|
- name: "All checks passed"
|
||||||
|
id: passed
|
||||||
if: ${{ success() }}
|
if: ${{ success() }}
|
||||||
|
env:
|
||||||
|
PART: ${{ matrix.channel }}-${{ matrix.part }}
|
||||||
run: |
|
run: |
|
||||||
echo "### :tada: Checks Passed!" >> "${GITHUB_STEP_SUMMARY}"
|
echo "### :tada: Checks Passed!" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
echo "" >> "${GITHUB_STEP_SUMMARY}"
|
echo "" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
echo "${PART}=success" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
|
# The required status checks are named after these jobs, one per channel, so they stay the same
|
||||||
|
# however the build job is split. It runs even when a part failed or the run was cancelled, because
|
||||||
|
# a skipped job counts as passed for a required check.
|
||||||
|
result:
|
||||||
|
name: Build and Test ${{ matrix.channel }}
|
||||||
|
needs: build
|
||||||
|
if: ${{ always() }}
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
timeout-minutes: 5
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
channel:
|
||||||
|
- "rust-toolchain"
|
||||||
|
- "msrv"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: "Check that both parts passed"
|
||||||
|
env:
|
||||||
|
CHANNEL: ${{ matrix.channel }}
|
||||||
|
PASSED: ${{ toJSON(needs.build.outputs) }}
|
||||||
|
run: |
|
||||||
|
for part in 1 2; do
|
||||||
|
if [[ "$(jq -r --arg part "${CHANNEL}-${part}" '.[$part] // ""' <<< "${PASSED}")" != "success" ]]; then
|
||||||
|
echo "::error::Build and Test ${CHANNEL} (part ${part}) did not pass"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
Reference in new issue
Block a user