66 branches : " *"
77 workflow_dispatch :
88
9+ permissions :
10+ contents : read
11+ id-token : write
12+ pull-requests : write
13+
914concurrency :
1015 group : ${{ github.workflow }}-${{ github.ref }}
1116 cancel-in-progress : true
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