This commit is contained in:
jj 2025-11-18 16:42:33 +01:00 committed by GitHub
commit 719ed96469
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 67 additions and 8 deletions

View file

@ -49,6 +49,7 @@ describe('github', () => {
getReleaseByTag: () => Promise.reject('Not implemented'), getReleaseByTag: () => Promise.reject('Not implemented'),
createRelease: () => Promise.reject('Not implemented'), createRelease: () => Promise.reject('Not implemented'),
updateRelease: () => Promise.reject('Not implemented'), updateRelease: () => Promise.reject('Not implemented'),
finalizeRelease: () => Promise.reject('Not implemented'),
allReleases: async function* () { allReleases: async function* () {
yield { data: [mockRelease] }; yield { data: [mockRelease] };
}, },
@ -254,11 +255,12 @@ describe('github', () => {
name: 'test', name: 'test',
body: 'test', body: 'test',
target_commitish: 'main', target_commitish: 'main',
draft: false, draft: true,
prerelease: false, prerelease: false,
assets: [], assets: [],
}, },
}), }),
finalizeRelease: async () => {},
allReleases: async function* () { allReleases: async function* () {
yield { yield {
data: [ data: [

2
dist/index.js vendored

File diff suppressed because one or more lines are too long

View file

@ -58,6 +58,12 @@ export interface Releaser {
make_latest: 'true' | 'false' | 'legacy' | undefined; make_latest: 'true' | 'false' | 'legacy' | undefined;
}): Promise<{ data: Release }>; }): Promise<{ data: Release }>;
finalizeRelease(params: {
owner: string;
repo: string;
release_id: number;
}): Promise<{ data: Release }>;
allReleases(params: { owner: string; repo: string }): AsyncIterableIterator<{ data: Release[] }>; allReleases(params: { owner: string; repo: string }): AsyncIterableIterator<{ data: Release[] }>;
} }
@ -160,6 +166,15 @@ export class GitHubReleaser implements Releaser {
return this.github.rest.repos.updateRelease(params); return this.github.rest.repos.updateRelease(params);
} }
async finalizeRelease(params: { owner: string; repo: string; release_id: number }) {
return await this.github.rest.repos.updateRelease({
owner: params.owner,
repo: params.repo,
release_id: params.release_id,
draft: false,
});
}
allReleases(params: { owner: string; repo: string }): AsyncIterableIterator<{ data: Release[] }> { allReleases(params: { owner: string; repo: string }): AsyncIterableIterator<{ data: Release[] }> {
const updatedParams = { per_page: 100, ...params }; const updatedParams = { per_page: 100, ...params };
return this.github.paginate.iterator( return this.github.paginate.iterator(
@ -303,7 +318,6 @@ export const release = async (
body = workflowBody || existingReleaseBody; body = workflowBody || existingReleaseBody;
} }
const draft = config.input_draft !== undefined ? config.input_draft : existingRelease.draft;
const prerelease = const prerelease =
config.input_prerelease !== undefined ? config.input_prerelease : existingRelease.prerelease; config.input_prerelease !== undefined ? config.input_prerelease : existingRelease.prerelease;
@ -317,7 +331,7 @@ export const release = async (
target_commitish, target_commitish,
name, name,
body, body,
draft, draft: existingRelease.draft,
prerelease, prerelease,
discussion_category_name, discussion_category_name,
generate_release_notes, generate_release_notes,
@ -345,6 +359,45 @@ export const release = async (
} }
}; };
/**
* Finalizes a release by unmarking it as "draft" (if relevant)
* after all artifacts have been uploaded.
*
* @param config - Release configuration as specified by user
* @param releaser - The GitHub API wrapper for release operations
* @param release - The existing release to be finalized
* @param maxRetries - The maximum number of attempts to finalize the release
*/
export const finalizeRelease = async (
config: Config,
releaser: Releaser,
release: Release,
maxRetries: number = 3,
): Promise<Release> => {
if (config.input_draft === true) {
return release;
}
if (maxRetries <= 0) {
console.log(`❌ Too many retries. Aborting...`);
throw new Error('Too many retries.');
}
const [owner, repo] = config.github_repository.split('/');
try {
const { data } = await releaser.finalizeRelease({
owner,
repo,
release_id: release.id,
});
return data;
} catch {
console.log(`retrying... (${maxRetries - 1} retries remaining)`);
return finalizeRelease(config, releaser, release, maxRetries - 1);
}
};
/** /**
* Finds a release by tag name from all a repository's releases. * Finds a release by tag name from all a repository's releases.
* *
@ -385,7 +438,6 @@ async function createRelease(
const tag_name = tag; const tag_name = tag;
const name = config.input_name || tag; const name = config.input_name || tag;
const body = releaseBody(config); const body = releaseBody(config);
const draft = config.input_draft;
const prerelease = config.input_prerelease; const prerelease = config.input_prerelease;
const target_commitish = config.input_target_commitish; const target_commitish = config.input_target_commitish;
const make_latest = config.input_make_latest; const make_latest = config.input_make_latest;
@ -401,7 +453,7 @@ async function createRelease(
tag_name, tag_name,
name, name,
body, body,
draft, draft: true,
prerelease, prerelease,
target_commitish, target_commitish,
discussion_category_name, discussion_category_name,

View file

@ -1,6 +1,6 @@
import { setFailed, setOutput } from '@actions/core'; import { setFailed, setOutput } from '@actions/core';
import { getOctokit } from '@actions/github'; import { getOctokit } from '@actions/github';
import { GitHubReleaser, release, upload } from './github'; import { GitHubReleaser, release, finalizeRelease, upload } from './github';
import { isTag, parseConfig, paths, unmatchedPatterns, uploadUrl } from './util'; import { isTag, parseConfig, paths, unmatchedPatterns, uploadUrl } from './util';
import { env } from 'process'; import { env } from 'process';
@ -48,7 +48,8 @@ async function run() {
}, },
}); });
//); //);
const rel = await release(config, new GitHubReleaser(gh)); const releaser = new GitHubReleaser(gh);
let rel = await release(config, releaser);
if (config.input_files && config.input_files.length > 0) { if (config.input_files && config.input_files.length > 0) {
const files = paths(config.input_files, config.input_working_directory); const files = paths(config.input_files, config.input_working_directory);
if (files.length == 0) { if (files.length == 0) {
@ -81,6 +82,10 @@ async function run() {
const assets = results.filter(Boolean); const assets = results.filter(Boolean);
setOutput('assets', assets); setOutput('assets', assets);
} }
console.log('Finalizing release...');
rel = await finalizeRelease(config, releaser, rel);
console.log(`🎉 Release ready at ${rel.html_url}`); console.log(`🎉 Release ready at ${rel.html_url}`);
setOutput('url', rel.html_url); setOutput('url', rel.html_url);
setOutput('id', rel.id.toString()); setOutput('id', rel.id.toString());