Skip to content

fix(workflows): add skip-github-pull-request conditional to prevent bogus release PRs #559

@WilliamBerryiii

Description

@WilliamBerryiii

Problem

Merging a release-please PR to main triggers the main.yml workflow, which re-runs release-please. This produces a bogus v3.0.0 PR (e.g., PR #558) every time a release PR is merged.

The v2.3.0–v2.3.9 changelog entries document nine rapid-fire patches attempting to fix this (PRs #470, #511, #533, #536, #538, #545, #550, #552, #554). The manual tag creation workaround (PR #538) partially solved the anchoring problem but did not prevent the bogus PR from being created on the release commit itself.

Root Cause

Full chain traced through release-please v17.1.3 source code (bundled in action v4.4.0):

  1. release-please-config.json sets "draft": true — required for immutable asset upload before publish
  2. Draft releases use lazy tag creation — no git tag is materialized until the release is published
  3. GitHub's GraphQL API returns tagCommit: null for draft releases without a materialized tag
  4. release-please's github.ts ~L913 filters releases: .filter(release => !!release.tagCommit)drops the draft release
  5. backfillReleasesFromTags() also fails (no git tag exists for the draft release)
  6. Manifest fallback: synthetic release with sha: ''all commits treated as unreleased
  7. Old BREAKING CHANGE from PR feat(agents): add Task Reviewer and expand RPI to 4-phase workflow #277 (included in v2.0.0) is rediscovered → triggers a major version bump → bogus v3.0.0 PR

The manual tag creation step (lines 99-120 in main.yml) solves the anchoring problem for subsequent runs by creating the tag before the release is published. However, on the release commit itself, the tag from the current run hasn't been created yet, and release-please runs PR creation before the tag step executes.

Selected Fix

Add skip-github-pull-request to the release-please action step:

skip-github-pull-request: ${{ startsWith(github.event.head_commit.message, 'chore(main): release') }}

Why this works

Scenario head_commit.message startsWith result PR creation Impact
Release commit merged chore(main): release ... true Skipped Zero unreleased changes exist — nothing lost
Normal push to main feat: ... / fix: ... false Runs normally Tag from prior release exists, anchoring works
workflow_dispatch null (no head_commit) false Runs normally Manual trigger always creates PRs

The manual tag creation step still executes on release commits (it has its own conditional on release_created == 'true'), ensuring the tag is available for the next non-release push.

Why Other Approaches Were Rejected

Approach Reason
force-tag-creation: true Available in release-please v17.2.0 but action v4.4.0 bundles v17.1.3. No action release includes v17.2.0 yet.
Remove draft: true Breaks the immutable asset upload workflow (extension packaging needs to attach artifacts before publish)
Three-step workflow decomposition Unnecessarily complex for a single-line fix
last-release-sha override One-time emergency fix only, not durable
Pre-create tag before release-please Fragile tag format dependency, duplicates existing workaround

Future Cleanup

When release-please-action ships a version bundling v17.2.0+, both workarounds can be replaced:

  1. Remove skip-github-pull-request conditional
  2. Remove manual tag creation step (lines 99-120)
  3. Add force-tag-creation: true to release-please-config.json

Track upstream: googleapis/release-please#2627

Upstream References

Implementation

  • Target file: .github/workflows/main.yml
  • Single line addition to the release-please step (lines 91-97)
  • Update workaround comment to reference the skip conditional
  • Commit type: ci(workflows): (not fix:) to avoid triggering another patch release

Metadata

Metadata

Labels

bugSomething isn't workingworkflowsGitHub Actions workflows

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions