@@ -137,6 +137,26 @@ component {
137137 // Determine previous version for changelog range
138138 if ( idx lt arrayLen ( arguments .arrVersions ) ) {
139139 prevVersion = arguments .versions [ arguments .arrVersions [ idx + 1 ] ].version ;
140+
141+ // If current version is a stable release, check if there's an RC/Beta/Alpha with same base version
142+ if ( arguments .versions [ _version ].type eq " releases" ) {
143+ var baseVersion = listFirst ( version , " -" );
144+ // systemOutput( "Stable release #version#: looking for RC/Beta/Alpha with base version #baseVersion#, current prevVersion=#prevVersion#", true );
145+ // Look through all versions to find RC/Beta/Alpha with matching base
146+ loop array = arguments .arrVersions index = " local.checkIdx" item = " local.checkKey" {
147+ var checkVersion = arguments .versions [ checkKey ].version ;
148+ var checkType = arguments .versions [ checkKey ].type ;
149+ var checkBase = listFirst ( checkVersion , " -" );
150+ // If we find an RC/Beta/Alpha with the same base version, use it as prevVersion
151+ if ( ( checkType eq " rc" || checkType eq " beta" || checkType eq " alpha" )
152+ && checkBase eq baseVersion ) {
153+ // systemOutput( "Found match: #checkVersion# (type=#checkType#, base=#checkBase#), setting as prevVersion", true );
154+ prevVersion = checkVersion ;
155+ break ;
156+ }
157+ }
158+ // systemOutput( "Final prevVersion for stable #version# is #prevVersion#", true );
159+ }
140160 } else {
141161 // Last version - use the oldest version from the sorted array (last item)
142162 var lastKey = arguments .arrVersions [ arrayLen ( arguments .arrVersions ) ];
@@ -157,7 +177,12 @@ component {
157177 var changelog = {};
158178 var versionReleaseDate = " " ;
159179 if ( left ( version , len ( arguments .majorVersionFilter ) ) eq arguments .majorVersionFilter ) {
160- changelog = variables .download .getChangelog ( prevVersion , version , false , true );
180+ // For RC/Beta/Alpha, use the base version (without suffix) as upper bound to include tickets tagged without suffix
181+ var changelogVersion = version ;
182+ if ( arguments .versions [ _version ].type eq " rc" || arguments .versions [ _version ].type eq " beta" || arguments .versions [ _version ].type eq " alpha" ) {
183+ changelogVersion = listFirst ( version , " -" );
184+ }
185+ changelog = variables .download .getChangelog ( prevVersion , changelogVersion , false , true );
161186 versionReleaseDate = variables .download .getReleaseDate ( version );
162187 }
163188
@@ -180,6 +205,61 @@ component {
180205 return arrChangeLogs ;
181206 }
182207
208+ /**
209+ * Remove duplicate tickets from stable releases that also appear in their RC/Beta/Alpha
210+ * Handles two cases:
211+ * 1. Same base version (e.g., 6.2.3.35 stable and 6.2.3.35-RC)
212+ * 2. Different base version where stable's prevVersion is RC/Beta/Alpha (e.g., 6.2.2.91 stable with prevVersion 6.2.2.90-RC)
213+ * @arrChangeLogs The changelog data array from buildChangelogData
214+ * @return s The deduplicated changelog data array
215+ */
216+ function deduplicateStableReleaseTickets ( required array arrChangeLogs ) localmode = true {
217+ // Build a lookup map by version for quick access
218+ versionLookup = {};
219+ loop array = arguments .arrChangeLogs index = " changelog" {
220+ versionLookup [ changelog .version ] = changelog ;
221+ }
222+
223+ // Process each stable release
224+ loop array = arguments .arrChangeLogs index = " changelog" {
225+ if ( changelog .type eq " releases" && structCount ( changelog .changelog ) > 0 ) {
226+ stableRelease = changelog ;
227+ prevVersion = stableRelease .prevVersion ;
228+
229+ // Check if prevVersion is an RC/Beta/Alpha
230+ isPrevRC = ( findNoCase ( " -rc" , prevVersion ) || findNoCase ( " -beta" , prevVersion ) || findNoCase ( " -alpha" , prevVersion ) );
231+
232+ // If prevVersion is RC/Beta/Alpha and exists in our data, deduplicate
233+ if ( isPrevRC && structKeyExists ( versionLookup , prevVersion ) ) {
234+ rcRelease = versionLookup [ prevVersion ];
235+
236+ if ( structCount ( rcRelease .changelog ) > 0 ) {
237+ // Build a list of all ticket IDs in the RC changelog
238+ rcTicketIds = {};
239+ loop collection = rcRelease .changelog index = " ver" item = " tickets" {
240+ loop collection = tickets index = " ticketId" item = " ticketData" {
241+ rcTicketIds [ ticketId ] = true ;
242+ }
243+ }
244+
245+ // Remove those tickets from the stable changelog
246+ loop collection = stableRelease .changelog index = " ver" item = " tickets" {
247+ ticketsToKeep = {};
248+ loop collection = tickets index = " ticketId" item = " ticketData" {
249+ if ( ! structKeyExists ( rcTicketIds , ticketId ) ) {
250+ ticketsToKeep [ ticketId ] = ticketData ;
251+ }
252+ }
253+ stableRelease .changelog [ ver ] = ticketsToKeep ;
254+ }
255+ }
256+ }
257+ }
258+ }
259+
260+ return arguments .arrChangeLogs ;
261+ }
262+
183263 /**
184264 * Convert a version string to sortable format (from VersionUtils.cfc logic)
185265 * @version Version string like "7.0.1.44-SNAPSHOT"
0 commit comments