Skip to content

Commit cb77802

Browse files
paddymulclaude
andauthored
ci: publish dev wheel to TestPyPI on every PR (#537)
Adds a PublishTestPyPI job that builds a .dev{run_id} versioned wheel and publishes it to TestPyPI via trusted publishing (OIDC). Posts a PR comment with pip/uv install commands, updated in-place on new pushes. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8897a64 commit cb77802

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

.github/workflows/checks.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ on:
66
branches: "*"
77
workflow_dispatch:
88

9+
permissions:
10+
contents: read
11+
id-token: write
12+
pull-requests: write
13+
914
concurrency:
1015
group: ${{ github.workflow }}-${{ github.ref }}
1116
cancel-in-progress: true
@@ -76,6 +81,13 @@ jobs:
7681
run: pnpm install --frozen-lockfile
7782
- name: Install the project
7883
run: uv sync --all-extras --dev
84+
- name: Patch version for TestPyPI
85+
if: github.event_name == 'pull_request'
86+
run: |
87+
BASE=$(grep -Po '^version = "\K[^"]+' pyproject.toml)
88+
DEV="${BASE}.dev${{ github.run_id }}"
89+
sed -i "s/^version = \".*\"/version = \"${DEV}\"/" pyproject.toml
90+
echo "Published version: ${DEV}"
7991
- name: Build JS extension + Python wheel
8092
run: ./scripts/full_build.sh
8193
- name: Upload build artifacts
@@ -88,6 +100,74 @@ jobs:
88100
./packages/buckaroo-js-core/dist/
89101
./packages/buckaroo-widget/dist/
90102
103+
PublishTestPyPI:
104+
name: Publish to TestPyPI
105+
if: >-
106+
github.event_name == 'pull_request' &&
107+
github.event.pull_request.head.repo.full_name == github.repository
108+
needs: [BuildWheel]
109+
runs-on: depot-ubuntu-latest
110+
timeout-minutes: 5
111+
environment: testpypi
112+
permissions:
113+
id-token: write
114+
pull-requests: write
115+
steps:
116+
- name: Download build artifacts
117+
uses: actions/download-artifact@v4
118+
with:
119+
name: buckaroo-build
120+
path: artifacts
121+
- name: Publish to TestPyPI
122+
uses: pypa/gh-action-pypi-publish@release/v1
123+
with:
124+
repository-url: https://test.pypi.org/legacy/
125+
packages-dir: artifacts/dist/
126+
- name: Comment on PR with install command
127+
uses: actions/github-script@v7
128+
with:
129+
script: |
130+
const fs = require('fs');
131+
const distFiles = fs.readdirSync('artifacts/dist');
132+
const wheel = distFiles.find(f => f.endsWith('.whl'));
133+
const version = wheel.match(/buckaroo-(.+?)-/)[1];
134+
const body = [
135+
'## :package: TestPyPI package published',
136+
'',
137+
'```bash',
138+
`pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo==${version}`,
139+
'```',
140+
'',
141+
'or with uv:',
142+
'',
143+
'```bash',
144+
`uv pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo==${version}`,
145+
'```',
146+
].join('\n');
147+
148+
const { data: comments } = await github.rest.issues.listComments({
149+
owner: context.repo.owner,
150+
repo: context.repo.repo,
151+
issue_number: context.issue.number,
152+
});
153+
const marker = '## :package: TestPyPI package published';
154+
const existing = comments.find(c => c.body.startsWith(marker));
155+
if (existing) {
156+
await github.rest.issues.updateComment({
157+
owner: context.repo.owner,
158+
repo: context.repo.repo,
159+
comment_id: existing.id,
160+
body,
161+
});
162+
} else {
163+
await github.rest.issues.createComment({
164+
owner: context.repo.owner,
165+
repo: context.repo.repo,
166+
issue_number: context.issue.number,
167+
body,
168+
});
169+
}
170+
91171
# ---------------------------------------------------------------------------
92172
# Source-level tests — operate on the codebase, no wheel needed
93173
# ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)