githubgithub-actions

Global and environment secrets/variables


I'm trying to refactor a workflow that manages different environment deployments to use the GitHub environments feature, but I got stuck on how to use both global and environment secrets.

For a bit of context, my aim is to use the same workflow, but depending on the branch name (that matches a environment), get values from that environment.

All the secrets and vars have the same name for each environment, just different values, and then I have repo level secrets and variables, that are common for all envs (e.g. AWS keys).

Let's say I have a workflow that its triggered for each merge to dev, staging or main branches, then I have some steps:

      - name: Configure AWS credentials
    if: ${{ github.event_name == 'workflow_dispatch' || steps.client-changes.outputs.client == 'true' }}
    uses: aws-actions/configure-aws-credentials@v4
    with:
    // Those I'd like to get from global
      aws-access-key-id: ${{ secrets.PIPELINE_USER_ACCESS_KEY_ID }}
      aws-secret-access-key: ${{ secrets.PIPELINE_USER_SECRET_ACCESS_KEY }}
      aws-region: ${{ secrets.AWS_REGION }}


      - name: Build, tag, and push Client image to Amazon ECR
    if: ${{ github.event_name == 'workflow_dispatch' || steps.client-changes.outputs.client == 'true' }}
    uses: docker/build-push-action@v5
    with:
      build-args: |
      // Those I'd like to get from environments (Ideally set dynamically)
        NEXT_PUBLIC_API_URL=${{ vars.NEXT_PUBLIC_API_URL }}
        NEXTAUTH_URL=${{ vars.NEXTAUTH_URL }}
        NEXTAUTH_SECRET=${{ secrets.NEXTAUTH_SECRET }}

Then I would use the same workflow file, using the branch name to reference the environment, so that I can get the right values

Does anyone have any working example?


Solution

  • As you are already doing, when using deployment environments in GitHub, if the variables or secrets have the same name across environments, it'll automatically fetch the value based on the environment defined at the job level. If a variable is "global", so defined outside any environment, it'll have its value injected from there directly, GitHub will take care of searching for the values at the right place.

    In order to have these values added dynamically you can make use of something like this:

    jobs:
      deployment:
        runs-on: ubuntu-latest
        environment: ${{ github.ref_name == 'prod' && 'prod' || github.ref_name == 'staging' && 'staging' }} 
        steps:
          - name: step1
        .....
    

    This will add the environment name based on the branch name, in this case if the ref is prod then an environment with name prod will be added, otherwise it'll select staging. You can make use of that strategy to add as many checks as needed.