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
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions