Skip to content

New logchange.py script to simplify changelog in wizard#4413

Open
janhoy wants to merge 12 commits into
apache:mainfrom
janhoy:changelog-rc-improvements
Open

New logchange.py script to simplify changelog in wizard#4413
janhoy wants to merge 12 commits into
apache:mainfrom
janhoy:changelog-rc-improvements

Conversation

@janhoy
Copy link
Copy Markdown
Contributor

@janhoy janhoy commented May 11, 2026

Lightweight changelog process for RC2+

Problem

When an RC1 vote fails and a new RC is needed, the release wizard provided no structured path for updating the changelog. All changelog tasks (logchange_release, logchange_generate, validate_changelog_unreleased, push_changelog_to_branches) lived in the branching_versions phase — outside the RC loop — meaning the release manager had to manually re-run complex multi-branch git operations with no guidance. There was also no clean way to defer forward-porting to stable and main until after a successful vote.

Additionally, those tasks embedded fragile shell one-liners directly in the YAML, making them hard to test, debug, or run independently of the wizard.

Solution

A new standalone Python script dev-tools/scripts/logchange.py handles all changelog git operations. The wizard calls it, but it can also be run directly by the release manager at any time.

prepare — run before each RC (in the RC loop)

Automatically detects RC1 vs RC2+:

  • RC1 (changelog/v<version>/ does not yet exist): calls gradlew logchangeRelease --releaseDate none --versionToRelease <version>, which moves all files from changelog/unreleased/ into the new version folder without writing a release date.
  • RC2+ (changelog/v<version>/ already exists): logchangeRelease would hard-fail here, so the script manually copies only the new files from changelog/unreleased/ into the existing version folder.

Both paths then run logchangeGenerate, strip the empty [unreleased] block from CHANGELOG.md, and optionally commit (--commit). Nothing is pushed or cherry-picked — that is deferred to post-vote.

forward-port — run once after a successful vote (in publish phase)

  1. Writes release-date.txt to the version folder
  2. Regenerates CHANGELOG.md — now with the correct release date
  3. Commits to the release branch
  4. Finds all changelog-touching commits on the release branch not yet on the stable branch (git log stable..release -- changelog/ CHANGELOG.md)
  5. Cherry-picks them to stable and main:
    • commits touching changelog/unreleased/ use -X ours -X no-renames to preserve the target branch's own unreleased entries
    • other commits (version folder additions, CHANGELOG.md) are cherry-picked plainly so real conflicts are not silently discarded
  6. Optionally pushes all three branches (--push)

Wizard changes

  • Removed four old tasks: logchange_release, logchange_generate, validate_changelog_unreleased, push_changelog_to_branches
  • Added changelog_update_rc as the first task in the artifacts group (is_in_rc_loop: true) — handles both RC1 and RC2+ via the script
  • Re-added validate_changelog_unreleased after changelog_update_rc with --skip-sync-check (branches intentionally differ until forward-port runs)
  • Added forward_port_changelog as the first task in the publish group

Other details

  • --commit (prepare) and --push (forward-port) are opt-in flags: the wizard passes them, but standalone use defaults to leaving changes for review first
  • --dry-run available on both subcommands — no files or git state are touched
  • --git-remote overrides the push remote (default: origin)
  • --release-date YYYY-MM-DD overrides the date written at forward-port time (default: today); input is validated
  • Cherry-pick failures print a git cherry-pick --abort hint before exiting
  • Documented in dev-docs/changelog.adoc section 5.4 and dev-tools/scripts/README.md

@github-actions github-actions Bot added documentation Improvements or additions to documentation scripts labels May 11, 2026
@janhoy janhoy marked this pull request as draft May 11, 2026 12:45
@janhoy janhoy requested a review from Copilot May 11, 2026 13:13
@janhoy janhoy changed the title New changelogRelease.py script to simplify changelog in wizard New logchange.py script to simplify changelog in wizard May 11, 2026
@janhoy janhoy force-pushed the changelog-rc-improvements branch from c04be97 to d55ffda Compare May 11, 2026 13:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a dedicated dev-tools/scripts/changelogRelease.py helper and rewires the Release Wizard to use it so release managers can reliably update changelogs across RC respins (RC1 vs RC2+) and then forward-port changelog commits post-vote.

Changes:

  • Added dev-tools/scripts/changelogRelease.py with prepare (RC loop) and forward-port (post-vote) subcommands to manage changelog file moves, CHANGELOG.md regeneration, committing, cherry-picking, and optional pushing.
  • Updated dev-tools/scripts/releaseWizard.yaml to replace the previous YAML-embedded shell one-liners with the new script-driven tasks.
  • Documented the new flow in dev-tools/scripts/README.md and dev-docs/changelog.adoc.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
dev-tools/scripts/releaseWizard.yaml Removes old changelog todos and adds new RC-loop + publish-phase tasks that call changelogRelease.py.
dev-tools/scripts/README.md Adds standalone usage documentation for changelogRelease.py.
dev-tools/scripts/changelogRelease.py New script implementing prepare and forward-port changelog operations.
dev-docs/changelog.adoc Updates release-manager documentation to describe the new script and workflow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread dev-tools/scripts/releaseWizard.yaml Outdated
Comment thread dev-tools/scripts/README.md Outdated
Copy link
Copy Markdown
Contributor

@dsmiley dsmiley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seemed like kind of a refactor as much as it fixes a problem... albeit maybe not as there's still plenty of lines in the release wizard, especially because of the repeated & verbose description. I do appreciate the clarity when I'm the RM as to what's happening. Maybe LLMs will help us maintain all this repeated information as well as it generates tokens.

+1 from me

Comment thread dev-tools/scripts/README.md Outdated
Comment thread dev-tools/scripts/README.md Outdated
@janhoy
Copy link
Copy Markdown
Contributor Author

janhoy commented May 11, 2026

I asked claude to perform a full simulation in a fresh git repo. It constructed a git repo with three branches and various changelog files on the branches, and ran the commands. Results:

Test scenarios for logchange.py

Tested against a real git repo at https://github.com/janhoy/changelogtest

Branch setup

Branch Contents in changelog/unreleased/
main feature-a, feature-b, feature-c
branch_10x (stable) feature-a, feature-b (feature-c not backported)
branch_10_1 (release) feature-a, feature-b, fix-d (release-only, not on stable or main)

RC1: prepare

python3 dev-tools/scripts/logchange.py prepare \
--version 10.1.0 --release-branch branch_10_1

Expected: runs gradlew logchangeRelease, moves all unreleased entries (A, B, D) to changelog/v10.1.0/, regenerates CHANGELOG.md, leaves uncommitted for review.

Result: ✅ All three files moved correctly. [unreleased] block stripped from CHANGELOG.md.

RC2: prepare after a new fix added

A new fix (fix-e) was committed to changelog/unreleased/ on branch_10_1 after RC1.

python3 dev-tools/scripts/logchange.py prepare \
--version 10.1.0 --release-branch branch_10_1 --commit

Expected: detects v10.1.0/ already exists (RC2+ path), moves only fix-e, leaves A/B/D untouched.

Result: ✅ Only fix-e moved. Existing entries not duplicated. Committed automatically.

prepare idempotency: no new unreleased files

python3 dev-tools/scripts/logchange.py prepare \
--version 10.1.0 --release-branch branch_10_1 --commit

Expected: nothing to move, logchangeGenerate produces no diff, nothing staged → no commit created.

Result: ✅ Clean NOP. Output: "Nothing staged — changelog is already up to date."

forward-port review run (no push)

python3 dev-tools/scripts/logchange.py forward-port \
--version 10.1.0 --release-branch branch_10_1 \
--stable-branch branch_10x --release-date 2026-05-12

Expected:

  • Writes release-date.txt, regenerates CHANGELOG.md with date, commits to branch_10_1
  • Cherry-picks 5 changelog commits to branch_10x and main
  • On branch_10x: A and B deleted from unreleased, D and E land in v10.1.0/
  • On main: feature-c remains untouched in unreleased; A, B, D, E appear in v10.1.0/
  • Release-only fix D causes no conflicts on either branch
  • Nothing pushed

Result: ✅ All cherry-picks applied cleanly. main unreleased correctly retains only feature-c.

forward-port re-run with --push (idempotency + push test)

python3 dev-tools/scripts/logchange.py forward-port \
--version 10.1.0 --release-branch branch_10_1 \
--stable-branch branch_10x --release-date 2026-05-12 --push

Expected: detects all patches already applied, skips cherry-pick step, pushes all three branches.

Result: ✅ Output: "No changelog commits to forward-port — branch_10x is already up to date." All three branches pushed to GitHub.

Bug found and fixed during testing: the original commit detection used git log A..B (SHA-based), which caused already-applied cherry-picks to be re-applied on a second run. Fixed by switching to git log --cherry-pick --right-only A...B (patch-id-based), making the command fully idempotent.

forward-port idempotency: everything already done

python3 dev-tools/scripts/logchange.py forward-port \
--version 10.1.0 --release-branch branch_10_1 \
--stable-branch branch_10x --release-date 2026-05-12

Expected: release-date.txt already correct, no staged changes, no new commits to cherry-pick → complete NOP.

Result:"Nothing staged — release-date.txt and CHANGELOG.md were already up to date." and "No changelog commits to forward-port — branch_10x is already up to date."

@janhoy janhoy marked this pull request as ready for review May 11, 2026 23:27
Comment thread dev-tools/scripts/releaseWizard.yaml Outdated
janhoy added 8 commits May 12, 2026 12:40
Simplify wizard wrt logchange
The script handles both RC preparation and post-vote forward-porting,
not just the logchangeRelease step, so 'logchange.py' is a better fit.
Update all references in releaseWizard.yaml, changelog.adoc, and README.md.
Remove the validate_changelog_unreleased step which has limited value at this stage
@janhoy janhoy force-pushed the changelog-rc-improvements branch from 93390ed to db03964 Compare May 12, 2026 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation no-changelog scripts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants