name: Build permissions: {} on: push: paths: - ".github/workflows/build.yml" - "src/**" - "migrations/**" - "Cargo.*" - "build.rs" - "rust-toolchain.toml" - "rustfmt.toml" - "diesel.toml" - "docker/Dockerfile.j2" - "docker/DockerSettings.yaml" pull_request: paths: - ".github/workflows/build.yml" - "src/**" - "migrations/**" - "Cargo.*" - "build.rs" - "rust-toolchain.toml" - "rustfmt.toml" - "diesel.toml" - "docker/Dockerfile.j2" - "docker/DockerSettings.yaml" jobs: build: name: Build and Test ${{ matrix.channel }} permissions: actions: write contents: read # We use Ubuntu 22.04 here because this matches the library versions used within the Debian docker containers runs-on: ubuntu-22.04 timeout-minutes: 120 # Make warnings errors, this is to prevent warnings slipping through. # This is done globally to prevent rebuilds when the RUSTFLAGS env variable changes. env: RUSTFLAGS: "-Dwarnings" strategy: fail-fast: false matrix: channel: - "rust-toolchain" # The version defined in rust-toolchain - "msrv" # The supported MSRV steps: # Install dependencies - 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 # End Install dependencies # Checkout the repo - name: "Checkout" uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: persist-credentials: false fetch-depth: 0 # End Checkout the repo # Determine rust-toolchain version - name: Init Variables id: toolchain shell: bash run: | if [[ "${{ matrix.channel }}" == 'rust-toolchain' ]]; then RUST_TOOLCHAIN="$(grep -oP 'channel.*"(\K.*?)(?=")' rust-toolchain.toml)" elif [[ "${{ matrix.channel }}" == 'msrv' ]]; then RUST_TOOLCHAIN="$(grep -oP 'rust-version.*"(\K.*?)(?=")' Cargo.toml)" else RUST_TOOLCHAIN="${{ matrix.channel }}" fi echo "RUST_TOOLCHAIN=${RUST_TOOLCHAIN}" | tee -a "${GITHUB_OUTPUT}" # End Determine rust-toolchain version # Only install the clippy and rustfmt components on the default rust-toolchain - name: "Install rust-toolchain version" uses: dtolnay/rust-toolchain@c5a29ddb4d9d194e7c84ec8c3fba61b1c31fee8c # master @ Jan 30, 2025, 8:16 PM GMT+1 if: ${{ matrix.channel == 'rust-toolchain' }} with: toolchain: "${{steps.toolchain.outputs.RUST_TOOLCHAIN}}" components: clippy, rustfmt # End Uses the rust-toolchain file to determine version # Install the any other channel to be used for which we do not execute clippy and rustfmt - name: "Install MSRV version" uses: dtolnay/rust-toolchain@c5a29ddb4d9d194e7c84ec8c3fba61b1c31fee8c # master @ Jan 30, 2025, 8:16 PM GMT+1 if: ${{ matrix.channel != 'rust-toolchain' }} with: toolchain: "${{steps.toolchain.outputs.RUST_TOOLCHAIN}}" # End Install the MSRV channel to be used # Set the current matrix toolchain version as default - name: "Set toolchain ${{steps.toolchain.outputs.RUST_TOOLCHAIN}} as default" env: RUST_TOOLCHAIN: ${{steps.toolchain.outputs.RUST_TOOLCHAIN}} run: | # Remove the rust-toolchain.toml rm rust-toolchain.toml # Set the default rustup default "${RUST_TOOLCHAIN}" # Show environment - name: "Show environment" run: | rustc -vV cargo -vV # End Show environment # Enable Rust Caching - name: Rust Caching uses: Swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2.7.7 with: # Use a custom prefix-key to force a fresh start. This is sometimes needed with bigger changes. # Like changing the build host from Ubuntu 20.04 to 22.04 for example. # Only update when really needed! Use a .[.] format. prefix-key: "v2023.07-rust" # End Enable Rust Caching # Run cargo tests # First test all features together, afterwards test them separately. - name: "test features: sqlite,mysql,postgresql,enable_mimalloc,query_logger" id: test_sqlite_mysql_postgresql_mimalloc_logger if: ${{ !cancelled() }} run: | cargo test --features sqlite,mysql,postgresql,enable_mimalloc,query_logger - name: "test features: sqlite,mysql,postgresql,enable_mimalloc" id: test_sqlite_mysql_postgresql_mimalloc if: ${{ !cancelled() }} run: | cargo test --features sqlite,mysql,postgresql,enable_mimalloc - name: "test features: sqlite,mysql,postgresql" id: test_sqlite_mysql_postgresql if: ${{ !cancelled() }} run: | cargo test --features sqlite,mysql,postgresql - name: "test features: sqlite" id: test_sqlite if: ${{ !cancelled() }} run: | cargo test --features sqlite - name: "test features: mysql" id: test_mysql if: ${{ !cancelled() }} run: | cargo test --features mysql - name: "test features: postgresql" id: test_postgresql if: ${{ !cancelled() }} run: | cargo test --features postgresql # End Run cargo tests # Run cargo clippy, and fail on warnings - name: "clippy features: sqlite,mysql,postgresql,enable_mimalloc" id: clippy if: ${{ !cancelled() && matrix.channel == 'rust-toolchain' }} run: | cargo clippy --features sqlite,mysql,postgresql,enable_mimalloc # End Run cargo clippy # Run cargo fmt (Only run on rust-toolchain defined version) - name: "check formatting" id: formatting if: ${{ !cancelled() && matrix.channel == 'rust-toolchain' }} run: | cargo fmt --all -- --check # End Run cargo fmt # 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 - name: "Some checks failed" if: ${{ failure() }} env: TEST_DB_M_L: ${{ steps.test_sqlite_mysql_postgresql_mimalloc_logger.outcome }} TEST_DB_M: ${{ steps.test_sqlite_mysql_postgresql_mimalloc.outcome }} TEST_DB: ${{ steps.test_sqlite_mysql_postgresql.outcome }} TEST_SQLITE: ${{ steps.test_sqlite.outcome }} TEST_MYSQL: ${{ steps.test_mysql.outcome }} TEST_POSTGRESQL: ${{ steps.test_postgresql.outcome }} CLIPPY: ${{ steps.clippy.outcome }} FMT: ${{ steps.formatting.outcome }} run: | echo "### :x: Checks Failed!" >> "${GITHUB_STEP_SUMMARY}" echo "" >> "${GITHUB_STEP_SUMMARY}" echo "|Job|Status|" >> "${GITHUB_STEP_SUMMARY}" echo "|---|------|" >> "${GITHUB_STEP_SUMMARY}" echo "|test (sqlite,mysql,postgresql,enable_mimalloc,query_logger)|${TEST_DB_M_L}|" >> "${GITHUB_STEP_SUMMARY}" echo "|test (sqlite,mysql,postgresql,enable_mimalloc)|${TEST_DB_M}|" >> "${GITHUB_STEP_SUMMARY}" echo "|test (sqlite,mysql,postgresql)|${TEST_DB}|" >> "${GITHUB_STEP_SUMMARY}" echo "|test (sqlite)|${TEST_SQLITE}|" >> "${GITHUB_STEP_SUMMARY}" echo "|test (mysql)|${TEST_MYSQL}|" >> "${GITHUB_STEP_SUMMARY}" echo "|test (postgresql)|${TEST_POSTGRESQL}|" >> "${GITHUB_STEP_SUMMARY}" echo "|clippy (sqlite,mysql,postgresql,enable_mimalloc)|${CLIPPY}|" >> "${GITHUB_STEP_SUMMARY}" echo "|fmt|${FMT}|" >> "${GITHUB_STEP_SUMMARY}" echo "" >> "${GITHUB_STEP_SUMMARY}" echo "Please check the failed jobs and fix where needed." >> "${GITHUB_STEP_SUMMARY}" echo "" >> "${GITHUB_STEP_SUMMARY}" exit 1 # 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 - name: "All checks passed" if: ${{ success() }} run: | echo "### :tada: Checks Passed!" >> "${GITHUB_STEP_SUMMARY}" echo "" >> "${GITHUB_STEP_SUMMARY}"