self-host →

Environments in GitHub Actions

Learn how to isolate secrets and manage different stages for your GitHub Actions workflows using environments.

GitHub Actions is a great tool for automating software workflows, and one of its standout features is environments. This functionality allows you to handle different stages of your project, like development, staging, and production, each with its own set of configurations and secrets. Here’s a straightforward guide on how to set up and use environments in GitHub Actions, and why they’re so handy.

What are environments?#

Environments in GitHub Actions help you manage different settings for your project phases. You can define specific configurations, secrets, and deployment strategies for each environment directly in your GitHub repository settings.

How to set up environments with specific secrets and variables#

  1. Define your environments: Go to your repository settings and add environments like production, staging, or test under the “Environments” section.
  2. Configure secrets and variables: Select an environment and use “Add environment secret” (or “Add environment variable”) to set up unique values like API keys, which are only accessible to jobs that reference that environment.
  3. Use environments in your workflows: In your workflow file (.github/workflows/my-workflow.yml), specify the environment using the environment keyword. This controls which settings and secrets are used based on the environment specified.

Example: Deploying to production#

name: Deploy to Production
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: '20'
- run: npm ci
- run: npm run build
- run: npm run deploy
env:
API_KEY: ${{ secrets.API_KEY }}

In this workflow, the API_KEY will be specific to the production environment, ensuring the right settings are used during deployment.

Example: Deploying to staging with ephemeral environment URL#

When setting up environments, you can also specify an environment URL. This URL is useful as it appears in pull requests associated with the environment, providing a direct link to view the deployment or relevant resources.

Here’s how you can specify an environment URL in your workflow:

name: Deploy to staging with ephemeral environment URL
on:
pull_request:
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: staging
url: ${{ steps.deploy.outputs.url }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: '20'
- run: npm ci
- run: npm run build
- run: npm run deploy
env:
API_KEY: ${{ secrets.API_KEY }}
- id: deploy
run: echo "url=https://staging-pr-${{ github.event.pull_request.number }}.example.com" >> $GITHUB_OUTPUT

Environment URL can either be static or dynamic. In the example above, the URL is dynamic and changes based on the PR number.

Security note: The pull_request trigger runs in the context of the fork’s branch and does not expose repository or environment secrets to workflows triggered from forks. For pull requests opened within the same repository, secrets are available as usual. If you need to deploy untrusted fork PRs with secrets, gate the job behind an environment that has a required-reviewers protection rule so a maintainer must approve each run before secrets are released. Avoid pull_request_target for this purpose unless you fully understand its risks, since it runs with the base repository’s secrets and write token.

Why use environments?#

  • Security: Keeping secrets specific to an environment reduces the risk of exposure, as they aren’t accessible outside their designated environment.
  • Controlled deployments: You can set environments to require manual approvals or other complex deployment protection rules, adding an extra layer of oversight before changes go live, which is especially useful for production environments.
  • Audit trails and notifications: GitHub tracks who accesses each environment and when, providing clear audit trails. You can also set up notifications for actions related to your environments, keeping you informed about deployments.