Skip to content

Commit ce037ed

Browse files
committed
Support deleting existing releases
Extracted from #181
1 parent fe9a9bd commit ce037ed

File tree

6 files changed

+122
-53
lines changed

6 files changed

+122
-53
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ The following are optional as `step.with` keys
180180
| `token` | String | Secret GitHub Personal Access Token. Defaults to `${{ github.token }}` |
181181
| `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) |
182182
| `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 |
183-
| `append_body` | Boolean | Append existed body instead of overrides |
183+
| `append_body` | Boolean | Whether to append to the existing body instead of overwriting. |
184+
| `delete_on_existing` | Boolean | Whether or not to delete an existing release entirely when running this action. |
184185

185186
💡 When providing a `body` and `body_path` at the same time, `body_path` will be
186187
attempted first, then falling back on `body` if the path can not be read from.

__tests__/util.test.ts

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ describe("util", () => {
5151
input_tag_name: undefined,
5252
input_target_commitish: undefined,
5353
input_discussion_category_name: undefined,
54-
input_generate_release_notes: false
54+
input_generate_release_notes: false,
55+
input_delete_on_existing: false
5556
})
5657
);
5758
});
@@ -71,7 +72,8 @@ describe("util", () => {
7172
input_tag_name: undefined,
7273
input_target_commitish: undefined,
7374
input_discussion_category_name: undefined,
74-
input_generate_release_notes: false
75+
input_generate_release_notes: false,
76+
input_delete_on_existing: false
7577
})
7678
);
7779
});
@@ -91,7 +93,8 @@ describe("util", () => {
9193
input_tag_name: undefined,
9294
input_target_commitish: undefined,
9395
input_discussion_category_name: undefined,
94-
input_generate_release_notes: false
96+
input_generate_release_notes: false,
97+
input_delete_on_existing: false
9598
})
9699
);
97100
});
@@ -124,7 +127,8 @@ describe("util", () => {
124127
input_fail_on_unmatched_files: false,
125128
input_target_commitish: undefined,
126129
input_discussion_category_name: undefined,
127-
input_generate_release_notes: false
130+
input_generate_release_notes: false,
131+
input_delete_on_existing: false
128132
}
129133
);
130134
});
@@ -149,7 +153,8 @@ describe("util", () => {
149153
input_fail_on_unmatched_files: false,
150154
input_target_commitish: "affa18ef97bc9db20076945705aba8c516139abd",
151155
input_discussion_category_name: undefined,
152-
input_generate_release_notes: false
156+
input_generate_release_notes: false,
157+
input_delete_on_existing: false
153158
}
154159
);
155160
});
@@ -173,7 +178,8 @@ describe("util", () => {
173178
input_fail_on_unmatched_files: false,
174179
input_target_commitish: undefined,
175180
input_discussion_category_name: "releases",
176-
input_generate_release_notes: false
181+
input_generate_release_notes: false,
182+
input_delete_on_existing: false
177183
}
178184
);
179185
});
@@ -198,7 +204,34 @@ describe("util", () => {
198204
input_fail_on_unmatched_files: false,
199205
input_target_commitish: undefined,
200206
input_discussion_category_name: undefined,
201-
input_generate_release_notes: true
207+
input_generate_release_notes: true,
208+
input_delete_on_existing: false
209+
}
210+
);
211+
});
212+
213+
it("supports deleting existing releases", () => {
214+
assert.deepStrictEqual(
215+
parseConfig({
216+
INPUT_DELETE_ON_EXISTING: "true"
217+
}),
218+
{
219+
github_ref: "",
220+
github_repository: "",
221+
github_token: "",
222+
input_append_body: false,
223+
input_body: undefined,
224+
input_body_path: undefined,
225+
input_draft: undefined,
226+
input_prerelease: undefined,
227+
input_files: [],
228+
input_name: undefined,
229+
input_tag_name: undefined,
230+
input_fail_on_unmatched_files: false,
231+
input_target_commitish: undefined,
232+
input_discussion_category_name: undefined,
233+
input_generate_release_notes: false,
234+
input_delete_on_existing: true
202235
}
203236
);
204237
});
@@ -226,7 +259,8 @@ describe("util", () => {
226259
input_fail_on_unmatched_files: false,
227260
input_target_commitish: undefined,
228261
input_discussion_category_name: undefined,
229-
input_generate_release_notes: false
262+
input_generate_release_notes: false,
263+
input_delete_on_existing: false
230264
}
231265
);
232266
});
@@ -252,7 +286,8 @@ describe("util", () => {
252286
input_fail_on_unmatched_files: false,
253287
input_target_commitish: undefined,
254288
input_discussion_category_name: undefined,
255-
input_generate_release_notes: false
289+
input_generate_release_notes: false,
290+
input_delete_on_existing: false
256291
}
257292
);
258293
});
@@ -277,7 +312,8 @@ describe("util", () => {
277312
input_fail_on_unmatched_files: false,
278313
input_target_commitish: undefined,
279314
input_discussion_category_name: undefined,
280-
input_generate_release_notes: false
315+
input_generate_release_notes: false,
316+
input_delete_on_existing: false
281317
}
282318
);
283319
});
@@ -301,7 +337,8 @@ describe("util", () => {
301337
input_fail_on_unmatched_files: false,
302338
input_target_commitish: undefined,
303339
input_discussion_category_name: undefined,
304-
input_generate_release_notes: false
340+
input_generate_release_notes: false,
341+
input_delete_on_existing: false
305342
}
306343
);
307344
});

