-
Notifications
You must be signed in to change notification settings - Fork 125
Description
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):
release-please-config.jsonsets"draft": true— required for immutable asset upload before publish- Draft releases use lazy tag creation — no git tag is materialized until the release is published
- GitHub's GraphQL API returns
tagCommit: nullfor draft releases without a materialized tag - release-please's
github.ts~L913 filters releases:.filter(release => !!release.tagCommit)— drops the draft release backfillReleasesFromTags()also fails (no git tag exists for the draft release)- Manifest fallback: synthetic release with
sha: ''→ all commits treated as unreleased - 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:
- Remove
skip-github-pull-requestconditional - Remove manual tag creation step (lines 99-120)
- Add
force-tag-creation: truetorelease-please-config.json
Track upstream: googleapis/release-please#2627
Upstream References
- googleapis/release-please-action#962 — Same symptom (draft + lazy tag)
- googleapis/release-please-action#1111 — Release not found with draft
- googleapis/release-please-action#906 — Maintainer-endorsed skip approach
- googleapis/release-please#1650 — Core lazy tag issue
- googleapis/release-please#2627 —
force-tag-creationfix (v17.2.0)
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):(notfix:) 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
- Type
/clearto start a fresh context. - Attach or open the files listed above.
- 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
- Type
/clearto start a fresh context. - Open the research document from Phase 1.
- 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
- Type
/clearto start a fresh context. - Open the plan document from Phase 2.
- 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
- Type
/clearto start a fresh context. - Open the plan and changes log.
- 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, notfix:). - 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-requestconditional 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:yamlpasses