diff --git a/ng-dev/pr/merge/defaults/lts-branch.ts b/ng-dev/pr/merge/defaults/lts-branch.ts index a23d31c6c..c84665be2 100644 --- a/ng-dev/pr/merge/defaults/lts-branch.ts +++ b/ng-dev/pr/merge/defaults/lts-branch.ts @@ -18,6 +18,7 @@ import { } from '../../../release/versioning'; import {promptConfirm, red, warn, yellow} from '../../../utils/console'; import {InvalidTargetBranchError} from '../target-label'; +import {defaultLocale} from '../../../utils/locale'; /** * Asserts that the given branch corresponds to an active LTS version-branch that can receive @@ -63,7 +64,7 @@ export async function assertActiveLtsBranch( // allow the merge as per our LTS guarantees. Can be forcibly overridden if desired. // See: https://angular.io/guide/releases#support-policy-and-schedule. if (today > ltsEndDate) { - const ltsEndDateText = ltsEndDate.toLocaleDateString('en-US'); + const ltsEndDateText = ltsEndDate.toLocaleDateString(defaultLocale); warn(red(`Long-term support ended for v${version.major} on ${ltsEndDateText}.`)); warn( yellow( diff --git a/ng-dev/release/notes/context.ts b/ng-dev/release/notes/context.ts index dfa75e993..898df519f 100644 --- a/ng-dev/release/notes/context.ts +++ b/ng-dev/release/notes/context.ts @@ -10,6 +10,7 @@ import {COMMIT_TYPES, ReleaseNotesLevel} from '../../commit-message/config'; import {CommitFromGitLog} from '../../commit-message/parse'; import {GithubConfig} from '../../utils/config'; import {ReleaseNotesConfig} from '../config/index'; +import {compareString} from '../../utils/locale'; /** List of types to be included in the release notes. */ const typesToIncludeInReleaseNotes = Object.values(COMMIT_TYPES) @@ -68,6 +69,19 @@ export class RenderContext { }); } + /** + * Comparator used for sorting commits within a release notes group. Commits + * are sorted alphabetically based on their type. Commits having the same type + * will be sorted alphabetically based on their determined description + */ + private _commitsWithinGroupComparator = (a: CategorizedCommit, b: CategorizedCommit): number => { + const typeCompareOrder = compareString(a.type, b.type); + if (typeCompareOrder === 0) { + return compareString(a.description, b.description); + } + return typeCompareOrder; + }; + /** * Organizes and sorts the commits into groups of commits. * @@ -94,9 +108,9 @@ export class RenderContext { const commitGroups = Array.from(groups.entries()) .map(([title, commits]) => ({ title, - commits: commits.sort((a, b) => (a.type > b.type ? 1 : a.type < b.type ? -1 : 0)), + commits: commits.sort(this._commitsWithinGroupComparator), })) - .sort((a, b) => (a.title > b.title ? 1 : a.title < b.title ? -1 : 0)); + .sort((a, b) => compareString(a.title, b.title)); // If the configuration provides a sorting order, updated the sorted list of group keys to // satisfy the order of the groups provided in the list with any groups not found in the list at diff --git a/ng-dev/release/publish/test/common.spec.ts b/ng-dev/release/publish/test/common.spec.ts index 72a18f80e..b18742b76 100644 --- a/ng-dev/release/publish/test/common.spec.ts +++ b/ng-dev/release/publish/test/common.spec.ts @@ -132,8 +132,8 @@ describe('common release action logic', () => { ### test | Commit | Description | | -- | -- | - | <..> | second commit | | <..> | first commit | + | <..> | second commit | ## Special Thanks `, ); diff --git a/ng-dev/release/publish/test/cut-lts-patch.spec.ts b/ng-dev/release/publish/test/cut-lts-patch.spec.ts index 3c5670e82..7d528ca1e 100644 --- a/ng-dev/release/publish/test/cut-lts-patch.spec.ts +++ b/ng-dev/release/publish/test/cut-lts-patch.spec.ts @@ -108,8 +108,8 @@ describe('cut an LTS patch action', () => { ### pkg1 | Commit | Type | Description | | -- | -- | -- | - | <..> | feat | not yet released *2 | | <..> | feat | not yet released *1 | + | <..> | feat | not yet released *2 | ## Special Thanks `); }); diff --git a/ng-dev/release/publish/test/cut-new-patch.spec.ts b/ng-dev/release/publish/test/cut-new-patch.spec.ts index 46c1f7755..dfa382875 100644 --- a/ng-dev/release/publish/test/cut-new-patch.spec.ts +++ b/ng-dev/release/publish/test/cut-new-patch.spec.ts @@ -88,8 +88,8 @@ describe('cut new patch action', () => { ### pkg1 | Commit | Type | Description | | -- | -- | -- | - | <..> | feat | not yet released *2 | | <..> | feat | not yet released *1 | + | <..> | feat | not yet released *2 | ## Special Thanks `); }); diff --git a/ng-dev/release/publish/test/cut-next-prerelease.spec.ts b/ng-dev/release/publish/test/cut-next-prerelease.spec.ts index e42051e39..b35f6e10e 100644 --- a/ng-dev/release/publish/test/cut-next-prerelease.spec.ts +++ b/ng-dev/release/publish/test/cut-next-prerelease.spec.ts @@ -101,8 +101,8 @@ describe('cut next pre-release action', () => { | Commit | Type | Description | | -- | -- | -- | | <..> | feat | not released yet, but cherry-picked | - | <..> | feat | only in next, not released yet *2 | | <..> | feat | only in next, not released yet *1 | + | <..> | feat | only in next, not released yet *2 | ## Special Thanks `); }, @@ -150,8 +150,8 @@ describe('cut next pre-release action', () => { ### pkg1 | Commit | Type | Description | | -- | -- | -- | - | <..> | feat | not released yet *2 | | <..> | feat | not released yet *1 | + | <..> | feat | not released yet *2 | ## Special Thanks `); }); @@ -198,8 +198,8 @@ describe('cut next pre-release action', () => { ### pkg1 | Commit | Type | Description | | -- | -- | -- | - | <..> | feat | not released yet *2 | | <..> | feat | not released yet *1 | + | <..> | feat | not released yet *2 | ## Special Thanks `); }); diff --git a/ng-dev/release/publish/test/cut-stable.spec.ts b/ng-dev/release/publish/test/cut-stable.spec.ts index 78ccf9307..95080d6b5 100644 --- a/ng-dev/release/publish/test/cut-stable.spec.ts +++ b/ng-dev/release/publish/test/cut-stable.spec.ts @@ -152,15 +152,15 @@ describe('cut stable action', () => { ### pkg1 | Commit | Type | Description | | -- | -- | -- | - | <..> | fix | not yet released *2 | + | <..> | fix | landed in patch, not released but cherry-picked *1 | | <..> | fix | not yet released *1 | - | <..> | fix | released release-candidate *2 | - | <..> | fix | released release-candidate *1 | - | <..> | fix | released feature-freeze pre-release *2 | + | <..> | fix | not yet released *2 | | <..> | fix | released feature-freeze pre-release *1 | - | <..> | fix | released first next pre-release *2 | + | <..> | fix | released feature-freeze pre-release *2 | | <..> | fix | released first next pre-release *1 | - | <..> | fix | landed in patch, not released but cherry-picked *1 | + | <..> | fix | released first next pre-release *2 | + | <..> | fix | released release-candidate *1 | + | <..> | fix | released release-candidate *2 | ## Special Thanks `); }, diff --git a/ng-dev/release/publish/test/move-next-into-feature-freeze.spec.ts b/ng-dev/release/publish/test/move-next-into-feature-freeze.spec.ts index 940028f14..3061be774 100644 --- a/ng-dev/release/publish/test/move-next-into-feature-freeze.spec.ts +++ b/ng-dev/release/publish/test/move-next-into-feature-freeze.spec.ts @@ -129,8 +129,8 @@ describe('move next into feature-freeze action', () => { | Commit | Type | Description | | -- | -- | -- | | <..> | feat | not released yet, but cherry-picked | - | <..> | feat | only in next, not released yet *2 | | <..> | feat | only in next, not released yet *1 | + | <..> | feat | only in next, not released yet *2 | `); }, ); diff --git a/ng-dev/release/publish/test/move-next-into-release-candidate.spec.ts b/ng-dev/release/publish/test/move-next-into-release-candidate.spec.ts index 53b01cdbe..3fd9b84af 100644 --- a/ng-dev/release/publish/test/move-next-into-release-candidate.spec.ts +++ b/ng-dev/release/publish/test/move-next-into-release-candidate.spec.ts @@ -112,8 +112,8 @@ describe('move next into release-candidate action', () => { | Commit | Type | Description | | -- | -- | -- | | <..> | feat | not released yet, but cherry-picked | - | <..> | feat | only in next, not released yet *2 | | <..> | feat | only in next, not released yet *1 | + | <..> | feat | only in next, not released yet *2 | `); }, ); diff --git a/ng-dev/release/publish/test/release-notes/generation.spec.ts b/ng-dev/release/publish/test/release-notes/generation.spec.ts index fdadc1583..72dcdb0ee 100644 --- a/ng-dev/release/publish/test/release-notes/generation.spec.ts +++ b/ng-dev/release/publish/test/release-notes/generation.spec.ts @@ -54,13 +54,13 @@ describe('release notes generation', () => { ### @angular-devkit/core | Commit | Type | Description | | -- | -- | -- | - | <..> | fix | commit *2 | | <..> | fix | commit *1 | + | <..> | fix | commit *2 | ### @angular-devkit/test | Commit | Type | Description | | -- | -- | -- | - | <..> | fix | commit *4 | | <..> | fix | commit *3 | + | <..> | fix | commit *4 | ## Special Thanks `); }); @@ -85,13 +85,13 @@ describe('release notes generation', () => { ### cdk | Commit | Type | Description | | -- | -- | -- | - | <..> | fix | commit *2 | | <..> | fix | commit *1 | + | <..> | fix | commit *2 | ### material | Commit | Type | Description | | -- | -- | -- | - | <..> | fix | commit *4 | | <..> | fix | commit *3 | + | <..> | fix | commit *4 | ## Special Thanks `); }); @@ -158,8 +158,8 @@ describe('release notes generation', () => { ### cdk | Commit | Type | Description | | -- | -- | -- | - | <..> | fix | platform: fix detection of chromium | | <..> | fix | a11y: fix module definition | + | <..> | fix | platform: fix detection of chromium | ### material | Commit | Type | Description | | -- | -- | -- | @@ -257,13 +257,13 @@ describe('release notes generation', () => { ### @angular-devkit/core | Commit | Description | | -- | -- | - | <..> | commit *2 | | <..> | commit *1 | + | <..> | commit *2 | ### @angular-devkit/test | Commit | Description | | -- | -- | - | <..> | commit *4 | | <..> | commit *3 | + | <..> | commit *4 | ## Special Thanks `); }); @@ -288,13 +288,13 @@ describe('release notes generation', () => { ### cdk | Commit | Description | | -- | -- | - | <..> | commit *2 | | <..> | commit *1 | + | <..> | commit *2 | ### material | Commit | Description | | -- | -- | - | <..> | commit *4 | | <..> | commit *3 | + | <..> | commit *4 | ## Special Thanks `); }); @@ -361,8 +361,8 @@ describe('release notes generation', () => { ### cdk | Commit | Description | | -- | -- | - | <..> | platform: fix detection of chromium | | <..> | a11y: fix module definition | + | <..> | platform: fix detection of chromium | ### material | Commit | Description | | -- | -- | diff --git a/ng-dev/utils/locale.ts b/ng-dev/utils/locale.ts new file mode 100644 index 000000000..e1315dc8d --- /dev/null +++ b/ng-dev/utils/locale.ts @@ -0,0 +1,18 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +/** Default locale used in the tool for string comparisons and locale-specific output. */ +export const defaultLocale = 'en-US'; + +/** + * Compares a given string to another one, returning a number indicating + * whether `a` should be positioned before `b` or the other way around. + */ +export function compareString(a: string, b: string): number { + return a.localeCompare(b, defaultLocale); +}