Skip to content

Commit 5301eb5

Browse files
rustyconoverclaude
andcommitted
CI: resolve latest haybarn at runtime; add Dependabot + auto-merge
- Drop the hardcoded HAYBARN_RELEASE pin; a resolve-haybarn job queries the latest haybarn release and feeds it to the whole matrix. - Commit uv.lock and install via 'uv sync --frozen' / 'uv run --frozen' so CI exercises locked versions and Dependabot's uv ecosystem has a bump target. - Add .github/dependabot.yml: github-actions weekly, Python deps (vgi-python / vgi-rpc via uv.lock) daily. - Add dependabot-auto-merge.yml: squash-merge green Dependabot PRs after CI passes (workflow_run-triggered, so no branch protection needed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3c73b44 commit 5301eb5

6 files changed

Lines changed: 647 additions & 34 deletions

File tree

.github/dependabot.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright 2026 Query Farm LLC - https://query.farm
2+
#
3+
# Automated dependency updates. github-actions keeps the workflow actions
4+
# current; uv bumps the Python dependencies recorded in uv.lock (driven by the
5+
# constraints in pyproject.toml). Updates are grouped to minimise PR noise and
6+
# auto-merged once CI is green (see .github/workflows/dependabot-auto-merge.yml).
7+
version: 2
8+
updates:
9+
- package-ecosystem: "github-actions"
10+
directory: "/"
11+
schedule:
12+
interval: "weekly"
13+
groups:
14+
github-actions:
15+
patterns: ["*"]
16+
17+
# The Python deps are the point of this repo's freshness (vgi-python /
18+
# vgi-rpc), so check daily — the most frequent interval Dependabot supports.
19+
- package-ecosystem: "uv"
20+
directory: "/"
21+
schedule:
22+
interval: "daily"
23+
groups:
24+
python:
25+
patterns: ["*"]

.github/workflows/ci.yml

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,23 @@ concurrency:
2121
group: ci-${{ github.ref }}
2222
cancel-in-progress: true
2323

24-
env:
25-
# Haybarn release providing the prebuilt haybarn-unittest binary. Must be
26-
# ABI-compatible with the community-published vgi extension. See ci/README.md.
27-
HAYBARN_RELEASE: haybarn-v1.5.3-rc10
28-
2924
jobs:
25+
# Resolve the latest published haybarn release once, so the whole matrix tests
26+
# the same version (and we never hardcode/pin it). haybarn is public, so the
27+
# default token can read it — including on Dependabot PRs.
28+
resolve-haybarn:
29+
runs-on: ubuntu-latest
30+
outputs:
31+
release: ${{ steps.r.outputs.release }}
32+
steps:
33+
- id: r
34+
run: |
35+
REL=$(gh release view --repo Query-farm-haybarn/haybarn --json tagName --jq .tagName)
36+
echo "release=$REL" >> "$GITHUB_OUTPUT"
37+
echo "Latest haybarn release: $REL"
38+
env:
39+
GH_TOKEN: ${{ github.token }}
40+
3041
unit:
3142
strategy:
3243
fail-fast: false
@@ -37,9 +48,10 @@ jobs:
3748
- uses: actions/checkout@v4
3849
- uses: astral-sh/setup-uv@v6
3950
- name: Run unit tests
40-
run: uv run --python 3.13 pytest tests/ -q
51+
run: uv run --frozen --python 3.13 pytest tests/ -q
4152

4253
integration:
54+
needs: resolve-haybarn
4355
strategy:
4456
fail-fast: false
4557
matrix:
@@ -56,10 +68,8 @@ jobs:
5668
- uses: actions/checkout@v4
5769
- uses: astral-sh/setup-uv@v6
5870

59-
- name: Install the easter worker
60-
run: |
61-
uv venv --python 3.13 .venv
62-
uv pip install --python .venv .
71+
- name: Install the easter worker (from the lockfile)
72+
run: uv sync --frozen --python 3.13
6373

