Deployment Environments
Contents
- What Are Environments?
- Deployment Protection Rules
- Environment-Scoped Secrets and Variables
- Referencing an Environment in a Job
- The Environment URL
- Repository Availability
- Custom Protection Rules
- Key Takeaways
- Complete Working Example
What Are Environments?
An environment in GitHub Actions is a named object that represents a deployment target. Common names are preview, staging, and production, but you can name them anything that reflects your infrastructure.
Each workflow job can reference at most one environment. That reference does three things:
- Gives the job access to secrets and variables scoped to that environment.
- Activates any protection rules configured on the environment.
- Records the deployment in GitHub's deployment history, including the target URL if one is supplied.
Environments are defined per-repository under Settings → Environments. Each environment, with its own secrets, variables, and protection rules, is configured independently from the others.
Deployment Protection Rules
Protection rules act as gates: a job that references an environment will not start executing its steps until every protection rule on that environment has been satisfied. GitHub provides three built-in rules.
Required Reviewers
Up to six people or teams can be designated as required reviewers. When the workflow reaches a job that references the environment, it pauses and sends a notification to each reviewer. The job only proceeds after one of the designated reviewers approves — or is rejected outright, which cancels the job.
This pattern is common for production deployments where a second set of eyes is required before code reaches live systems.
Wait Timer
Specifies a delay in minutes (between 0 and 43,200, which equals 30 days) that must elapse after the job is triggered before it may run. A wait timer can act as a cooling-off period — for example, ensuring a canary deployment has been live for thirty minutes before the full rollout proceeds.
Deployment Branches
Restricts which branches are permitted to deploy to the environment. There are three options:
All branches
Any branch can deploy to this environment. Useful for non-production environments where all developers need access.
Protected branches only
Only branches that have branch protection rules configured in the repository can deploy here.
Selected branches
Only branches whose names match patterns you specify are permitted. For example, a pattern of release/* restricts deployments to branches that start with release/.
Protection rules compose: configuring all three on the same environment means a job must satisfy every rule before it can proceed.
Environment-Scoped Secrets and Variables
Secrets and variables that you add to an environment are separate from repository-level and organisation-level secrets and variables. They are only accessible to jobs that reference that specific environment.
A common pattern is to keep the same secret name across environments — for example, DEPLOY_TOKEN — but store a different value in each environment. The correct value is injected automatically depending on which environment the job targets.
The same scoping applies to variables. A variable named API_VERSION can hold 2.3.0-beta in the preview environment and 2.2.1 in production, letting the two deploy jobs use appropriate version identifiers without any conditional logic in the workflow file.
Referencing an Environment in a Job
Add an environment: block inside the job definition. The minimal form requires only the environment name:
The extended form also accepts a url: key, which GitHub displays as a link on the deployment status summary:
It is possible to make the URL dynamic using expressions — combining a base URL stored in an environment variable with a version number from an environment variable, for instance. GitHub renders the final resolved URL as a clickable link on the Actions run summary page.
The Environment URL
The deployment URL appears in GitHub's deployment history and on the workflow run summary. It serves as a direct link to the running application after a successful deployment, making it easy for reviewers or stakeholders to validate the result without searching for the address manually.
Both vars.* and secrets.* can be used in the URL expression, though embedding secrets in a URL that will appear in logs is not recommended. Prefer variables for the URL components.
Repository Availability
Environments can be created and configured freely for public repositories. For private repositories, environment support is available on:
- Personal accounts with a GitHub Pro subscription.
- Organisations on the GitHub Team plan or higher.
On plans that do not support environments for private repositories, you can still reference an environment name in a workflow. GitHub will create the environment automatically on the first run, but without any secrets, variables, or protection rules configured, jobs that expect environment-scoped secrets will fail because the values do not exist.
Custom Protection Rules
Beyond the three built-in rules, GitHub supports custom deployment protection rules backed by third-party services. These are implemented as GitHub Apps that respond to a webhook event when a deployment is waiting. The app performs its own checks — such as querying a security scanner, verifying a change management ticket, or checking a feature flag system — and then calls back to GitHub to approve or reject the deployment.
Custom deployment protection rules require familiarity with GitHub Apps, webhooks, and the deployment callbacks API. As of early 2026 this feature is still in beta and subject to change.
Key Takeaways
- An environment is a named deployment target (e.g.
preview,production) configured in repository settings. A job can reference at most one environment. - Deployment protection rules — required reviewers, wait timer, and deployment branch restrictions — gate the job before any of its steps execute.
- Environment-scoped secrets and variables are separate from repository and organisation secrets. They are injected only into jobs that reference their environment.
- Reuse the same secret or variable name across environments (e.g.
DEPLOY_TOKEN) and store different values per environment. The correct value is resolved automatically. - The optional
url:key on an environment block produces a clickable deployment link on the GitHub Actions summary page. - Environments for private repositories require GitHub Pro (personal) or GitHub Team (organisation). Without the plan, the environment is created on first run but holds no secrets or protection rules.
- Custom protection rules integrate third-party approval systems via GitHub Apps and are currently in beta.
Complete Working Example
The workflow below demonstrates a three-job deployment pipeline for a Node.js API. One build job feeds two deployment jobs, each linked to a different environment with its own scoped secrets and variables. The production environment is intended to be configured with a required-reviewer protection rule in repository settings.