Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 1, 2025

PyPI rejected the OIDC trusted publisher flow with invalid-publisher error because the workflow's environment: pypi block added claims that didn't match PyPI's trusted publisher configuration.

Changes

  • Remove environment: pypi block to eliminate claim mismatch
  • Add password: ${{ secrets.PYPI_API_TOKEN }} to use explicit API token auth
  • Add id-token: write to top-level permissions
  • Add contents: read to job-level permissions
  • Tighten conditional to github.event_name == 'release' && github.event.action == 'published'

Required Setup

After merge, create repository secret PYPI_API_TOKEN with a PyPI API token scoped to the numta package.

Alternatively, reconfigure PyPI trusted publisher to match this repository/workflow without environment claims.

Original prompt

Problem

GitHub Actions run (job 56800936197) failed with PyPI trusted publishing error: "invalid-publisher: valid token, but no corresponding publisher (Publisher with matching claims was not found)". This indicates PyPI rejected the OIDC/trusted-publisher flow because the GitHub OIDC claims did not match a configured trusted publisher on PyPI. The current workflow (.github/workflows/publish-to-pypi.yml at ref 951bd50) uses the pypa/gh-action-pypi-publish action with OIDC by default (no password provided), and also defines an environment 'pypi' which can add claims that must match PyPI configuration.

Goal

Make the workflow reliably publish to PyPI by using an explicit PyPI API token stored in repository secrets, and ensure appropriate permissions are set. This avoids relying on PyPI trusted publisher configuration which currently doesn't match and causes the invalid-publisher error.

Changes to make

  1. Update .github/workflows/publish-to-pypi.yml to:

    • Add id-token: write to top-level permissions (keeps OIDC capability if required elsewhere).
    • Remove the environment: pypi block from the publish job (prevents environment claims from being included and reduces mismatch risk).
    • Ensure the publish job has permissions: id-token: write and contents: read.
    • Provide the PyPI API token to pypa/gh-action-pypi-publish action via password: ${{ secrets.PYPI_API_TOKEN }}.
    • Update the job conditional to explicitly check that the release action is 'published' to match the trigger.
  2. Add guidance in the PR description for the repository administrator to create a repository secret named PYPI_API_TOKEN with a PyPI API token created on https://pypi.org (Account > API tokens).

Modified file content

Replace the repository file .github/workflows/publish-to-pypi.yml with the following content (preserves build steps but updates publish job):

name: Publish to PyPI

on:
  release:
    types: [published]
  workflow_dispatch:  # Allow manual trigger

permissions:
  id-token: write
  contents: read

jobs:
  build:
    name: Build distribution
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0  # Fetch all history and tags for setuptools-scm

    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: "3.x"

    - name: Install build dependencies
      run: |
        python -m pip install --upgrade pip
        pip install build

    - name: Build distribution
      run: python -m build

    - name: Store the distribution packages
      uses: actions/upload-artifact@v4
      with:
        name: python-package-distributions
        path: dist/

  publish-to-pypi:
    name: Publish to PyPI
    needs:
    - build
    runs-on: ubuntu-latest
    # Only run this job for published releases
    if: github.event_name == 'release' && github.event.action == 'published'
    permissions:
      id-token: write
      contents: read

    steps:
    - name: Download all the dists
      uses: actions/download-artifact@v4
      with:
        name: python-package-distributions
        path: dist/

    - name: Publish distribution to PyPI
      uses: pypa/gh-action-pypi-publish@release/v1
      with:
        password: ${{ secrets.PYPI_API_TOKEN }}

Notes for reviewers / repo admins

  • After this change is merged, create a repository secret named PYPI_API_TOKEN in Settings > Secrets and variables > Actions and store a PyPI API token with the appropriate scope for the numta package.
  • Alternatively, if you prefer the OIDC trusted-publisher approach, you can reconfigure PyPI to trust this repository/workflow. That requires adding a Trusted Publisher on PyPI matching the repository owner/name and the workflow file path. The current workflow at ref 951bd50 had environment name 'pypi' which could affect the token claims; removing the environment simplifies matching.

Reference

Original failing job logs and workflow file at ref 951bd50


Please apply the above changes in a new branch and open a pull request merging into the default branch. The PR should include the file change and the notes above in the PR description.

This pull request was created as a result of the following prompt from Copilot chat.

Problem

GitHub Actions run (job 56800936197) failed with PyPI trusted publishing error: "invalid-publisher: valid token, but no corresponding publisher (Publisher with matching claims was not found)". This indicates PyPI rejected the OIDC/trusted-publisher flow because the GitHub OIDC claims did not match a configured trusted publisher on PyPI. The current workflow (.github/workflows/publish-to-pypi.yml at ref 951bd50) uses the pypa/gh-action-pypi-publish action with OIDC by default (no password provided), and also defines an environment 'pypi' which can add claims that must match PyPI configuration.

Goal

Make the workflow reliably publish to PyPI by using an explicit PyPI API token stored in repository secrets, and ensure appropriate permissions are set. This avoids relying on PyPI trusted publisher configuration which currently doesn't match and causes the invalid-publisher error.

