Skip to main content
In this lesson we’ll cover how to define and use environment variables and secrets in GitHub Actions workflows. We’ll continue with a simple example workflow that creates a text file containing a greeting and uploads it as an artifact. You can declare environment variables at the workflow (global) level or the job level. Sensitive values — such as API keys or passwords — should be stored as secrets in GitHub, not hard-coded into your workflow YAML.

Global environment variables

To make a variable available to every job and step in a workflow, define it at the top-level env: block. These values are accessible through the env context (${{ env.NAME }}) in expressions and are also exposed as environment variables inside each step. Example: a workflow that defines a global GREETING and uses it to create hello.txt:

Job-level environment variables

If a variable should only be visible to a single job, place it inside that job’s env: block. Job-level variables override workflow-level variables with the same name for that job. Example: define a job-specific GREETING2 used only in the test job:

How to reference environment variables in steps

  • In YAML expressions and action inputs use the expression syntax: ${{ env.VAR_NAME }}.
  • Inside a run: step, workflow env entries are injected as environment variables, so you can also access them using the shell form $VAR_NAME (for POSIX shells) or %VAR_NAME% (on Windows). The expression form ${{ env.VAR_NAME }} is evaluated before the step runs.
Example inline usages:
  • Expression (evaluated by GitHub Actions): ${{ env.GREETING }}
  • Shell usage inside a run step: echo "$GREETING"

Secrets

Secrets are intended for sensitive values (API keys, tokens, passwords). Create repository secrets via Settings → Secrets and variables → Actions. You can create secrets at different scopes: Create a repository secret named WORLD with the value world (or your actual secret). The UI will not display the secret value after creation. To reference secrets in a workflow, use the secrets context: ${{ secrets.WORLD }}. Example: combine a global GREETING env var with a WORLD secret to create the artifact:
Secrets are never shown in workflow logs. GitHub masks secret values (usually displayed as ***) when commands that include them are printed to logs. Learn more at the GitHub Actions secrets docs: Encrypted secrets for GitHub Actions.
When the workflow runs, the build job creates hello.txt and uploads it as an artifact. In the build logs you will see the run command with the secret masked:
Note: the secret value is present inside the produced artifact (e.g., hello.txt) because the secret was used during the job — but the value is not revealed in the logs. After downloading the artifact (from the Actions run) you can verify the file content:
Screenshot of a GitHub Actions run page for "Demo-2 #5" showing a successful workflow. The graph shows completed "build" and "test" jobs and an artifact named "hello-file" listed below.

Quick reference

That’s how you define and use environment variables and secrets in GitHub Actions workflows.

Watch Video

Practice Lab