Skip to content

rscrypto: cleaning out the nightmare that was the CRC32 and CRC32C #63

rscrypto: cleaning out the nightmare that was the CRC32 and CRC32C

rscrypto: cleaning out the nightmare that was the CRC32 and CRC32C #63

Workflow file for this run

name: Commit
on:
push:
branches:
- "**"
# Allow manual trigger
workflow_dispatch:
# Cancel in-progress runs for the same branch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
RUST_BACKTRACE: 1
CARGO_TERM_COLOR: always
RSCRYPTO_TEST_MODE: commit
CARGO_INCREMENTAL: 0
# Lock down permissions to read-only by default
permissions:
contents: read # Required for actions/checkout
jobs:
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Change Detection (cargo-rail)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
detect:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
count: ${{ steps.rail.outputs.count }}
docs-only: ${{ steps.rail.outputs.docs-only }}
rebuild-all: ${{ steps.rail.outputs.rebuild-all }}
cargo-args: ${{ steps.rail.outputs.cargo-args }}
matrix: ${{ steps.rail.outputs.matrix }}
base-ref: ${{ steps.rail.outputs.base-ref }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # Required for change detection
- name: Detect Changes
id: rail
uses: loadingalias/cargo-rail-action@6c5c295be5d51edbf8f88bfd9540acd460027f4a # v1.0.3
with:
since: ${{ github.event.before }}
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Core Platform Testing (GitHub Free Runners)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Full CI on all platforms: quality checks, build, and test
# Uses GitHub free runners wherever possible
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ci:
name: CI (${{ matrix.target.name }})
needs: [detect]
if: |
github.event_name == 'workflow_dispatch' ||
needs.detect.outputs.rebuild-all == 'true' ||
(needs.detect.outputs.count != '0' &&
needs.detect.outputs.docs-only != 'true')
runs-on: ${{ matrix.target.runner }}
env:
# Pass base-ref to scripts for consistent change detection
RAIL_SINCE: ${{ needs.detect.outputs.base-ref }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
target:
# ─────────────────────────────────────────────────────────────────────
# Linux (GitHub Free Runners)
# ─────────────────────────────────────────────────────────────────────
- name: x86_64-unknown-linux-gnu
runner: ubuntu-latest
tier: a
# ─────────────────────────────────────────────────────────────────────
# Linux ARM64 (Namespace Runners - no free GitHub ARM runners)
# ─────────────────────────────────────────────────────────────────────
- name: aarch64-unknown-linux-gnu
runner: namespace-profile-rscrypto-linux-arm64
tier: a
# ─────────────────────────────────────────────────────────────────────
# Windows (GitHub Free Runners)
# ─────────────────────────────────────────────────────────────────────
- name: x86_64-pc-windows-msvc
runner: windows-latest
tier: a
# ─────────────────────────────────────────────────────────────────────
# Windows ARM64 (Namespace Runners - no free GitHub ARM runners)
# ─────────────────────────────────────────────────────────────────────
- name: aarch64-pc-windows-msvc
runner: namespace-profile-rscrypto-windows-arm64
tier: b
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # Required for cargo rail affected (needs git history)
# Compute cache key from environment and runner metadata
- name: Compute Cache Key
id: cache
shell: bash
run: |
OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]')
ARCH=$(echo "${{ runner.arch }}" | tr '[:upper:]' '[:lower:]')
echo "key=${{ env.RSCRYPTO_TEST_MODE }}-${OS}-${ARCH}" >> "$GITHUB_OUTPUT"
- name: Setup
uses: ./.github/actions/setup
with:
cache-key: ${{ steps.cache.outputs.key }}
- name: Quality Checks
run: just ci-check
- name: Build
run: just build
- name: Tests
run: just test
# ─────────────────────────────────────────────────────────────────────────
# SIMD Tier Smoke Tests - Platform-specific kernel verification
# ─────────────────────────────────────────────────────────────────────────
# x86_64 Linux: PCLMUL (SSE)
- name: CRC64 Tier Smoke (force PCLMUL)
if: matrix.target.name == 'x86_64-unknown-linux-gnu'
run: cargo test -p checksum test_crc64_forced_kernel_smoke_from_env --lib
env:
RSCRYPTO_CRC64_FORCE: pclmul
RSCRYPTO_CRC64_STREAMS: "2"
# x86_64 Windows: PCLMUL (SSE)
- name: CRC64 Tier Smoke (force PCLMUL)
if: matrix.target.name == 'x86_64-pc-windows-msvc'
run: cargo test -p checksum test_crc64_forced_kernel_smoke_from_env --lib
env:
RSCRYPTO_CRC64_FORCE: pclmul
RSCRYPTO_CRC64_STREAMS: "2"
# aarch64 Linux: PMULL (NEON/crypto)
- name: CRC64 Tier Smoke (force PMULL)
if: matrix.target.name == 'aarch64-unknown-linux-gnu'
run: cargo test -p checksum test_crc64_forced_kernel_smoke_from_env --lib
env:
RSCRYPTO_CRC64_FORCE: pmull
# aarch64 Linux: SVE2 PMULL (where available)
- name: CRC64 Tier Smoke (force SVE2 PMULL)
if: matrix.target.name == 'aarch64-unknown-linux-gnu'
run: cargo test -p checksum test_crc64_forced_kernel_smoke_from_env --lib
env:
RSCRYPTO_CRC64_FORCE: sve2-pmull
RSCRYPTO_CRC64_STREAMS: "2"
# aarch64 Windows: PMULL (NEON/crypto)
- name: CRC64 Tier Smoke (force PMULL)
if: matrix.target.name == 'aarch64-pc-windows-msvc'
run: cargo test -p checksum test_crc64_forced_kernel_smoke_from_env --lib
env:
RSCRYPTO_CRC64_FORCE: pmull
# ─────────────────────────────────────────────────────────────────────────
# Portable Fallback Verification - Ensure all platforms work without SIMD
# ─────────────────────────────────────────────────────────────────────────
- name: CRC64 Portable Fallback Verification
run: cargo test -p checksum test_crc64_forced_kernel_smoke_from_env --lib
env:
RSCRYPTO_CRC64_FORCE: portable
# ─────────────────────────────────────────────────────────────────────────
# Static Linking Verification (MUSL - Linux only)
# ─────────────────────────────────────────────────────────────────────────
- name: Build Verification (MUSL x86-64)
if: matrix.target.name == 'x86_64-unknown-linux-gnu'
run: |
rustup target add x86_64-unknown-linux-musl
cargo build --workspace --target x86_64-unknown-linux-musl
- name: Build Verification (MUSL ARM64)
if: matrix.target.name == 'aarch64-unknown-linux-gnu'
run: |
rustup target add aarch64-unknown-linux-musl
cargo build --workspace --target aarch64-unknown-linux-musl
# Ensure cache directories exist to avoid ENOENT warnings from rust-cache
- name: Ensure Cache Directories
shell: bash
run: mkdir -p target/tests/trybuild target/tests/target
crc64-avx512:
name: CRC64 Tiers (x86_64 AVX-512)
needs: [detect]
if: |
github.event_name == 'workflow_dispatch' ||
needs.detect.outputs.rebuild-all == 'true' ||
(needs.detect.outputs.count != '0' &&
needs.detect.outputs.docs-only != 'true')
runs-on: namespace-profile-rscrypto-linux-x86
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Compute Cache Key
id: cache
shell: bash
run: |
OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]')
ARCH=$(echo "${{ runner.arch }}" | tr '[:upper:]' '[:lower:]')
echo "key=${{ env.RSCRYPTO_TEST_MODE }}-${OS}-${ARCH}-crc64-avx512" >> "$GITHUB_OUTPUT"
- name: Setup
uses: ./.github/actions/setup
with:
cache-key: ${{ steps.cache.outputs.key }}
- name: CRC64 Tier Smoke (force VPCLMUL, 7-way)
run: cargo test -p checksum test_crc64_forced_kernel_smoke_from_env --lib
env:
RSCRYPTO_CRC64_FORCE: vpclmul
RSCRYPTO_CRC64_STREAMS: "7"
- name: CRC64 Tier Smoke (force PCLMUL, 2-way)
run: cargo test -p checksum test_crc64_forced_kernel_smoke_from_env --lib
env:
RSCRYPTO_CRC64_FORCE: pclmul
RSCRYPTO_CRC64_STREAMS: "2"
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# no_std Targets (Cross-compile verification)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Strategic target selection:
# - thumbv6m-none-eabi: Smallest Cortex-M (M0/M0+), if this works, M3/M4/M7/M33 work
# - riscv32imac-unknown-none-elf: RISC-V 32-bit, different ISA coverage
# - aarch64-unknown-none: ARM64 bare metal
# - x86_64-unknown-none: x86_64 bare metal
#
# These can't run tests (no OS), but cargo check/build verifies:
# - no_std compatibility
# - no accidental std dependencies
# - Feature flag combinations work
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
no-std:
name: no_std (${{ matrix.target }})
needs: [detect]
if: |
github.event_name == 'workflow_dispatch' ||
needs.detect.outputs.rebuild-all == 'true' ||
(needs.detect.outputs.count != '0' &&
needs.detect.outputs.docs-only != 'true')
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
target:
# ARM Cortex-M0/M0+ (smallest, most restrictive - proves all larger Cortex-M work)
- thumbv6m-none-eabi
# RISC-V 32-bit (different ISA, atomics via 'a' extension)
- riscv32imac-unknown-none-elf
# ARM64 bare metal (bootloaders, hypervisors, secure enclaves)
- aarch64-unknown-none
# x86_64 bare metal (kernels, bootloaders, hypervisors)
- x86_64-unknown-none
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Install Rust toolchain (reads version from rust-toolchain.toml)
- name: Read Toolchain Version
id: toolchain
run: |
TOOLCHAIN=$(awk -F'"' '/^channel/ {print $2}' rust-toolchain.toml)
echo "version=$TOOLCHAIN" >> "$GITHUB_OUTPUT"
- name: Install Rust Toolchain
uses: dtolnay/rust-toolchain@f7ccc83f9ed1e5b9c81d8a67d7ad1a747e22a561 # master
with:
toolchain: ${{ steps.toolchain.outputs.version }}
# Explicit target installation (rust-toolchain.toml doesn't include no_std targets)
- name: Install Target
run: rustup target add ${{ matrix.target }}
- name: Setup Rust Cache
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
with:
shared-key: "rscrypto-v1"
key: no-std-${{ matrix.target }}
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/main' }}
# ─────────────────────────────────────────────────────────────────────────
# no_std Feature Matrix Verification
# Note: Use -p instead of --workspace to properly disable default features
# ─────────────────────────────────────────────────────────────────────────
- name: Check no_std (no features - pure no_std)
run: cargo check -p platform -p traits -p backend --target ${{ matrix.target }} --no-default-features --lib
- name: Check no_std with alloc
run: cargo check -p platform -p traits -p backend --target ${{ matrix.target }} --no-default-features --features alloc --lib
- name: Build no_std release (pure no_std)
run: cargo build -p platform -p traits -p backend --target ${{ matrix.target }} --no-default-features --lib --release
- name: Build no_std release with alloc
run: cargo build -p platform -p traits -p backend --target ${{ matrix.target }} --no-default-features --features alloc --lib --release
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# WASM Targets (Cross-compile verification)
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Strategic target selection:
# - wasm32-unknown-unknown: Core browser WASM (most common)
# - wasm32-wasip1: WASI preview 1 (server-side WASM)
#
# Verifies:
# - WASM compatibility
# - No accidental WASM-incompatible dependencies
# - Feature flag combinations work in WASM context
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
wasm:
name: WASM (${{ matrix.target }})
needs: [detect]
if: |
github.event_name == 'workflow_dispatch' ||
needs.detect.outputs.rebuild-all == 'true' ||
(needs.detect.outputs.count != '0' &&
needs.detect.outputs.docs-only != 'true')
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
target:
# Core browser WASM (most common deployment target)
- wasm32-unknown-unknown
# WASI preview 1 (server-side WASM, Wasmtime/Wasmer)
- wasm32-wasip1
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Install Rust toolchain (reads version from rust-toolchain.toml)
- name: Read Toolchain Version
id: toolchain
run: |
TOOLCHAIN=$(awk -F'"' '/^channel/ {print $2}' rust-toolchain.toml)
echo "version=$TOOLCHAIN" >> "$GITHUB_OUTPUT"
- name: Install Rust Toolchain
uses: dtolnay/rust-toolchain@f7ccc83f9ed1e5b9c81d8a67d7ad1a747e22a561 # master
with:
toolchain: ${{ steps.toolchain.outputs.version }}
# Explicit target installation (rust-toolchain.toml doesn't include WASM targets)
- name: Install Target
run: rustup target add ${{ matrix.target }}
- name: Setup Rust Cache
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
with:
shared-key: "rscrypto-v1"
key: wasm-${{ matrix.target }}
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/main' }}
# ─────────────────────────────────────────────────────────────────────────
# WASM Feature Matrix Verification
# Note: Use -p instead of --workspace to properly disable default features
# ─────────────────────────────────────────────────────────────────────────
- name: Check WASM (no features - pure no_std)
run: cargo check -p platform -p traits -p backend --target ${{ matrix.target }} --no-default-features --lib
- name: Check WASM with alloc
run: cargo check -p platform -p traits -p backend --target ${{ matrix.target }} --no-default-features --features alloc --lib
- name: Build WASM release (no features)
run: cargo build -p platform -p traits -p backend --target ${{ matrix.target }} --no-default-features --lib --release
- name: Build WASM release with alloc
run: cargo build -p platform -p traits -p backend --target ${{ matrix.target }} --no-default-features --features alloc --lib --release
# Additional wasm-pack verification for browser target
- name: Install wasm-pack
if: matrix.target == 'wasm32-unknown-unknown'
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Build with wasm-pack (browser target)
if: matrix.target == 'wasm32-unknown-unknown'
run: |
# Build each library crate with wasm-pack
for crate in crates/*/; do
if [ -f "${crate}Cargo.toml" ]; then
echo "Building $(basename "$crate") with wasm-pack..."
wasm-pack build "$crate" --target web --no-default-features --features alloc 2>/dev/null || true
fi
done
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Summary Job
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
complete:
name: All checks complete
needs: [detect, ci, crc64-avx512, no-std, wasm]
if: always()
runs-on: ubuntu-latest
steps:
- name: Check results
run: |
echo "Checking workflow results..."
echo "Should skip (docs-only): ${{ needs.detect.outputs.docs-only }}"
if [ "${{ needs.detect.outputs.docs-only }}" == "true" ]; then
echo "Documentation-only changes - no CI required"
exit 0
fi
# Check if any job failed
if [ "${{ needs.ci.result }}" == "failure" ] || \
[ "${{ needs.crc64-avx512.result }}" == "failure" ] || \
[ "${{ needs.no-std.result }}" == "failure" ] || \
[ "${{ needs.wasm.result }}" == "failure" ]; then
echo "One or more jobs failed"
exit 1
fi
echo "All jobs passed"