Put the publish job in a GitHub environment and add a required reviewer. The job then pauses until someone approves it, and environment secrets stay hidden until that approval. For a solo repo this adds a deliberate pause before anything reaches npm or PyPI.
What an environment gives you
A GitHub environment is a named deployment target, such as npm or pypi, that your workflow job can reference. GitHub documents three controls that matter for publishing:
- Required reviewers. You can name up to 6 people or teams. Only one needs to approve for the job to go ahead.
- Prevent self-review. An optional setting that stops people from approving runs they triggered.
- Deployment branches and tags. You can limit which branches and tags may deploy, with separate patterns for each ref type.
Secrets stored on the environment are available only to jobs that use it, and only after the protection rules pass.
Does approval make sense when you are the only person?
It depends on what you are guarding against. If you are the only maintainer, approving your own run adds little against your own mistakes beyond a pause. But it does protect against a different failure: a workflow triggered by something you did not intend, such as a stray tag, a compromised contributor token or a bad merge. The job waits, you see a notification, and you can reject it.
Prevent self-review only helps when a second person exists. With a single maintainer, leave it off or the run could never be approved. If you later add a co-maintainer, turn it on. Our post on adding a co-maintainer safely covers the roles.
Steps
- In the repository, open Settings, then Environments, and create one named for the registry.
- Add yourself, or a trusted second person, as a required reviewer.
- Under deployment branches and tags, allow only your release tag pattern or main branch.
- Reference the environment in the publish job with the
environmentkey. - Keep registry credentials, if you still have any, as environment secrets rather than repository secrets.
If you use trusted publishing, give the same environment name to the registry. The PyPI docs describe the environment as optional but strongly recommended, and it ties the upload to a gated job.
Plan limits to check
The GitHub docs say Free accounts can configure environments only for public repositories. If a repository becomes private, its protection rules and environment secrets are ignored. Team and Pro plans can use environments in private repositories. If your package source is private, confirm your plan before you rely on this gate.
Pair it with tag rules
An approval gate is stronger when only trusted people can create release tags. See protecting release tags with a ruleset and publishing from CI or from a laptop.
Try it yourself
Click through it at your own pace, or open it full screen. Watch how a failing check stops a change before it merges, the same idea as an approval stopping a release.
Quick check
How many reviewers can an environment have?
GitHub documents up to 6 people or teams, and one approval is enough.
Do environment rules work on a private repo on the Free plan?
No. GitHub says protection rules and environment secrets are ignored there.
Sources
Last reviewed: 19 October 2026.