6474
- name: Download haybarn-unittest
6575
run: |
@@ -70,14 +80,14 @@ jobs:
7080
mkdir -p hb && unzip -o -q haybarn-unittest.zip -d hb
7181
env:
7282
GH_TOKEN: ${{ github.token }}
83+
HAYBARN_RELEASE: ${{ needs.resolve-haybarn.outputs.release }}
7384

7485
- name: Resolve runner + worker paths
7586
run: |
76-
# The worker LOCATION is consumed by the (native) extension process,
77-
# so on Windows it must be a native path to the .exe launcher; the
78-
# unittest binary itself is exec'd by bash, so a POSIX path is fine.
7987
# Absolute paths: run-integration.sh cd's into a staging dir before
80-
# invoking the runner, so a relative path would not resolve.
88+
# invoking the runner, so relative paths would not resolve. The worker
89+
# LOCATION is consumed by the (native) extension process, so on Windows
90+
# it must be a native path to the .exe launcher.
8191
if [ "$RUNNER_OS" = "Windows" ]; then
8292
UNITTEST="$PWD/$(find hb -name 'haybarn-unittest.exe' -type f | head -1)"
8393
WORKER=$(cygpath -w "$PWD/.venv/Scripts/vgi-easter.exe")
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright 2026 Query Farm LLC - https://query.farm
2+
#
3+
# Auto-merge Dependabot PRs once CI is green. Triggered by the CI workflow
4+
# *completing* (workflow_run), so the merge only happens after the unit +
5+
# extension suites pass on all three OSes — without requiring branch protection
6+
# (direct pushes to main keep working). Squash-merges and deletes the branch.
7+
name: Dependabot auto-merge
8+
9+
on:
10+
workflow_run:
11+
workflows: ["CI"]
12+
types: [completed]
13+
14+
permissions:
15+
contents: write
16+
pull-requests: write
17+
18+
jobs:
19+
auto-merge:
20+
# Only for a successful CI run that was itself triggered by a Dependabot PR.
21+
if: >
22+
github.event.workflow_run.event == 'pull_request' &&
23+
github.event.workflow_run.conclusion == 'success' &&
24+
startsWith(github.event.workflow_run.head_branch, 'dependabot/')
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Squash-merge the green Dependabot PR
28+
env:
29+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30+
REPO: ${{ github.repository }}
31+
BRANCH: ${{ github.event.workflow_run.head_branch }}
32+
run: |
33+
PR=$(gh pr list --repo "$REPO" --head "$BRANCH" --state open \
34+
--json number,author \
35+
--jq '.[] | select(.author.login == "app/dependabot") | .number' | head -1)
36+
if [ -z "$PR" ]; then
37+
echo "No open Dependabot PR for $BRANCH — nothing to merge."
38+
exit 0
39+
fi
40+
echo "Merging Dependabot PR #$PR ($BRANCH)"
41+
gh pr merge "$PR" --repo "$REPO" --squash --delete-branch

CLAUDE.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,14 @@ uv run --python 3.13 easter_worker.py
8282
# Run the HTTP server
8383
VGI_SIGNING_KEY=dev uv run --python 3.13 serve.py --host 0.0.0.0 --port 8000
8484

