Commit a47b285e87 for woocommerce

commit a47b285e87160b28746481483a1cba92db72d669
Author: Jorge A. Torres <jorge.torres@automattic.com>
Date:   Tue Nov 25 13:13:11 2025 +0000

    Various changelog workflow enhancements (#62077)

diff --git a/.github/workflows/release-compile-changelog.yml b/.github/workflows/release-compile-changelog.yml
index c75419dc82..f181219911 100644
--- a/.github/workflows/release-compile-changelog.yml
+++ b/.github/workflows/release-compile-changelog.yml
@@ -121,15 +121,23 @@ jobs:
           echo "Using branch: $SELECTED_BRANCH"
           echo "selected_branch=${SELECTED_BRANCH}" >> $GITHUB_OUTPUT

+      - name: Checkout release branch
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ steps.check-branch.outputs.selected_branch }}
+          path: release-branch
+          sparse-checkout: |
+            /plugins/woocommerce/woocommerce.php
+            /plugins/woocommerce/readme.txt
+          sparse-checkout-cone-mode: false
+
       - name: Validate input version matches current version in the selected branch
         id: validate-selected-branch-version
         env:
           VERSION: ${{ steps.validate-version.outputs.version }}
           SELECTED_BRANCH: ${{ steps.check-branch.outputs.selected_branch }}
         run: |
-          git fetch origin ${SELECTED_BRANCH}
-          git checkout ${SELECTED_BRANCH}
-          current_version=$( cat plugins/woocommerce/woocommerce.php | grep -oP '(?<=Version: )(.+)' | head -n1 )
+          current_version=$( cat release-branch/plugins/woocommerce/woocommerce.php | grep -oP '(?<=Version: )(.+)' | head -n1 )

           echo "Current version from woocommerce.php: '$current_version'"
           echo "Input version: '$VERSION'"
@@ -141,9 +149,6 @@ jobs:

           echo "current_version=$current_version" >> $GITHUB_OUTPUT

-          # Go back to trunk.
-          git checkout trunk
-
       - name: Setup PNPM
         uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0

@@ -177,14 +182,9 @@ jobs:
           if [[ -z "${{ github.event.inputs.append_changelog }}" || "${{ github.event.inputs.append_changelog }}" == "auto" ]]; then
             # If a prerelease, append if there's already content in the changelog.
             if [[ "$VERSION" == *"-"* || "$VERSION" =~ \.0$ ]]; then
-              git checkout ${SELECTED_BRANCH}
-
-              if sed -n '/== Changelog ==/,$p' plugins/woocommerce/readme.txt | grep -Fq '**WooCommerce**'; then
+              if sed -n '/== Changelog ==/,$p' release-branch/plugins/woocommerce/readme.txt | grep -Fq '**WooCommerce**'; then
                 APPEND_CHANGELOG="--append-changelog"
               fi
-
-              # Go back to trunk to run the tools.
-              git checkout trunk
             fi
           elif [[ "${{ github.event.inputs.append_changelog }}" == "append" ]]; then
             # append_changelog: append.
diff --git a/tools/monorepo-utils/src/code-freeze/commands/changelog/lib/index.ts b/tools/monorepo-utils/src/code-freeze/commands/changelog/lib/index.ts
index 5256cd9ae3..0e144e0906 100644
--- a/tools/monorepo-utils/src/code-freeze/commands/changelog/lib/index.ts
+++ b/tools/monorepo-utils/src/code-freeze/commands/changelog/lib/index.ts
@@ -202,20 +202,43 @@ export const updateReleaseBranchChangelogs = async (

 		Logger.notice( `Running the changelog script in ${ tmpRepoPath }` );

-		execSync(
-			`pnpm --filter=@woocommerce/plugin-woocommerce changelog write --add-pr-num -n -vvv --use-version ${ mainVersion }`,
+		const changelogOutput = execSync(
+			`pnpm --filter=@woocommerce/plugin-woocommerce changelog write --add-pr-num -n --yes -vvv --use-version ${ mainVersion }`,
 			{
 				cwd: tmpRepoPath,
-				stdio: 'inherit',
+				encoding: 'utf-8',
 			}
 		);
+
+		const noEntriesWritten =
+			changelogOutput.includes( `No changes were found` ) ||
+			changelogOutput.includes(
+				`no changes with content for this write`
+			);
+
+		Logger.notice( `Changelog command output: ${ changelogOutput }` );
 		Logger.notice( `Committing deleted files in ${ tmpRepoPath }` );
 		//Checkout pnpm-lock.yaml to prevent issues in case of an out of date lockfile.
 		await git.checkout( 'pnpm-lock.yaml' );
 		await git.add( 'plugins/woocommerce/changelog/' );
-		await git.commit( `Delete changelog files from ${ version } release` );
-		const deletionCommitHash = await git.raw( [ 'rev-parse', 'HEAD' ] );
-		Logger.notice( `git deletion hash: ${ deletionCommitHash }` );
+
+		// Check if any files were actually deleted.
+		const status = await git.status();
+		let deletionCommitHash = '';
+
+		if ( status.staged.length > 0 ) {
+			await git.commit(
+				`Delete changelog files from ${ version } release`
+			);
+			deletionCommitHash = (
+				await git.raw( [ 'rev-parse', 'HEAD' ] )
+			 ).trim();
+			Logger.notice( `git deletion hash: ${ deletionCommitHash }` );
+		} else {
+			Logger.notice(
+				'No changelog files to delete, skipping deletion commit'
+			);
+		}

 		Logger.notice( `Updating readme.txt in ${ tmpRepoPath }` );
 		await updateReleaseChangelogs(
@@ -244,16 +267,19 @@ export const updateReleaseBranchChangelogs = async (
 				`Changelog update was committed directly to ${ releaseBranch }`
 			);
 			return {
-				deletionCommitHash: deletionCommitHash.trim(),
+				deletionCommitHash,
 				prNumber: -1,
 			};
 		}
 		Logger.notice( `Creating PR for ${ branch }` );
+		const warningMessage = noEntriesWritten
+			? '> [!WARNING]\n> No entries were written to the changelog. Consider adding a generic changelog entry before releasing.\n\n'
+			: '';
 		const pullRequest = await createPullRequest( {
 			owner,
 			name,
 			title: `Release: Prepare the changelog for ${ version }`,
-			body: `This pull request was automatically generated to prepare the changelog for ${ version }`,
+			body: `${ warningMessage }This pull request was automatically generated to prepare the changelog for ${ version }`,
 			head: branch,
 			base: releaseBranch,
 		} );
@@ -270,7 +296,7 @@ export const updateReleaseBranchChangelogs = async (
 		}

 		return {
-			deletionCommitHash: deletionCommitHash.trim(),
+			deletionCommitHash,
 			prNumber: pullRequest.number,
 		};
 	} catch ( e ) {
@@ -297,6 +323,15 @@ export const updateBranchChangelog = async (
 ): Promise< number > => {
 	const { owner, name, version } = options;
 	const { deletionCommitHash, prNumber } = releaseBranchChanges;
+
+	// Skip if there were no changelog files to delete
+	if ( ! deletionCommitHash ) {
+		Logger.notice(
+			`No deletion commit hash found, skipping changelog deletion from ${ releaseBranch }`
+		);
+		return -1;
+	}
+
 	Logger.notice( `Deleting changelogs from trunk ${ tmpRepoPath }` );
 	const git = simpleGit( {
 		baseDir: tmpRepoPath,