action.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ inputs:
4444
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."
4545
required: false
4646
append_body:
47-
description: "Append existed body instead of overrites. Default is false."
47+
description: "Whether to append to the existing body instead of overwriting. Default is false."
48+
required: false
49+
delete_on_existing:
50+
description: "Whether or not to delete an existing release entirely when running this action."
4851
required: false
4952
env:
5053
"GITHUB_TOKEN": "As provided by Github Actions"

dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/github.ts

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ export interface Releaser {
6161
generate_release_notes: boolean | undefined;
6262
}): Promise<{ data: Release }>;
6363

64+
deleteRelease(params: {
65+
owner: string;
66+
repo: string;
67+
release_id: number;
68+
}): Promise<{ data: Release }>;
69+
6470
allReleases(params: {
6571
owner: string;
6672
repo: string;
@@ -112,6 +118,14 @@ export class GitHubReleaser implements Releaser {
112118
return this.github.rest.repos.updateRelease(params);
113119
}
114120

121+
deleteRelease(params: {
122+
owner: string;
123+
repo: string;
124+
release_id: number;
125+
}): Promise<{ data: Release }> {
126+
return this.github.rest.repos.deleteRelease(params);
127+
}
128+
115129
allReleases(params: {
116130
owner: string;
117131
repo: string;
@@ -198,6 +212,48 @@ export const release = async (
198212

199213
const discussion_category_name = config.input_discussion_category_name;
200214
const generate_release_notes = config.input_generate_release_notes;
215+
216+
const createRelease = async () => {
217+
const tag_name = tag;
218+
const name = config.input_name || tag;
219+
const body = releaseBody(config);
220+
const draft = config.input_draft;
221+
const prerelease = config.input_prerelease;
222+
const target_commitish = config.input_target_commitish;
223+
let commitMessage: string = "";
224+
if (target_commitish) {
225+
commitMessage = ` using commit "${target_commitish}"`;
226+
}
227+
console.log(
228+
`👩‍🏭 Creating new GitHub release for tag ${tag_name}${commitMessage}...`
229+
);
230+
try {
231+
let release = await releaser.createRelease({
232+
owner,
233+
repo,
234+
tag_name,
235+
name,
236+
body,
237+
draft,
238+
prerelease,
239+
target_commitish,
240+
discussion_category_name,
241+
generate_release_notes
242+
});
243+
return release.data;
244+
} catch (error) {
245+
// presume a race with competing metrix runs
246+
console.log(
247+
`⚠️ GitHub release failed with status: ${
248+
error.status
249+
}\n${JSON.stringify(
250+
error.response.data.errors
251+
)}\nretrying... (${maxRetries - 1} retries remaining)`
252+
);
253+
return release(config, releaser, maxRetries - 1);
254+
}
255+
};
256+
201257
try {
202258
// you can't get a an existing draft by tag
203259
// so we must find one in the list of all releases
@@ -219,6 +275,13 @@ export const release = async (
219275
});
220276

221277
const release_id = existingRelease.data.id;
278+
279+
if (config.input_delete_on_existing) {
280+
console.log(`⚠ Deleting existing release ${owner}/${repo}@${release_id}`);
281+
await releaser.deleteRelease({ owner, repo, release_id });
282+
return createRelease();
283+
}
284+
222285
let target_commitish: string;
223286
if (
224287
config.input_target_commitish &&
@@ -272,44 +335,7 @@ export const release = async (
272335
return release.data;
273336
} catch (error) {
274337
if (error.status === 404) {
275-
const tag_name = tag;
276-
const name = config.input_name || tag;
277-
const body = releaseBody(config);
278-
const draft = config.input_draft;
279-
const prerelease = config.input_prerelease;
280-
const target_commitish = config.input_target_commitish;
281-
let commitMessage: string = "";
282-
if (target_commitish) {
283-
commitMessage = ` using commit "${target_commitish}"`;
284-
}
285-
console.log(
286-
`👩‍🏭 Creating new GitHub release for tag ${tag_name}${commitMessage}...`
287-
);
288-
try {
289-
let release = await releaser.createRelease({
290-
owner,
291-
repo,
292-
tag_name,
293-
name,
294-
body,
295-
draft,
296-
prerelease,
297-
target_commitish,
298-
discussion_category_name,
299-
generate_release_notes
300-
});
301-
return release.data;
302-
} catch (error) {
303-
// presume a race with competing metrix runs
304-
console.log(
305-
`⚠️ GitHub release failed with status: ${
306-
error.status
307-
}\n${JSON.stringify(
308-
error.response.data.errors
309-
)}\nretrying... (${maxRetries - 1} retries remaining)`
310-
);
311-
return release(config, releaser, maxRetries - 1);
312-
}
338+
return createRelease();
313339
} else {
314340
console.log(
315341
`⚠️ Unexpected error fetching GitHub release for tag ${config.github_ref}: ${error}`

src/util.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export interface Config {
1919
input_discussion_category_name?: string;
2020
input_generate_release_notes?: boolean;
2121
input_append_body?: boolean;
22+
input_delete_on_existing?: boolean;
2223
}
2324

2425
export const uploadUrl = (url: string): string => {
@@ -69,7 +70,8 @@ export const parseConfig = (env: Env): Config => {
6970
input_discussion_category_name:
7071
env.INPUT_DISCUSSION_CATEGORY_NAME || undefined,
7172
input_generate_release_notes: env.INPUT_GENERATE_RELEASE_NOTES == "true",
72-
input_append_body: env.INPUT_APPEND_BODY == "true"
73+
input_append_body: env.INPUT_APPEND_BODY == "true",
74+
input_delete_on_existing: env.INPUT_DELETE_ON_EXISTING == "true"
7375
};
7476
};
7577

0 commit comments

Comments
 (0)