Commit 50f443e3698 for woocommerce

commit 50f443e369898f20d89956b98d7bfd8c77e42eca
Author: Rostislav Wolný <1082140+costasovo@users.noreply.github.com>
Date:   Wed Aug 5 16:49:17 2026 +0200

    Fix changelogger corrupting hand-edited breaking-change markers (#67158)

    * Fix changelogger corrupting hand-edited breaking-change markers

    PR #67059 taught parse() to strip the breaking-change marker that format()
    writes, but it applied the strip to every row before the subentry branch and
    matched only one byte-exact marker string. Both halves misread hand-edited
    changelogs.

    A row under a `###` subheading keeps its whole text as content, so stripping
    there removes a marker the author typed deliberately. This is reachable
    through Legacy_Core_Formatter, whose entry pattern matches `###`. Gating the
    strip on `! $is_subentry` mirrors format(), which emits the marker only for
    non-subentries.

    Matching one exact string also meant a marker written as `[**BREAKING
    CHANGE**]` or `[ __BREAKING CHANGE__ ]` landed in the significance segment, so
    the entry was re-emitted with no significance and the five-space indent that
    fails markdownlint MD007 — the release-blocking symptom #67059 set out to fix.
    Since format() derives the marker from the significance on every write rather
    than preserving what it read, parse() can match the brackets loosely instead.

diff --git a/tools/changelogger/class-formatter.php b/tools/changelogger/class-formatter.php
index a707129140b..0648ac27984 100644
--- a/tools/changelogger/class-formatter.php
+++ b/tools/changelogger/class-formatter.php
@@ -27,8 +27,10 @@ class Formatter extends KeepAChangelogParser {
 	use PluginTrait;

 	/**
-	 * Marker appended after the significance of a major change. Written by format() and stripped by
-	 * parse(), so both sides must share this definition for a changelog to survive a round trip.
+	 * Marker appended after the significance of a major change. format() regenerates it from the
+	 * significance on every write, so it is never read back: parse() discards whatever bracketed
+	 * decoration sits in that slot, including hand-written variants of the marker. Subentry rows are
+	 * exempt, since their text is content verbatim.
 	 *
 	 * @var string
 	 */
@@ -193,9 +195,14 @@ class Formatter extends KeepAChangelogParser {
 					if ( 0 === strpos( $row, $this->bullet ) ) {
 						$row = substr( $row, strlen( $this->bullet ) );
 					}
-					// Drop the marker that format() appends after a major significance, otherwise it lands in the
+					// Drop any bracketed decoration following the significance, otherwise it lands in the
 					// significance segment below and the entry is re-emitted with no significance at all.
-					$row = preg_replace( '/^(major)\s*' . preg_quote( self::BREAKING_CHANGE_MARKER, '/' ) . '/i', '$1', $row );
+					// format() derives the breaking-change marker from the significance rather than preserving
+					// it, so matching brackets loosely instead of that exact marker keeps a hand-edited
+					// changelog parseable when its emphasis or spacing differs.
+					if ( ! $is_subentry ) {
+						$row = preg_replace( '/^(patch|minor|major)\s*\[[^\]]*\]/i', '$1', $row );
+					}

 					// Limit the split so that content containing " - " is not truncated at its own separator.
 					$row_segments = explode( ' - ', $row, 2 );