Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .cargo/mutants.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: 2026 jlreq contributors
# SPDX-License-Identifier: MIT OR Apache-2.0

# These files are emitted from attested specification data. `just generate-check` and
# `just attest` validate them byte-for-byte; mutation testing covers the adjacent,
# handwritten `generated.rs` integrity checks.
exclude_globs = ["crates/jlreq/src/generated/**"]

# Each proven-equivalent mutant is pinned to the source hash and justified individually
# in docs/mutation-ledger.toml. Anchoring the full cargo-mutants name prevents a broad
# expression class from being hidden by accident.
exclude_re = [
'^crates/jlreq/src/generated[.]rs:35:5: replace [|] with \^$',
'^crates/jlreq/src/generated[.]rs:36:5: replace [|] with \^$',
'^crates/jlreq/src/generated[.]rs:37:5: replace [|] with \^$',
'^crates/jlreq/src/generated[.]rs:38:5: replace [|] with \^$',
'^crates/jlreq/src/generated[.]rs:55:41: replace < with <= in ascends$',
]
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
/xtask/ @P4suta

# The release controls the gates read. Relaxing one is a review, never an edit in passing.
/docs/api-1.0.toml @P4suta
/docs/public-api.toml @P4suta
/docs/conformance-deferrals.toml @P4suta
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ body:
id: version
attributes:
label: Version
placeholder: "jlreq 0.0.0 (git revision), rustc 1.85.0, x86_64-unknown-linux-gnu"
placeholder: "jlreq 0.1.0, rustc 1.85.0, x86_64-unknown-linux-gnu"
validations:
required: true
37 changes: 34 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ jobs:
- run: just wasm

fuzz:
name: fuzz (public API invariants)
name: fuzz (validation, composition, protocol)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
Expand All @@ -180,6 +180,21 @@ jobs:
workspaces: fuzz -> target
- run: just fuzz-check-linux-ci

coverage:
name: coverage (handwritten products)
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
with:
components: llvm-tools-preview
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
with:
tool: just@1.50.0,cargo-llvm-cov@0.9.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
- run: just coverage

purity:
name: purity (no std, I/O, font, or float in the core)
runs-on: ubuntu-latest
Expand Down Expand Up @@ -217,6 +232,18 @@ jobs:
# it.
- run: just design

semver:
name: semver compatibility (0.1.x)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
with:
tool: just@1.50.0,cargo-semver-checks@0.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
- run: just semver

conform-ocaml:
# The independent OCaml reference engine (engines/ocaml/README.md) answering the
# conformance protocol from an implementation that shares no code with the Rust one
Expand Down Expand Up @@ -361,13 +388,15 @@ jobs:
- run: just shear

actionlint:
name: actionlint + zizmor (workflow self-check)
name: shellcheck + actionlint + zizmor (automation self-check)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
with:
tool: just@1.50.0,zizmor@1.28.0
tool: just@1.50.0,shellcheck@0.11.0,zizmor@1.28.0
- name: shellcheck
run: just shellcheck
- name: actionlint
env:
ACTIONLINT_VERSION: 1.7.12
Expand Down Expand Up @@ -400,8 +429,10 @@ jobs:
- no_std
- wasm
- fuzz
- coverage
- purity
- design
- semver
- conform-ocaml
- conform-racket
- doc
Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/fuzz-scheduled.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# SPDX-FileCopyrightText: 2026 jlreq contributors
# SPDX-License-Identifier: MIT OR Apache-2.0

name: Scheduled fuzz

on:
workflow_dispatch:
schedule:
- cron: "19 2 * * 6"

permissions:
contents: read

concurrency:
group: scheduled-fuzz
cancel-in-progress: true

jobs:
fuzz:
runs-on: ubuntu-latest
timeout-minutes: 55
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # nightly
with:
toolchain: nightly
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
with:
tool: just@1.50.0,cargo-fuzz@0.13.2
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
workspaces: fuzz -> target
- run: just fuzz-scheduled
87 changes: 47 additions & 40 deletions .github/workflows/mutants.yml
Original file line number Diff line number Diff line change
@@ -1,72 +1,79 @@
# SPDX-FileCopyrightText: 2026 jlreq contributors
#
# SPDX-License-Identifier: MIT OR Apache-2.0

# Mutation testing (cargo-mutants) for the sole public Rust library. xtask is tooling and
# jlreq-conformance is tested through its process protocol.
#
# This is a scheduled report rather than a required gate: a complete mutation run is slow,
# and surviving mutants are evidence for the next independently-authored test rather than a
# reason to hide the report behind a permanently red workflow. The command outcome and full
# report remain visible in the job summary and artifact.
#
# Each matrix leg runs `just mutants <crate>`, scoped to one package the way `-p` scopes
# every other per-crate gate in this repository (see `just msrv`).
# Pull requests smoke-test changed Rust code. Weekly/manual runs cover both handwritten
# products in four shards. Generated tables and five exact, proof-backed equivalent mutants
# are the only configured exclusions and are pinned in docs/mutation-ledger.toml; a missed
# or timed-out mutant fails the workflow.
name: Mutants

on:
pull_request:
paths:
- "**/*.rs"
- "**/Cargo.toml"
- "Justfile"
- ".cargo/mutants.toml"
- "docs/mutation-ledger.toml"
- "scripts/verify-mutation-ledger.sh"
- ".github/workflows/mutants.yml"
workflow_dispatch:
schedule:
# Weekly (Thu 04:38 UTC, offset from codeql.yml's Mon 03:27 UTC) so the baseline tracks
# the test suite even between direct changes to the public library.
- cron: "38 4 * * 4"

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
mutants:
name: mutants (${{ matrix.crate }})
smoke:
name: changed-surface smoke
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
# The full library has a broad mutation surface; keep generous runner headroom.
timeout-minutes: 60
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
with:
tool: just@1.50.0,cargo-mutants@27.1.0,nextest@0.9.140
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
- run: just mutants-smoke '${{ github.event.pull_request.base.sha }}'
- if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: mutants-smoke
path: mutants.out/
if-no-files-found: ignore
retention-days: 14

full:
name: full (${{ matrix.crate }}, ${{ matrix.shard }})
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
crate: [jlreq]
crate: [jlreq, jlreq-conformance]
shard: [1, 2, 3, 4]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
with:
tool: just@1.50.0,cargo-mutants@27.1.0,nextest@0.9.140
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
# Deliberately no `RUSTFLAGS: -D warnings` (unlike clippy/test/design/etc. in
# ci.yml): that env var, not the workspace lint levels themselves, is what turns a
# warning into a build failure elsewhere in this repo, and mutated code that merely
# provokes a new lint should still build and run against the tests here. See the
# Justfile's `mutants` recipe for the fuller version of this reasoning.
- name: cargo mutants
id: cargo_mutants
continue-on-error: true
run: just mutants ${{ matrix.crate }}
- name: summarize mutation result
if: always()
env:
MUTANTS_OUTCOME: ${{ steps.cargo_mutants.outcome }}
run: |-
echo "## cargo-mutants: $MUTANTS_OUTCOME" >> "$GITHUB_STEP_SUMMARY"
if [ "$MUTANTS_OUTCOME" != "success" ]; then
echo "Surviving mutants or a runner error were reported; inspect the artifact." >> "$GITHUB_STEP_SUMMARY"
fi
- name: upload mutants.out
if: always()
- run: just mutants '${{ matrix.crate }}' '${{ matrix.shard }}/4'
- if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: mutants.out-${{ matrix.crate }}
name: mutants-${{ matrix.crate }}-${{ matrix.shard }}-of-4
path: mutants.out/
if-no-files-found: error
retention-days: 14
Loading
Loading