mirror of
https://gh-proxy.org/https://github.com/softprops/action-gh-release.git
synced 2026-07-16 07:23:00 +08:00
Compare commits
4 Commits
7e13ed4ac5
...
d100e75a45
| Author | SHA1 | Date | |
|---|---|---|---|
| d100e75a45 | |||
| 81bcd9dd59 | |||
| b05950fac2 | |||
| 3d0d9888cb |
+38
-3
@@ -1,3 +1,35 @@
|
|||||||
|
## 3.0.2
|
||||||
|
|
||||||
|
`3.0.2` is a patch release focused on release reliability and compatibility. It
|
||||||
|
reuses existing draft releases when publishing prereleases, supports replacing
|
||||||
|
release assets on Gitea, hardens streamed asset uploads, and provides clearer
|
||||||
|
release-creation diagnostics. It also includes TypeScript, coverage, and tooling
|
||||||
|
maintenance merged since `3.0.1`.
|
||||||
|
|
||||||
|
This release fixes #795, #438, and #803. The upload transport hardening covers the
|
||||||
|
historical failure reported in #790, although current hosted Node 24 runners did
|
||||||
|
not reproduce it naturally. The diagnostics work is related to #786 and does not
|
||||||
|
claim a reproducible release-creation fix.
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
|
||||||
|
### Exciting New Features 🎉
|
||||||
|
|
||||||
|
* feat: improve release error reporting and test coverage by @chenrui333 in https://github.com/softprops/action-gh-release/pull/813
|
||||||
|
|
||||||
|
### Bug fixes 🐛
|
||||||
|
|
||||||
|
* fix: publish existing draft releases as prereleases by @godfengliang in https://github.com/softprops/action-gh-release/pull/801
|
||||||
|
* fix: upload small checksum assets reliably by @chenrui333 in https://github.com/softprops/action-gh-release/pull/815
|
||||||
|
* fix: replace existing release assets on Gitea by @chenrui333 in https://github.com/softprops/action-gh-release/pull/816
|
||||||
|
* fix: clarify release creation 404 errors by @chenrui333 in https://github.com/softprops/action-gh-release/pull/817
|
||||||
|
|
||||||
|
### Other Changes 🔄
|
||||||
|
|
||||||
|
* chore(deps): upgrade TypeScript to 7 by @chenrui333 in https://github.com/softprops/action-gh-release/pull/812
|
||||||
|
* chore(deps): remove unused TypeScript tooling by @chenrui333 in https://github.com/softprops/action-gh-release/pull/814
|
||||||
|
* dependency, Node 24 pin, and CI maintenance merged since `3.0.1`
|
||||||
|
|
||||||
## 3.0.1
|
## 3.0.1
|
||||||
|
|
||||||
- maintenance release with updated dependencies
|
- maintenance release with updated dependencies
|
||||||
@@ -6,8 +38,8 @@
|
|||||||
|
|
||||||
`3.0.0` is a major release that moves the action runtime from Node 20 to Node 24.
|
`3.0.0` is a major release that moves the action runtime from Node 20 to Node 24.
|
||||||
Use `v3` on GitHub-hosted runners and self-hosted fleets that already support the
|
Use `v3` on GitHub-hosted runners and self-hosted fleets that already support the
|
||||||
Node 24 Actions runtime. If you still need the last Node 20-compatible line, stay on
|
Node 24 Actions runtime. `v2.6.2` was the final Node 20-compatible release and is
|
||||||
`v2.6.2`.
|
no longer maintained or supported.
|
||||||
|
|
||||||
## What's Changed
|
## What's Changed
|
||||||
|
|
||||||
@@ -15,10 +47,13 @@ Node 24 Actions runtime. If you still need the last Node 20-compatible line, sta
|
|||||||
|
|
||||||
* Move the action runtime and bundle target to Node 24
|
* Move the action runtime and bundle target to Node 24
|
||||||
* Update `@types/node` to the Node 24 line and allow future Dependabot updates
|
* Update `@types/node` to the Node 24 line and allow future Dependabot updates
|
||||||
* Keep the floating major tag on `v3`; `v2` remains pinned to the latest `2.x` release
|
* Keep the floating major tag on `v3`; freeze `v2` at the final `v2.6.2` release
|
||||||
|
|
||||||
## 2.6.2
|
## 2.6.2
|
||||||
|
|
||||||
|
`2.6.2` is the final `v2` release and is no longer maintained or supported. Upgrade
|
||||||
|
to `v3` for the supported Node 24 runtime and current fixes.
|
||||||
|
|
||||||
## What's Changed
|
## What's Changed
|
||||||
|
|
||||||
### Other Changes 🔄
|
### Other Changes 🔄
|
||||||
|
|||||||
@@ -39,8 +39,11 @@ Typically usage of this action involves adding a step to a build that
|
|||||||
is gated pushes to git tags. You may find `step.if` field helpful in accomplishing this
|
is gated pushes to git tags. You may find `step.if` field helpful in accomplishing this
|
||||||
as it maximizes the reuse value of your workflow for non-tag pushes.
|
as it maximizes the reuse value of your workflow for non-tag pushes.
|
||||||
|
|
||||||
`v3` requires a GitHub Actions runtime that supports Node 24. If you still need the
|
`v2.6.2` is the final `v2` release and is no longer maintained or supported. It
|
||||||
last Node 20-compatible line, stay on `v2.6.2`.
|
uses the [Node 20 runtime deprecated by GitHub Actions](https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/).
|
||||||
|
Upgrade to `v3`, which runs on Node 24. If a problem still reproduces on the
|
||||||
|
latest `v3`, open a new issue with the exact action ref, workflow run URL,
|
||||||
|
runner, and relevant logs.
|
||||||
|
|
||||||
Below is a simple example of `step.if` tag gating
|
Below is a simple example of `step.if` tag gating
|
||||||
|
|
||||||
|
|||||||
+23
-10
@@ -23,21 +23,34 @@ Use this checklist when cutting a new `action-gh-release` release.
|
|||||||
- `npm run build`
|
- `npm run build`
|
||||||
- `npm test`
|
- `npm test`
|
||||||
5. Commit the release prep.
|
5. Commit the release prep.
|
||||||
- Use a plain release commit message like `release 3.0.0`.
|
- Use `git commit -s` so the release commit carries a DCO sign-off.
|
||||||
6. Create the annotated tag for the release commit.
|
- Use a plain release commit message like `release X.Y.Z`.
|
||||||
- Example: `git tag -a v3.0.0 -m "v3.0.0"`
|
6. Push a release branch and open a pull request against `master`.
|
||||||
7. Push the commit and tag.
|
- Wait for required checks and reviews.
|
||||||
- Example: `git push origin master && git push origin v3.0.0`
|
- Do not bypass branch protection or tag an unmerged release branch.
|
||||||
8. Move the floating major tag to the new release tag.
|
7. After merge, fetch `origin/master` and resolve the exact merged release commit.
|
||||||
|
- Confirm that commit contains the expected package version and top changelog entry.
|
||||||
|
- When the PR is squash-merged, do not assume the release branch commit is the release commit.
|
||||||
|
8. Create and push the full annotated version tag on the merged release commit.
|
||||||
|
- Example: `git tag -a vX.Y.Z -m "vX.Y.Z" <release-commit>`
|
||||||
|
- Push only the full version tag first, then wait for its tag-triggered CI to pass.
|
||||||
|
9. Move the floating major tag to the same merged release commit.
|
||||||
- For the current major line, run `npm run updatetag` to move `v3`.
|
- For the current major line, run `npm run updatetag` to move `v3`.
|
||||||
- Keep `v2` pinned to the latest `2.x` release for consumers that still need the Node 20 runtime.
|
- Do not move `v2`; it is frozen at the final, unsupported `v2.6.2` release.
|
||||||
- Verify the floating tag points at the same commit as the new full tag.
|
- Verify `v3` and the full version tag are annotated and peel to the same commit.
|
||||||
9. Create the GitHub release from the new tag.
|
- Verify `v2` did not move, then wait for the separate `v3` tag-triggered CI run to pass.
|
||||||
|
10. Create the GitHub release from the full version tag.
|
||||||
- Prefer the release body from [CHANGELOG.md](CHANGELOG.md), then let GitHub append generated notes only if they add value.
|
- Prefer the release body from [CHANGELOG.md](CHANGELOG.md), then let GitHub append generated notes only if they add value.
|
||||||
- Verify the release shows the expected tag, title, notes, and attached artifacts.
|
- Verify the release shows the expected tag, title, notes, draft/prerelease state, and attached artifacts.
|
||||||
|
11. Run post-release consumer verification in `ruitest2/action-gh-release-test`.
|
||||||
|
- Run the generic smoke against both the full version tag and `v3`.
|
||||||
|
- Run regression workflows relevant to the fixes in the release.
|
||||||
|
- Confirm that every disposable release, tag, discussion, container, volume, and temporary credential was cleaned up.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Behavior changes should already have matching updates in [README.md](README.md), [action.yml](action.yml), tests, and `dist/index.js` before release prep begins.
|
- Behavior changes should already have matching updates in [README.md](README.md), [action.yml](action.yml), tests, and `dist/index.js` before release prep begins.
|
||||||
- Docs-only releases still need an intentional changelog entry and version bump decision.
|
- Docs-only releases still need an intentional changelog entry and version bump decision.
|
||||||
- If a release is mainly bug fixes, keep the title and summary patch-oriented; do not bury the actual fixes under dependency noise.
|
- If a release is mainly bug fixes, keep the title and summary patch-oriented; do not bury the actual fixes under dependency noise.
|
||||||
|
- Do not move the floating major tag or publish the GitHub release until the full
|
||||||
|
version tag's CI passes.
|
||||||
|
|||||||
@@ -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([
|
it.each([
|
||||||
['an omitted draft input', undefined],
|
['an omitted draft input', undefined],
|
||||||
['a null-expression draft input', undefined],
|
['a null-expression draft input', undefined],
|
||||||
|
|||||||
@@ -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 () => {
|
it('leaves an existing draft recoverable when an upload fails', async () => {
|
||||||
config = {
|
config = {
|
||||||
...config,
|
...config,
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "action-gh-release",
|
"name": "action-gh-release",
|
||||||
"version": "3.0.1",
|
"version": "3.0.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "action-gh-release",
|
"name": "action-gh-release",
|
||||||
"version": "3.0.1",
|
"version": "3.0.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^3.0.1",
|
"@actions/core": "^3.0.1",
|
||||||
"@actions/github": "^9.1.1",
|
"@actions/github": "^9.1.1",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "action-gh-release",
|
"name": "action-gh-release",
|
||||||
"version": "3.0.1",
|
"version": "3.0.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "GitHub Action for creating GitHub Releases",
|
"description": "GitHub Action for creating GitHub Releases",
|
||||||
"main": "lib/main.js",
|
"main": "lib/main.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user