Skip to content

CI: remove dead upload_pypi job from reusable workflow and drop unnecessary id-token permission #824

@nikagra

Description

@nikagra

Context

PR #820 added permissions: id-token: write to the test-wheels-build job in build-test.yml to work around a GitHub Actions parse-time validation issue.

The problem: build-test.yml is triggered by pull_request, which implicitly sets id-token: none. The reusable workflow lib-build-and-push.yml contains an upload_pypi job that declares id-token: write. GitHub validates permissions statically — before evaluating any if: conditions — so even though upload: false means upload_pypi never runs, the caller must still grant the permission the job declares.

@Lorak-mmk correctly pointed out in the PR review:

"This also gives unnecessary permissions to the whole workflow, no? This job could run perfectly well without write permissions, but now it has them. I wonder if there are other possible solutions, for example splitting the upload job into a separate file."

Root Cause

The upload_pypi job inside lib-build-and-push.yml is effectively dead code. None of the four callers ever pass upload: true:

Caller upload: passed Has own publish job?
build-test.yml false No
build-pre-release.yml (default = false) No
build-push.yml false Yes
publish-manually.yml false Yes

build-push.yml and publish-manually.yml already implement publishing as separate jobs in the caller workflow. This is a deliberate workaround for pypa/gh-action-pypi-publish#166: PyPI Trusted Publishing embeds the caller workflow path in the OIDC token, so publishing must happen in the caller workflow, not inside a reusable workflow.

Solution

  1. Remove the upload_pypi job and upload input from lib-build-and-push.yml
  2. Rename lib-build-and-push.ymllib-build.yml (it no longer handles uploading)
  3. Update all caller workflows (build-test.yml, build-push.yml, publish-manually.yml, build-pre-release.yml) to reference the new path
  4. Remove permissions: id-token: write and with: upload: false from build-test.yml — no longer needed
  5. Update the TODO comments in build-push.yml and publish-manually.yml — the separate publish job is now the intended design, not a temporary workaround

Result

  • build-test.yml no longer grants any elevated permissions (principle of least privilege restored)
  • The reusable workflow contains only what it actually does: building wheels and the source distribution
  • Publishing remains a caller-side responsibility, consistent with how PyPI Trusted Publishing works

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions