Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
53b172c
perf(nix): wrap the outputs that will be kept out of the shared cache
daniel-noland Aug 20, 2026
d548732
ci: reserve Cachix for reusable build inputs
daniel-noland Aug 15, 2026
3b67b2a
ci: keep workspace outputs substitutable
daniel-noland Aug 15, 2026
6b7c3a1
fix(nix): keep `results` out of the build source
daniel-noland Aug 15, 2026
7666f92
perf(nix): share one dependency build per flag-set
daniel-noland Aug 15, 2026
7424efd
perf(nix): remap sources to a relative prefix
daniel-noland Aug 15, 2026
21604fb
ci: widen matrix parallelism for deep runs
daniel-noland Aug 15, 2026
376472e
ci: honour ci:-vlab again
daniel-noland Aug 15, 2026
5d693b0
ci: retry container pushes
daniel-noland Aug 15, 2026
21ed20a
perf(nix): keep the git version out of the dependency build
daniel-noland Aug 15, 2026
76fce62
ci: check that the dependency build stays reusable
daniel-noland Aug 15, 2026
528c9df
ci: build clippy, doctests, and docs through nix
daniel-noland Aug 15, 2026
c74f7fb
perf(nix): lint the workspace in one derivation
daniel-noland Aug 15, 2026
c37b3e3
ci: give nix the whole core budget, and split it for test_each
daniel-noland Aug 15, 2026
8323c59
ci: cut the coverage test floor and stop checking the fuzz profile twice
daniel-noland Aug 15, 2026
23eeee1
docs(ci): document the ci:-vlab label
daniel-noland Aug 16, 2026
9e1c795
ci: check that default.nix stays formatted
daniel-noland Aug 17, 2026
23ea7cd
perf(nix): keep prose and dev config out of the build source
daniel-noland Aug 17, 2026
368146d
ci: actually run nixfmt, and check that the lint lists agree
daniel-noland Aug 17, 2026
96561e1
ci: keep every container image out of the shared cache
daniel-noland Aug 17, 2026
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
4 changes: 2 additions & 2 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ CARGO_LLVM_COV_TARGET_DIR = { value = "target/llvm-cov/build", relative = true,
CARGO_LLVM_COV_BUILD_DIR = { value = "target/llvm-cov/target", relative = true, force = false }

[build]
# Register `emulated` so cfg_attr sites don't trip unexpected_cfgs natively.
rustflags = ["--cfg=tokio_unstable", "--check-cfg=cfg(emulated)"]
# Register `emulated` and `instrumented` so cfg sites do not trip unexpected_cfgs natively.
rustflags = ["--cfg=tokio_unstable", "--check-cfg=cfg(emulated)", "--check-cfg=cfg(instrumented)"]

[target.wasm32-wasip1]
# Trailing `--` separates wasmtime's CLI from the module + module args
Expand Down
6 changes: 6 additions & 0 deletions .github/actions/nix-shell/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ runs:
signingKey: '${{ inputs.cachix_signing_key }}'
# prettier-ignore
authToken: '${{ inputs.cachix_auth_token }}'
# Exclude images and dockerTools assembly paths, whose customization
# layers can reintroduce the source closure. Match artifact shapes so new
# images are covered automatically; `check-push-filter` verifies them.
# Anchor `stream-` to a store-path name so cached crates such as
# tokio-stream are not swept up by it.
pushFilter: '(-dataplane-volatile-|-customisation-layer$|-(base|conf|layers)\.json$|-excludePaths$|/[0-9a-z]{32}-stream-|-env$)'

- name: "use nix shell"
uses: "rrbutani/use-nix-shell-action@59a52b2b9bbfe3cc0e7deb8f9059abe37a439edf" # v1.1.0
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ Production artifacts are produced via nix builds in a separate CI workflow.
overrides it, because the merge queue has no labels to read and would
run the upgrade legs anyway; a `merge-ready` run that skipped them would
not be the preview it claims to be
- `ci:-vlab` - Skip VLAB and HLAB tests on this PR, even with `ci:+merge-ready`

Labels are additive, and optional: a pull request needs none of them.
`ci:-upgrade` is the sole exception, subtracting a job that would otherwise run.
`ci:-vlab` and `ci:-upgrade` are the exceptions, subtracting jobs that would
otherwise run.

Adding a label starts a **new** workflow run, and that run repeats the default
jobs as well as the ones the label enabled. This applies to _every_ label, not
Expand Down
73 changes: 67 additions & 6 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ jobs:
runs-on: "ubuntu-latest"
outputs:
container_profiles: "${{ steps.container-profiles.outputs.value }}"
parallel: "${{ steps.parallel.outputs.value }}"
profiles: "${{ steps.profiles.outputs.value }}"
concurrency: "${{ steps.concurrency.outputs.value }}"
cross: "${{ steps.cross.outputs.value }}"
Expand All @@ -81,6 +82,19 @@ jobs:
with:
persist-credentials: "false"

# Let merge-gating runs finish quickly without allowing pull requests to
# crowd them out. `strategy` cannot read `env`, so expose this via `plan`.
- id: "parallel"
env:
EVENT: "${{ github.event_name }}"
run: |
set -euo pipefail
case "${EVENT}" in
merge_group | push) value="4" ;;
*) value="1" ;;
esac
printf 'value=%s\n' "${value}" >>"${GITHUB_OUTPUT}"

