DEV Community

Cover image for Secrets and Environment Variables in your GitHub Action
Leonardo Montini for This is Learning

Posted on • Originally published at

Secrets and Environment Variables in your GitHub Action

If you need to use some secret values in your pipeline, for example an API key to send a Slack message or to deploy to a server, first of all you'd like those values to be... secret!

With GitHub Action you also have a way to store and use secrets in your workflows to make sure the values are not exposed in the logs or in the code. Similarly, there's also the possibility to use environment variables or values in general that can be kept in clear and shared across the different steps of the workflow.

That's what I'm going to show you today!

Repository Variables

Secrets vs Variables vs Environments

First of all, secrets never show their value, you can just create, delete or overwrite them, but you'll never see the current value in the UI or in the logs once set.

Variables instead are always displayed and can be edited.

I haven't mentioned environments yet... so here's where they come into play: you can group variables (and secrets) at an organization level, so that they can be shared across all repositories in that specific organization. There's also a repository level, so all workflows on that specific repo have shared access and... environments!

You can set up an environment inside a repository and define variables and secrets there.

In case of conflicts, organization is overridden by repository and repository is overridden by environment.

How to use secrets and variables

Once set, you can access your values in many different ways inside your workflows and even from external scripts. I recorded a video to showcase a demo and this is the code of the workflow:

name: Secrets and Environment Variables

on: workflow_dispatch

    runs-on: ubuntu-latest
      MY_APP_ID: ${{ vars.APP_ID }}

      - name: Read a variable
        run: echo "My APP_ID value is ${{ vars.APP_ID }}"

      - name: Tell me a secret!
        run: echo "My existing secret is ${{ secrets.API_KEY }}"

      - name: Unset secret
        run: echo "My unknown secret is ${{ secrets.DOES_NOT_EXIST }}"

      - name: Github stuff
        run: echo "My Github repo is called ${{ github.repository }}"

      - name: Read an env variable
        run: echo "My APP_ID value is ${{ env.APP_ID }} (also accessible as $MY_APP_ID)"

      - uses: actions/checkout@v2
      - name: Read the env from an external script
        run: |
          chmod +x .github/scripts/
        shell: bash

    runs-on: ubuntu-latest
    environment: production
      APP_ID: ${{ vars.APP_ID }}

      - name: Read a variable
        run: echo "My APP_ID value in the production job is $APP_ID"
Enter fullscreen mode Exit fullscreen mode

The ones above are some possible ways of accessing the values, assuming they're existing and set in your settings (repository/organization).

If you want to learn more and watch a live demo with that action being setup and executed, check out the video!

I will also go through each step, compare the code with the ouput and explain what's happening. Enjoy :)

Thanks for reading this article, I hope you found it interesting!

I recently launched my Discord server to talk about Open Source and Web Development, feel free to join:

Do you like my content? You might consider subscribing to my YouTube channel! It means a lot to me ❤️
You can find it here:

Feel free to follow me to get notified when new articles are out ;)

Top comments (1)

duit profile image
Dirk Ulrich

How can I persistently modify a repository variable within workflows? I am able to read it and modify it using
- name: Storing version for Backend Version
GH_TOKEN: ${{ secrets.GH_PAT_SECRET }}
run: |
echo "VERSION_BE is ${{ vars.VERSION_BE }}"
gh variable set VERSION_BE --body "${{ env.SHORT_SHA }}"
echo "VERSION_BE is now ${{ vars.VERSION_BE }}"

but in a further called workflow the old value is used when I do
- name: Deploy to development
run: ./do deploy dev aks-dev ${{ vars.VERSION_BE }} ${{ vars.VERSION_FE }}