Release 0.6.0 #751
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: CI | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| version-check: | |
| name: Version consistency | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-python@v7 | |
| with: | |
| python-version: '3.10' | |
| - name: Check version sync | |
| run: python scripts/version_sync.py --check | |
| rust: | |
| name: Rust (fmt, clippy, test) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Check formatting | |
| run: cargo fmt --all --check | |
| - name: Run clippy | |
| run: cargo clippy --workspace --exclude iscc-rb --all-targets -- -D warnings | |
| - name: Clippy iscc-lib (no default features) | |
| run: cargo clippy -p iscc-lib --no-default-features -- -D warnings | |
| - name: Clippy iscc-lib (all features) | |
| run: cargo clippy -p iscc-lib --all-features -- -D warnings | |
| - name: Run tests | |
| run: cargo test --workspace --exclude iscc-rb | |
| - name: Test iscc-lib (no default features) | |
| run: cargo test -p iscc-lib --no-default-features | |
| - name: Test iscc-lib (all features) | |
| run: cargo test -p iscc-lib --all-features | |
| - name: Test iscc-lib (text-processing only) | |
| run: cargo test -p iscc-lib --no-default-features --features text-processing | |
| python-test: | |
| name: Python ${{ matrix.python-version }} (ruff, pytest) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ['3.10', '3.14'] | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - uses: actions/setup-python@v7 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| allow-prereleases: true | |
| # exact tag: setup-uv publishes no floating major tag past v7 (v8/v9 are | |
| # exact release tags only), so @v9 does not resolve | |
| - uses: astral-sh/setup-uv@v9.0.0 | |
| - name: Install dev dependencies | |
| run: uv sync --group dev | |
| - name: Build Python bindings | |
| run: uv run maturin develop --manifest-path crates/iscc-py/Cargo.toml | |
| - name: Run ruff check | |
| run: uv run ruff check | |
| - name: Run ruff format check | |
| run: uv run ruff format --check | |
| - name: Run pytest | |
| run: uv run pytest | |
| python: | |
| name: Python (ruff, pytest) | |
| if: always() | |
| needs: python-test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify all Python versions passed | |
| run: test "${{ needs.python-test.result }}" = "success" | |
| nodejs: | |
| name: Node.js (napi build, test) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: '20' | |
| - name: Install npm dependencies | |
| run: npm install | |
| working-directory: crates/iscc-napi | |
| - name: Build native addon | |
| run: npx napi build --platform | |
| working-directory: crates/iscc-napi | |
| - name: Run tests | |
| run: npm test | |
| working-directory: crates/iscc-napi | |
| wasm: | |
| name: WASM (wasm-pack test) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: wasm32-unknown-unknown | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Install wasm-pack | |
| run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh | |
| # The blake3 dep in crates/iscc-wasm/Cargo.toml exists only to feature-unify | |
| # `wasm32_simd` onto iscc-lib's blake3 — nothing in the crate imports it, so a | |
| # dep-pruner or refactor could drop it and silently return the published | |
| # @iscc/wasm to the scalar BLAKE3 backend with every test still green. | |
| - name: Assert blake3 wasm32_simd feature is enabled | |
| run: | | |
| cargo tree -p iscc-wasm --target wasm32-unknown-unknown -i blake3 -f "{p} {f}" \ | |
| | grep -q 'wasm32_simd' \ | |
| || { echo "::error::blake3 wasm32_simd feature is not enabled for iscc-wasm — the published WASM build would fall back to scalar BLAKE3"; exit 1; } | |
| - name: Run tests | |
| env: | |
| RUSTFLAGS: -C target-feature=+simd128 | |
| run: wasm-pack test --node crates/iscc-wasm --features conformance | |
| c-ffi: | |
| name: C FFI (cbindgen, gcc, test) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Install cbindgen | |
| run: cargo install cbindgen | |
| - name: Build FFI crate | |
| run: cargo build -p iscc-ffi | |
| - name: Check C header freshness | |
| run: | | |
| cbindgen --config crates/iscc-ffi/cbindgen.toml --crate iscc-ffi --output crates/iscc-ffi/include/iscc.h | |
| git diff --exit-code crates/iscc-ffi/include/iscc.h || \ | |
| (echo "::error::iscc.h is stale. Run: cbindgen --config crates/iscc-ffi/cbindgen.toml --crate iscc-ffi --output crates/iscc-ffi/include/iscc.h" && exit 1) | |
| - name: Compile C test program | |
| run: > | |
| gcc -o test_iscc | |
| crates/iscc-ffi/tests/test_iscc.c | |
| -I crates/iscc-ffi/include | |
| -L target/debug | |
| -liscc_ffi | |
| -lpthread -ldl -lm | |
| - name: Run C test program | |
| run: LD_LIBRARY_PATH=target/debug ./test_iscc | |
| dotnet: | |
| name: C# / .NET (dotnet build, test) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - uses: actions/setup-dotnet@v6 | |
| with: | |
| dotnet-version: '8.0' | |
| - name: Build FFI native library | |
| run: cargo build -p iscc-ffi | |
| - name: Restore .NET packages (locked mode) | |
| run: dotnet restore packages/dotnet/Iscc.Lib.Tests/Iscc.Lib.Tests.csproj --locked-mode | |
| - name: Build .NET projects | |
| run: dotnet build packages/dotnet/Iscc.Lib.Tests/Iscc.Lib.Tests.csproj --no-restore | |
| - name: Run .NET tests | |
| run: > | |
| dotnet test packages/dotnet/Iscc.Lib.Tests/ --no-restore | |
| -e LD_LIBRARY_PATH=${{ github.workspace }}/target/debug | |
| java: | |
| name: Java (JNI build, mvn test) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - uses: actions/setup-java@v5 | |
| with: | |
| distribution: temurin | |
| java-version: '17' | |
| - name: Build JNI native library | |
| run: cargo build -p iscc-jni | |
| - name: Run Maven tests | |
| run: mvn test -f crates/iscc-jni/java/pom.xml | |
| go: | |
| name: Go (go test, go vet) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v7 | |
| with: | |
| go-version-file: packages/go/go.mod | |
| - name: Run Go tests | |
| run: CGO_ENABLED=0 go test -v -count=1 ./... | |
| working-directory: packages/go | |
| - name: Run Go vet | |
| run: go vet ./... | |
| working-directory: packages/go | |
| ruby: | |
| name: Ruby (magnus build, test) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Install libclang-dev | |
| run: sudo apt-get update && sudo apt-get install -y libclang-dev | |
| - uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: '3.1' | |
| working-directory: crates/iscc-rb | |
| bundler-cache: true | |
| - name: Run standardrb | |
| run: bundle exec standardrb | |
| working-directory: crates/iscc-rb | |
| - name: Run clippy | |
| run: cargo clippy -p iscc-rb -- -D warnings | |
| - name: Compile native extension | |
| run: bundle exec rake compile | |
| working-directory: crates/iscc-rb | |
| - name: Run tests | |
| run: bundle exec rake test | |
| working-directory: crates/iscc-rb | |
| cpp: | |
| name: C++ (cmake, ASAN, test) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Install cmake | |
| run: sudo apt-get update && sudo apt-get install -y cmake | |
| - name: Build FFI native library | |
| run: cargo build -p iscc-ffi | |
| - name: Configure CMake | |
| run: > | |
| cmake -B build -DCMAKE_BUILD_TYPE=Debug | |
| -DFFI_LIB_DIR=../../target/debug -DSANITIZE_ADDRESS=ON | |
| working-directory: packages/cpp | |
| - name: Build C++ tests | |
| run: cmake --build build | |
| working-directory: packages/cpp | |
| - name: Run C++ tests | |
| run: LD_LIBRARY_PATH=../../target/debug ./build/tests/test_iscc | |
| working-directory: packages/cpp | |
| swift: | |
| name: Swift (swift build, swift test) | |
| runs-on: macos-14 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Validate root Package.swift manifest | |
| run: swift package dump-package | |
| - name: Build UniFFI native library | |
| run: cargo build -p iscc-uniffi | |
| - name: Build Swift package | |
| run: > | |
| swift build | |
| -Xlinker -L${{ github.workspace }}/target/debug | |
| working-directory: packages/swift | |
| - name: Run Swift tests | |
| run: > | |
| swift test | |
| -Xlinker -L${{ github.workspace }}/target/debug | |
| -Xlinker -rpath | |
| -Xlinker ${{ github.workspace }}/target/debug | |
| working-directory: packages/swift | |
| kotlin: | |
| name: Kotlin (gradle build, test) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - uses: actions/setup-java@v5 | |
| with: | |
| distribution: temurin | |
| java-version: '17' | |
| - name: Build UniFFI native library | |
| run: cargo build -p iscc-uniffi | |
| - name: Run Gradle tests | |
| run: ./gradlew test | |
| working-directory: packages/kotlin | |
| bench: | |
| name: Bench (compile check) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Compile benchmarks | |
| run: cargo bench --no-run | |
| perf: | |
| name: Perf (iai-callgrind) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Install valgrind | |
| run: sudo apt-get update && sudo apt-get install -y valgrind | |
| - name: Install cargo-binstall | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-binstall | |
| # --force is load-bearing: Swatinem/rust-cache restores cargo's install | |
| # metadata WITHOUT the ~/.cargo/bin/iai-callgrind-runner binary, so a plain | |
| # binstall would skip the install and the next `cargo bench` would die with | |
| # "no such command". The version must match the iai-callgrind dep (0.16.1). | |
| - name: Install iai-callgrind-runner | |
| run: cargo binstall -y --force iai-callgrind-runner@0.16.1 | |
| # IAI_CALLGRIND_ALLOW_ASLR pins ASLR-on everywhere so CI and local runs | |
| # behave identically and the committed baseline is portable; ASLR does not | |
| # affect Ir counts. The regression gate runs in the "Check perf regression" | |
| # step below against the committed .iai-baseline.json. | |
| - name: Run iai-callgrind benches | |
| env: | |
| IAI_CALLGRIND_ALLOW_ASLR: 'true' | |
| run: cargo bench -p iscc-lib --bench iai_benches | |
| # Guard against a false green: the bench binary must keep its | |
| # __iai_callgrind_wrapper symbols (see [profile.bench] in Cargo.toml) or | |
| # callgrind collects zero instructions for every bench while still exiting 0. | |
| # On a clean runner target/iai/ holds only this run, so a non-zero summary | |
| # proves real counts were collected. | |
| - name: Assert non-zero instruction collection | |
| run: | | |
| if grep -rEq '^summary: [1-9]' target/iai/; then | |
| echo "iai-callgrind collected non-zero instructions" | |
| else | |
| echo "::error::iai-callgrind collected ZERO instructions for all benches" | |
| exit 1 | |
| fi | |
| # Enforcing regression gate: fail if any benchmark's instruction count (Ir) | |
| # exceeds the committed .iai-baseline.json by more than 10%. Stdlib-only | |
| # Python, so no uv/Python setup step is needed. Refresh the baseline in a | |
| # reviewed commit via `mise run bench:iai:baseline`. | |
| - name: Check perf regression | |
| run: python3 scripts/iai_regression.py --check | |
| # if: always() preserves the artifact even when the regression step fails, | |
| # so a real regression can be inspected against the committed baseline. | |
| - name: Upload iai-callgrind results | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: iai-baseline | |
| path: target/iai/ | |
| semver: | |
| name: Semver (cargo-semver-checks) | |
| runs-on: ubuntu-latest | |
| # Informational during the 0.4.0 -> 1.0.0 transition; enforcing from v1.0.0. | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Check semver | |
| uses: obi1kenobi/cargo-semver-checks-action@v2 | |
| with: | |
| package: iscc-lib | |
| coverage: | |
| name: Coverage + CRAP (cargo llvm-cov + cargo crap) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: llvm-tools-preview | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Install cargo-llvm-cov | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-llvm-cov | |
| - name: Install cargo-binstall | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-binstall | |
| - name: Install cargo-crap | |
| run: cargo binstall -y --force cargo-crap@0.2.2 | |
| - name: Generate LCOV coverage report | |
| run: cargo llvm-cov -p iscc-lib --lcov --output-path lcov.info | |
| - name: Upload coverage report | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: lcov | |
| path: lcov.info | |
| # Phase 2: report-only CRAP scoring. No score gate, so these steps exit 0. | |
| - name: CRAP report (GitHub annotations) | |
| run: cargo crap --lcov lcov.info --format github | |
| - name: CRAP report (SARIF) | |
| run: cargo crap --lcov lcov.info --format sarif --output crap.sarif | |
| - name: Upload CRAP SARIF to Code Scanning | |
| uses: github/codeql-action/upload-sarif@v4 | |
| with: | |
| sarif_file: crap.sarif | |
| # Phase 3: enforcing regression + absolute gate. `--fail-regression` fails if | |
| # any function's CRAP score worsens versus the committed .crap-baseline.json | |
| # (refresh via `mise run crap:baseline`); `--fail-above` independently fails any | |
| # function whose CRAP score exceeds the `.cargo-crap.toml` threshold (30), | |
| # including new/renamed functions absent from the baseline. Runs last so the | |
| # report-only diagnostics above still execute when the gate fails. | |
| - name: CRAP regression gate | |
| run: cargo crap --lcov lcov.info --baseline .crap-baseline.json --fail-regression | |
| --fail-above | |
| audit: | |
| name: Audit (cargo-deny) | |
| runs-on: ubuntu-latest | |
| # Enforcing supply-chain gate: cargo deny check fails CI on a RustSec | |
| # advisory, a yanked or banned crate, a disallowed license, or an unknown | |
| # source. Policy lives in the workspace-root deny.toml. No continue-on-error. | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| # taiki-e/install-action fetches a prebuilt cargo-deny binary; pin the | |
| # version for reproducibility (same discipline as cargo-crap / iai-runner). | |
| - name: Install cargo-deny | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-deny@0.19.9 | |
| - name: Run cargo-deny | |
| run: cargo deny check | |
| release-workflow: | |
| name: Release workflow (action inputs) | |
| runs-on: ubuntu-latest | |
| # Validates release.yml `with:` keys and step-output reads against each | |
| # action's published action.yml (needs network, so CI-only — prek and the | |
| # pytest suite run the network-free checks). Transport failures degrade to | |
| # a stderr warning, never a red gate. | |
| steps: | |
| - uses: actions/checkout@v7 | |
| # exact tag: setup-uv publishes no floating major tag past v7 (v8/v9 are | |
| # exact release tags only), so @v9 does not resolve | |
| - uses: astral-sh/setup-uv@v9.0.0 | |
| - name: Check release workflow action inputs | |
| run: uv run --no-project --with pyyaml python scripts/check_release_workflow.py | |
| --check-action-inputs |