support for asset retries, and deleting existing releases

This commit is contained in:
Nathan James 2021-11-10 14:38:16 +02:00
parent 0465cdad11
commit 0edcedf52f
8 changed files with 202 additions and 56 deletions

View file

@ -61,6 +61,12 @@ export interface Releaser {
generate_release_notes: boolean | undefined;
}): Promise<{ data: Release }>;
deleteRelease(params: {
owner: string;
repo: string;
release_id: number;
}): Promise<{ data: Release }>;
allReleases(params: {
owner: string;
repo: string;
@ -112,6 +118,14 @@ export class GitHubReleaser implements Releaser {
return this.github.rest.repos.updateRelease(params);
}
deleteRelease(params: {
owner: string;
repo: string;
release_id: number;
}): Promise<{ data: Release }> {
return this.github.rest.repos.deleteRelease(params);
}
allReleases(params: {
owner: string;
repo: string;
@ -141,7 +155,8 @@ export const upload = async (
github: GitHub,
url: string,
path: string,
currentAssets: Array<{ id: number; name: string }>
currentAssets: Array<{ id: number; name: string }>,
maxRetries: number = config.input_retries || 0
): Promise<any> => {
const [owner, repo] = config.github_repository.split("/");
const { name, size, mime, data: body } = asset(path);
@ -170,11 +185,23 @@ export const upload = async (
});
const json = await resp.json();
if (resp.status !== 201) {
throw new Error(
`Failed to upload release asset ${name}. received status code ${
resp.status
}\n${json.message}\n${JSON.stringify(json.errors)}`
if (maxRetries <= 0) {
throw new Error(
`Failed to upload release asset ${name}. received status code ${
resp.status
}\n${json.message}\n${JSON.stringify(json.errors)}`
);
}
console.log(
`Failed to upload asset ${name} (${maxRetries - 1} retries remaining).`
);
if (config.input_retry_interval) {
await new Promise(r => setTimeout(r, config.input_retry_interval));
}
return upload(config, github, url, path, currentAssets, maxRetries - 1);
}
return json;
};
@ -198,6 +225,49 @@ export const release = async (
const discussion_category_name = config.input_discussion_category_name;
const generate_release_notes = config.input_generate_release_notes;
const createRelease = async () => {
const tag_name = tag;
const name = config.input_name || tag;
const body = releaseBody(config);
const draft = config.input_draft;
const prerelease = config.input_prerelease;
const target_commitish = config.input_target_commitish;
let commitMessage: string = "";
if (target_commitish) {
commitMessage = ` using commit "${target_commitish}"`;
}
console.log(
`👩‍🏭 Creating new GitHub release for tag ${tag_name}${commitMessage}...`
);
try {
let release = await releaser.createRelease({
owner,
repo,
tag_name,
name,
body,
draft,
prerelease,
target_commitish,
discussion_category_name,
generate_release_notes
});
return release.data;
} catch (error) {
// presume a race with competing metrix runs
console.log(
`⚠️ GitHub release failed with status: ${
error.status
}\n${JSON.stringify(
error.response.data.errors
)}\nretrying... (${maxRetries - 1} retries remaining)`
);
return release(config, releaser, maxRetries - 1);
}
};
try {
// you can't get a an existing draft by tag
// so we must find one in the list of all releases
@ -219,6 +289,13 @@ export const release = async (
});
const release_id = existingRelease.data.id;
if (config.input_delete_on_existing) {
console.log(`⚠ Deleting existing release ${owner}/${repo}@${release_id}`);
await releaser.deleteRelease({ owner, repo, release_id });
return createRelease();
}
let target_commitish: string;
if (
config.input_target_commitish &&
@ -265,44 +342,7 @@ export const release = async (
return release.data;
} catch (error) {
if (error.status === 404) {
const tag_name = tag;
const name = config.input_name || tag;
const body = releaseBody(config);
const draft = config.input_draft;
const prerelease = config.input_prerelease;
const target_commitish = config.input_target_commitish;
let commitMessage: string = "";
if (target_commitish) {
commitMessage = ` using commit "${target_commitish}"`;
}
console.log(
`👩‍🏭 Creating new GitHub release for tag ${tag_name}${commitMessage}...`
);
try {
let release = await releaser.createRelease({
owner,
repo,
tag_name,
name,
body,
draft,
prerelease,
target_commitish,
discussion_category_name,
generate_release_notes
});
return release.data;
} catch (error) {
// presume a race with competing metrix runs
console.log(
`⚠️ GitHub release failed with status: ${
error.status
}\n${JSON.stringify(
error.response.data.errors
)}\nretrying... (${maxRetries - 1} retries remaining)`
);
return release(config, releaser, maxRetries - 1);
}
return createRelease();
} else {
console.log(
`⚠️ Unexpected error fetching GitHub release for tag ${config.github_ref}: ${error}`