Global environment variables
To make a variable available to every job and step in a workflow, define it at the top-levelenv: 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’senv: 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, workflowenventries 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.
- 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:| Scope | Availability | Typical use |
|---|---|---|
| Repository-level | Workflows in the repository | Repo-specific API keys |
| Environment-level | Jobs that target that environment | Deployment credentials for a staging/production environment |
| Organization-level | Repositories allowed to use the secret | Shared organization secrets (when permitted) |
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.hello.txt and uploads it as an artifact. In the build logs you will see the run command with the secret masked:
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:

Quick reference
| Topic | Syntax / example |
|---|---|
| Global env | env:\n GREETING: "Hello" |
| Job-level env | jobs:\n test:\n env:\n GREETING2: "Hello2" |
| Secret reference | ${{ secrets.WORLD }} |
| Use in run step (expression) | run: echo "${{ env.GREETING }}, ${{ secrets.WORLD }}!" |
| Use in run step (shell var) | run: echo "$GREETING, $WORLD!" (only if WORLD is exported into the environment) |
Links and references
- Encrypted secrets for GitHub Actions
- GitHub Actions environment variables
- Using artifacts in GitHub Actions