- id: "miri"
uses: &gate "./.github/actions/ci-gate"
with:
Expand Down Expand Up @@ -183,10 +197,14 @@ jobs:
JUST_VARS: ""
strategy:
fail-fast: false
# Keep one pull request from occupying the shared lab pool.
max-parallel: 1
# Each entry gets its own runner; this limits shared-pool occupancy.
max-parallel: ${{ fromJSON(needs.plan.outputs.parallel) }}
matrix:
profile: "${{ fromJSON(needs.plan.outputs.profiles) }}"
exclude:
# Fuzz repeats the release compile here; coverage, sanitizers, and
# fuzzing jobs already exercise that profile.
- profile: "fuzz"
steps:
- *checkout

Expand Down Expand Up @@ -219,6 +237,13 @@ jobs:
recipe: "ci::check-doctest"
recipe_args: "${{ matrix.profile }}"

# Build API docs so links and cfg declarations cannot rot unnoticed.
- name: "docs"
uses: *just
with:
recipe: "ci::check-docs"
recipe_args: "${{ matrix.profile }}"

- &verify-clean-tree
name: "verify-clean-tree"
run: |
Expand Down Expand Up @@ -319,6 +344,35 @@ jobs:
with:
recipe: "markdownlint"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The earlier likely nixfmt changes should probably be here in ci: actually run nixfmt, and check that the lint lists agree


- name: "nixfmt"
id: "nixfmt"
continue-on-error: true
uses: *just
with:
recipe: "nixfmt"

- name: "check-lint-wiring"
id: "check-lint-wiring"
continue-on-error: true
uses: *just
with:
recipe: "check-lint-wiring"

- name: "check-push-filter"
id: "check-push-filter"
continue-on-error: true
uses: *just
with:
recipe: "check-push-filter"

# Cache misses still pass, so guard dependency reuse explicitly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you fixed the commit message for ci: check that the dependency build stays reusable, it doesn't make sense to me.

- name: "check-deps-reuse"
id: "check-deps-reuse"
continue-on-error: true
uses: *just
with:
recipe: "check-deps-reuse"

