-
Notifications
You must be signed in to change notification settings - Fork 0
196 lines (186 loc) · 9.17 KB
/
Copy pathci.yaml
File metadata and controls
196 lines (186 loc) · 9.17 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
name: CI
on:
push:
branches: [main]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Actions are pinned to full commit SHAs (repo policy: sha_pinning_required).
jobs:
rust:
name: Rust (fmt / clippy / test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- run: cargo fmt --check
- run: cargo clippy --all-targets -- -D warnings
# --locked fails if Cargo.lock is out of sync with Cargo.toml (e.g. a version
# bump that forgot to regenerate the lock), catching it before a release tag.
- run: cargo test --locked
python:
name: Python (ruff / mypy / pytest) - locked
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable (uv sync builds the PyO3 ext)
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
# Pin uv so CI resolves uv.lock identically to local -- required for the
# `uv sync --locked` guard to be reliable (lock revision is uv-version-tied).
version: "0.11.16"
python-version: ${{ matrix.python-version }}
# Route PyPI installs through Takumi Guard (blocks known-malicious packages
# before they execute; sets UV_INDEX_URL for this job). Blocking-only mode,
# no account needed. Must precede any uv/pip install.
- uses: flatt-security/setup-takumi-guard-pypi@733047c120b6377fa05fb77f714df8d8cd3a41a9 # v1.0.1
# --locked fails if uv.lock drifts from pyproject.toml (e.g. a version bump
# that forgot to sync the lock), the uv-side counterpart to cargo --locked.
- run: uv sync --locked
- run: cargo build --bin firepact # the binary front-end (py<->rust parity test)
- run: uv run ruff check .
- run: uv run ruff format --check .
- run: uv run mypy .
- run: uv run pytest # unit + integration (exact golden on locked pydantic)
pydantic-matrix:
name: Pydantic drift canary
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
pydantic: ["2.9.*", "2.10.*", "2.11.*", "2.12.*", "2.13.*"]
env:
# Skip the exact schema-layer golden (frozen against the locked pydantic);
# the emit-layer golden + semantic checks must still hold across versions.
FIREPACT_PYDANTIC_MATRIX: "1"
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
# Pin uv so CI resolves uv.lock identically to local -- required for the
# `uv sync --locked` guard to be reliable (lock revision is uv-version-tied).
version: "0.11.16"
python-version: "3.12"
# Route PyPI installs through Takumi Guard (blocks known-malicious packages
# before they execute; sets UV_INDEX_URL for this job). Blocking-only mode,
# no account needed. Must precede any uv/pip install.
- uses: flatt-security/setup-takumi-guard-pypi@733047c120b6377fa05fb77f714df8d8cd3a41a9 # v1.0.1
- run: uv sync
- name: Run tests against pydantic ${{ matrix.pydantic }}
run: uv run --with "pydantic==${{ matrix.pydantic }}" pytest tests/unit tests/integration
frontend-typecheck:
name: Frontend tsc (generated types)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
# Rust rewrite is distributed via the canary channel only; canary is a
# moving tag, so never reuse a cached executable.
bun-version: canary
no-cache: true
- run: cargo build
- name: Generate TypeScript from the contract fixture
run: ./target/debug/firepact emit fixtures/message.bundle.json > tests/e2e/frontend/generated.ts
- name: Type-check the consumer against the generated types
working-directory: tests/e2e/frontend
run: |
bun install
bunx tsc --noEmit
compat:
name: Compatibility gate (FULL_TRANSITIVE)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
# Pin uv so CI resolves uv.lock identically to local -- required for the
# `uv sync --locked` guard to be reliable (lock revision is uv-version-tied).
version: "0.11.16"
python-version: "3.13"
- uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
# Route PyPI installs through Takumi Guard (blocks known-malicious packages
# before they execute; sets UV_INDEX_URL for this job). Blocking-only mode,
# no account needed. Must precede any uv/pip install.
- uses: flatt-security/setup-takumi-guard-pypi@733047c120b6377fa05fb77f714df8d8cd3a41a9 # v1.0.1
- run: uv sync
- name: Gate the example contract against schemas/ history
run: just example-compat
e2e:
name: E2E (Firestore emulator + onSnapshot)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
# Pin uv so CI resolves uv.lock identically to local -- required for the
# `uv sync --locked` guard to be reliable (lock revision is uv-version-tied).
version: "0.11.16"
python-version: "3.13"
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
# Rust rewrite is distributed via the canary channel only; canary is a
# moving tag, so never reuse a cached executable.
bun-version: canary
no-cache: true
- uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.2.0 (firestore emulator needs a JVM)
with:
distribution: temurin
java-version: "21"
- uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
- run: npm install -g firebase-tools
# Route PyPI installs through Takumi Guard (blocks known-malicious packages
# before they execute; sets UV_INDEX_URL for this job). Blocking-only mode,
# no account needed. Must precede any uv/pip install.
- uses: flatt-security/setup-takumi-guard-pypi@733047c120b6377fa05fb77f714df8d8cd3a41a9 # v1.0.1
- run: uv sync
- run: bun install
working-directory: tests/e2e/frontend
- name: Run the E2E suite under the Firestore emulator
run: >-
firebase emulators:exec --only firestore --project demo-firepact
--config tests/e2e/firebase.json "just test-e2e"
markdown:
name: Markdown lint + link check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
# Rust rewrite is distributed via the canary channel only; canary is a
# moving tag, so never reuse a cached executable.
bun-version: canary
no-cache: true
- uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
- run: just lint-md
# Relative-link integrity (files + heading anchors); python3 is preinstalled.
- run: just check-links
semgrep:
name: Semgrep (py / rust / ts + project rules)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
- name: Install semgrep
run: pipx install semgrep
# Registry language packs (p/python, p/rust, p/typescript) + any local rules;
# findings fail the job. Needs network to fetch the registry rulesets.
- name: Run semgrep
run: just semgrep