Repository navigation
138 lines (133 loc) · 5.51 KB
/
Copy pathci.yml
File metadata and controls
138 lines (133 loc) · 5.51 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
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
# Cancel in-flight runs on the same PR ref when a new push lands.
# Push-to-main runs always complete (cancel-in-progress only on PRs).
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
lint-commits:
name: lint commit messages (no AI-tool attribution)
runs-on: ubuntu-latest
timeout-minutes: 2
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# PR: scan only new commits the PR introduces (base..head).
# Push to main: scan the just-pushed commits (before..after).
# fetch-depth=0 ensures both refs are available.
fetch-depth: 0
- name: scan new commit messages
env:
GH_EVENT: ${{ github.event_name }}
BEFORE_SHA: ${{ github.event.before }}
BASE_REF: ${{ github.event.pull_request.base.sha }}
HEAD_REF: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
if [ "$GH_EVENT" = "pull_request" ]; then
RANGE="${BASE_REF}..${HEAD_REF}"
else
# push event; before is 0..0 on first push or branch creation
if [ -z "${BEFORE_SHA:-}" ] || [ "$BEFORE_SHA" = "0000000000000000000000000000000000000000" ]; then
RANGE="HEAD~1..HEAD"
else
RANGE="${BEFORE_SHA}..HEAD"
fi
fi
echo "Scanning commit-message bodies in $RANGE"
# Collect messages joined by NUL bytes; grep -P for fixed alternation.
BODIES=$(git log --format='%B%x00' "$RANGE" || true)
if [ -z "$BODIES" ]; then
echo " (no commits in range)"
exit 0
fi
PATTERN='(Co-Authored-By:|🤖|Generated with Claude|Generated with \[Cursor\]|noreply@anthropic\.com)'
if printf '%s' "$BODIES" | grep -i -E -q "$PATTERN"; then
echo "::error::AI-tool attribution detected in new commit messages."
echo "Offending lines:"
printf '%s' "$BODIES" | grep -i -n -E "$PATTERN" || true
echo ""
echo "Strip Co-Authored-By trailers, 🤖, 'Generated with ...',"
echo "and noreply@anthropic.com refs, then force-push the fixed range."
exit 1
fi
echo " clean"
ratch:
name: ratch check
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
cache: pip
- name: install ratch and package
run: pip install ratch==0.1.6 -e .
- name: ratch check
run: python -m ratch check
test:
name: test py${{ matrix.python }} / ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
python: ["3.11", "3.12", "3.13"]
os: [ubuntu-latest, macos-latest]
# Steps below mirror ./build.sh check, inlined for per-step Actions UI
# granularity AND because coverage requires extra pytest flags not in
# the local `test` task. CONTRIBUTING.md states the parity intentionally.
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python }}
cache: pip
- name: install
# [sandbox] pulls the pure-Python Landlock/seccomp bindings only on
# Linux (their sys_platform=='linux' markers make this a no-op on
# macOS), so the Linux legs exercise real seccomp enforcement in the
# kill-tests; test_kill_tests_not_skipped.py fails loudly if a
# capable runner ever skips them instead of asserting the denial.
run: pip install -e ".[dev,sandbox]"
- name: ruff
run: |
ruff check .
ruff format --check .
- name: vulture (dead-code scan)
# Config in [tool.vulture]; exits nonzero on any finding. No pipe — a
# `| tail` would swallow the exit code and let dead code through.
run: vulture
- name: tests with coverage
# Two passes so `serial` tests (install process-wide signal handlers /
# self-signals -- unsafe to share an xdist worker process) still run
# every time: parallel set + serial set == the full suite, mirroring
# ./build.sh test. pytest-cov 7.x auto-combines worker coverage data.
run: |
pytest -q --ignore=tests/e2e --ignore=tests/literate \
-n auto --dist worksteal -m "not serial" --cov --cov-report=xml --cov-report=term
pytest -q --ignore=tests/e2e --ignore=tests/literate -m serial --cov --cov-append --cov-report=xml --cov-report=term
- name: docs CI gate
run: |
python -m agent_runner._docgen
git diff --exit-code docs/
- name: literate quickstart
run: pytest tests/literate/ -q
- name: upload coverage
if: matrix.python == '3.12' && matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
with:
files: ./coverage.xml
fail_ci_if_error: false
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}