- name: "license-headers"
id: "license-headers"
continue-on-error: true
Expand All @@ -337,6 +391,10 @@ jobs:
pinact=${{ steps.pinact.outcome }}
actionlint=${{ steps.actionlint.outcome }}
markdownlint=${{ steps.markdownlint.outcome }}
nixfmt=${{ steps.nixfmt.outcome }}
check-lint-wiring=${{ steps.check-lint-wiring.outcome }}
check-push-filter=${{ steps.check-push-filter.outcome }}
check-deps-reuse=${{ steps.check-deps-reuse.outcome }}
license-headers=${{ steps.license-headers.outcome }}
run: |
set -euo pipefail
Expand Down Expand Up @@ -365,7 +423,7 @@ jobs:
env: *ci-env
strategy:
fail-fast: false
max-parallel: 1
max-parallel: ${{ fromJSON(needs.plan.outputs.parallel) }}
matrix:
nix-target:
- frr.dataplane
Expand Down Expand Up @@ -399,7 +457,7 @@ jobs:
env: *ci-env
strategy:
fail-fast: false
max-parallel: 1
max-parallel: ${{ fromJSON(needs.plan.outputs.parallel) }}
matrix:
sanitizer:
- thread
Expand Down Expand Up @@ -444,7 +502,7 @@ jobs:
env: *ci-env
strategy:
fail-fast: false
max-parallel: 1
max-parallel: ${{ fromJSON(needs.plan.outputs.parallel) }}
# Fuzz provides optimized coverage while retaining safety checks.
matrix:
profile: "${{ fromJSON(needs.plan.outputs.profiles) }}"
Expand Down Expand Up @@ -632,6 +690,7 @@ jobs:
JUST_VARS: ""
strategy:
fail-fast: false
# Keep cross serial so one pull request cannot occupy the lab.
max-parallel: 1
matrix:
platform:
Expand Down Expand Up @@ -699,14 +758,16 @@ jobs:
with:
# ci:+hlab is required to enable hybrid lab tests on PR
# ci:+vlab is required to enable virtual lab tests on PR
# ci:-vlab opts back out, including for ci:+merge-ready
# ci:-upgrade disables upgrade tests on PR
# hlab is disabled for main and merge_queue till we have gateway tests for it
# ci:+merge-ready mirrors the merge queue, which skips HLAB.
skip: >-
${{
github.event_name == 'pull_request'
&& (
matrix.hybrid && !contains(github.event.pull_request.labels.*.name, 'ci:+hlab')
contains(github.event.pull_request.labels.*.name, 'ci:-vlab')
|| matrix.hybrid && !contains(github.event.pull_request.labels.*.name, 'ci:+hlab')
|| !matrix.hybrid
&& !contains(github.event.pull_request.labels.*.name, 'ci:+vlab')
&& !contains(github.event.pull_request.labels.*.name, 'ci:+merge-ready')
Expand Down
2 changes: 1 addition & 1 deletion acl/src/dpdk/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::dpdk::rule::RuleSpec;
///
/// The `rte_acl` field count is computed from `K`'s layout at runtime and
/// dispatched to the const-`N` builder shared with the dynamic install path
/// (see [`dispatch_build_classifier`]). The resulting `DpdkAclLookup<K, A>`
/// (see `dispatch_build_classifier`, crate-private). The resulting `DpdkAclLookup<K, A>`
/// carries no field-count or stride const generics, so one type covers every
/// monomorphization of a generic key.
pub fn install_table<K, A>(
Expand Down
4 changes: 2 additions & 2 deletions acl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
//! - `dpdk` module (`dpdk` feature): production `rte_acl` backend --
//! layout planner, rule lowering, install, and the single-shot /
//! batched classify path.
//! - [`reference`](mod@reference): linear-scan software classifier;
//! differential oracle for the `dpdk` backend. Always built.
//! - `reference` (behind the `reference` feature): linear-scan software
//! classifier; differential oracle for the `dpdk` backend.
//!
//! [`lookup::Lookup`]: lookup::Lookup
//! [`match_action::MatchKey`]: match_action::MatchKey
Expand Down
23 changes: 19 additions & 4 deletions ci.just
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,25 @@ set script-interpreter := ["/usr/bin/env", "bash", "-euo", "pipefail"]

debug_justfile := env("CI_DEBUG_JUSTFILE", "false")

# Nix build budget for a 10-core lab runner.
# The container cannot discover its ten-core cgroup limit. Keep `jobs * cores`
# within that budget and give single large derivations all of it.
jobs := "1"

cores := "8"
cores := "10"

# Small per-package derivations use the budget better when split two ways.
test_each_jobs := "2"

test_each_cores := "5"

[private]
_lab-common := " docker_sock=/run/docker/docker.sock" + " oci_repo=ghcr.io" + " debug_justfile=" + debug_justfile

[private]
_lab := "jobs=" + jobs + " cores=" + cores + " docker_sock=/run/docker/docker.sock" + " oci_repo=ghcr.io" + " debug_justfile=" + debug_justfile
_lab := "jobs=" + jobs + " cores=" + cores + _lab-common

[private]
_lab-test-each := "jobs=" + test_each_jobs + " cores=" + test_each_cores + _lab-common

[default]
[private]
Expand All @@ -37,11 +49,14 @@ check-clippy profile:
check-doctest profile:
just {{ _lab }} profile={{ profile }} doctest

check-docs profile:
just {{ _lab }} profile={{ profile }} docs

sanitize san profile="fuzz":
just {{ _lab }} profile={{ profile }} sanitize={{ san }} test

test-each profile="debug":
just {{ _lab }} profile={{ profile }} test-each
just {{ _lab-test-each }} profile={{ profile }} test-each

coverage profile="debug":
just {{ _lab }} profile={{ profile }} instrument=coverage coverage-archive
Expand Down
2 changes: 1 addition & 1 deletion concurrency/src/slot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
//! the miri job (which runs against the real `ArcSwap` in
//! permissive-provenance mode) is where it lives.
//!
//! [`Subscriber::snapshot`]: crate::Subscriber::snapshot
//! [`Subscriber::snapshot`]: crate::quiescent::Subscriber::snapshot

// Strict provenance checks fail with arc-swap since it uses hazard pointers and does not (yet) use the new
// std features to expose provenance information in their mechanics.
Expand Down
2 changes: 1 addition & 1 deletion concurrency/src/stress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn shuttle_config() -> shuttle::Config {
///
/// * default backend -- one direct call, no scheduling exploration.
/// * `loom` -- `loom::model`.
/// * `shuttle` -- the [`shuttle_config`]-configured `PortfolioRunner`
/// * `shuttle` -- the `shuttle_config`-configured `PortfolioRunner`
/// (`RandomScheduler` + `PctScheduler`, plus `DfsScheduler` under
/// `shuttle_dfs`).
///
Expand Down
2 changes: 1 addition & 1 deletion concurrency/src/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//!
//! `std::thread::scope` (stable since 1.63) and `shuttle::thread::scope`
//! are re-exported directly. `loom` 0.7 does not provide `scope`, so we
//! ship a local shim in [`loom_scope`] that matches the std API on top
//! ship a local shim in `loom_scope` that matches the std API on top
//! of loom's `spawn` + `park`/`unpark` + atomic primitives, with a
//! narrow `unsafe` lifetime launder (same trick std uses internally).
//!
Expand Down
2 changes: 1 addition & 1 deletion config/src/external/overlay/acl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub struct AclPattern {
/// Port ranges for match entries that specified neither `cidr` nor `vpcSubnet`, meaning "any
/// address within the peering, restricted to these ports". These can't be resolved into
/// concrete prefixes until the peering's manifests are known, so they're materialized into
/// `src`/`dst` during [`AclRule::validate_patterns_coverage`] rather than at conversion time.
/// `src`/`dst` during `AclRule::validate_patterns_coverage` rather than at conversion time.
pub src_any_ports: Vec<PortRange>,
pub dst_any_ports: Vec<PortRange>,
pub proto: AclProtoMatch,
Expand Down
Loading
Loading