Skip to content

Commit

Permalink
Support deleting existing releases
Browse files Browse the repository at this point in the history
Extracted from softprops#181
  • Loading branch information
ncfavier committed Dec 4, 2021
1 parent 58fa4b7 commit 2a671de
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 50 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -180,6 +180,7 @@ The following are optional as `step.with` keys
| `token` | String | Secret GitHub Personal Access Token. Defaults to `${{ github.token }}` |
| `discussion_category_name` | String | If specified, a discussion of the specified category is created and linked to the release. The value must be a category that already exists in the repository. For more information, see ["Managing categories for discussions in your repository."](https://docs.github.com/en/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository) |
| `generate_release_notes` | Boolean | Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. See the [GitHub docs for this feature](https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes) for more information |
| `delete_on_existing` | Boolean | Whether or not to delete an existing release entirely when running this action. |

💡 When providing a `body` and `body_path` at the same time, `body_path` will be
attempted first, then falling back on `body` if the path can not be read from.
Expand Down
55 changes: 45 additions & 10 deletions __tests__/util.test.ts
Expand Up @@ -51,7 +51,8 @@ describe("util", () => {
input_tag_name: undefined,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: false
input_generate_release_notes: false,
input_delete_on_existing: false
})
);
});
Expand All @@ -71,7 +72,8 @@ describe("util", () => {
input_tag_name: undefined,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: false
input_generate_release_notes: false,
input_delete_on_existing: false
})
);
});
Expand All @@ -91,7 +93,8 @@ describe("util", () => {
input_tag_name: undefined,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: false
input_generate_release_notes: false,
input_delete_on_existing: false
})
);
});
Expand Down Expand Up @@ -123,7 +126,8 @@ describe("util", () => {
input_fail_on_unmatched_files: false,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: false
input_generate_release_notes: false,
input_delete_on_existing: false
}
);
});
Expand All @@ -147,7 +151,8 @@ describe("util", () => {
input_fail_on_unmatched_files: false,
input_target_commitish: "affa18ef97bc9db20076945705aba8c516139abd",
input_discussion_category_name: undefined,
input_generate_release_notes: false
input_generate_release_notes: false,
input_delete_on_existing: false
}
);
});
Expand All @@ -170,7 +175,8 @@ describe("util", () => {
input_fail_on_unmatched_files: false,
input_target_commitish: undefined,
input_discussion_category_name: "releases",
input_generate_release_notes: false
input_generate_release_notes: false,
input_delete_on_existing: false
}
);
});
Expand All @@ -194,7 +200,33 @@ describe("util", () => {
input_fail_on_unmatched_files: false,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: true
input_generate_release_notes: true,
input_delete_on_existing: false
}
);
});

it("supports deleting existing releases", () => {
assert.deepStrictEqual(
parseConfig({
INPUT_DELETE_ON_EXISTING: "true"
}),
{
github_ref: "",
github_repository: "",
github_token: "",
input_body: undefined,
input_body_path: undefined,
input_draft: undefined,
input_prerelease: undefined,
input_files: [],
input_name: undefined,
input_tag_name: undefined,
input_fail_on_unmatched_files: false,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: false,
input_delete_on_existing: true
}
);
});
Expand All @@ -221,7 +253,8 @@ describe("util", () => {
input_fail_on_unmatched_files: false,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: false
input_generate_release_notes: false,
input_delete_on_existing: false
}
);
});
Expand All @@ -246,7 +279,8 @@ describe("util", () => {
input_fail_on_unmatched_files: false,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: false
input_generate_release_notes: false,
input_delete_on_existing: false
}
);
});
Expand All @@ -270,7 +304,8 @@ describe("util", () => {
input_fail_on_unmatched_files: false,
input_target_commitish: undefined,
input_discussion_category_name: undefined,
input_generate_release_notes: false
input_generate_release_notes: false,
input_delete_on_existing: false
}
);
});
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Expand Up @@ -43,6 +43,9 @@ inputs:
generate_release_notes:
description: "Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes."
required: false
delete_on_existing:
description: "Whether or not to delete an existing release entirely when running this action."
required: false
env:
"GITHUB_TOKEN": "As provided by Github Actions"
outputs:
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

102 changes: 64 additions & 38 deletions src/github.ts
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -198,6 +212,48 @@ 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
Expand All @@ -219,6 +275,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 &&
Expand Down Expand Up @@ -265,44 +328,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}`
Expand Down
4 changes: 3 additions & 1 deletion src/util.ts
Expand Up @@ -18,6 +18,7 @@ export interface Config {
input_target_commitish?: string;
input_discussion_category_name?: string;
input_generate_release_notes?: boolean;
input_delete_on_existing?: boolean;
}

export const uploadUrl = (url: string): string => {
Expand Down Expand Up @@ -67,7 +68,8 @@ export const parseConfig = (env: Env): Config => {
input_target_commitish: env.INPUT_TARGET_COMMITISH || undefined,
input_discussion_category_name:
env.INPUT_DISCUSSION_CATEGORY_NAME || undefined,
input_generate_release_notes: env.INPUT_GENERATE_RELEASE_NOTES == "true"
input_generate_release_notes: env.INPUT_GENERATE_RELEASE_NOTES == "true",
input_delete_on_existing: env.INPUT_DELETE_ON_EXISTING == "true"
};
};

Expand Down

0 comments on commit 2a671de

Please sign in to comment.