Repository navigation
139 lines (132 loc) · 6.35 KB
/
Copy pathci.yml
File metadata and controls
139 lines (132 loc) · 6.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# Rust and Python checks, and an audit of the dependencies and the workflows,
# on Linux, for every pull request and every push to main. Other systems join
# only when an issue needs them: Actions minutes are limited, and macOS and
# Windows runners count several times as much.
name: CI
on:
pull_request:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
# A push to a pull request supersedes its earlier run; every run on main finishes.
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
CARGO_TERM_COLOR: always
jobs:
rust:
name: Rust
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install the toolchain of rust-toolchain.toml
run: rustup toolchain install
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
with:
# Preserve rustup and tools installed outside cargo install.
cache-bin: false
- name: Format
run: cargo fmt --all --check
- name: Lint
run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
- name: Test
run: cargo test --workspace --all-features --locked
python:
name: Python ${{ matrix.python }}
timeout-minutes: 20
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# The floor of the abi3-py311 extension, the newest CPython, and its
# free-threaded build, for which PyO3 builds a version-specific
# extension (DESIGN.md section 4.6).
python: ["3.11", "3.15", "3.15t"]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install the toolchain of rust-toolchain.toml
run: rustup toolchain install
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
with:
# Keep one cache per interpreter: PyO3 rebuilds for each.
key: python-${{ matrix.python }}
# Preserve rustup and tools installed outside cargo install.
cache-bin: false
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
with:
version: "0.13.7"
cache-suffix: python-${{ matrix.python }}
- name: Install qpdf and poppler
# The consistency harness checks saved documents with qpdf, and the
# embedded font tests compare poppler's render with hayro's.
run: sudo apt-get update && sudo apt-get install --yes --no-install-recommends qpdf poppler-utils
- name: Build and install
# Install the wheel rather than an editable build, so that the tests
# import what a release would ship.
run: uv sync --locked --no-editable-package pyropdf --python ${{ matrix.python }}
- name: Lint
run: uv run --no-sync ruff check .
- name: Format
run: uv run --no-sync ruff format --check .
- name: Type check
# ty checks the Python 3.11 floor from project.requires-python.
run: uv run --no-sync ty check
- name: Test
# The tests include the check that the crates' dependencies follow
# DESIGN.md section 11, which runs cargo metadata.
env:
PYROPDF_REQUIRE_QPDF: "1"
run: uv run --no-sync pytest -rs
- name: Validate the PDF/A and PDF/UA corpora and their saves with veraPDF
# One Python suffices: the saved bytes do not depend on it. The
# runner's Java runs the jars, pinned by their SHA-256; the Arlington
# build checks each file against the Arlington PDF Model.
if: matrix.python == '3.11'
env:
VERAPDF_URL: https://repo1.maven.org/maven2/org/verapdf/apps/greenfield-apps/1.28.2/greenfield-apps-1.28.2.jar
VERAPDF_SHA256: 687d4d8bcfec48c9f7e931cf78ed061f1eeccfba55d4cdc000ba9b4d8aa46ce6
ARLINGTON_URL: https://repo1.maven.org/maven2/org/verapdf/apps/greenfield-apps-arlington/1.28.2/greenfield-apps-arlington-1.28.2.jar
ARLINGTON_SHA256: a780142be33c9ce00a0fd075c6d7b706074a01e87aa5c7d7328db4ff345a4464
run: |
mkdir -p target/verapdf
curl --fail --silent --show-error --location --output target/verapdf/greenfield-apps.jar "$VERAPDF_URL"
curl --fail --silent --show-error --location --output target/verapdf/greenfield-apps-arlington.jar "$ARLINGTON_URL"
echo "$VERAPDF_SHA256 target/verapdf/greenfield-apps.jar" | sha256sum --check --strict
echo "$ARLINGTON_SHA256 target/verapdf/greenfield-apps-arlington.jar" | sha256sum --check --strict
uv run --no-sync python tools/verapdf.py --jar target/verapdf/greenfield-apps.jar \
--arlington target/verapdf/greenfield-apps-arlington.jar
- name: Read every save of the corpus with pdf.js
# pdf.js is a development-only reader oracle (tools/oracles.py); the
# runner's Node installs it from tools/pdfjs's lockfile without
# install scripts. Its optional canvas package provides the DOMMatrix
# that pdf.js needs in Node.
if: matrix.python == '3.11'
run: |
node --version
npm ci --ignore-scripts --no-audit --no-fund --prefix tools/pdfjs
uv run --no-sync python tools/oracles.py --readers pdfjs
audit:
name: Audit
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install the pinned cargo-audit and actionlint
id: tools
run: bash tools/install_audit_tools.sh
- name: Audit Cargo.lock against the RustSec advisory database
# Only the workspace's Cargo.lock, which pins what ships: no release
# builds the measurement workspaces under evidence/. Warnings fail
# too, such as an unmaintained, unsound, or yanked crate. Through
# `cargo audit`, rustup would first install the toolchain of
# rust-toolchain.toml, which the audit does not need.
run: cargo-audit audit --deny warnings
- name: Validate the workflows
# Run after a failed audit too, so that one run reports both. The
# shellcheck and pyflakes that actionlint would call are not pinned.
if: ${{ !cancelled() && steps.tools.outcome == 'success' }}
run: actionlint -shellcheck= -pyflakes=