mirror of
https://github.com/softprops/action-gh-release.git
synced 2026-05-05 06:48:00 +08:00
fix: draft prereleases before uploading assets
Signed-off-by: Rui Chen <rui@chenrui.dev>
This commit is contained in:
@@ -240,6 +240,11 @@ will retain its original info.
|
|||||||
existing draft release, set `draft: true` to keep it draft; if `draft` is omitted,
|
existing draft release, set `draft: true` to keep it draft; if `draft` is omitted,
|
||||||
the action will publish that draft after uploading assets.
|
the action will publish that draft after uploading assets.
|
||||||
|
|
||||||
|
💡 When the action creates a new release that uploads assets, it stages the release
|
||||||
|
as a draft first, uploads the assets, and then publishes it unless `draft: true`
|
||||||
|
keeps it as a draft. This keeps new prereleases compatible with GitHub immutable
|
||||||
|
releases.
|
||||||
|
|
||||||
💡 `files` is glob-based, so literal filenames that contain glob metacharacters such as
|
💡 `files` is glob-based, so literal filenames that contain glob metacharacters such as
|
||||||
`[` or `]` must be escaped in the pattern.
|
`[` or `]` must be escaped in the pattern.
|
||||||
|
|
||||||
|
|||||||
@@ -517,7 +517,7 @@ describe('github', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates published prereleases without the forced draft-first path', async () => {
|
it('creates published prereleases without the forced draft-first path when no assets are configured', async () => {
|
||||||
const prereleaseConfig = {
|
const prereleaseConfig = {
|
||||||
...config,
|
...config,
|
||||||
input_prerelease: true,
|
input_prerelease: true,
|
||||||
@@ -564,6 +564,54 @@ describe('github', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('creates draft prereleases when assets are configured so uploads can finish before publish', async () => {
|
||||||
|
const prereleaseConfig = {
|
||||||
|
...config,
|
||||||
|
input_prerelease: true,
|
||||||
|
input_draft: false,
|
||||||
|
input_files: ['draft-false.txt'],
|
||||||
|
};
|
||||||
|
const createdRelease: Release = {
|
||||||
|
id: 1,
|
||||||
|
upload_url: 'test',
|
||||||
|
html_url: 'test',
|
||||||
|
tag_name: 'v1.0.0',
|
||||||
|
name: 'test',
|
||||||
|
body: 'test',
|
||||||
|
target_commitish: 'main',
|
||||||
|
draft: true,
|
||||||
|
prerelease: true,
|
||||||
|
assets: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const createReleaseSpy = vi.fn(async () => ({ data: createdRelease }));
|
||||||
|
const mockReleaser: Releaser = {
|
||||||
|
getReleaseByTag: () => Promise.reject({ status: 404 }),
|
||||||
|
createRelease: createReleaseSpy,
|
||||||
|
updateRelease: () => Promise.reject('Not implemented'),
|
||||||
|
finalizeRelease: () => Promise.reject('Not implemented'),
|
||||||
|
allReleases: async function* () {
|
||||||
|
yield { data: [createdRelease] };
|
||||||
|
},
|
||||||
|
listReleaseAssets: () => Promise.reject('Not implemented'),
|
||||||
|
deleteReleaseAsset: () => Promise.reject('Not implemented'),
|
||||||
|
deleteRelease: () => Promise.reject('Not implemented'),
|
||||||
|
updateReleaseAsset: () => Promise.reject('Not implemented'),
|
||||||
|
uploadReleaseAsset: () => Promise.reject('Not implemented'),
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
const result = await release(prereleaseConfig, mockReleaser, 1);
|
||||||
|
|
||||||
|
assert.equal(result.release.id, createdRelease.id);
|
||||||
|
assert.equal(result.created, true);
|
||||||
|
expect(createReleaseSpy).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
draft: true,
|
||||||
|
prerelease: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('retries upload after deleting conflicting asset on 422 already_exists race', async () => {
|
it('retries upload after deleting conflicting asset on 422 already_exists race', async () => {
|
||||||
const uploadReleaseAsset = vi
|
const uploadReleaseAsset = vi
|
||||||
.fn()
|
.fn()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ inputs:
|
|||||||
description: "Gives a tag name. Defaults to github.ref_name. refs/tags/<name> values are normalized to <name>."
|
description: "Gives a tag name. Defaults to github.ref_name. refs/tags/<name> values are normalized to <name>."
|
||||||
required: false
|
required: false
|
||||||
draft:
|
draft:
|
||||||
description: "Keeps the release as a draft. Defaults to false. When reusing an existing draft release, set this to true to keep it draft; omit it to publish after upload."
|
description: "Keeps the release as a draft. Defaults to false. New releases that upload assets are staged as drafts first; set this to true to keep the release draft instead of publishing it after upload."
|
||||||
required: false
|
required: false
|
||||||
prerelease:
|
prerelease:
|
||||||
description: "Identify the release as a prerelease. Defaults to false"
|
description: "Identify the release as a prerelease. Defaults to false"
|
||||||
|
|||||||
2
dist/index.js
vendored
2
dist/index.js
vendored
File diff suppressed because one or more lines are too long
@@ -875,7 +875,8 @@ async function createRelease(
|
|||||||
const name = config.input_name || tag;
|
const name = config.input_name || tag;
|
||||||
const body = releaseBody(config);
|
const body = releaseBody(config);
|
||||||
const prerelease = config.input_prerelease;
|
const prerelease = config.input_prerelease;
|
||||||
const draft = prerelease === true ? config.input_draft === true : true;
|
const draft =
|
||||||
|
config.input_draft === true || prerelease !== true || (config.input_files?.length ?? 0) > 0;
|
||||||
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;
|
||||||
let commitMessage: string = '';
|
let commitMessage: string = '';
|
||||||
|
|||||||
Reference in New Issue
Block a user