Skip to content
10 changes: 6 additions & 4 deletions src/changelog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function stringifyRelease(
const categorizedChanges = orderedChangeCategories
.filter((category) => categories[category])
.map((category) => {
const changes = categories[category] as string[];
const changes = categories[category] ?? [];
return stringifyCategory(category, changes);
})
.join('\n\n');
Expand Down Expand Up @@ -383,11 +383,13 @@ export default class Changelog {

const unreleasedChanges = this.#changes[unreleased];

for (const category of Object.keys(unreleasedChanges) as ChangeCategory[]) {
for (const category of Object.keys(
unreleasedChanges,
) as (keyof typeof unreleasedChanges)[]) {
if (releaseChanges[category]) {
releaseChanges[category] = [
...(unreleasedChanges[category] as string[]),
...(releaseChanges[category] as string[]),
...(unreleasedChanges[category] ?? []),
...(releaseChanges[category] ?? []),
];
} else {
releaseChanges[category] = unreleasedChanges[category];
Expand Down
13 changes: 5 additions & 8 deletions src/update-changelog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export async function updateChangelog({

if (
isReleaseCandidate &&
mostRecentTag === `${tagPrefixes[0]}${currentVersion || ''}`
mostRecentTag === `${tagPrefixes[0]}${currentVersion ?? ''}`
) {
throw new Error(
`Current version already has tag, which is unexpected for a release candidate.`,
Expand Down Expand Up @@ -250,19 +250,16 @@ export async function updateChangelog({
// Ensure release header exists, if necessary
if (
isReleaseCandidate &&
currentVersion &&
!changelog
.getReleases()
.find((release) => release.version === currentVersion)
) {
// Typecast: currentVersion will be defined here due to type guard at the
// top of this function.
changelog.addRelease({ version: currentVersion as Version });
changelog.addRelease({ version: currentVersion });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is referring to this code at the top of the function:

if (isReleaseCandidate && !currentVersion) {
  throw new Error(
    `A version must be specified if 'isReleaseCandidate' is set.`,
  );
}

Since we're checking for isReleaseCandidate here, there's no way that currentVersion is not set. Hence why I believe that the typecast was added originally. (Why TypeScript doesn't see this, I'm not sure.)

This change doesn't hurt, but I wanted to make sure you saw that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consolidated the conditional branches so that we can just rely on type narrowing here: 033cd4e. The tradeoff is that the errors now throw a bit later than they strictly should, but the overhead from that seems minimal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think with these changes we are now always shelling out a couple of times to gather commit hashes and commits regardless of the arguments given. I gather that the current changes were motivated by principle, that generally, if there are invalid inputs, the user wants to know about it right away rather than have to wait a bit. I agree, though, that this doesn't matter, at least right now, so these changes seem fine.

}

if (isReleaseCandidate && hasUnreleasedChanges) {
// Typecast: currentVersion will be defined here due to type guard at the
// top of this function.
changelog.migrateUnreleasedChangesToRelease(currentVersion as Version);
if (isReleaseCandidate && currentVersion && hasUnreleasedChanges) {
changelog.migrateUnreleasedChangesToRelease(currentVersion);
}

const newChangeEntries = newCommits.map(({ prNumber, description }) => {
Expand Down