-
-
Notifications
You must be signed in to change notification settings - Fork 6
package rename changelog validation #157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
a64929d
9d93abb
96cb711
2ba442d
daf65a5
694ac81
6a43fba
0dbe4fc
dc83e68
b51a4fa
dee072d
bac92c7
920aec1
5b24367
b674e81
c553d22
3c4c682
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -164,24 +164,19 @@ function getTagUrl(repoUrl: string, tag: string) { | |||||||||||||
* @param repoUrl - The URL for the GitHub repository. | ||||||||||||||
* @param tagPrefix - The prefix used in tags before the version number. | ||||||||||||||
* @param releases - The releases to generate link definitions for. | ||||||||||||||
* @param [versionBeforePkgRename] - A version string of the package before being renamed. | ||||||||||||||
mcmire marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
* An optional, which is required only in case of package renamed. | ||||||||||||||
* @param [tagPrefixBeforePkgRename] - A tag prefix string of the package before being renamed. | ||||||||||||||
* An optional, which is required only in case of package renamed. | ||||||||||||||
* @returns The stringified release link definitions. | ||||||||||||||
*/ | ||||||||||||||
function stringifyLinkReferenceDefinitions( | ||||||||||||||
repoUrl: string, | ||||||||||||||
tagPrefix: string, | ||||||||||||||
releases: ReleaseMetadata[], | ||||||||||||||
versionBeforePkgRename?: string, | ||||||||||||||
tagPrefixBeforePkgRename?: string, | ||||||||||||||
mcmire marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
) { | ||||||||||||||
// A list of release versions in descending SemVer order | ||||||||||||||
const descendingSemverVersions = releases | ||||||||||||||
.map(({ version }) => version) | ||||||||||||||
.sort((a: Version, b: Version) => { | ||||||||||||||
return semver.gt(a, b) ? -1 : 1; | ||||||||||||||
}); | ||||||||||||||
const latestSemverVersion = descendingSemverVersions[0]; | ||||||||||||||
// A list of release versions in chronological order | ||||||||||||||
const chronologicalVersions = releases.map(({ version }) => version); | ||||||||||||||
const hasReleases = chronologicalVersions.length > 0; | ||||||||||||||
|
||||||||||||||
// The "Unreleased" section represents all changes made since the *highest* | ||||||||||||||
mcmire marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
// release, not the most recent release. This is to accomodate patch releases | ||||||||||||||
// of older versions that don't represent the latest set of changes. | ||||||||||||||
|
@@ -192,42 +187,137 @@ function stringifyLinkReferenceDefinitions( | |||||||||||||
// | ||||||||||||||
// If there have not been any releases yet, the repo URL is used directly as | ||||||||||||||
// the link definition. | ||||||||||||||
const unreleasedLinkReferenceDefinition = `[${unreleased}]: ${ | ||||||||||||||
hasReleases | ||||||||||||||
? getCompareUrl(repoUrl, `${tagPrefix}${latestSemverVersion}`, 'HEAD') | ||||||||||||||
: withTrailingSlash(repoUrl) | ||||||||||||||
}`; | ||||||||||||||
const unreleasedLinkReferenceDefinition = | ||||||||||||||
getUnreleasedLinkReferenceDefinition( | ||||||||||||||
repoUrl, | ||||||||||||||
tagPrefix, | ||||||||||||||
releases, | ||||||||||||||
versionBeforePkgRename, | ||||||||||||||
tagPrefixBeforePkgRename, | ||||||||||||||
); | ||||||||||||||
|
||||||||||||||
// The "previous" release that should be used for comparison is not always | ||||||||||||||
mcmire marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
// the most recent release chronologically. The _highest_ version that is | ||||||||||||||
// lower than the current release is used as the previous release, so that | ||||||||||||||
// patch releases on older releases can be accomodated. | ||||||||||||||
const releaseLinkReferenceDefinitions = releases | ||||||||||||||
.map(({ version }) => { | ||||||||||||||
let diffUrl; | ||||||||||||||
if (version === chronologicalVersions[chronologicalVersions.length - 1]) { | ||||||||||||||
diffUrl = getTagUrl(repoUrl, `${tagPrefix}${version}`); | ||||||||||||||
// by default tag prefix from new package will be used | ||||||||||||||
const releaseLinkReferenceDefinitions = getReleaseLinkReferenceDefinitions( | ||||||||||||||
repoUrl, | ||||||||||||||
tagPrefix, | ||||||||||||||
releases, | ||||||||||||||
versionBeforePkgRename, | ||||||||||||||
tagPrefixBeforePkgRename, | ||||||||||||||
).join('\n'); | ||||||||||||||
return `${unreleasedLinkReferenceDefinition}\n${releaseLinkReferenceDefinitions}${ | ||||||||||||||
releases.length > 0 ? '\n' : '' | ||||||||||||||
}`; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
/** | ||||||||||||||
* Get a string of unreleased link reference definition. | ||||||||||||||
* | ||||||||||||||
* @param repoUrl - The URL for the GitHub repository. | ||||||||||||||
* @param tagPrefix - The prefix used in tags before the version number. | ||||||||||||||
* @param releases - The releases to generate link definitions for. | ||||||||||||||
* @param [versionBeforePkgRename] - A version string of the package before being renamed. | ||||||||||||||
* @param [tagPrefixBeforePkgRename] - A tag prefix string of the package before being renamed. | ||||||||||||||
* @returns A unreleased link reference definition string. | ||||||||||||||
*/ | ||||||||||||||
function getUnreleasedLinkReferenceDefinition( | ||||||||||||||
repoUrl: string, | ||||||||||||||
tagPrefix: string, | ||||||||||||||
releases: ReleaseMetadata[], | ||||||||||||||
versionBeforePkgRename?: string, | ||||||||||||||
tagPrefixBeforePkgRename?: string, | ||||||||||||||
mcmire marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
): string { | ||||||||||||||
// A list of release versions in descending SemVer order | ||||||||||||||
const descendingSemverVersions = releases | ||||||||||||||
.map(({ version }) => version) | ||||||||||||||
.sort((a: Version, b: Version) => { | ||||||||||||||
return semver.gt(a, b) ? -1 : 1; | ||||||||||||||
}); | ||||||||||||||
const latestSemverVersion = descendingSemverVersions[0]; | ||||||||||||||
const hasReleases = descendingSemverVersions.length > 0; | ||||||||||||||
// if there is a package renamed, the tag prefix before the rename will be considered for compare | ||||||||||||||
// [Unreleased]: https://github.com/ExampleUsernameOrOrganization/ExampleRepository/compare/[email protected] | ||||||||||||||
const tagPrefixToCompare = | ||||||||||||||
tagPrefixBeforePkgRename && versionBeforePkgRename === latestSemverVersion | ||||||||||||||
? tagPrefixBeforePkgRename | ||||||||||||||
: tagPrefix; | ||||||||||||||
|
||||||||||||||
return `[${unreleased}]: ${ | ||||||||||||||
hasReleases | ||||||||||||||
? getCompareUrl( | ||||||||||||||
repoUrl, | ||||||||||||||
`${tagPrefixToCompare}${latestSemverVersion}`, | ||||||||||||||
'HEAD', | ||||||||||||||
) | ||||||||||||||
: withTrailingSlash(repoUrl) | ||||||||||||||
}`; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
/** | ||||||||||||||
* Get a list of release link reference definitions. | ||||||||||||||
* | ||||||||||||||
* @param repoUrl - The URL for the GitHub repository. | ||||||||||||||
* @param tagPrefix - The prefix used in tags before the version number. | ||||||||||||||
* @param releases - The releases to generate link definitions for. | ||||||||||||||
* @param [versionBeforePkgRename] - A version string of the package before being renamed. | ||||||||||||||
* @param [tagPrefixBeforePkgRename] - A tag prefix string of the package before being renamed. | ||||||||||||||
* @returns A list of release link reference definitions. | ||||||||||||||
*/ | ||||||||||||||
function getReleaseLinkReferenceDefinitions( | ||||||||||||||
repoUrl: string, | ||||||||||||||
tagPrefix: string, | ||||||||||||||
releases: ReleaseMetadata[], | ||||||||||||||
versionBeforePkgRename?: string, | ||||||||||||||
tagPrefixBeforePkgRename?: string, | ||||||||||||||
mcmire marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
): string[] { | ||||||||||||||
const chronologicalVersions = releases.map(({ version }) => version); | ||||||||||||||
let tagPrefixToCompare = tagPrefix; | ||||||||||||||
const releaseLinkReferenceDefinitions = releases.map(({ version }) => { | ||||||||||||||
let diffUrl; | ||||||||||||||
// once the version matches with original version, rest of the lines in changelog will be assumed as migrated tags | ||||||||||||||
if (tagPrefixBeforePkgRename && versionBeforePkgRename === version) { | ||||||||||||||
tagPrefixToCompare = tagPrefixBeforePkgRename; | ||||||||||||||
} | ||||||||||||||
mcmire marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
if (version === chronologicalVersions[chronologicalVersions.length - 1]) { | ||||||||||||||
diffUrl = getTagUrl(repoUrl, `${tagPrefixToCompare}${version}`); | ||||||||||||||
} else { | ||||||||||||||
const versionIndex = chronologicalVersions.indexOf(version); | ||||||||||||||
const previousVersion = chronologicalVersions | ||||||||||||||
.slice(versionIndex) | ||||||||||||||
.find((releaseVersion: Version) => { | ||||||||||||||
return semver.gt(version, releaseVersion); | ||||||||||||||
}); | ||||||||||||||
// when there is a package renamed below if will fix the validation for renamed package's first release | ||||||||||||||
mcmire marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
// In the below example `test` package has been renamed to `@metamask/test` | ||||||||||||||
// [1.0.0]: https://github.com/ExampleUsernameOrOrganization/ExampleRepository/compare/[email protected]...@metamask/[email protected] | ||||||||||||||
if ( | ||||||||||||||
tagPrefixBeforePkgRename && | ||||||||||||||
versionBeforePkgRename === previousVersion | ||||||||||||||
) { | ||||||||||||||
diffUrl = previousVersion | ||||||||||||||
? getCompareUrl( | ||||||||||||||
repoUrl, | ||||||||||||||
`${tagPrefixBeforePkgRename}${previousVersion}`, | ||||||||||||||
`${tagPrefixToCompare}${version}`, | ||||||||||||||
) | ||||||||||||||
: getTagUrl(repoUrl, `${tagPrefixToCompare}${version}`); | ||||||||||||||
} else { | ||||||||||||||
const versionIndex = chronologicalVersions.indexOf(version); | ||||||||||||||
const previousVersion = chronologicalVersions | ||||||||||||||
.slice(versionIndex) | ||||||||||||||
.find((releaseVersion: Version) => { | ||||||||||||||
return semver.gt(version, releaseVersion); | ||||||||||||||
}); | ||||||||||||||
diffUrl = previousVersion | ||||||||||||||
? getCompareUrl( | ||||||||||||||
repoUrl, | ||||||||||||||
`${tagPrefix}${previousVersion}`, | ||||||||||||||
`${tagPrefix}${version}`, | ||||||||||||||
`${tagPrefixToCompare}${previousVersion}`, | ||||||||||||||
`${tagPrefixToCompare}${version}`, | ||||||||||||||
) | ||||||||||||||
: getTagUrl(repoUrl, `${tagPrefix}${version}`); | ||||||||||||||
: getTagUrl(repoUrl, `${tagPrefixToCompare}${version}`); | ||||||||||||||
} | ||||||||||||||
mcmire marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
return `[${version}]: ${diffUrl}`; | ||||||||||||||
}) | ||||||||||||||
.join('\n'); | ||||||||||||||
return `${unreleasedLinkReferenceDefinition}\n${releaseLinkReferenceDefinitions}${ | ||||||||||||||
releases.length > 0 ? '\n' : '' | ||||||||||||||
}`; | ||||||||||||||
} | ||||||||||||||
return `[${version}]: ${diffUrl}`; | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
return releaseLinkReferenceDefinitions; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
type AddReleaseOptions = { | ||||||||||||||
|
@@ -264,28 +354,42 @@ export default class Changelog { | |||||||||||||
|
||||||||||||||
#formatter: Formatter; | ||||||||||||||
|
||||||||||||||
readonly #versionBeforePkgRename: string | undefined; | ||||||||||||||
|
||||||||||||||
readonly #tagPrefixBeforePkgRename: string | undefined; | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consistent typing for optional properties.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An optional property and a property that can be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I like My concern is around consistent typing for the other properties in these files that are defined as optional. |
||||||||||||||
|
||||||||||||||
/** | ||||||||||||||
* Construct an empty changelog. | ||||||||||||||
* | ||||||||||||||
* @param options - Changelog options. | ||||||||||||||
* @param options.repoUrl - The GitHub repository URL for the current project. | ||||||||||||||
* @param options.tagPrefix - The prefix used in tags before the version number. | ||||||||||||||
* @param options.formatter - A function that formats the changelog string. | ||||||||||||||
* @param [options.tagPrefix] - The prefix used in tags before the version number. | ||||||||||||||
* @param [options.formatter] - A function that formats the changelog string. | ||||||||||||||
* @param [options.versionBeforePkgRename] - A version string of the package before being renamed. | ||||||||||||||
* An optional, which is required only in case of package renamed. | ||||||||||||||
* @param [options.tagPrefixBeforePkgRename] - A tag prefix string of the package before being renamed. | ||||||||||||||
* An optional, which is required only in case of package renamed. | ||||||||||||||
*/ | ||||||||||||||
constructor({ | ||||||||||||||
repoUrl, | ||||||||||||||
tagPrefix = 'v', | ||||||||||||||
formatter = (changelog) => changelog, | ||||||||||||||
versionBeforePkgRename = undefined, | ||||||||||||||
tagPrefixBeforePkgRename = undefined, | ||||||||||||||
}: { | ||||||||||||||
repoUrl: string; | ||||||||||||||
tagPrefix?: string; | ||||||||||||||
formatter?: Formatter; | ||||||||||||||
versionBeforePkgRename?: string | undefined; | ||||||||||||||
tagPrefixBeforePkgRename?: string | undefined; | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consistent typing for optional values. With
Suggested change
|
||||||||||||||
}) { | ||||||||||||||
this.#releases = []; | ||||||||||||||
this.#changes = { [unreleased]: {} }; | ||||||||||||||
this.#repoUrl = repoUrl; | ||||||||||||||
this.#tagPrefix = tagPrefix; | ||||||||||||||
this.#formatter = formatter; | ||||||||||||||
this.#versionBeforePkgRename = versionBeforePkgRename; | ||||||||||||||
this.#tagPrefixBeforePkgRename = tagPrefixBeforePkgRename; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
/** | ||||||||||||||
|
@@ -467,6 +571,8 @@ ${stringifyLinkReferenceDefinitions( | |||||||||||||
this.#repoUrl, | ||||||||||||||
this.#tagPrefix, | ||||||||||||||
this.#releases, | ||||||||||||||
this.#versionBeforePkgRename, | ||||||||||||||
this.#tagPrefixBeforePkgRename, | ||||||||||||||
)}`; | ||||||||||||||
|
||||||||||||||
return this.#formatter(changelog); | ||||||||||||||
|
MajorLift marked this conversation as resolved.
Show resolved
Hide resolved
MajorLift marked this conversation as resolved.
Show resolved
Hide resolved
mcmire marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.