diff --git a/.github/actions/install-tools/action.yml b/.github/actions/install-tools/action.yml new file mode 100644 index 00000000..1585a2b2 --- /dev/null +++ b/.github/actions/install-tools/action.yml @@ -0,0 +1,23 @@ +name: Install tools +inputs: + tools: + required: true +runs: + using: composite + steps: + - id: parse + env: + TOOLS: ${{ inputs.tools }} + run: | + for tool in $TOOLS; do + case "$tool" in + just|uv) echo "$tool=true" >> "$GITHUB_OUTPUT" ;; + *) echo "::error::Unknown tool: $tool"; exit 1 ;; + esac + done + shell: bash + - if: steps.parse.outputs.just == 'true' + run: sudo apt-get update && sudo apt-get install -y just + shell: bash + - if: steps.parse.outputs.uv == 'true' + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 09b43ec5..d0e448a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,14 +27,16 @@ jobs: run: rustup toolchain install stable --profile minimal -c rustfmt -c clippy - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - - name: Check formatting - run: cargo fmt --check - - name: Clippy - run: cargo clippy --all-features --tests -- -D warnings - - name: Install zizmor - run: pipx install zizmor==1.23.1 - - name: Run zizmor - run: zizmor --format plain .github/ + - uses: ./.github/actions/install-tools + with: + tools: just + + - name: Check lint + run: just check-lint + - name: Check Zizmor + run: | + pipx install zizmor==1.23.1 + zizmor --format plain .github/ - name: Check `cargo package` # creates a .crate for distribution and verifies it can build in isolation # see https://doc.rust-lang.org/cargo/commands/cargo-package.html @@ -57,10 +59,12 @@ jobs: run: rustup toolchain install ${{ matrix.rust }} --profile minimal && rustup default ${{ matrix.rust }} - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + - uses: ./.github/actions/install-tools + with: + tools: just uv - name: Run tests - run: RUST_BACKTRACE=1 cargo test + run: just check-tests test-all-features: name: test-all-features (${{ matrix.rust }}) @@ -79,10 +83,12 @@ jobs: run: rustup toolchain install ${{ matrix.rust }} --profile minimal && rustup default ${{ matrix.rust }} - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + - uses: ./.github/actions/install-tools + with: + tools: just uv - name: Run tests with all features - run: RUST_BACKTRACE=1 cargo test --all-features + run: just check-tests-all-features docs: name: docs @@ -93,17 +99,19 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Install Rust run: rustup toolchain install nightly --profile minimal && rustup default nightly - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 + - uses: ./.github/actions/install-tools + with: + tools: just + - name: Install cargo-docs-rs run: cargo install --locked cargo-docs-rs - - name: Build docs - env: - RUSTDOCFLAGS: "-D warnings" - run: cargo docs-rs + + - name: Check docs + run: just check-docs # test with the minimal versions of all our dependencies test-minimal-versions: @@ -115,19 +123,17 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Install Rust run: rustup toolchain install nightly --profile minimal && rustup default nightly - - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - - - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + - uses: Swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db # v2 + - uses: ./.github/actions/install-tools + with: + tools: just uv - - name: Generate minimal versions lockfile + - name: Generate lockfile run: cargo generate-lockfile -Z minimal-versions - name: Run tests - # --locked tells cargo not to update the lockfile. this makes sure we use the lockfile we just generated - # and don't regenerate it for non-minimal versions. - run: HEGEL_RUNNING_TESTS_WITH_RUST_NIGHTLY=1 RUST_BACKTRACE=1 cargo test --locked --all-features + run: just check-tests-minimal-versions compile-examples: name: compile-examples (${{ matrix.rust }}) @@ -164,12 +170,12 @@ jobs: - name: Install cargo-llvm-cov run: cargo install --locked cargo-llvm-cov - - name: Install just - run: sudo apt-get update && sudo apt-get install -y just - - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + - uses: ./.github/actions/install-tools + with: + tools: just uv - name: Run coverage - run: RUST_BACKTRACE=1 just coverage + run: just check-coverage conformance: name: conformance @@ -185,12 +191,12 @@ jobs: run: rustup toolchain install stable --profile minimal - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - - name: Install just - run: sudo apt-get update && sudo apt-get install -y just - - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + - uses: ./.github/actions/install-tools + with: + tools: just uv - name: Run conformance tests - run: just conformance + run: just check-conformance nix: name: nix @@ -203,8 +209,9 @@ jobs: persist-credentials: false - uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934 # v31.10.1 - - name: Install just - run: sudo apt-get update && sudo apt-get install -y just + - uses: ./.github/actions/install-tools + with: + tools: just - name: lint run: just check-format-nix diff --git a/Cargo.toml b/Cargo.toml index 1bdf23d2..b90fb868 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,4 +49,6 @@ antithesis = ["dep:serde_json"] [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] +# -D warnings means "deny warnings", which actually means "turn warnings into errors". Have +# we mentioned naming things is hard? +rustdoc-args = ["--cfg", "docsrs", "-D", "warnings"] diff --git a/justfile b/justfile index afe5258c..dc2953ac 100644 --- a/justfile +++ b/justfile @@ -1,43 +1,57 @@ -# don't print bash comments as output during `just` invocation +# `just` prints bash comments in stdout by default. this suppresses that set ignore-comments := true -check: lint docs test test-all-features - -docs: - cargo clean --doc && cargo doc --open --all-features --no-deps - -test: +check-tests: RUST_BACKTRACE=1 cargo test -test-all-features: +check-tests-all-features: RUST_BACKTRACE=1 cargo test --all-features +check-tests-minimal-versions: + # This is an annoyingly specific check and feels like it overly couples CI concerns and check + # concerns. I don't have a better proposal right now. + + # --locked tells cargo not to update the lockfile. this makes sure we use the lockfile we just generated + # and don't regenerate it for non-minimal versions. + HEGEL_RUNNING_TESTS_WITH_RUST_NIGHTLY=1 RUST_BACKTRACE=1 cargo test --locked --all-features + format: cargo fmt # also run format-nix if we have nix installed @which nix && just format-nix || true -check-format: - cargo fmt --check - format-nix: nix run nixpkgs#nixfmt -- nix/flake.nix +check-format: + cargo fmt --check + check-format-nix: nix run nixpkgs#nixfmt -- --check nix/flake.nix -lint: - cargo fmt --check +check-clippy: cargo clippy --all-features --tests -- -D warnings - RUSTDOCFLAGS="-D warnings" cargo doc --all-features --no-deps -coverage: +check-docs: + cargo +nightly docs-rs + +docs: + cargo +nightly docs-rs --open + +check-lint: check-format check-clippy + +check-coverage: # requires cargo-llvm-cov and llvm-tools-preview RUST_BACKTRACE=1 cargo llvm-cov --all-features --fail-under-lines 30 --show-missing-lines -build-conformance: +check-conformance: cargo build --release --manifest-path tests/conformance/rust/Cargo.toml - -conformance: build-conformance - uv run --with hegel-core \ - --with pytest --with hypothesis pytest tests/conformance/test_conformance.py + uv run --with hegel-core --with pytest --with hypothesis \ + pytest tests/conformance/test_conformance.py + +# these aliases are provided as ux improvements for local developers. CI should use the longer +# forms. +test: check-tests +coverage: check-coverage +lint: check-lint +check: check-lint check-tests check-tests-all-features