# Fast checks always run; native builds run for code/CI changes. # Cross-compilation is opt-in through Run workflow; release builds remain in release.yml. name: CI on: pull_request: workflow_dispatch: inputs: cross_compile: description: "Also check WebAssembly and RISC-V (before a release)" type: boolean default: false permissions: contents: read concurrency: group: ci-${{ github.ref }} cancel-in-progress: true env: CARGO_TERM_COLOR: always jobs: changes: name: Select checks runs-on: ubuntu-24.04 outputs: native: ${{ steps.paths.outputs.native }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 - id: paths name: Detect code and CI changes env: EVENT_NAME: ${{ github.event_name }} BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: | native=false if [ "$EVENT_NAME" = workflow_dispatch ]; then native=true else # Compare both old and new paths of renames; unknown paths run native checks. git diff --no-renames --name-only -z "$BASE_SHA...$HEAD_SHA" > "$RUNNER_TEMP/ci-paths" while IFS= read -r -d '' path; do case "$path" in .github/workflows/ci.yml) native=true ;; *.rs|Cargo.toml|Cargo.lock|*/Cargo.toml|.cargo/*|rust-toolchain*) native=true ;; docs/*|*.md|.github/*|packaging/*|LICENSE*|NOTICE|THIRD-PARTY-LICENSES.txt) ;; *) native=true ;; esac done < "$RUNNER_TEMP/ci-paths" fi echo "native=$native" >> "$GITHUB_OUTPUT" checks: name: Format and repository checks runs-on: ubuntu-24.04 timeout-minutes: 15 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: dtolnay/rust-toolchain@stable with: components: rustfmt - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: key: repo-checks - name: Format run: cargo fmt --all -- --check - name: Asset attribution run: cargo xtask assets - name: Licences run: cargo xtask licences --check - name: Dependency layers run: cargo xtask layers clippy: name: Native Linux Clippy needs: changes if: needs.changes.outputs.native == 'true' runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: dtolnay/rust-toolchain@stable with: components: clippy - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: key: native-clippy - run: cargo clippy --workspace --all-targets --profile ci --locked -- -D warnings tests: name: Native Linux tests needs: changes if: needs.changes.outputs.native == 'true' runs-on: ubuntu-24.04 timeout-minutes: 90 env: CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: sccache SCCACHE_GHA_ENABLED: "true" SCCACHE_IGNORE_SERVER_IO_ERROR: "1" steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: key: native-tests - name: Set up compiler cache uses: mozilla-actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11 with: version: v0.16.0 - name: Compile tests run: cargo test --workspace --profile ci --locked --no-run - name: Run tests # Every test binary at once (cargo test runs them one after another). run: cargo xtask test --locked - name: Compiler cache statistics if: always() run: sccache --show-stats oracle: name: Reference tests needs: changes if: needs.changes.outputs.native == 'true' runs-on: ubuntu-24.04 timeout-minutes: 60 env: CARGO_INCREMENTAL: "0" RUSTC_WRAPPER: sccache SCCACHE_GHA_ENABLED: "true" SCCACHE_IGNORE_SERVER_IO_ERROR: "1" steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: key: oracle - name: Set up compiler cache uses: mozilla-actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11 with: version: v0.16.0 - name: Build the command line run: cargo build -p solvecraft-cli --profile ci --locked - name: Replay tests/oracle and compare with expected.json run: cargo xtask oracle --cli target/ci/solvecraft-cli - name: Upload the report if: always() uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: oracle-report path: docs/oracle.md # Preserve the existing check name for branch protection, including docs-only PRs. ci: needs: [changes, checks, clippy, tests, oracle] if: always() runs-on: ubuntu-24.04 steps: - name: Verify required checks env: CHANGES: ${{ needs.changes.result }} CHECKS: ${{ needs.checks.result }} NATIVE: ${{ needs.changes.outputs.native }} CLIPPY: ${{ needs.clippy.result }} TESTS: ${{ needs.tests.result }} ORACLE: ${{ needs.oracle.result }} run: | test "$CHANGES" = success test "$CHECKS" = success if [ "$NATIVE" = true ]; then test "$CLIPPY" = success test "$TESTS" = success test "$ORACLE" = success fi wasm: name: Compile WebAssembly (manual) if: github.event_name == 'workflow_dispatch' && inputs.cross_compile runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: dtolnay/rust-toolchain@stable with: targets: wasm32-unknown-unknown - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: key: wasm - run: cargo xtask wasm riscv64-gates: name: Compile RISC-V (manual) if: github.event_name == 'workflow_dispatch' && inputs.cross_compile runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Check out craft-fonts uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: storytold/craft-fonts ref: ${{ env.CRAFT_FONTS_REF }} path: craft-fonts - uses: dtolnay/rust-toolchain@stable with: targets: riscv64gc-unknown-linux-gnu - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: key: riscv64 - name: Install cross-compilation dependencies run: | # Ubuntu's regular archive serves amd64; RISC-V packages live in ports. # The 24.04 runner uses deb822 sources, so scope every Ubuntu stanza. sudo sed -i '/^Architectures:/d; /^Types:/a Architectures: amd64' /etc/apt/sources.list.d/ubuntu.sources sudo tee /etc/apt/sources.list.d/riscv64.sources >/dev/null <<'EOF' Types: deb URIs: http://ports.ubuntu.com/ubuntu-ports Suites: noble noble-updates noble-backports noble-security Components: main restricted universe multiverse Architectures: riscv64 Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg EOF sudo dpkg --add-architecture riscv64 sudo apt-get update sudo apt-get install -y gcc-riscv64-linux-gnu libasound2-dev:riscv64 libxkbcommon-dev:riscv64 \ libwayland-dev:riscv64 libx11-dev:riscv64 libxrandr-dev:riscv64 libxi-dev:riscv64 libgl1-mesa-dev:riscv64 - name: Cargo check on RISC-V env: CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER: riscv64-linux-gnu-gcc PKG_CONFIG_SYSROOT_DIR: / PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig:/usr/share/pkgconfig PKG_CONFIG_ALLOW_CROSS: 1 run: | . "$HOME/.cargo/env" export CRAFT_FONTS_DIR="$PWD/craft-fonts" cargo check --all-targets --locked --target riscv64gc-unknown-linux-gnu