Problem It Solves
The current publish.yml workflow references environment: release at the job level. GitHub's environment protection rules (with required reviewers) gate the entire job, not the inner step if: clauses. This means:
- Every PR merged into
main triggers a Release workflow run.
- The run creates a pending deployment to the
release environment.
- GitHub displays an approval request to the engineering team.
- This happens regardless of whether the merge commit introduced a changeset.
For an active repository with daily merges (CI fixes, docs, refactors), the engineering team faces approval fatigue for "no-op releases" that intentionally exit 0 with no publish. The release pipeline becomes a tax on every merge.
Proposed Solution
Split into two jobs in the same workflow file:
detect (no environment): runs first, uses git diff or pnpm changeset status to determine whether the merge introduced a changeset. Sets an output has_changesets: bool. No environment, runs on every merge, no approval required.
release (with release environment): only created/skipped based on the detect output. The approval gate only kicks in when there is a real release to publish.
This is the standard two-job pattern in monorepo release pipelines. It keeps the security gate on the publish step without making every merge on main an approval request.
Current state
The publish.yml workflow file on main defines a single release job that:
- Triggers on
pull_request: types: [closed], push: tags, workflow_dispatch.
- Uses
environment: release with required reviewers configured in the GitHub UI (per docs/engineering/plans/release-pipeline-github-ui-setup.md §1.1).
- Has step-level
if: clauses that skip individual publish steps when steps.detect.outputs.has_changeset == 'false'.
The GitHub Actions docs (deployments-and-environments.md) state: "When a workflow job references an environment, the job won't start until all of the environment's protection rules pass." The job-level if: clause is not evaluated before environment gating.
Reproduction steps
- Open a PR with only a documentation change (no
.changeset/*.md file added or modified).
- Merge into
main.
- Observe: the Release workflow run is created, the environment approval is requested, and the reviewer must approve even though the run will skip every publish step.
Acceptance criteria
Related
- Plan:
docs/engineering/plans/release-pipeline.md §6.4 (Version Packages PR pattern).
- Runbook:
docs/engineering/plans/release-pipeline-github-ui-setup.md §1.1.
- Validation: observed on the e2e release runs of
@deessejs/fp@1.1.0.
🤖 Generated with Claude Code
Problem It Solves
The current
publish.ymlworkflow referencesenvironment: releaseat the job level. GitHub's environment protection rules (with required reviewers) gate the entire job, not the inner stepif:clauses. This means:maintriggers a Release workflow run.releaseenvironment.For an active repository with daily merges (CI fixes, docs, refactors), the engineering team faces approval fatigue for "no-op releases" that intentionally exit 0 with no publish. The release pipeline becomes a tax on every merge.
Proposed Solution
Split into two jobs in the same workflow file:
detect(no environment): runs first, usesgit difforpnpm changeset statusto determine whether the merge introduced a changeset. Sets an outputhas_changesets: bool. No environment, runs on every merge, no approval required.release(withreleaseenvironment): only created/skipped based on thedetectoutput. The approval gate only kicks in when there is a real release to publish.This is the standard two-job pattern in monorepo release pipelines. It keeps the security gate on the publish step without making every merge on
mainan approval request.Current state
The
publish.ymlworkflow file onmaindefines a singlereleasejob that:pull_request: types: [closed],push: tags,workflow_dispatch.environment: releasewith required reviewers configured in the GitHub UI (perdocs/engineering/plans/release-pipeline-github-ui-setup.md§1.1).if:clauses that skip individual publish steps whensteps.detect.outputs.has_changeset == 'false'.The GitHub Actions docs (
deployments-and-environments.md) state: "When a workflow job references an environment, the job won't start until all of the environment's protection rules pass." The job-levelif:clause is not evaluated before environment gating.Reproduction steps
.changeset/*.mdfile added or modified).main.Acceptance criteria
releaseenvironment approval.releaseenvironment approval.detectjob logs which signal it used (changeset files added, manual dispatch, tag push).releaseenvironment still gates the actualpnpm changeset publish,git tag, and GitHub Release steps.Related
docs/engineering/plans/release-pipeline.md§6.4 (Version Packages PR pattern).docs/engineering/plans/release-pipeline-github-ui-setup.md§1.1.@deessejs/fp@1.1.0.🤖 Generated with Claude Code