Files

12 KiB

CI gate matrix

Use this when: a check is red and you need to know whether it blocks the merge, which workflow and job produced it, and how to reproduce it locally. Source of truth: the live main ruleset (command below) for required status; .github/workflows/<file>.yml for triggers, paths, timeout-minutes, and cron; .config/nextest.toml for e2e profile filters; .github/scheduled-validations.json for the freshness-watchdog list.

A job blocks a merge only when its exact check name is in the live main ruleset. A workflow name, a merge_group trigger, or a red PR check does not make a job required by itself.

Required merge checks

The main ruleset (6436880) requires exactly these contexts, with strict_required_status_checks_policy=false:

Required context Producer Validation
CLA Check cla.yml Contributor agreement
Quick Checks ci.yml job quick-checks Formatting and repository guard scripts
Test and Lint ci.yml job test-and-lint Clippy, workspace nextest (ci profile, excluding e2e_test), doctests, migration-gate count (scripts/check_migration_gate_count.sh)

For PRs limited to the paths-ignore list in ci.yml, ci-docs-only.yml reports Quick Checks and Test and Lint under the same names; it runs the quick checks and scripts/check_no_planning_docs.sh, not a Rust build or tests. scripts/check_ci_paths_sync.sh keeps the two path lists aligned.

Verify the live rule before changing merge policy:

gh api repos/rustfs/rustfs/rulesets/6436880 \
  --jq '.rules[] | select(.type == "required_status_checks") | .parameters'

Promotion rule: never promote a report-only lane to required from one green run. Require at least 14 days and 30 representative PRs with at least 99% complete execution, then update the ruleset and this file together.

Pull request and merge matrix

"Report-only" means visible and actionable but not in the required list. Budgets are each job's timeout-minutes in the named workflow and are not copied here.

Event Check name Workflow / job Merge status Reproduce
PR, non-doc change Quick Checks ci.yml quick-checks Required make pre-commit
PR, non-doc change Test and Lint ci.yml test-and-lint Required cargo clippy --all-targets -- -D warnings; cargo nextest run --profile ci --all --exclude e2e_test; cargo test --all --doc; scripts/check_migration_gate_count.sh
PR, non-doc change Typos ci.yml typos Report-only typos
PR, non-doc change ILM Integration (serial) ci.yml test-ilm-integration-serial Report-only exact command in the job
PR, non-doc change Test and Lint (rio-v2), Test and Lint (swift), Test and Lint (sftp) ci.yml test-and-lint-rio-v2, test-and-lint-protocols Report-only cargo nextest run with the job's --features
PR, non-doc change Connect Short Credential Boundary ci.yml connect-short-credential-boundary Report-only cargo test -p rustfs --test connect_registration --features connect-e2e-short-credentials; cargo check -p rustfs --release --features connect-e2e-short-credentials must fail
PR, non-doc change Build RustFS Debug Binary ci.yml build-rustfs-debug-binary Report-only; prerequisite for the black-box jobs cargo build -p rustfs --bins
PR, non-doc change io_uring Integration (real) ci.yml uring-integration Report-only cargo test -p rustfs-ecstore --lib uring_ -- --test-threads=1 --nocapture
PR, non-doc change End-to-End Tests ci.yml e2e-tests Report-only cargo nextest run --profile e2e-smoke -p e2e_test, then ./scripts/e2e-run.sh ./target/debug/rustfs <data-dir>; membership guards scripts/check_test_wiring.py --check-profile e2e-smoke <listing.json> and scripts/check_security_smoke_count.sh check <listing.json>
PR, non-doc change S3 Implemented Tests ci.yml s3-implemented-tests Report-only build rustfs, then scripts/s3-tests/run.sh with the job's DEPLOY_MODE / TEST_MODE / MAXFAIL env
PR, non-doc change S3 Lifecycle Behavior Tests ci.yml s3-lifecycle-behavior-tests Report-only scripts/s3-tests/run.sh with the job's accelerated-scanner env
PR touching paths in audit.yml Cargo Deny, Workflow Pin Report, Dependency Review audit.yml cargo-deny, workflow-pin-report, dependency-review Report-only cargo deny check; scripts/security/check_workflow_pins.sh
PR touching paths in architecture-migration-rules.yml Architecture Migration Rules architecture-migration-rules.yml architecture-migration-rules Report-only scripts/check_architecture_migration_rules.sh
PR touching paths in nix.yml Nix Build & Check nix.yml nix-validation Report-only nix flake check
PR touching paths in fuzz.yml Build Fuzz Harness, Smoke / <target> fuzz.yml fuzz-build, pr-fuzz-smoke Report-only MAX_TOTAL_TIME=60 ./scripts/fuzz/run.sh
PR touching paths in windows-filesystem.yml Rename Safety windows-filesystem.yml rename-safety Report-only the cargo test -p rustfs-ecstore --lib <filter> commands in the job, on Windows
PR touching paths in coverage.yml Workspace line coverage coverage.yml coverage Report-only make coverage; python3 scripts/check_security_coverage.py target/llvm-cov/coverage.json
PR touching paths in e2e-upgrade.yml Direct upgrade from rc.2 e2e-upgrade.yml direct-upgrade Report-only the cargo test --locked -p e2e_test command in the job with RUSTFS_UPGRADE_SOURCE_BINARY pointing at the pinned previous release
PR touching paths in oidc-keycloak.yml OIDC Keycloak live gate oidc-keycloak.yml oidc-keycloak-live Report-only cargo build --locked -p rustfs --bin rustfs, then bash scripts/test/oidc_keycloak_live.sh ./target/debug/rustfs
PR touching paths in targets-integration.yml PostgreSQL, MySQL, AMQP, and NATS targets-integration.yml targets-live Report-only start the containers as in the job, export the RUSTFS_TEST_* DSNs, then the job's cargo test --locked -p rustfs-targets --test <name> -- --ignored --test-threads=1 commands
PR limited to main-CI-excluded paths Quick Checks, Test and Lint ci-docs-only.yml quick-checks, test-and-lint Required git diff --check; make doc-paths-check; scripts/check_no_planning_docs.sh
merge_group; push to main End-to-End Tests (full merge gate) ci.yml e2e-full Report-only cargo nextest run --profile e2e-full -p e2e_test

e2e filters live in .config/nextest.toml; extend a profile instead of adding a second selector. Before a profile runs, scripts/check_test_wiring.py compares its listing to the committed digest in .config/e2e-<profile>-selection.txt, so a silent test drop fails closed.

Scheduled validation

Scheduled lanes never block a PR. Their workflow-local gate fails the run, scheduled failures route to the shared failure-issue action, and scheduled-validation-freshness.yml fails when a workflow listed in .github/scheduled-validations.json has not run within its max_age_hours (a never_ran_grace_until entry covers the window before a newly enabled cron's first slot). Cadence is qualitative here; the cron lives in each workflow's on.schedule.

Workflow (cadence) Jobs Verdict and artifacts In freshness list Reproduce
ci.yml (weekly) full matrix, including the schedule/dispatch-only rio-v2 jobs build-rustfs-debug-binary-rio-v2 and e2e-tests-rio-v2 per-job yes dispatch ci.yml
build.yml (weekly) build-rustfs over the six-target platform matrix in prepare-platform-matrix (four Linux, macOS aarch64, Windows x86_64) build/package integrity yes dispatch build.yml with an exact platform set
e2e-replication-nightly.yml (nightly) repl-nightly, cluster-nightly, protocols-nightly three independent gates; JUnit, membership listing, server logs yes cargo nextest run --profile e2e-repl-nightly -p e2e_test; --profile e2e-nightly; -j 1 --profile e2e-protocols
e2e-s3tests.yml (weekly) s3tests (single and distributed, four shards each), upstream-head-canary compatibility gate; report, JUnit, node IDs, server logs yes scripts/s3-tests/run.sh against an existing single or distributed target
fuzz.yml (nightly) nightly-fuzz-corpus per target gate; corpus and crash artifacts yes MAX_TOTAL_TIME=<seconds> ./scripts/fuzz/run.sh
minio-interop.yml (nightly) minio-interop EC + SSE read-parity gate yes, with never_ran_grace_until pinned Docker fixture steps in the workflow
performance-ab.yml (nightly) warp-ab regression-budget gate; A/B summaries and server logs yes bash scripts/run_hotpath_warp_abba.sh --help
nightly-gnu.yml (nightly) build, kms-vault-lane, kms-vault-ha-failover build, live Vault, and HA failover gates yes commands and pinned Vault images in the workflow
audit.yml (nightly) cargo-deny, workflow-pin-report dependency and workflow-pin gates yes cargo deny check; scripts/security/check_workflow_pins.sh
mint.yml (weekly) mint report-only by design; per-suite PASS/FAIL/NA and raw log.json yes pinned Docker sequence in the workflow
coverage.yml (weekly) coverage report-only trend; lcov and JSON artifact yes make coverage
runner-hygiene.yml (monthly) check-ephemerality runner ephemerality yes dispatch
e2e-upgrade.yml (weekly) direct-upgrade upgrade gate; server logs no see the PR row
oidc-keycloak.yml (weekly) oidc-keycloak-live live OIDC gate no see the PR row
targets-integration.yml (nightly) targets-live live target gate; container logs no see the PR row
scheduled-validation-freshness.yml (nightly) check-freshness fails on a never-created or stale schedule n/a dispatch

Manual workflow_dispatch runs are debugging evidence and do not open scheduled-failure issues. A manual performance run may explicitly allow a known regression; that override is not a passing baseline.

Release validation

Post-merge and tag-driven; not a substitute for a PR gate.

Trigger Workflow / job Result
Push to main, weekly schedule, dispatch build.yml build-rustfs (a development build on a main push restricts the matrix to the Linux targets) build artifacts; no release publication
Valid release or preview tag build.yml build-rustfs, create-release, upload-release-assets, publish-release draft release, checksummed assets, publish
Successful non-preview release-tag build (workflow_run) docker.yml build-docker, scan-docker-image multi-architecture images and vulnerability report
Successful release-tag build (workflow_run) package.yml package DEB/RPM packages and checksums uploaded to the release
Successful non-preview release-tag build (workflow_run) helm-package.yml build-helm-package, publish-helm-package versioned chart and repository index
Final tag's release published build.yml cleanup-preview-releases deletes every <target>-preview.<N> Release for that target; the tags are kept

Use an exact preview tag for an end-to-end release rehearsal. Manual dispatches are backfill/debug paths and do not prove the automatic workflow_run chain.

Change checklist

Update this file in the same PR when a job or check name changes, a workflow gains or loses a pull_request or schedule trigger, required contexts or strict/merge-queue policy change, report-only vs gating semantics change, or .github/scheduled-validations.json membership changes. Do not copy timeouts, crons, or test counts here.