Skip to content

Commit a6167e5

Browse files
committed
ci: pin lint tooling, install a dev requirements set, and skip the eval gate without secrets
1 parent e2d1be6 commit a6167e5

5 files changed

Lines changed: 44 additions & 16 deletions

File tree

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ jobs:
4343
cache: pip
4444
cache-dependency-path: |
4545
requirements.txt
46-
requirements-local.txt
46+
requirements-dev.txt
4747
4848
- name: Install dependencies
49-
# The Vercel-safe set plus test tooling. torch is excluded: it is a
50-
# multi-minute install for tests that do not exercise it.
49+
# requirements-dev.txt pulls in requirements.txt and adds pinned test
50+
# and lint tooling. torch is excluded: it is a multi-minute install for
51+
# tests that do not exercise it.
5152
run: |
5253
python -m pip install --upgrade pip
53-
pip install -r requirements.txt
54-
pip install pytest pytest-asyncio anyio ruff
54+
pip install -r requirements-dev.txt
5555
5656
- name: Lint
5757
run: ruff check app scripts tests

.github/workflows/evals.yml

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,45 @@ jobs:
5050
TOLERANCE: ${{ github.event.inputs.tolerance || '-0.03' }}
5151

5252
steps:
53+
- name: Check that the eval secrets are configured
54+
id: secrets
55+
# The eval gate needs a database and an API key. Until those secrets
56+
# exist the whole job is skipped with an explanatory notice rather than
57+
# failing — a workflow that goes red because an optional secret is
58+
# missing is a workflow people learn to ignore, and this one is meant
59+
# to be trusted enough to block a merge.
60+
run: |
61+
if [ -z "${{ secrets.EVAL_DATABASE_URL }}" ] || [ -z "${{ secrets.OPENAI_API_KEY }}" ]; then
62+
echo "configured=false" >> "$GITHUB_OUTPUT"
63+
echo "::notice title=Eval gate skipped::Set the EVAL_DATABASE_URL and OPENAI_API_KEY repository secrets to enable it. See the README."
64+
else
65+
echo "configured=true" >> "$GITHUB_OUTPUT"
66+
fi
67+
5368
- uses: actions/checkout@v4
69+
if: steps.secrets.outputs.configured == 'true'
5470
with:
5571
# compare.py reads the branch name from git, so it needs real refs.
5672
fetch-depth: 0
5773

5874
- uses: actions/setup-python@v5
75+
if: steps.secrets.outputs.configured == 'true'
5976
with:
6077
python-version: "3.12"
6178
cache: pip
6279

6380
- name: Install dependencies
81+
if: steps.secrets.outputs.configured == 'true'
6482
run: |
6583
python -m pip install --upgrade pip
6684
pip install -r requirements.txt
6785
6886
- name: Migrate
87+
if: steps.secrets.outputs.configured == 'true'
6988
run: alembic upgrade head
7089

7190
- name: Run evals
91+
if: steps.secrets.outputs.configured == 'true'
7292
# The corpus is assumed already ingested into the shared eval database.
7393
# Re-ingesting on every PR would cost more than the eval itself and add
7494
# embedding drift as a confounder — the corpus is a fixture, not part of
@@ -82,6 +102,7 @@ jobs:
82102
--notes "PR #${{ github.event.pull_request.number }}"
83103
84104
- name: Compare against main
105+
if: steps.secrets.outputs.configured == 'true'
85106
id: compare
86107
run: |
87108
python -m app.evals.compare \
@@ -91,7 +112,7 @@ jobs:
91112
| tee evals/out/comparison.txt
92113
93114
- name: Comment the results on the PR
94-
if: always() && github.event_name == 'pull_request'
115+
if: always() && steps.secrets.outputs.configured == 'true' && github.event_name == 'pull_request'
95116
uses: actions/github-script@v7
96117
with:
97118
script: |
@@ -116,7 +137,7 @@ jobs:
116137
});
117138
118139
- name: Upload artefacts
119-
if: always()
140+
if: always() && steps.secrets.outputs.configured == 'true'
120141
uses: actions/upload-artifact@v4
121142
with:
122143
name: eval-run-${{ github.run_id }}

requirements-dev.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Test and lint tooling. Pinned, and deliberately separate from
2+
# requirements-local.txt so CI can install it without pulling torch.
3+
#
4+
# ruff's version is pinned because `ruff format --check` is a CI gate: an
5+
# unpinned formatter means a new ruff release reformats something and the build
6+
# goes red with no code change. A formatter that fails on days you did not touch
7+
# the repo is a formatter people learn to ignore.
8+
9+
-r requirements.txt
10+
11+
pytest==8.3.4
12+
pytest-asyncio==0.25.0
13+
anyio==4.7.0
14+
ruff==0.16.0

requirements-local.txt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,7 @@
88
#
99
# Install with: pip install -r requirements.txt -r requirements-local.txt
1010

11-
-r requirements.txt
11+
-r requirements-dev.txt
1212

1313
sentence-transformers==3.3.1
1414
torch==2.5.1
15-
16-
# Test + tooling
17-
pytest==8.3.4
18-
pytest-asyncio==0.25.0
19-
anyio==4.7.0
20-
ruff==0.8.4

scripts/smoke_test.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,7 @@ async def check_query(use_llm: bool) -> None:
279279
check(
280280
"claims verified and supported by their citations",
281281
verification.get("verified", False) and coverage >= 0.99,
282-
f"coverage {coverage:.2f}, "
283-
f"unsupported {verification.get('unsupported_claims') or 'none'}",
282+
f"coverage {coverage:.2f}, unsupported {verification.get('unsupported_claims') or 'none'}",
284283
)
285284

286285
confidence = response.get("confidence") or {}

0 commit comments

Comments
 (0)