85-
# Unit tests (pytest). vgi-python resolves from PyPI; -o "addopts=" guards
86-
# against any inherited pytest addopts.
87-
uv run --python 3.13 \
88-
--with pytest --with vgi-python \
89-
pytest tests/ --rootdir=. -o "addopts=" -q
85+
# Unit tests (pytest), installing exactly what uv.lock pins.
86+
uv run --frozen --python 3.13 pytest tests/ -q
9087
```
9188

92-
There is no `.venv` checked in (it's gitignored); the `uv run --with ...`
93-
invocation above resolves a throwaway environment. If you create a project venv,
94-
prefer `.venv/bin/pytest` over bare `pytest`.
89+
`uv.lock` is committed (dev/CI reproducibility + the Dependabot `uv` update
90+
target); it does not affect end users, who install via the `pyproject.toml`
91+
ranges. `.venv/` is gitignored. `uv sync --frozen --python 3.13` materialises
92+
the locked environment (and the `vgi-easter` console script) under `.venv/`.
9593

9694
## Testing
9795

@@ -126,12 +124,17 @@ PyPI without a green extension run. See `ci/README.md`.
126124

127125
### CI / publishing
128126

129-
- `.github/workflows/ci.yml` — unit tests + extension integration suite
130-
(reusable via `workflow_call`).
127+
- `.github/workflows/ci.yml` — unit tests + extension integration suite on
128+
Linux, macOS, and Windows (reusable via `workflow_call`). A `resolve-haybarn`
129+
job picks the latest Haybarn release at run time (nothing pinned).
131130
- `.github/workflows/publish.yml` — on GitHub Release (or manual dispatch),
132131
runs `ci.yml` then `uv build && uv publish`. Token-based, no trusted
133132
publishing: needs the `PYPI_API_TOKEN` repo secret (passed as
134133
`UV_PUBLISH_TOKEN`).
134+
- `.github/dependabot.yml` — github-actions (weekly) + Python deps via `uv.lock`
135+
(daily). `.github/workflows/dependabot-auto-merge.yml` squash-merges green
136+
Dependabot PRs after CI passes (via `workflow_run`, so no branch protection is
137+
required and direct pushes to `main` still work).
135138

136139
## ATTACH syntax
137140

ci/README.md

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,34 @@ extension from the Haybarn community channel:
3838
## Run it locally
3939

4040
```bash
41-
uv venv .venv --python 3.13 && uv pip install --python .venv .
42-
gh release download haybarn-v1.5.3-rc10 --repo Query-farm-haybarn/haybarn \
41+
uv sync --frozen --python 3.13
42+
REL=$(gh release view --repo Query-farm-haybarn/haybarn --json tagName --jq .tagName)
43+
gh release download "$REL" --repo Query-farm-haybarn/haybarn \
4344
--pattern 'haybarn_unittest-osx-arm64.zip' --output /tmp/hb.zip --clobber
4445
unzip -o /tmp/hb.zip -d /tmp/hb
4546
HAYBARN_UNITTEST=/tmp/hb/haybarn-unittest \
4647
VGI_EASTER_WORKER="$PWD/.venv/bin/vgi-easter" \
4748
ci/run-integration.sh
4849
```
4950

50-
(Swap the asset pattern for your platform: `haybarn_unittest-linux-amd64.zip`
51-
on CI.)
51+
(Swap the asset pattern for your platform: `haybarn_unittest-linux-amd64.zip`,
52+
`haybarn_unittest-windows-amd64.zip`.)
5253

53-
## Version pin (and its coupling)
54+
## Haybarn version (resolved, not pinned)
5455

55-
`HAYBARN_RELEASE` in [`ci.yml`](../.github/workflows/ci.yml) pins the Haybarn
56-
release supplying `haybarn-unittest`; it must be ABI-compatible with the
57-
community-published `vgi` extension. The vgi extension is pulled live from the
56+
The `resolve-haybarn` job in [`ci.yml`](../.github/workflows/ci.yml) queries the
57+
**latest** published Haybarn release at run time and feeds that one tag to the
58+
whole matrix — nothing is hardcoded. The `vgi` extension is pulled live from the
5859
community channel (`INSTALL vgi FROM community`), which always serves the
59-
currently published build — so CI verifies the worker against what users can
60-
actually install today. Bump the pin deliberately and re-run the suite.
60+
currently published build, so CI verifies the worker against what users can
61+
actually install today. (The trade-off: a brand-new Haybarn release that isn't
62+
yet ABI-matched by the published `vgi` extension could break a run — that's the
63+
coupling to watch if the suite suddenly fails without a code change.)
64+
65+
## Dependency updates
66+
67+
[`.github/dependabot.yml`](../.github/dependabot.yml) keeps things current:
68+
`github-actions` weekly, and the Python deps (`vgi-python` / `vgi-rpc`, via
69+
`uv.lock`) **daily**. Green Dependabot PRs are squash-merged automatically by
70+
[`dependabot-auto-merge.yml`](../.github/workflows/dependabot-auto-merge.yml)
71+
after this CI workflow passes.

0 commit comments

Comments
 (0)