Skip to content

Commit b5c2871

Browse files
uipreligaclaude
andcommitted
ci: address review — SHA-pin release actions + fail-loud dev-version stamp
Two medium findings from the PR review: - [security] The wheel/sdist now published to PUBLIC PyPI is built in the release job, which pulled actions via mutable tags (setup-uv@v4, docker/{setup-buildx,login,build-push}@vn). A repointed tag / upstream takeover would reach every `pip install coder-eval` user, in a job that also holds RELEASE_APP_PRIVATE_KEY and the Azure PAT. Pin all four to full commit SHAs (setup-uv now matches publish-testpypi.yml). - [resilience] The TestPyPI dev-version stamp used re.sub, which returns the text unchanged (rc=0) on a version-line format drift, silently publishing the base version -> TestPyPI collision masked by skip-existing, so the dry run passes green having validated nothing. Switch to re.subn and SystemExit when the match count != 1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 28e3ac4 commit b5c2871

2 files changed

Lines changed: 11 additions & 5 deletions

File tree

‎.github/workflows/publish-testpypi.yml‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,13 @@ jobs:
7373
):
7474
p = pathlib.Path(path)
7575
key = "version" if path.endswith("toml") else "__version__"
76-
p.write_text(re.sub(pat, f'{key} = "${DEV_VERSION}"', p.read_text(), count=1))
76+
# re.subn (not re.sub) so a version-line format drift aborts loudly
77+
# instead of silently no-op'ing (rc=0) and publishing a stale/base
78+
# version that then collides on TestPyPI (masked by skip-existing).
79+
new, n = re.subn(pat, f'{key} = "${DEV_VERSION}"', p.read_text(), count=1)
80+
if n != 1:
81+
raise SystemExit(f"version pattern did not match {path} (matched {n}); refusing to publish a stale/colliding artifact")
82+
p.write_text(new)
7783
PY
7884
echo "Stamped dev version: ${DEV_VERSION}"
7985

‎.github/workflows/release.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ jobs:
7979
python-version: "3.13"
8080

8181
- name: Install uv
82-
uses: astral-sh/setup-uv@v4
82+
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0
8383
with:
8484
enable-cache: true
8585

@@ -161,19 +161,19 @@ jobs:
161161

162162
- name: Set up Docker Buildx
163163
if: steps.release.outputs.version != ''
164-
uses: docker/setup-buildx-action@v3
164+
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
165165

166166
- name: Log in to GHCR
167167
if: steps.release.outputs.version != ''
168-
uses: docker/login-action@v3
168+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
169169
with:
170170
registry: ghcr.io
171171
username: ${{ github.actor }}
172172
password: ${{ secrets.GITHUB_TOKEN }}
173173

174174
- name: Build and push versioned agent image
175175
if: steps.release.outputs.version != ''
176-
uses: docker/build-push-action@v6
176+
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
177177
with:
178178
context: .
179179
file: docker/Dockerfile

0 commit comments

Comments
 (0)