fchauvel
fchauvel

Reputation: 1143

How to access environment secrets from a Github workflow?

I am trying to publish a Python package to PyPI, from a Github workflow, but the authentication fails for "Test PyPI". I successfully published to Test PyPI from the command line, so my API token must be correct. I also checked for leading and trailing spaces in the secret value (i.e., on GitHub).

As the last commits show, I tried a few things without success.

I first tried to inline simple bash commands into the workflow as follows, but I have not been able to get my secrets into environment variables. Nothing showed up in the logs when I printed these variables.

- name: Publish on Test PyPI 
  env:
     TWINE_USERNAME: __token__
     TWINE_PASSWORD: ${{ secrets.PYPI_TEST_TOKEN }}
     TWINE_REPOSITORY_URL: "https://test.pypi.org/legacy/"
  run: |
     echo "$TWINE_PASSWORD"
     pip install twine
     twine check dist/*
     twine upload dist/*

I also tried to use a dedicated GitHub Action as follows, but it does not work either. I guess the problem comes from the secrets not being available in my workflow. What puzzled me is that my workflow uses another token/secret just fine! Though, if I put it in an environment variable, nothing is printed out. I also recreated my secrets under different names (PYPI_TEST_TOKEN and TEST_PYPI_API_TOKEN) but to no avail.

- name: Publish to Test PyPI
  uses: pypa/gh-action-pypi-publish@release/v1
  with:
    user: __token__
    password: ${{ secrets.TEST_PYPI_API_TOKEN }}
    repository_url: https://test.pypi.org/legacy/

I guess I miss something obvious (as usual). Any help is highly appreciated.

Upvotes: 28

Views: 35350

Answers (2)

James Windshield
James Windshield

Reputation: 335

This is the problem I struggled with, since I am working with multiple environments and they all share same named secrets with different values the following solution worked for me. Isolated pieces are described here and there, but it wasn't obvious how to piece it together.

At first I define that environment is selected during workflow_dispatch event:

on:
  workflow_dispatch:
    inputs:
      environment:
        type: choice
        description: Select the environment
        required: true
        options:
          - TEST
          - UAT

I then reference it in jobs context:

jobs:
  run-portal-tests:
    runs-on: ubuntu-latest
    environment: ${{ github.event.inputs.environment }}

Finally to be used in the step I need them in:

- name: Run tests
    env:
      ENDPOINT: ${{ secrets.ENDPOINT }}
      TEST_USER: ${{ secrets.TEST_USER }}
      TEST_USER_PASSWORD: ${{ secrets.TEST_USER_PASSWORD }}
      CLIENT_ID: ${{ secrets.CLIENT_ID }}
      CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
    run: python3 main.py

Upvotes: 10

fchauvel
fchauvel

Reputation: 1143

I eventually figured it out. My mistake was that I defined my secrets within an environment and, by default, workflows do not run in any specific environment. For this to happen, I have to explicitly name the environment in the job description as follows:

jobs:
  publish:
    environment: CI    # <--- /!\ Here is the link to the environment
    needs: build
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/v')
    steps:
    - uses: actions/checkout@v2
    # Some more steps here ...
    - name: Publish to Test PyPI
      env:
        TWINE_USERNAME: "__token__"
        TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
        TWINE_REPOSITORY_URL: "https://test.pypi.org/legacy/"
      run: |
        echo KEY: '${TWINE_PASSWORD}'
        twine check dist/*
        twine upload --verbose --skip-existing dist/*

The documentation mentions it actually.

Thanks to those who commented for pointing me in the right direction.

Upvotes: 64

Related Questions