Environments, deployments, rollback
Intermediate
Why this matters
"Is it live yet?" and "which version is on staging?" are questions you will ask and be asked constantly. Both platforms answer them on a page, if the pipeline is set up to record deployments, and knowing where that page is saves a great many messages.
Environments
An environment is a named place a build runs (lesson 1.5). The usual set:
| Environment | Is | Who sees it |
|---|---|---|
| Local | Your own machine | You |
| Review or preview | A temporary copy per merge request | Reviewers |
| Staging | A production-like copy | The team |
| Production | The real thing | Users |
The same code with different configuration: different databases, different addresses, different credentials. That is why "it works on staging" and "it is broken in production" can both be true, and why the first question about such a bug is usually about configuration rather than code.
Review environments deserve a mention because they are the ones that most help a writer. A pipeline can deploy each merge request to its own temporary address, so a reviewer reads the rendered documentation page rather than the Markdown diff. If your project publishes a site and does not do this, proposing it is a high-value, low-cost suggestion.
Deployments
A deployment is one act of putting a build into an environment. Both platforms record them when a job declares which environment it targets, and that record answers the two questions above:
- What is deployed here now, and which commit is it.
- Who deployed it and when.
- What was here before, which is what makes a one-click rollback possible.
Without that declaration the deployment still happens; it just is not tracked, and everyone goes back to asking in chat.
Approvals before production
Deploying to production is often gated: the job exists but waits for a person. Two mechanisms, one per platform:
| Platform | Mechanism |
|---|---|
| GitLab | when: manual on the job, so it waits for a play button; protected environments limit who may press it |
| GitHub | An environment with required reviewers, so the job pauses until someone approves |
The gate is a decision point, not an obstacle: it is where a release checklist is applied, and that checklist frequently includes whether the documentation and the release notes are ready. If you write those, you are part of this step whether or not you press the button.
Rollback: the three strategies
When a deployment turns out to be bad, there are three ways back, and teams pick by how fast they need to be.
1. Re-deploy the previous build
The fastest, and the platform button. GitLab's environment page has a rollback action for a previous deployment; GitHub re-runs the earlier deployment workflow. Nothing changes in Git: you are putting a known-good artefact back.
Use when: something is broken now and the cause is not yet understood. Restore service first, investigate second.
2. Revert the commit and let the pipeline deploy
$ git revert <hash>
$ git pushThe revert is an ordinary commit, so the pipeline builds and deploys it like anything else (lesson 12.2). Slower than a button, but Git and production end up agreeing, which matters: after strategy 1, the repository still contains the bad change and the next deployment would ship it again.
Use when: the cause is understood and the fix is "remove that change".
3. Roll forward
Fix the problem and deploy the fix. For a small, well-understood bug this is often quicker than either alternative and leaves a cleaner history.
Use when: the fix is small, obvious and testable, and the impact is not severe enough to demand immediate restoration.
Feature flags, briefly
Some teams deploy unfinished work and keep it invisible behind a feature flag: a setting that turns behaviour on for nobody, then for the team, then for everyone. It decouples deploying from releasing, which makes deployment boring and small, and it means the fastest rollback of all is turning the flag off, with no deployment at all.
For a writer, flags have a practical consequence: a feature can be in production and not yet announced, so "is it live?" needs a second question, "is the flag on?".
How to do it
Git has no notion of environments; deployments are the platform's. What the terminal answers is which commit is which:
$ git log --oneline -1 v1.2.0
$ git tag --contains <hash>Once you know the commit an environment is running, those two answer "does it include my fix?".
Nothing environment-specific. The platform extensions link to the deployment pages.
The same: links out to the platform.
Deploy → Environments lists each environment with what is deployed, who deployed it and when, plus actions to re-deploy or roll back. Settings → CI/CD → Protected environments limits who can deploy to production. A job joins this system by declaring environment: in .gitlab-ci.yml.
The Environments panel on the repository home page and Settings → Environments for configuration, including required reviewers and secrets scoped to an environment. A job joins by declaring environment: in the workflow.
Common mistakes
- Rolling back the deployment and not the commit, so the bad change ships again with the next release.
- Assuming staging and production run the same configuration. They do not, by design.
- Deploying without a recorded environment, so nobody can tell what is live.
- Treating the approval gate as a formality. It is where the checklist is applied.
- Announcing a feature because it deployed, when its flag is still off.
Try it yourself
Goal: find out what is deployed where, on a real project.
- Open your project's environments page, or the equivalent panel.
- For each environment, note the commit or tag deployed and when.
- Pick a recent fix and work out whether it is in each environment, using
git tag --containsor the compare view. - Find out how a deployment to production is triggered: automatic, manual, or approved.
- Find out what the rollback procedure is; if nobody knows, that is worth raising.
Expected result: you can answer "is my change live?" without asking anyone, and you know what happens when something goes wrong.
Show solution
Step 5 is the one that most often turns up an interesting answer. A team that cannot say how to roll back has not tried recently, and the moment to discover that is not during an incident. Asking the question is a genuine contribution.