Changes to make

  1. Update .github/workflows/publish-to-pypi.yml to:

    • Add id-token: write to top-level permissions (keeps OIDC capability if required elsewhere).
    • Remove the environment: pypi block from the publish job (prevents environment claims from being included and reduces mismatch risk).
    • Ensure the publish job has permissions: id-token: write and contents: read.
    • Provide the PyPI API token to pypa/gh-action-pypi-publish action via password: ${{ secrets.PYPI_API_TOKEN }}.
    • Update the job conditional to explicitly check that the release action is 'published' to match the trigger.
  2. Add guidance in the PR description for the repository administrator to create a repository secret named PYPI_API_TOKEN with a PyPI API token created on https://pypi.org (Account > API tokens).

Modified file content

Replace the repository file .github/workflows/publish-to-pypi.yml with the following content (preserves build steps but updates publish job):

name: Publish to PyPI

on:
  release:
    types: [published]
  workflow_dispatch:  # Allow manual trigger

permissions:
  id-token: write
  contents: read

jobs:
  build:
    name: Build distribution
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0  # Fetch all history and tags for setuptools-scm

    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: "3.x"

    - name: Install build dependencies
      run: |
        python -m pip install --upgrade pip
        pip install build

    - name: Build distribution
      run: python -m build

    - name: Store the distribution packages
      uses: actions/upload-artifact@v4
      with:
        name: python-package-distributions
        path: dist/

  publish-to-pypi:
    name: Publish to PyPI
    needs:
    - build
    runs-on: ubuntu-latest
    # Only run this job for published releases
    if: github.event_name == 'release' && github.event.action == 'published'
    permissions:
      id-token: write
      contents: read

    steps:
    - name: Download all the dists
      uses: actions/download-artifact@v4
      with:
        name: python-package-distributions
        path: dist/

    - name: Publish distribution to PyPI
      uses: pypa/gh-action-pypi-publish@release/v1
      with:
        password: ${{ secrets.PYPI_API_TOKEN }}

Notes for reviewers / repo admins

  • After this change is merged, create a repository secret named PYPI_API_TOKEN in Settings > Secrets and variables > Actions and store a PyPI API token with the appropriate scope for the numta package.
  • Alternatively, if you prefer the OIDC trusted-publisher approach, you can reconfigure PyPI to trust this repository/workflow. That requires adding a Trusted Publisher on PyPI matching the repository owner/name and the workflow file path. The current workflow at ref 951bd50 had environment name 'pypi' which could affect the token claims; removing the environment simplifies matching.

Reference

Original failing job logs and workflow file at ref 951bd50


Please apply the above changes in a new branch and open a pull request merging into the default branch. The PR should include the file change and the notes above in the PR description.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…ishing

Co-authored-by: deepentropy <8287111+deepentropy@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix PyPI trusted publishing error in GitHub Actions Fix PyPI publishing workflow to use API token instead of trusted publishing Dec 1, 2025
Copilot AI requested a review from deepentropy December 1, 2025 15:14
@deepentropy deepentropy marked this pull request as ready for review December 1, 2025 15:27
Copilot AI review requested due to automatic review settings December 1, 2025 15:27
@deepentropy deepentropy merged commit 4b74329 into main Dec 1, 2025
12 checks passed
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@deepentropy deepentropy deleted the copilot/fix-pypi-publishing-error branch December 1, 2025 15:27
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a PyPI publishing workflow failure caused by OIDC trusted publisher claim mismatches. The workflow now uses explicit API token authentication instead of relying on GitHub's OIDC trusted publishing flow.

Key Changes:

  • Switched from OIDC trusted publishing to API token authentication
  • Removed the environment: pypi block that was causing claim mismatches
  • Updated the publish job conditional to explicitly check for 'published' release action

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Comment on lines +46 to +47
# Only run this job for published releases
if: github.event_name == 'release' && github.event.action == 'published'
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conditional if: github.event_name == 'release' && github.event.action == 'published' will prevent this job from running when triggered via workflow_dispatch. If manual publishing is needed, the workflow won't work.

Consider using:

if: (github.event_name == 'release' && github.event.action == 'published') || github.event_name == 'workflow_dispatch'

This ensures the publish job runs both on release publications and manual triggers.

Suggested change
# Only run this job for published releases
if: github.event_name == 'release' && github.event.action == 'published'
# Only run this job for published releases or manual triggers
if: (github.event_name == 'release' && github.event.action == 'published') || github.event_name == 'workflow_dispatch'

Copilot uses AI. Check for mistakes.
Comment on lines +9 to 10
id-token: write
contents: read
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Since the workflow now uses API token authentication (password: ${{ secrets.PYPI_API_TOKEN }}), the id-token: write permission is no longer necessary. The OIDC token won't be used when an explicit password is provided.

Consider removing id-token: write from both top-level and job-level permissions unless you plan to use trusted publishing in the future. This follows the principle of least privilege.

Copilot uses AI. Check for mistakes.
if: github.event_name == 'release' && github.event.action == 'published'
permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing
id-token: write
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Since the workflow now uses API token authentication (password: ${{ secrets.PYPI_API_TOKEN }}), the id-token: write permission is no longer necessary at the job level. The OIDC token won't be used when an explicit password is provided.

Consider removing this permission unless you plan to use trusted publishing in the future. This follows the principle of least privilege.

Suggested change
id-token: write

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants