Repository navigation
168 lines (146 loc) · 5.93 KB
/
Copy pathci.yml
File metadata and controls
168 lines (146 loc) · 5.93 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
# AgentKthx CI — runs the full pytest suite on every push and PR.
#
# Audit TEST-02 (R07.01): the project has 16 PyPI releases across 0.6.x–0.7.x
# with substantial per-release churn, and prior to this workflow the 980-test
# suite ran only on maintainer machines. This workflow stands up the same
# command developers run locally (`pip install -e .[dev] && pytest`) on a
# 4-version Python matrix covering the project's declared floor (>=3.11).
#
# Audit ARCH-02 (R07.01): the `coverage` job runs the suite with
# `pytest --cov=agentkthx --cov-report=term-missing` and uploads the report
# as a build artifact. No threshold is enforced yet — the baseline is
# recorded as a starting point. Coverage is in a separate job so the
# fast `test` matrix (2-3s) is not slowed by the 5s cov-instrumented run.
#
# Design notes:
# - Zero runtime deps means `pip install -e .[dev]` only fetches the dev
# extras (pytest, pytest-cov, black, ruff) — install is fast (~5s) and
# reproducible.
# - The `test` job does NOT run with coverage — keeps PR feedback at ~3s
# instead of ~5s. Coverage runs once per push (Python 3.12 only).
# - Audit TEST-06 (R07.15): a separate `lint` job runs `ruff check` +
# `black --check` so style drift is surfaced on every push instead of
# being caught by review. It launched non-blocking because the repo
# predates the tooling (~2.8k findings of drift). The drift has since
# been burned down to zero (auto-fix + black reformat + hand fixes,
# including two latent dict-key bugs and a missing Path import the
# linters caught), so the job is now a REQUIRED check — new drift
# fails CI outright. Linter versions are pinned: bump them deliberately
# after validating the new rule set locally.
name: CI
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
# Cancel in-flight runs for the same ref when a new commit lands — keeps PR
# feedback fast and avoids burning Actions minutes on superseded pushes.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test:
name: pytest (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: pyproject.toml
- name: Install package + dev extras
# Zero runtime deps — install is fast and deterministic.
run: |
python -m pip install --upgrade pip
pip install -e .[dev]
- name: Run pytest
# Fast path: no coverage instrumentation. Suite runs in ~2-3s.
# Coverage runs in the separate `coverage` job below.
run: python -m pytest tests/ -q
coverage:
name: coverage (Python 3.12)
runs-on: ubuntu-latest
# Only push the badge back on push to main/master — skip on PRs
# (forks can't write to the base repo, and PR branches shouldn't get badge commits)
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install package + dev extras
run: |
python -m pip install --upgrade pip
pip install -e .[dev]
- name: Run pytest with coverage
run: |
python -m pytest tests/ -q \
--cov=agentkthx \
--cov-report=term-missing \
--cov-report=xml:coverage.xml
- name: Generate coverage badge
run: |
pip install "setuptools<81" coverage-badge
coverage-badge -f -o coverage.svg
- name: Verify changed files
uses: tj-actions/verify-changed-files@v20
id: changed
with:
files: coverage.svg
- name: Commit & push badge
if: steps.changed.outputs.files_changed == 'true' && github.event_name == 'push'
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add coverage.svg
git commit -m "chore: update coverage badge [skip ci]"
git push
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-${{ github.sha }}
path: coverage.xml
retention-days: 30
if-no-files-found: error
lint:
name: lint (ruff + black)
runs-on: ubuntu-latest
# TEST-06 (R07.15), follow-up: launched non-blocking while the
# pre-tooling drift was burned down (see header note). Gating now —
# the tree is lint-clean and pyproject documents the two intentional
# suppressions (E501 → black; per-file E402 for setup-then-import
# modules). Keep it that way: style regressions should fail CI,
# not review.
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install linters
# Lint-only job: no package install needed. Versions are PINNED to
# the pair the burn-down was validated against — a new ruff release
# can add rules, and with the job now gating that should be a
# deliberate bump (validate locally first), not a surprise red run.
run: python -m pip install ruff==0.16.9 black==26.5.1
- name: Ruff check
run: python -m ruff check agentkthx/ tests/
- name: Black check
run: python -m black --check agentkthx/ tests/