test: cover release lookup after tag replacement (#820)

Signed-off-by: Rui Chen <rui@chenrui.dev>
This commit is contained in:
Rui Chen
2026-07-13 12:39:38 -04:00
committed by GitHub
parent b05950fac2
commit 81bcd9dd59
2 changed files with 103 additions and 0 deletions
+55
View File
@@ -1063,6 +1063,61 @@ describe('github', () => {
);
});
it('reuses a published prerelease found by listing after direct tag lookup returns 404', async () => {
const existingRelease: Release = {
id: 77,
upload_url: 'existing-upload',
html_url: 'existing-html',
tag_name: 'v1.0.0',
name: 'nightly',
body: 'previous nightly body',
target_commitish: 'old-commit',
draft: false,
prerelease: true,
assets: [{ id: 5, name: 'nightly.zip' }],
};
const updatedRelease: Release = {
...existingRelease,
name: 'updated nightly',
body: 'updated nightly body',
target_commitish: 'new-commit',
};
const createRelease = unexpected('createRelease');
const updateRelease = vi.fn().mockResolvedValue({ data: updatedRelease });
const releaser = createReleaser({
getReleaseByTag: vi.fn().mockRejectedValue({ status: 404 }),
allReleases: async function* () {
yield { data: [existingRelease] };
},
createRelease,
updateRelease,
});
const result = await release(
{
...config,
input_name: 'updated nightly',
input_body: 'updated nightly body',
input_prerelease: true,
input_draft: false,
input_target_commitish: 'new-commit',
},
releaser,
);
expect(result).toEqual({ release: updatedRelease, created: false });
expect(updateRelease).toHaveBeenCalledWith(
expect.objectContaining({
release_id: existingRelease.id,
tag_name: existingRelease.tag_name,
target_commitish: 'new-commit',
draft: false,
prerelease: true,
}),
);
expect(createRelease).not.toHaveBeenCalled();
});
it.each([
['an omitted draft input', undefined],
['a null-expression draft input', undefined],
+48
View File
@@ -286,6 +286,54 @@ describe('run', () => {
);
});
it('uses the selected moving-tag release ID for upload, finalization, and outputs', async () => {
config = {
...config,
input_tag_name: 'nightly',
input_draft: false,
input_prerelease: true,
input_files: ['nightly.zip'],
};
const selectedRelease: Release = {
...initialRelease,
id: 77,
upload_url: 'https://uploads.example.test/releases/77/assets{?name,label}',
html_url: 'https://example.test/releases/77',
tag_name: 'nightly',
name: 'nightly',
prerelease: true,
};
const publishedRelease: Release = {
...selectedRelease,
draft: false,
};
mocks.release.mockResolvedValue({ release: selectedRelease, created: false });
mocks.paths.mockReturnValue(['nightly.zip']);
mocks.upload.mockResolvedValue({ id: 9 });
mocks.finalizeRelease.mockResolvedValue(publishedRelease);
mocks.listReleaseAssets.mockResolvedValue([{ id: 9, name: 'nightly.zip' }]);
await run();
expect(mocks.upload).toHaveBeenCalledWith(
config,
mocks.releaser,
'https://uploads.example.test/releases/77/assets',
'nightly.zip',
selectedRelease.assets,
77,
);
expect(mocks.finalizeRelease).toHaveBeenCalledWith(
config,
mocks.releaser,
selectedRelease,
false,
);
expect(mocks.listReleaseAssets).toHaveBeenCalledWith(config, mocks.releaser, publishedRelease);
expect(mocks.setOutput).toHaveBeenCalledWith('id', '77');
expect(mocks.setOutput).toHaveBeenCalledWith('url', publishedRelease.html_url);
});
it('leaves an existing draft recoverable when an upload fails', async () => {
config = {
...config,