@@ -125,12 +125,21 @@ export function clampSummary(summary, limit = 180) {
125125 * it — the released frontend change would vanish from the release record, the
126126 * very failure this whole mechanism exists to prevent.
127127 *
128- * @returns {{ entries: Array<{ path: string, sha: string, subject: string }>, totalCommits: number, commitsWithChangeset: number } }
128+ * `commits` is every non-merge commit in the range (newest first) and
129+ * `commitsWithChangesetShas` the subset that added one, so a caller can NAME
130+ * the commits it is leaving out instead of only counting them (#4843).
131+ *
132+ * @returns {{ entries: Array<{ path: string, sha: string, subject: string }>, commits: Array<{ sha: string, subject: string }>, totalCommits: number, commitsWithChangeset: number, commitsWithChangesetShas: Set<string> } }
129133 */
130134export function collectAddedChangesets ( objectuiRoot , from , to ) {
131- const totalCommits = git ( objectuiRoot , [ 'log' , '--no-merges' , '--format=%H' , `${ from } ..${ to } ` ] )
135+ const commits = git ( objectuiRoot , [ 'log' , '--no-merges' , '--format=%H%x09%s ' , `${ from } ..${ to } ` ] )
132136 . split ( '\n' )
133- . filter ( Boolean ) . length ;
137+ . filter ( Boolean )
138+ . map ( ( line ) => {
139+ const tab = line . indexOf ( '\t' ) ;
140+ return { sha : line . slice ( 0 , tab ) , subject : line . slice ( tab + 1 ) } ;
141+ } ) ;
142+ const totalCommits = commits . length ;
134143
135144 const raw = git ( objectuiRoot , [
136145 'log' ,
@@ -164,7 +173,13 @@ export function collectAddedChangesets(objectuiRoot, from, to) {
164173 commitsWithChangeset . add ( sha ) ;
165174 entries . push ( { path, sha, subject } ) ;
166175 }
167- return { entries, totalCommits, commitsWithChangeset : commitsWithChangeset . size } ;
176+ return {
177+ entries,
178+ commits,
179+ totalCommits,
180+ commitsWithChangeset : commitsWithChangeset . size ,
181+ commitsWithChangesetShas : commitsWithChangeset ,
182+ } ;
168183}
169184
170185/** Read a changeset's content at `to`, falling back to the commit that added it. */
@@ -196,31 +211,36 @@ export function inPreMode(frameworkRoot) {
196211}
197212
198213/**
199- * Build the digest for a range.
214+ * THE criterion: which objectui changes over `from..to` actually ship in the
215+ * frontend release, as objectui DECLARED it — plus a full account of what is
216+ * being left out and why.
200217 *
201- * @returns {{ bump: string, declaredLevel: string|null, breaking: number, releasing: Array<object>, releaseNothing: number, noChangeset: number, totalCommits: number, downgradedMajor: boolean, body: string } }
218+ * This is the single shared implementation. `bump-objectui.sh` (via
219+ * `buildDigest` below, #4731) and `scripts/objectui-range.mjs` (#4843) both go
220+ * through it, so the platform release record and the release page's Console
221+ * section can never disagree about what "a releasing frontend change" means.
222+ * Two copies of this rule would drift, and the first thing they would drift on
223+ * is the class that already went missing once: breaking `refactor(...)!`.
224+ *
225+ * Nothing here reads a commit type. Grouping output BY type is presentation and
226+ * belongs to the caller; it must never become a filter again.
227+ *
228+ * @returns {{ releasing: Array<object>, releaseNothingEntries: Array<object>, noChangesetCommits: Array<object>, releaseNothing: number, noChangeset: number, changesetsAdded: number, totalCommits: number } }
202229 */
203- export function buildDigest ( {
204- objectuiRoot,
205- frameworkRoot = REPO_ROOT ,
206- from,
207- to,
208- max = DEFAULT_MAX_ENTRIES ,
209- bumpOverride = '' ,
210- } ) {
211- const { entries, totalCommits, commitsWithChangeset } = collectAddedChangesets (
230+ export function classifyRange ( { objectuiRoot, from, to } ) {
231+ const { entries, commits, totalCommits, commitsWithChangesetShas } = collectAddedChangesets (
212232 objectuiRoot ,
213233 from ,
214234 to ,
215235 ) ;
216236
217237 const releasing = [ ] ;
218- let releaseNothing = 0 ;
238+ const releaseNothingEntries = [ ] ;
219239 for ( const entry of entries ) {
220240 const { packages, summary } = parseChangeset ( readAt ( objectuiRoot , to , entry . sha , entry . path ) ) ;
221241 const level = highestLevel ( packages ) ;
222242 if ( ! level ) {
223- releaseNothing ++ ;
243+ releaseNothingEntries . push ( { ... entry , summary : summary || entry . subject } ) ;
224244 continue ;
225245 }
226246 releasing . push ( {
@@ -236,6 +256,38 @@ export function buildDigest({
236256 const order = { major : 0 , minor : 1 , patch : 2 } ;
237257 releasing . sort ( ( a , b ) => order [ a . level ] - order [ b . level ] ) ;
238258
259+ const noChangesetCommits = commits . filter ( ( c ) => ! commitsWithChangesetShas . has ( c . sha ) ) ;
260+
261+ return {
262+ releasing,
263+ releaseNothingEntries,
264+ noChangesetCommits,
265+ releaseNothing : releaseNothingEntries . length ,
266+ noChangeset : noChangesetCommits . length ,
267+ changesetsAdded : entries . length ,
268+ totalCommits,
269+ } ;
270+ }
271+
272+ /**
273+ * Build the digest for a range.
274+ *
275+ * @returns {{ bump: string, declaredLevel: string|null, breaking: number, releasing: Array<object>, releaseNothing: number, noChangeset: number, totalCommits: number, downgradedMajor: boolean, body: string } }
276+ */
277+ export function buildDigest ( {
278+ objectuiRoot,
279+ frameworkRoot = REPO_ROOT ,
280+ from,
281+ to,
282+ max = DEFAULT_MAX_ENTRIES ,
283+ bumpOverride = '' ,
284+ } ) {
285+ const { releasing, releaseNothing, noChangeset, changesetsAdded, totalCommits } = classifyRange ( {
286+ objectuiRoot,
287+ from,
288+ to,
289+ } ) ;
290+
239291 const declaredLevel = releasing . length
240292 ? releasing . reduce (
241293 ( best , r ) => ( LEVEL_RANK [ r . level ] > LEVEL_RANK [ best ] ? r . level : best ) ,
@@ -273,7 +325,6 @@ export function buildDigest({
273325 ) ;
274326 }
275327
276- const noChangeset = Math . max ( 0 , totalCommits - commitsWithChangeset ) ;
277328 const omitted = [ ] ;
278329 if ( releaseNothing > 0 ) {
279330 omitted . push (
@@ -286,7 +337,7 @@ export function buildDigest({
286337
287338 const accounting =
288339 `Derived from the changesets objectui declared over the range — ` +
289- `${ releasing . length } releasing of ${ entries . length } changeset${ entries . length === 1 ? '' : 's' } added ` +
340+ `${ releasing . length } releasing of ${ changesetsAdded } changeset${ changesetsAdded === 1 ? '' : 's' } added ` +
290341 `across ${ totalCommits } non-merge commit${ totalCommits === 1 ? '' : 's' } ` +
291342 ( omitted . length ? `; omitted: ${ omitted . join ( ', ' ) } (they ship no package code).` : '.' ) ;
292343
0 commit comments