Compare commits

...

13 Commits

Author SHA1 Message Date
Rui Chen
a06a81a03e release 2.5.0
Some checks failed
main / build (push) Has been cancelled
Signed-off-by: Rui Chen <rui@chenrui.dev>
2025-12-01 01:02:34 -05:00
jj
7da8983734 feat: mark release as draft until all artifacts are uploaded (#692)
Previously, the releases were created and then artifacts (if any)
were added to them. This broke when GitHub released "immutable"
releases, which disallow changes after the release is published.

Make it so that releases are always marked as "draft" when being
worked on by the action, and unmarked as draft (if desired) once
the action is completed.

Fixes #653
2025-12-01 00:59:24 -05:00
dependabot[bot]
87973286a4 chore(deps): bump actions/checkout in the github-actions group (#689)
Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout).


Updates `actions/checkout` from 5.0.0 to 5.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](08c6903cd8...93cb6efe18)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 00:56:27 -05:00
dependabot[bot]
1bfc62a71b chore(deps): bump the npm group across 1 directory with 5 updates (#697)
Bumps the npm group with 4 updates in the / directory: [glob](https://github.com/isaacs/node-glob), [mime-types](https://github.com/jshttp/mime-types), [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) and [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8).


Updates `glob` from 11.0.3 to 13.0.0
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v11.0.3...v13.0.0)

Updates `mime-types` from 3.0.1 to 3.0.2
- [Release notes](https://github.com/jshttp/mime-types/releases)
- [Changelog](https://github.com/jshttp/mime-types/blob/master/HISTORY.md)
- [Commits](https://github.com/jshttp/mime-types/compare/v3.0.1...v3.0.2)

Updates `@types/node` from 20.19.24 to 20.19.25
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@vitest/coverage-v8` from 4.0.6 to 4.0.13
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.13/packages/coverage-v8)

Updates `vitest` from 4.0.6 to 4.0.13
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.13/packages/vitest)

---
updated-dependencies:
- dependency-name: glob
  dependency-version: 13.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm
- dependency-name: mime-types
  dependency-version: 3.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/node"
  dependency-version: 20.19.25
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: vitest
  dependency-version: 4.0.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 00:56:07 -05:00
Rui Chen
5be0e66d93 release 2.4.2
Some checks failed
main / build (push) Has been cancelled
Signed-off-by: Rui Chen <rui@chenrui.dev>
2025-11-08 14:21:57 -05:00
Jens L.
af658b4d5d feat: Ensure generated release notes cannot be over 125000 characters (#684)
* Ensure generated release notes cannot be over 125000 characters

* simpler truncate, and always truncate even without generated
2025-11-08 14:20:00 -05:00
Rui Chen
237aaccf71 chore: bump node to 24.11.0
Signed-off-by: Rui Chen <rui@chenrui.dev>
2025-11-08 14:18:20 -05:00
dependabot[bot]
00362bea6f chore(deps): bump the npm group with 5 updates (#687)
Some checks failed
main / build (push) Has been cancelled
Bumps the npm group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [@octokit/plugin-retry](https://github.com/octokit/plugin-retry.js) | `8.0.2` | `8.0.3` |
| [@octokit/plugin-throttling](https://github.com/octokit/plugin-throttling.js) | `11.0.2` | `11.0.3` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `20.19.23` | `20.19.24` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `4.0.4` | `4.0.6` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.0.4` | `4.0.6` |


Updates `@octokit/plugin-retry` from 8.0.2 to 8.0.3
- [Release notes](https://github.com/octokit/plugin-retry.js/releases)
- [Commits](https://github.com/octokit/plugin-retry.js/compare/v8.0.2...v8.0.3)

Updates `@octokit/plugin-throttling` from 11.0.2 to 11.0.3
- [Release notes](https://github.com/octokit/plugin-throttling.js/releases)
- [Commits](https://github.com/octokit/plugin-throttling.js/compare/v11.0.2...v11.0.3)

Updates `@types/node` from 20.19.23 to 20.19.24
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@vitest/coverage-v8` from 4.0.4 to 4.0.6
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.6/packages/coverage-v8)

Updates `vitest` from 4.0.4 to 4.0.6
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.6/packages/vitest)

---
updated-dependencies:
- dependency-name: "@octokit/plugin-retry"
  dependency-version: 8.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@octokit/plugin-throttling"
  dependency-version: 11.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/node"
  dependency-version: 20.19.24
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: vitest
  dependency-version: 4.0.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-07 21:47:12 -05:00
dependabot[bot]
0adea5aa98 chore(deps): bump the npm group with 3 updates (#686)
Some checks failed
main / build (push) Has been cancelled
Bumps the npm group with 3 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `@types/node` from 20.19.22 to 20.19.23
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@vitest/coverage-v8` from 3.2.4 to 4.0.4
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.4/packages/coverage-v8)

Updates `vitest` from 3.2.4 to 4.0.4
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.4/packages/vitest)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 20.19.23
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.4
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm
- dependency-name: vitest
  dependency-version: 4.0.4
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-30 14:36:32 -04:00
dependabot[bot]
aa05f9d779 chore(deps): bump actions/setup-node from 5.0.0 to 6.0.0 in the github-actions group (#683)
Some checks failed
main / build (push) Has been cancelled
* chore(deps): bump actions/setup-node in the github-actions group

Bumps the github-actions group with 1 update: [actions/setup-node](https://github.com/actions/setup-node).


Updates `actions/setup-node` from 5.0.0 to 6.0.0
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](a0853c2454...2028fbc5c2)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>

* update comment

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rui Chen <rui@chenrui.dev>
2025-10-23 22:23:58 -04:00
dependabot[bot]
bbaccb3a0c chore(deps): bump @types/node from 20.19.21 to 20.19.22 in the npm group (#682)
Bumps the npm group with 1 update: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node).


Updates `@types/node` from 20.19.21 to 20.19.22
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 20.19.22
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-23 22:22:08 -04:00
dependabot[bot]
50fda3f773 chore(deps): bump vite from 7.1.5 to 7.1.11 (#681)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.1.5 to 7.1.11.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.1.11/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.1.11
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-23 22:21:57 -04:00
dependabot[bot]
5434409c2b chore(deps): bump @types/node from 20.19.19 to 20.19.21 in the npm group (#679)
Some checks failed
main / build (push) Has been cancelled
Bumps the npm group with 1 update: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node).


Updates `@types/node` from 20.19.19 to 20.19.21
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 20.19.21
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-16 18:49:13 -04:00
9 changed files with 696 additions and 1038 deletions

View File

@@ -8,9 +8,9 @@ jobs:
build:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v4
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
with:
node-version-file: ".tool-versions"
cache: "npm"

View File

@@ -1 +1 @@
nodejs 24.2.0
nodejs 24.11.0

View File

@@ -1,3 +1,27 @@
## 2.5.0
## What's Changed
### Exciting New Features 🎉
* feat: mark release as draft until all artifacts are uploaded by @dumbmoron in https://github.com/softprops/action-gh-release/pull/692
### Other Changes 🔄
* dependency updates
## 2.4.2
## What's Changed
### Exciting New Features 🎉
* feat: Ensure generated release notes cannot be over 125000 characters by @BeryJu in https://github.com/softprops/action-gh-release/pull/684
### Other Changes 🔄
* dependency updates
## 2.4.1
## What's Changed

View File

@@ -49,6 +49,7 @@ describe('github', () => {
getReleaseByTag: () => Promise.reject('Not implemented'),
createRelease: () => Promise.reject('Not implemented'),
updateRelease: () => Promise.reject('Not implemented'),
finalizeRelease: () => Promise.reject('Not implemented'),
allReleases: async function* () {
yield { data: [mockRelease] };
},
@@ -254,11 +255,12 @@ describe('github', () => {
name: 'test',
body: 'test',
target_commitish: 'main',
draft: false,
draft: true,
prerelease: false,
assets: [],
},
}),
finalizeRelease: async () => {},
allReleases: async function* () {
yield {
data: [

4
dist/index.js vendored

File diff suppressed because one or more lines are too long

1565
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "action-gh-release",
"version": "2.4.1",
"version": "2.5.0",
"private": true,
"description": "GitHub Action for creating GitHub Releases",
"main": "lib/main.js",
@@ -24,21 +24,21 @@
"dependencies": {
"@actions/core": "^1.11.1",
"@actions/github": "^6.0.1",
"@octokit/plugin-retry": "^8.0.2",
"@octokit/plugin-throttling": "^11.0.2",
"glob": "^11.0.3",
"mime-types": "^3.0.1"
"@octokit/plugin-retry": "^8.0.3",
"@octokit/plugin-throttling": "^11.0.3",
"glob": "^13.0.0",
"mime-types": "^3.0.2"
},
"devDependencies": {
"@types/glob": "^9.0.0",
"@types/mime-types": "^3.0.1",
"@types/node": "^20.19.19",
"@types/node": "^20.19.25",
"@vercel/ncc": "^0.38.4",
"@vitest/coverage-v8": "^3.2.4",
"@vitest/coverage-v8": "^4.0.13",
"prettier": "3.6.2",
"ts-node": "^10.9.2",
"typescript": "^5.9.3",
"typescript-formatter": "^7.2.2",
"vitest": "^3.1.4"
"vitest": "^4.0.4"
}
}

View File

@@ -58,6 +58,12 @@ export interface Releaser {
make_latest: 'true' | 'false' | 'legacy' | undefined;
}): Promise<{ data: Release }>;
finalizeRelease(params: {
owner: string;
repo: string;
release_id: number;
}): Promise<{ data: Release }>;
allReleases(params: { owner: string; repo: string }): AsyncIterableIterator<{ data: Release[] }>;
}
@@ -75,7 +81,27 @@ export class GitHubReleaser implements Releaser {
return this.github.rest.repos.getReleaseByTag(params);
}
createRelease(params: {
async getReleaseNotes(params: {
owner: string;
repo: string;
tag_name: string;
target_commitish: string | undefined;
}): Promise<{
data: {
name: string;
body: string;
};
}> {
return await this.github.rest.repos.generateReleaseNotes(params);
}
truncateReleaseNotes(input: string): string {
// release notes can be a maximum of 125000 characters
const githubNotesMaxCharLength = 125000;
return input.substring(0, githubNotesMaxCharLength - 1);
}
async createRelease(params: {
owner: string;
repo: string;
tag_name: string;
@@ -94,11 +120,20 @@ export class GitHubReleaser implements Releaser {
) {
params.make_latest = undefined;
}
if (params.generate_release_notes) {
const releaseNotes = await this.getReleaseNotes(params);
params.generate_release_notes = false;
if (params.body) {
params.body = `${params.body}\n\n${releaseNotes.data.body}`;
} else {
params.body = releaseNotes.data.body;
}
}
params.body = params.body ? this.truncateReleaseNotes(params.body) : undefined;
return this.github.rest.repos.createRelease(params);
}
updateRelease(params: {
async updateRelease(params: {
owner: string;
repo: string;
release_id: number;
@@ -118,10 +153,28 @@ export class GitHubReleaser implements Releaser {
) {
params.make_latest = undefined;
}
if (params.generate_release_notes) {
const releaseNotes = await this.getReleaseNotes(params);
params.generate_release_notes = false;
if (params.body) {
params.body = `${params.body}\n\n${releaseNotes.data.body}`;
} else {
params.body = releaseNotes.data.body;
}
}
params.body = params.body ? this.truncateReleaseNotes(params.body) : undefined;
return this.github.rest.repos.updateRelease(params);
}
async finalizeRelease(params: { owner: string; repo: string; release_id: number }) {
return await this.github.rest.repos.updateRelease({
owner: params.owner,
repo: params.repo,
release_id: params.release_id,
draft: false,
});
}
allReleases(params: { owner: string; repo: string }): AsyncIterableIterator<{ data: Release[] }> {
const updatedParams = { per_page: 100, ...params };
return this.github.paginate.iterator(
@@ -265,7 +318,6 @@ export const release = async (
body = workflowBody || existingReleaseBody;
}
const draft = config.input_draft !== undefined ? config.input_draft : existingRelease.draft;
const prerelease =
config.input_prerelease !== undefined ? config.input_prerelease : existingRelease.prerelease;
@@ -279,7 +331,7 @@ export const release = async (
target_commitish,
name,
body,
draft,
draft: existingRelease.draft,
prerelease,
discussion_category_name,
generate_release_notes,
@@ -307,6 +359,45 @@ export const release = async (
}
};
/**
* Finalizes a release by unmarking it as "draft" (if relevant)
* after all artifacts have been uploaded.
*
* @param config - Release configuration as specified by user
* @param releaser - The GitHub API wrapper for release operations
* @param release - The existing release to be finalized
* @param maxRetries - The maximum number of attempts to finalize the release
*/
export const finalizeRelease = async (
config: Config,
releaser: Releaser,
release: Release,
maxRetries: number = 3,
): Promise<Release> => {
if (config.input_draft === true) {
return release;
}
if (maxRetries <= 0) {
console.log(`❌ Too many retries. Aborting...`);
throw new Error('Too many retries.');
}
const [owner, repo] = config.github_repository.split('/');
try {
const { data } = await releaser.finalizeRelease({
owner,
repo,
release_id: release.id,
});
return data;
} catch {
console.log(`retrying... (${maxRetries - 1} retries remaining)`);
return finalizeRelease(config, releaser, release, maxRetries - 1);
}
};
/**
* Finds a release by tag name from all a repository's releases.
*
@@ -347,7 +438,6 @@ async function createRelease(
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;
const make_latest = config.input_make_latest;
@@ -363,7 +453,7 @@ async function createRelease(
tag_name,
name,
body,
draft,
draft: true,
prerelease,
target_commitish,
discussion_category_name,

View File

@@ -1,6 +1,6 @@
import { setFailed, setOutput } from '@actions/core';
import { getOctokit } from '@actions/github';
import { GitHubReleaser, release, upload } from './github';
import { GitHubReleaser, release, finalizeRelease, upload } from './github';
import { isTag, parseConfig, paths, unmatchedPatterns, uploadUrl } from './util';
import { env } from 'process';
@@ -48,7 +48,8 @@ async function run() {
},
});
//);
const rel = await release(config, new GitHubReleaser(gh));
const releaser = new GitHubReleaser(gh);
let rel = await release(config, releaser);
if (config.input_files && config.input_files.length > 0) {
const files = paths(config.input_files, config.input_working_directory);
if (files.length == 0) {
@@ -81,6 +82,10 @@ async function run() {
const assets = results.filter(Boolean);
setOutput('assets', assets);
}
console.log('Finalizing release...');
rel = await finalizeRelease(config, releaser, rel);
console.log(`🎉 Release ready at ${rel.html_url}`);
setOutput('url', rel.html_url);
setOutput('id', rel.id.toString());