Skip to content

generate-changelog: new branch per run causes changelog PRs to accumulate and go permanently conflicting #77

Description

@marc0olo

Problem

When generate_changelog runs and finds a changelog diff, create-pr opens a new randomly-suffixed branch and a new PR (chore/generate-changelog-m68pzu, -1aqpfr, -viap3f, …) rather than updating the changelog PR that is already open. While an earlier changelog PR sits unmerged, every subsequent push to main legitimately still sees a diff against main — and opens another PR for it.

The result is a queue of near-identical PRs, all requiring individual review, which then go permanently conflicting the moment a release lands (the release commit folds the Unreleased entries into a version section, so every outstanding PR now wants to re-add already-released content as unreleased).

To be clear about what is not the problem: create-pr already correctly skips PR creation when the regenerated changelog is unchanged. Verified on https://github.com/dfinity/icp-js-core/actions/runs/30821425842 — it ran on a chore: generate changelog merge, cz produced byte-identical content, and no PR was created. So this is not about no-op runs. The defect is purely branch reuse.

Evidence

dfinity/icp-js-core — 8 changelog PRs for what amounted to 2 distinct changelog states:

  • #1376, #1378, #1382 — byte-identical diffs, all three adding one entry (feat: Revamp Agent.readState (#1375)). Spawned by three separate pushes to main while the first one sat unmerged. Two closed as duplicates, one merged.
  • #1363, #1368, #1369, #1372, #1373 — all permanently CONFLICTING after v6.0.0 shipped; the content they wanted to add as Unreleased was already in the released section. All five closed as obsolete, nothing recoverable.

Oldest had been open since 2026-06-09.

dfinity/pic-js — currently 6 open (#269, #270, #272 conflicting; #274, #277, #279 mergeable), none merged since 2026-04-14. Same pattern, further along.

Notably, the repos that stay clean (icp-js-auth, icp-js-signer, icp-js-bindgen) aren't configured differently — they just release frequently enough to drain the queue. All five repos require 1 approving review with no bot bypass, so the design converts "we haven't shipped in a while" into "we have a pile of conflicting bot PRs."

Root cause

actions/create-pr appends a random suffix to branch_name, and no input exposes a way to disable it — the reusable workflow's branch_name default (chore/generate-changelog) is only ever a prefix in practice.

Possible solutions

Option A — reuse a single canonical branch (preferred)

Add an input such as reuse_branch: true (or make it the default for this workflow) so create-pr force-pushes to a fixed branch name and updates the existing open PR instead of opening a new one. One long-lived, self-updating changelog PR per repo.

Option B — swap create-pr for peter-evans/create-pull-request in this workflow

It does exactly this natively: fixed branch, updates in place, and closes the PR automatically when the diff empties. Larger change, and diverges from the shared create-pr action used elsewhere.

Option C — additionally allow auto-merge for the bot's changelog PR

Orthogonal, but worth considering: even one self-updating PR still needs a human approval per release cycle. A ruleset bypass for the PR-automation app plus auto-merge would make the changelog PR fully hands-off. This is a per-repo ruleset change rather than a ci-tools change.

Blast radius

icp-js-core, icp-js-auth, icp-js-signer, icp-js-bindgen, and pic-js all consume this reusable workflow.

Relation to #75

Separate failure mode. #75 is cz changelog exiting nonzero on release commits, which fails the job in the Generate changelog step before create-pr runs. This issue is about create-pr's branching behavior on runs where cz succeeds. Fixing either does not fix the other.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions