ci(pdftract-3cp3a): add clippy-unwrap quality gate for INV-8 enforcement
Add fifth quality gate to quality-matrix DAG: - New template: clippy-unwrap - Runs clippy with features default,serve,decrypt -- -D warnings - Runs library-only pass with -D clippy::unwrap_used -D clippy::expect_used - Uses pdftract-test-glibc:1.78 base image (precompiled dep tree) - Enforces INV-8 (no panic at public boundary of pdftract-core) This completes the 5 Tier 1 hard gates from Phase 0.4 Quality Targets. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
080ceeb62b
commit
9c3ffdf38f
1 changed files with 106 additions and 4 deletions
|
|
@ -35,7 +35,7 @@
|
|||
# - setup: Clone repo, fetch dependencies, warm cargo cache
|
||||
# - build-matrix: Cross-compile for 5 targets (x86_64/aarch64 Linux musl, macOS x64/ARM64, Windows x64)
|
||||
# - test-matrix: Run unit tests across feature combinations (default, full, with OCR)
|
||||
# - quality-matrix: Linting (clippy, fmt), security audit (cargo-audit), dependency review
|
||||
# - quality-matrix: Five Tier 1 quality gates (clippy-fmt, clippy-unwrap, msrv-check, cargo-audit, cargo-deny)
|
||||
# - bench-matrix: Performance benchmarks (cargo bench) against fixture corpus
|
||||
# - publish-if-tag: On tags only, upload binaries to GitHub Releases
|
||||
#
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
# - pdftract-xxxx: setup step, volume mount points, cache warming logic
|
||||
# - pdftract-yyyy: build-matrix templates (5 target builds with cross)
|
||||
# - pdftract-zzzz: test-matrix templates (feature combinations)
|
||||
# - pdftract-wwww: quality-matrix templates (clippy, fmt, audit)
|
||||
# - pdftract-wwww: quality-matrix templates (clippy-fmt, clippy-unwrap, msrv-check, cargo-audit, cargo-deny)
|
||||
# - pdftract-vvvv: bench-matrix templates (cargo bench)
|
||||
# - pdftract-uuuu: publish-if-tag template (gh release create)
|
||||
#
|
||||
|
|
@ -516,8 +516,12 @@ spec:
|
|||
memory: 8Gi
|
||||
|
||||
# === Quality Matrix ===
|
||||
# Run linting (clippy, fmt), security audit (cargo-audit), dependency review,
|
||||
# and MSRV check (build with rust:1.78-slim to detect new-Rust feature usage)
|
||||
# Five parallel Tier 1 quality gates — any failure blocks PR merge:
|
||||
# 1. clippy-fmt: General linting and formatting check
|
||||
# 2. clippy-unwrap: Feature-specific clippy with INV-8 unwrap/expect ban
|
||||
# 3. msrv-check: Verify no newer Rust features are used (MSRV 1.78)
|
||||
# 4. cargo-audit: Security advisory check on dependencies
|
||||
# 5. cargo-deny: License and security policy enforcement
|
||||
#
|
||||
# CRITICAL: All cargo commands MUST use --locked (or --locked --frozen)
|
||||
- name: quality-matrix
|
||||
|
|
@ -526,10 +530,14 @@ spec:
|
|||
tasks:
|
||||
- name: clippy-fmt
|
||||
template: clippy-fmt
|
||||
- name: clippy-unwrap
|
||||
template: clippy-unwrap
|
||||
- name: msrv-check
|
||||
template: msrv-check
|
||||
- name: cargo-audit
|
||||
template: cargo-audit
|
||||
- name: cargo-deny
|
||||
template: cargo-deny
|
||||
|
||||
# === Clippy and Fmt Check ===
|
||||
# Runs clippy with MSRV-aware lints and verifies formatting
|
||||
|
|
@ -570,6 +578,56 @@ spec:
|
|||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
|
||||
# === Clippy Unwrap/Expect Check (INV-8 Enforcement) ===
|
||||
# Runs clippy with specific features (default,serve,decrypt) and enforces INV-8
|
||||
# (no panic at public boundary) via unwrap_used/expect_used lints on library code.
|
||||
# This is one of the 5 Tier 1 hard gates — any failure blocks PR merge.
|
||||
#
|
||||
# Uses pdftract-test-glibc:1.78 base image where the dependency tree is precompiled,
|
||||
# making clippy significantly faster than cold images.
|
||||
#
|
||||
# CRITICAL: All cargo commands MUST use --locked (or --locked --frozen)
|
||||
- name: clippy-unwrap
|
||||
activeDeadlineSeconds: 600
|
||||
container:
|
||||
image: pdftract-test-glibc:1.78
|
||||
command: [bash, -c]
|
||||
args:
|
||||
- |
|
||||
set -eo pipefail
|
||||
|
||||
echo "=========================================="
|
||||
echo "Clippy Unwrap/Expect Check (INV-8)"
|
||||
echo "=========================================="
|
||||
|
||||
cd /workspace
|
||||
export CARGO_HOME="/cache/cargo/registry"
|
||||
export CARGO_TARGET_DIR="/cache/cargo/target-clippy-unwrap"
|
||||
|
||||
echo "=== Running clippy with features default,serve,decrypt ==="
|
||||
cargo clippy --locked --all-targets --features default,serve,decrypt -- -D warnings
|
||||
|
||||
echo "=== Running library-only clippy with unwrap/expect bans (INV-8) ==="
|
||||
echo "This enforces the invariant: no panic reaches the public boundary of pdftract-core"
|
||||
cargo clippy --locked --lib -p pdftract-core --features default,serve,decrypt -- \
|
||||
-D clippy::unwrap_used \
|
||||
-D clippy::expect_used
|
||||
|
||||
echo "=== Clippy unwrap/expect checks passed ==="
|
||||
echo "INV-8 invariant verified: no unwrap() or expect() in pdftract-core library code"
|
||||
volumeMounts:
|
||||
- name: workspace
|
||||
mountPath: /workspace
|
||||
- name: cargo-cache
|
||||
mountPath: /cache/cargo
|
||||
resources:
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
|
||||
# === MSRV Check ===
|
||||
# Builds with rust:1.78-slim to verify no newer Rust features are used.
|
||||
# This gate prevents silent MSRV drift that would break downstream consumers
|
||||
|
|
@ -653,6 +711,50 @@ spec:
|
|||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
|
||||
# === Cargo Deny ===
|
||||
# Runs cargo-deny to check licenses, bans, advisories, and sources
|
||||
- name: cargo-deny
|
||||
activeDeadlineSeconds: 300
|
||||
container:
|
||||
image: rust:1.83-bookworm
|
||||
command: [bash, -c]
|
||||
args:
|
||||
- |
|
||||
set -eo pipefail
|
||||
|
||||
echo "=========================================="
|
||||
echo "License and Security Policy (cargo-deny)"
|
||||
echo "=========================================="
|
||||
|
||||
cd /workspace
|
||||
export CARGO_HOME="/cache/cargo/registry"
|
||||
|
||||
# Install cargo-deny if not present
|
||||
if ! command -v cargo-deny &> /dev/null; then
|
||||
echo "Installing cargo-deny..."
|
||||
cargo install cargo-deny --locked
|
||||
fi
|
||||
|
||||
echo "=== Updating advisory database ==="
|
||||
cargo deny fetch
|
||||
|
||||
echo "=== Running cargo deny check ==="
|
||||
cargo deny check licenses bans advisories sources
|
||||
|
||||
echo "=== License and security checks passed ==="
|
||||
volumeMounts:
|
||||
- name: workspace
|
||||
mountPath: /workspace
|
||||
- name: cargo-cache
|
||||
mountPath: /cache/cargo
|
||||
resources:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
|
||||
# === Bench Matrix ===
|
||||
# Competitive benchmarks: pdftract vs pdfminer.six, pypdf, pdfplumber
|
||||
# Runs hyperfine against 50-PDF corpus (25 vector + 25 raster)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue