Skip to content

Rename the four Reader types so only one reads bytes #2282

Rename the four Reader types so only one reads bytes

Rename the four Reader types so only one reads bytes #2282

Workflow file for this run

# Clippy (runtime-safety restriction lints), unused-dependency checks, the
# cargo-deny supply-chain gate (advisories, bans, sources, licences), the
# MSRV compile on the declared `rust-version`, a docs.rs-shape rustdoc lane,
# and the format/content sweep.
name: lint
on:
pull_request:
merge_group:
push:
branches: [main]
env:
CARGO_TERM_COLOR: always
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
clippy:
name: clippy
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
- uses: ./.github/actions/rust-setup
with:
components: clippy
# `-D warnings` goes after `--` per invocation, never in a job-level
# `RUSTFLAGS`: that would lint the dependency graph too, and
# `rust-setup` needs `RUSTFLAGS` byte-identical across jobs.
# Lints every target (libs, bins, tests, benches, examples) with
# default features; the `deny`-level restriction lints in
# `[workspace.lints.clippy]` fail on panicking/overflowing
# operations, with test code exempted per crate.
- name: cargo clippy
run: cargo clippy --workspace --all-targets --locked -- -D warnings
# The async io adapters sit behind the tokio feature, outside the
# default-features pass above.
- name: cargo clippy (tokio adapters)
run: cargo clippy --locked --all-targets -p nectar-file --features tokio -- -D warnings
# The tokio spawner sits behind the tasks crate's tokio feature,
# likewise outside the default-features pass.
- name: cargo clippy (tokio spawner)
run: cargo clippy --locked --all-targets -p nectar-tasks --features tokio -- -D warnings
# The batch ingest sits behind the rayon feature, likewise
# outside the default-features pass.
- name: cargo clippy (rayon ingest)
run: cargo clippy --locked --all-targets -p nectar-file --features rayon -- -D warnings
# The encrypted split mode sits behind the encryption feature,
# likewise outside the default-features pass.
- name: cargo clippy (encrypted split)
run: cargo clippy --locked --all-targets -p nectar-file --features encryption -- -D warnings
# The feature-gated integration suites are invisible to the
# default pass; compile them all in so the disallowed-methods
# gate sees them.
- name: cargo clippy (integration-test shapes)
run: cargo clippy --locked --all-targets -p nectar-integration-tests --features rayon,encryption -- -D warnings
# The seam conformance suites drive both formats at the encrypted
# reference width, likewise outside the default-features pass.
- name: cargo clippy (manifest encryption)
run: cargo clippy --locked --all-targets -p nectar-manifest --features test-encryption -- -D warnings
# The postage-usage issuer surfaces are feature-gated, so their tests
# are invisible to the passes above; compile them in so the
# disallowed-methods gate sees them.
- name: cargo clippy (postage-usage surfaces)
run: cargo clippy --workspace --all-targets --locked --features nectar-postage-usage/issuer -- -D warnings
# The postage-primitives serde impls are off the default build, so
# the passes above never see them.
- name: cargo clippy (postage-primitives serde)
run: cargo clippy --locked --all-targets -p nectar-postage-primitives --features serde -- -D warnings
# The parallel verifier and the bench that drives it sit behind the
# parallel feature, likewise outside the default-features pass.
- name: cargo clippy (postage-primitives parallel)
run: cargo clippy --locked --all-targets -p nectar-postage-primitives --features parallel -- -D warnings
# The generators and oracles ride the arbitrary feature, likewise
# outside the default-features pass.
- name: cargo clippy (postage-primitives arbitrary)
run: cargo clippy --locked --all-targets -p nectar-postage-primitives --features arbitrary -- -D warnings
# The raw node internals and the manifest seam are off the default
# build, so the trie bench is invisible to the passes above.
- name: cargo clippy (mantaray hazmat)
run: cargo clippy --locked --all-targets -p nectar-mantaray --features hazmat,manifest -- -D warnings
# The pipeline's parallel engine sits behind the parallel
# feature, likewise outside the default-features pass.
- name: cargo clippy (postage-issuer parallel)
run: cargo clippy --locked --all-targets -p nectar-postage-issuer --features parallel -- -D warnings
# The batched signer body against the inline engine.
- name: cargo clippy (postage-issuer sign-parallel)
run: cargo clippy --locked --all-targets -p nectar-postage-issuer --features sign-parallel -- -D warnings
# The encrypted node walk sits behind the encryption feature,
# likewise outside the default-features pass.
- name: cargo clippy (ldb encryption)
run: cargo clippy --locked --all-targets -p nectar-ldb --features encryption -- -D warnings
# The envelope sealing lane sits behind the encryption feature,
# likewise outside the default-features pass.
- name: cargo clippy (envelope)
run: cargo clippy --locked --all-targets -p nectar-envelope --features encryption -- -D warnings
# The pipeline's inline engine only compiles with the parallel
# feature off, so lint the inline shape on its own.
- name: cargo clippy (postage-issuer inline engine)
run: cargo clippy --locked --all-targets -p nectar-postage-issuer -- -D warnings
# `unused_crate_dependencies` is enforced per-library via `cargo
# rustc` (not `[workspace.lints]`) so the flag applies only to each
# crate's own lib target, never to benches/examples/tests (which
# inherit the package's full dependency set and would false-positive)
# or to third-party crates. cargo-machete (below) is the broader gate
# that also covers non-lib targets.
- name: unused lib dependencies
run: |
for crate in nectar-primitives nectar-primitives-core \
nectar-envelope nectar-postage \
nectar-postage-primitives nectar-postage-issuer \
nectar-postage-usage nectar-proof \
nectar-contracts nectar-file \
nectar-spec nectar-marker nectar-clock \
nectar-governor nectar-tasks; do
cargo rustc --locked -p "$crate" --lib -- -D unused_crate_dependencies
done
# nectar-mantaray by path: the editor's differential gate pins a
# second nectar-mantaray (0.3.0) as an oracle, so a bare -p spec is
# ambiguous. The manifest path selects the workspace member
# regardless of version, so this needs no revisiting when the oracle
# is removed or the workspace version bumps.
cargo rustc --locked --manifest-path crates/mantaray/Cargo.toml --lib -- -D unused_crate_dependencies
unused-deps:
name: unused-deps (machete)
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: taiki-e/install-action@1b57bc699ba2af96a06eb2a2a0d32b43a7d8e8b8 # install-action
with:
tool: cargo-machete
- name: cargo machete
run: cargo machete
deny:
name: deny
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Not `rust-setup`: this job compiles nothing, so warming the shared
# registry cache with an empty ~/.cargo would cost the compiling jobs.
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master 2026-06-30
with:
toolchain: "1.94"
- uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
tool: cargo-deny
# `--all-features` so the graph reaches feature-gated dependencies.
# `bans` cannot fail while deny.toml keeps its warn-level settings;
# it is wired up so a future ban needs no CI change.
# `RUSTUP_TOOLCHAIN` beats `rust-toolchain.toml`, whose `components`
# would otherwise pull rustfmt and clippy in for `cargo metadata`.
- name: cargo deny
env:
RUSTUP_TOOLCHAIN: "1.94"
run: cargo deny --all-features --locked check advisories bans sources licenses
# Compiles on the declared `rust-version`, read from the manifest rather than
# written here: declaration and pin both sit at 1.94, so a literal would stop
# testing the declaration the moment they part.
msrv:
name: msrv
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: test the derivation
run: .github/scripts/declared-msrv-test.sh
- name: read the declared rust-version
id: declared
# Assigned, not inlined: a failed substitution inside `echo` leaves
# the step green and the toolchain input empty.
run: |
msrv="$(.github/scripts/declared-msrv.sh)"
echo "version=$msrv" >> "$GITHUB_OUTPUT"
# Not `rust-setup`: rustup resolves `rust-toolchain.toml` at cargo
# time, so the file beats any `toolchain:` input. `RUSTUP_TOOLCHAIN`
# on the check step does override it.
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master 2026-06-30
with:
toolchain: ${{ steps.declared.outputs.version }}
# Default features and `--locked`: the committed graph only, no claim
# about a fresh resolve or an optional feature.
- name: cargo check
env:
RUSTUP_TOOLCHAIN: ${{ steps.declared.outputs.version }}
MSRV: ${{ steps.declared.outputs.version }}
run: |
# Catches the toolchain file winning, which would check on the
# pinned channel and report green.
actual="$(rustc --version | cut -d' ' -f2)"
case "$actual" in
"$MSRV" | "$MSRV".*) ;;
*)
echo "::error::checking on $actual, not the declared $MSRV"
exit 1
;;
esac
cargo check --workspace --all-targets --locked
# Backstop for `.claude/hooks/rustfmt-on-edit.sh`, which exits 0 without
# formatting whenever `rustfmt` is off `PATH`.
format:
name: format
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Not `rust-setup`: this job compiles nothing, so it would beat the
# compiling jobs to the shared registry cache key with an empty ~/.cargo.
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master 2026-06-30
with:
toolchain: "1.94"
components: rustfmt
- name: cargo fmt
run: cargo fmt --all --check
# `fuzz/` carries its own `[workspace]` table, so the sweep above misses it.
- name: cargo fmt (fuzz)
run: cargo fmt --manifest-path fuzz/Cargo.toml --all --check
# Wider than the hook's `.rs`/`.md` scope on purpose. The pattern
# lives in the script so this file can be scanned too.
- name: no em dashes
run: .github/scripts/no-em-dash.sh
# JSON belongs to fixtures and tests. `nectar-mantaray` is exempt
# because mantaray metadata is JSON on the wire.
- name: serde_json stays a dev-dependency
run: .github/scripts/serde-json-dev-only.sh
reinvention-gate:
name: reinvention-gate
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# Source-only grep gate; fails if a burned-down concurrency shape
# (waker cell, boxed-future alias, hand-rolled put window)
# reappears without its in-source justification comment. Needs
# no toolchain.
- name: reinvention gate
run: bash tools/reinvention-gate.sh
# Property-test tooling does not ship. `proptest` must be a dev
# dependency; `arbitrary` may be an optional normal dependency (the
# shipped `arbitrary` feature) but never a required one.
test-deps-gate:
name: test-deps off the default build
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Not `rust-setup`: this job runs `cargo metadata` and compiles
# nothing, so it must not claim the compiling jobs' registry
# cache key with an empty ~/.cargo.
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master 2026-06-30
with:
toolchain: "1.94"
- name: arbitrary and proptest stay off the default build
run: .github/scripts/arbitrary-proptest-dev-only.sh
docs:
name: docs
runs-on: ubuntu-latest
timeout-minutes: 30
env:
# nightly is required: --cfg docsrs enables feature(doc_cfg), which stable rejects.
RUSTDOCFLAGS: "-D warnings -D rustdoc::broken_intra_doc_links --cfg docsrs"
# the env var beats the repo's rust-toolchain.toml pin, which outranks rustup's default.
RUSTUP_TOOLCHAIN: nightly-2026-08-19
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- uses: rui314/setup-mold@7e4f20ad28a2e8ca6fd0892ccf72e2abb706b9c3 # v1
- uses: ./.github/actions/rust-setup
# the date-pinned nightly then owns the default slot for the doc build.
- uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master 2026-08-05
with:
toolchain: "nightly-2026-08-19"
# workspace --all-features unifies mutually exclusive feature pairs (nectar-file rayon vs unsync), so each published crate is documented alone with the set its own [package.metadata.docs.rs] declares.
- name: cargo doc
run: |
TAB="$(printf "\t")"
while IFS="$TAB" read -r pkg features; do
if [ "$features" = "all" ]; then
cargo doc --locked --no-deps --all-features -p "$pkg"
else
cargo doc --locked --no-deps --features "$features" -p "$pkg"
fi
done < <(cargo metadata --no-deps --locked --format-version 1 | jq -r '
.packages[] | select(.publish == null)
| [.name,
(if (.metadata.docs.rs["all-features"] // false) then "all"
else ((.metadata.docs.rs.features // ["default"]) | join(",")) end)]
| join("\t")')
# The one required context for this workflow: later jobs append to `needs`
# rather than to the branch ruleset.
lint-success:
name: lint success
runs-on: ubuntu-latest
if: always()
needs: [clippy, unused-deps, deny, msrv, format, docs, reinvention-gate, test-deps-gate]
timeout-minutes: 30
steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1
with:
jobs: ${{ toJSON(needs) }}