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

How to Build This

This is a targeted workflow fix using the task-implementor workflow.

Workflow: /task-research/task-plan/task-implement/task-review

Tip

Between each phase, type /clear or start a new chat to reset context.

Note

Before starting, verify whether this fix has already been applied. The skip-github-pull-request
conditional may already exist in main.yml. If the fix is already present, Phase 1 research
will confirm this and the issue can be closed without further phases.

Phase 1: Research

Source Material

  • This issue body
  • #file:.github/workflows/main.yml (release-please step, around lines 91-120)
  • #file:release-please-config.json (release configuration)

Steps

  1. Type /clear to start a fresh context.
  2. Attach or open the files listed above.
  3. Copy and run this prompt:
/task-research topic="verifying skip-github-pull-request conditional in release-please workflow"

Research the current state of the release-please configuration in main.yml. Investigate:

1. Whether skip-github-pull-request is already present in the release-please step
2. If present, whether the conditional expression matches the proposed fix
   (startsWith(github.event.head_commit.message, 'chore(main): release'))
3. Whether the manual tag creation step (lines 99-120) is still present and still needed
4. The current release-please-action version and whether it bundles v17.2.0+ with
   force-tag-creation support
5. Whether any of the workaround comments reference this issue or the upstream issues
6. If the fix is already applied, confirm no bogus release PRs have been created recently

Output: Research document at .copilot-tracking/research/{{YYYY-MM-DD}}-skip-pr-conditional-research.md

Phase 2: Plan

Source Material

  • Research document from Phase 1

Steps

  1. Type /clear to start a fresh context.
  2. Open the research document from Phase 1.
  3. Copy and run this prompt:
/task-plan

Create an implementation plan based on the research findings. If the fix is already
applied, the plan should document the verification result and recommend closing the issue.
If changes are needed, plan the specific YAML modifications to the release-please step
and any comment updates.

Output: Plan at .copilot-tracking/plans/ and details at .copilot-tracking/details/

Phase 3: Implement

Source Material

  • Plan from Phase 2

Steps

  1. Type /clear to start a fresh context.
  2. Open the plan document from Phase 2.
  3. Copy and run this prompt:
/task-implement

Implement the skip-github-pull-request fix following the plan. If the fix is already
applied, update workaround comments to reference this issue for traceability.
If changes are needed, add the conditional and update related comments.

Output: Modified .github/workflows/main.yml (if changes needed), changes log at .copilot-tracking/changes/

Phase 4: Review

Source Material

  • Plan from Phase 2
  • Changes log from Phase 3

Steps

  1. Type /clear to start a fresh context.
  2. Open the plan and changes log.
  3. Copy and run this prompt:
/task-review

Review the skip-github-pull-request implementation. Run these validation commands:
- npm run lint:yaml (validate main.yml)
Verify the conditional expression is correct, that it handles all three scenarios
from the issue (release commit, normal push, workflow_dispatch), and that the
commit type uses ci(workflows): prefix to avoid triggering a patch release.

Output: Review log at .copilot-tracking/reviews/

After Review

  • Pass: All criteria met. Create a PR referencing this issue (using ci(workflows): commit type, not fix:).
  • Iterate: Review found issues. Run /clear, return to Phase 3 with the review feedback.
  • Escalate: Fundamental design issue discovered. Run /clear, return to Phase 1 to research the gap.

Authoring Standards

  • Workflow changes follow .github/instructions/hve-core/workflows.instructions.md
  • Commit type is ci(workflows): to avoid triggering a patch release
  • YAML comments reference this issue and upstream issues for traceability

Success Criteria

  • skip-github-pull-request conditional is present and correctly formatted
  • Conditional handles release commits, normal pushes, and workflow_dispatch scenarios
  • Manual tag creation step is preserved (still needed until action bundles v17.2.0+)
  • Workaround comments reference this issue for traceability
  • npm run lint:yaml passes

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