From 23502aee27fc3a0e91846a2c706704b1a3652b88 Mon Sep 17 00:00:00 2001 From: Francesco Gringl-Novy Date: Fri, 10 Jan 2025 11:40:22 +0100 Subject: [PATCH] fix(github): Fix making github releases latest or not (#536) This updates the github release creation to ensure that the release is correctly marked as latest. We used to set this for when we created the release draft, but according to https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#create-a-release, this cannot actually be set on drafts. Instead, we need to set it when we publish the release. There is also an option `legacy`, which, according to the docs, _seems_ like it may also work: > `legacy` specifies that the latest release should be determined based on the release creation date and higher semantic version. But since this option is a legacy option, _and_ since the behavior is a bit under-specced (e.g. if it determines based on creation date, it may be wrong, if it always uses semantic version, it may be correct), we decided to implement this consistently for ourselves. --- src/targets/github.ts | 60 ++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/src/targets/github.ts b/src/targets/github.ts index 7dd29c9c..b7f5324e 100644 --- a/src/targets/github.ts +++ b/src/targets/github.ts @@ -127,26 +127,6 @@ export class GitHubTarget extends BaseTarget { }; } - let latestRelease: { tag_name: string } | undefined; - try { - latestRelease = ( - await this.github.repos.getLatestRelease({ - owner: this.githubConfig.owner, - repo: this.githubConfig.repo, - }) - ).data; - } catch (error) { - // if the error is a 404 error, it means that no release exists yet - // all other errors should be rethrown - if (error.status !== 404) { - throw error; - } - } - - const isLatest = isPreview - ? false - : isLatestRelease(latestRelease, version); - const { data } = await this.github.repos.createRelease({ draft: true, name: tag, @@ -154,7 +134,6 @@ export class GitHubTarget extends BaseTarget { prerelease: isPreview, repo: this.githubConfig.repo, tag_name: tag, - make_latest: isLatest ? 'true' : 'false', target_commitish: revision, ...changes, }); @@ -347,7 +326,10 @@ export class GitHubTarget extends BaseTarget { * * @param release Release object */ - public async publishRelease(release: GitHubRelease) { + public async publishRelease( + release: GitHubRelease, + options: { makeLatest: boolean } = { makeLatest: true } + ) { if (isDryRun()) { this.logger.info(`[dry-run] Not publishing the draft release`); return; @@ -356,6 +338,8 @@ export class GitHubTarget extends BaseTarget { await this.github.repos.updateRelease({ ...this.githubConfig, release_id: release.id, + // This is a string on purpose - see https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#create-a-release + make_latest: options.makeLatest ? 'true' : 'false', draft: false, }); } @@ -418,6 +402,36 @@ export class GitHubTarget extends BaseTarget { })) ); + let latestRelease: { tag_name: string } | undefined = undefined; + try { + latestRelease = ( + await this.github.repos.getLatestRelease({ + owner: this.githubConfig.owner, + repo: this.githubConfig.repo, + }) + ).data; + } catch (error) { + // if the error is a 404 error, it means that no release exists yet + // all other errors should be rethrown + if (error.status !== 404) { + throw error; + } + } + + const latestReleaseTag = latestRelease?.tag_name; + this.logger.info( + latestReleaseTag + ? `Previous release: ${latestReleaseTag}` + : 'No previous release found' + ); + + // Preview versions should never be marked as latest + const isPreview = + this.githubConfig.previewReleases && isPreviewRelease(version); + const makeLatest = isPreview + ? false + : isLatestRelease(latestRelease, version); + const draftRelease = await this.createDraftRelease( version, revision, @@ -430,7 +444,7 @@ export class GitHubTarget extends BaseTarget { ) ); - await this.publishRelease(draftRelease); + await this.publishRelease(draftRelease, { makeLatest }); } }