githubgithub-actionspypi

Why does Github not use my id-token permissions, but sets other permissions correctly?


I am trying to set up Github actions to push to Pypi automatically.

However, for some reason, Github isn't setting the permissions of the token correctly. In the job logs, they show up as only:

metadata: read

However, if I include permissions for other services, such as pages: write, that does work - it's only id-token that is completely failing.

I've verified that at the project, organization, and enterprise level, the GITHUB_TOKEN permissions are set to "Read & Write" as well.

Any idea what may be causing this?

Here's the full code:

name: Publish CLI distribution to PyPI and TestPyPI

on: push

jobs:
  build:
    name: Build Wheel Distribution
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Install pypa/build
        run: >-
          python3 -m
          pip install
          build
          --user
      - name: Build a binary wheel and a source tarball
        run: python3 -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 Production PyPi Server
    if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
    needs:
      - build
    runs-on: ubuntu-latest
    environment:
      name: pypi-prod
      url: https://pypi.org/p/<my project>
    permissions:
      id-token: write # IMPORTANT: mandatory for trusted publishing

    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

  github-release:
    name: >-
      Sign Distribution and upload to GitHub Release
    needs:
      - publish-to-pypi
    runs-on: ubuntu-latest

    permissions:
      contents: write # IMPORTANT: mandatory for making GitHub Releases
      id-token: write # IMPORTANT: mandatory for sigstore

    steps:
      - name: Download all the dists
        uses: actions/download-artifact@v4
        with:
          name: python-package-distributions
          path: dist/
      - name: Sign the dists with Sigstore
        uses: sigstore/gh-action-sigstore-python@v2.1.1
        with:
          inputs: >-
            ./dist/*.tar.gz
            ./dist/*.whl
      - name: Create GitHub Release
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: >-
          gh release create
          '${{ github.ref_name }}'
          --repo '${{ github.repository }}'
          --notes ""
      - name: Upload artifact signatures to GitHub Release
        env:
          GITHUB_TOKEN: ${{ github.token }}
        # Upload to GitHub Release using the `gh` CLI.
        # `dist/` contains the built packages, and the
        # sigstore-produced signatures and certificates.
        run: >-
          gh release upload
          '${{ github.ref_name }}' dist/**
          --repo '${{ github.repository }}'

  publish-to-testpypi:
    name: Publish Distribution to TestPyPI
    needs:
      - build
    runs-on: ubuntu-latest

    environment:
      name: pypi-test
      url: https://test.pypi.org/project/<my project>/

    permissions:
      id-token: write
      pages: write

    steps:
      - name: Download all the dists
        uses: actions/download-artifact@v4
        with:
          name: python-package-distributions
          path: dist/
      - name: Publish distribution to TestPyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          repository-url: https://test.pypi.org/legacy/

Solution

  • This is solved. Apparently, even if an id-token is used, it still won't show up in the logs (in GITHUB_TOKEN Permissions), unlike permissions for something like Pages.

    The problem was actually in my PyPi config - the .yml file name was incorrect.