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
7 changes: 7 additions & 0 deletions .cargo/initial-release-patch.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: 2026 jlreq contributors
# SPDX-License-Identifier: MIT OR Apache-2.0

# Used only by local package and publish dry-run verification before jlreq-core 0.1.0
# exists in the crates.io index. Published manifests retain the version-only dependency.
[patch.crates-io]
jlreq-core = { path = "crates/jlreq-core" }
12 changes: 6 additions & 6 deletions .cargo/mutants.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
# 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/**"]
exclude_globs = ["crates/jlreq-core/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$',
'^crates/jlreq-core/src/generated[.]rs:35:5: replace [|] with \^$',
'^crates/jlreq-core/src/generated[.]rs:36:5: replace [|] with \^$',
'^crates/jlreq-core/src/generated[.]rs:37:5: replace [|] with \^$',
'^crates/jlreq-core/src/generated[.]rs:38:5: replace [|] with \^$',
'^crates/jlreq-core/src/generated[.]rs:55:41: replace < with <= in ascends$',
]
43 changes: 43 additions & 0 deletions .github/REPOSITORY-SETTINGS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Repository settings required for release

These controls live in GitHub and cannot be made reproducible by a workflow in this tree.
A repository administrator must verify them against the candidate and record the reviewer
and verification date in the release handoff. No crate credential belongs in these
settings during preparation.

## Actions and branch protection

- Require every third-party GitHub Action to be pinned to a full 40-character commit SHA.
The checked-in workflows already satisfy this; keep the platform setting enabled so a
later workflow cannot weaken it.
- Protect `main` and require the aggregate CI job plus CodeQL, dependency review, REUSE,
API/semver, all four mutation shards for all three products, and the manual Release Check
used by a candidate.
- Require the branch to be current before merge and prevent required checks from being
bypassed by ordinary maintainers.
- Confirm Dependabot has no open update pull request and code/dependency scanning has no
high or critical alert before approving a release candidate.

## `release` environment

- Restrict deployment branches to `main` only.
- Configure at least one required reviewer who is not the workflow initiator.
- Disable administrator/self-review bypass where the repository policy permits it.
- Do not store `CRATES_IO_TOKEN` during preparation.
- For the first publication only, add a narrowly scoped crates.io token immediately before
approval, then remove and revoke it after Trusted Publishing is verified.

The manual [Release workflow](workflows/release.yml) names this environment and requires an
exact candidate SHA, successful Release Check run ID, version, authentication mode, and
confirmation phrase. Merging workflow files cannot trigger publication.

## Handoff record

Before the first irreversible action, record outside the repository:

- repository administrator who verified these controls;
- required reviewer identity;
- verification timestamp;
- candidate commit SHA and successful Release Check run ID; and
- the result of checking crates.io names, existing tags/releases, open dependency PRs, and
high/critical alerts.
67 changes: 40 additions & 27 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
# alternatives JLReq records; complete JIS X 4051 conformance is not claimed).
#
# Layout under test:
# - jlreq dependency-free no_std + alloc public library.
# - jlreq std high-level font/shaping/layout facade (MSRV 1.88).
# - jlreq-core dependency-free no_std + alloc composition core (MSRV 1.85).
# - jlreq-conformance binary-only protocol runner and sample engine.
# - xtask repository policy checks shared by Just and CI.
# - engines/ocaml an independent reference engine, outside the Cargo workspace,
Expand Down Expand Up @@ -60,7 +61,7 @@ jobs:
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
with:
components: rustfmt
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
- run: just fmt-check
Expand All @@ -70,7 +71,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0,taplo-cli@0.10.0
- run: just toml-check
Expand All @@ -85,7 +86,7 @@ jobs:
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
with:
components: clippy
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -104,7 +105,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0,nextest@0.9.140
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -122,7 +123,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0,cargo-hack@0.6.45
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -138,7 +139,7 @@ jobs:
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
with:
targets: thumbv7em-none-eabi
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -157,7 +158,7 @@ jobs:
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
with:
targets: wasm32-unknown-unknown
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -174,7 +175,7 @@ jobs:
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # nightly
with:
toolchain: nightly
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0,cargo-fuzz@0.13.2
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -191,31 +192,43 @@ jobs:
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
with:
components: llvm-tools-preview
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0,cargo-llvm-cov@0.9.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
- run: just coverage

mutation-smoke:
name: mutation smoke (changed Rust product lines)
name: mutation smoke (changed Rust product lines, shard ${{ matrix.shard.display }}/4)
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
shard:
- index: 0
display: 1
- index: 1
display: 2
- index: 2
display: 3
- index: 3
display: 4
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
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
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 }}'
- run: just mutants-smoke '${{ github.event.pull_request.base.sha }}' '${{ matrix.shard.index }}/4'
- if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: mutants-smoke
name: mutants-smoke-${{ matrix.shard.display }}-of-4
path: mutants.out/
if-no-files-found: ignore
retention-days: 14
Expand All @@ -228,7 +241,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -245,7 +258,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -263,7 +276,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0,cargo-semver-checks@0.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -287,7 +300,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -303,7 +316,7 @@ jobs:
conform-racket:
# The independent Racket reference engine (engines/racket/README.md), on the same
# terms as conform-ocaml: it shares no code with the Rust engine, builds its tables
# from spec/ rather than from crates/jlreq/src/generated/, and is gated by the
# from spec/ rather than from crates/jlreq-core/src/generated/, and is gated by the
# cumulative suite engines/racket/milestones/CURRENT points at rather than by the
# whole one.
name: conform-racket (independent Racket engine)
Expand All @@ -319,7 +332,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -342,7 +355,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -356,7 +369,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand All @@ -370,13 +383,13 @@ jobs:
- uses: crate-ci/typos@8a48f81b6c64dcfea44b3633223084c4be58ac5f # v1.49.0

msrv:
name: msrv (workspace 1.85)
name: msrv (facade 1.88; core/tooling 1.85)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: cargo-msrv@0.19.3,just@1.50.0
# `cargo-msrv verify` reads each crate's declared `rust-version` and proves it builds
Expand All @@ -389,7 +402,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0
# Run REUSE through `uvx` exactly as `just reuse` does locally rather than the
Expand All @@ -406,7 +419,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: cargo-deny@0.20.2,cargo-shear@1.13.3,just@1.50.0
- run: just deny
Expand All @@ -417,7 +430,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0,shellcheck@0.11.0,zizmor@1.28.0
- name: shellcheck
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/fuzz-scheduled.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # nightly
with:
toolchain: nightly
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
with:
tool: just@1.50.0,cargo-fuzz@0.13.2
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand Down
22 changes: 15 additions & 7 deletions .github/workflows/mutants.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2026 jlreq contributors
# SPDX-License-Identifier: MIT OR Apache-2.0

# Weekly/manual runs cover both handwritten products in four shards. Pull-request smoke
# Weekly/manual runs cover all three handwritten Rust products in four shards. Pull-request smoke
# mutation belongs to CI so its result feeds the single required aggregation gate there.
# 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
Expand All @@ -22,26 +22,34 @@ concurrency:

jobs:
full:
name: full (${{ matrix.crate }}, ${{ matrix.shard }})
name: full (${{ matrix.crate }}, shard ${{ matrix.shard.display }}/4)
runs-on: ubuntu-latest
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
crate: [jlreq, jlreq-conformance]
shard: [1, 2, 3, 4]
crate: [jlreq, jlreq-core, jlreq-conformance]
shard:
- index: 0
display: 1
- index: 1
display: 2
- index: 2
display: 3
- index: 3
display: 4
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
- uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2.86.7
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 '${{ matrix.crate }}' '${{ matrix.shard }}/4'
- run: just mutants '${{ matrix.crate }}' '${{ matrix.shard.index }}/4'
- if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: mutants-${{ matrix.crate }}-${{ matrix.shard }}-of-4
name: mutants-${{ matrix.crate }}-${{ matrix.shard.display }}-of-4
path: mutants.out/
if-no-files-found: error
retention-days: 14
Loading
Loading