From 6cc947388d06b4b72a5fdf92b146929f4b3bb069 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Wed, 8 Oct 2025 15:19:09 -0700 Subject: [PATCH 1/3] Manually Generate Release Notes --- .github/actionlint.yaml | 4 +++ .github/workflows/lint.yaml | 6 ++-- .github/workflows/pull.yaml | 1 + .github/workflows/release.yaml | 1 + .github/workflows/tags.yaml | 1 + .github/workflows/test.yaml | 8 ++++- action.yml | 7 +--- dist/index.js | 43 ++++++++++++++++++----- package-lock.json | 55 +++++++++++++++-------------- package.json | 6 ++-- src/api.js | 64 ++++++++++++++++++++++++++++++++++ src/index.js | 14 ++++++-- 12 files changed, 160 insertions(+), 50 deletions(-) create mode 100644 .github/actionlint.yaml create mode 100644 src/api.js diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml new file mode 100644 index 0000000..71a1f60 --- /dev/null +++ b/.github/actionlint.yaml @@ -0,0 +1,4 @@ +paths: + .github/workflows/**/*.{yml,yaml}: + ignore: + - 'invalid runner name "node24" at runs.using' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 2b702f5..eba38fa 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -10,15 +10,15 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -permissions: - pull-requests: write - jobs: lint: name: "Lint" runs-on: ubuntu-latest timeout-minutes: 5 + permissions: + pull-requests: write + steps: - name: "Checkout" uses: actions/checkout@v5 diff --git a/.github/workflows/pull.yaml b/.github/workflows/pull.yaml index dbd0036..81ac338 100644 --- a/.github/workflows/pull.yaml +++ b/.github/workflows/pull.yaml @@ -12,6 +12,7 @@ jobs: name: "Pull" runs-on: ubuntu-latest timeout-minutes: 5 + permissions: pull-requests: write diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index facc764..c37a857 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -9,6 +9,7 @@ jobs: name: "Release" runs-on: ubuntu-latest timeout-minutes: 5 + permissions: contents: write diff --git a/.github/workflows/tags.yaml b/.github/workflows/tags.yaml index 9539e5e..38b5c74 100644 --- a/.github/workflows/tags.yaml +++ b/.github/workflows/tags.yaml @@ -12,6 +12,7 @@ jobs: name: "Tags" runs-on: ubuntu-latest timeout-minutes: 5 + permissions: contents: write diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index da8faac..98e140c 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -7,11 +7,11 @@ on: #push: # branches: ["**"] # paths: + # - ".github/workflows/test.yaml" # - "dist/**" # - "src/**" # - "package*.json" # - "requirements*.txt" - # - ".github/workflows/test.yaml" # - "action.yml" concurrency: @@ -23,6 +23,7 @@ jobs: name: "Test" runs-on: ubuntu-latest timeout-minutes: 5 + permissions: contents: write @@ -36,6 +37,11 @@ jobs: run: | cat "${GITHUB_EVENT_PATH}" + - name: "INOP" + run: | + echo "This test must be updated for this action" + exit 1 + - name: "Test Local Action" id: test uses: ./ diff --git a/action.yml b/action.yml index 3532b09..3e81b75 100644 --- a/action.yml +++ b/action.yml @@ -8,11 +8,9 @@ branding: inputs: semver: description: "New Version: See semver.inc" - required: false default: "prerelease" identifier: description: "Prerelease Tag to Append" - required: false default: "beta" #patch: # description: "New Version: major, minor, micro, patch" @@ -20,15 +18,12 @@ inputs: # default: "" prerelease: description: "Mark release as prerelease" - required: false default: "true" summary: description: "Add Summary to Job" - required: false default: "true" token: description: "GitHub Token" - required: false default: ${{ github.token }} outputs: @@ -38,5 +33,5 @@ outputs: description: "Release HTML URL" runs: - using: "node20" + using: "node24" main: "dist/index.js" diff --git a/dist/index.js b/dist/index.js index 53e9021..65450b4 100644 --- a/dist/index.js +++ b/dist/index.js @@ -7820,6 +7820,7 @@ const isSatisfiable = (comparators, options) => { // already replaced the hyphen ranges // turn into a set of JUST comparators. const parseComparator = (comp, options) => { + comp = comp.replace(re[t.BUILD], '') debug('comp', comp, options) comp = replaceCarets(comp, options) debug('caret', comp) @@ -8240,11 +8241,25 @@ class SemVer { other = new SemVer(other, this.options) } - return ( - compareIdentifiers(this.major, other.major) || - compareIdentifiers(this.minor, other.minor) || - compareIdentifiers(this.patch, other.patch) - ) + if (this.major < other.major) { + return -1 + } + if (this.major > other.major) { + return 1 + } + if (this.minor < other.minor) { + return -1 + } + if (this.minor > other.minor) { + return 1 + } + if (this.patch < other.patch) { + return -1 + } + if (this.patch > other.patch) { + return 1 + } + return 0 } comparePre (other) { @@ -9145,6 +9160,10 @@ module.exports = debug const numeric = /^[0-9]+$/ const compareIdentifiers = (a, b) => { + if (typeof a === 'number' && typeof b === 'number') { + return a === b ? 0 : a < b ? -1 : 1 + } + const anum = numeric.test(a) const bnum = numeric.test(b) @@ -34622,7 +34641,6 @@ async function processRelease(inputs) { console.log('previous.draft:', previous?.draft) console.log('latest.tag_name:', latest?.tag_name) console.log('previous.tag_name:', previous?.tag_name) - // if (latest.draft && latest.body.includes(script_id)) { if (latest.draft && latest.author.id === bot_id && latest.body.includes(script_id)) { core.info(`⛔ Deleting Latest Draft: \u001b[31;1m${latest.tag_name}`) const response = await octokit.rest.repos.deleteRelease({ @@ -34638,14 +34656,23 @@ async function processRelease(inputs) { throw new Error(`Unable to parse ${inputs.semver} from ${latest.tag_name}`) } + const notes = await octokit.rest.repos.generateReleaseNotes({ + ...github.context.repo, + tag_name, + previous_tag_name: latest.tag_name, + }) + console.log('notes.status:', notes.status) + console.log('notes.data:', notes.data) + core.info(`Creating New Draft: \u001b[33;1m${tag_name}`) const response = await octokit.rest.repos.createRelease({ ...github.context.repo, tag_name, draft: true, prerelease: inputs.prerelease, - generate_release_notes: true, - body: `\n\n\n\n${script_id}`, + generate_release_notes: false, + name: notes.data.name, + body: notes.data.body, }) console.log('response.status:', response.status) return response diff --git a/package-lock.json b/package-lock.json index 0c89562..1f9f12e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,12 +8,12 @@ "dependencies": { "@actions/core": "^1.11.1", "@actions/github": "^6.0.1", - "semver": "^7.7.2" + "semver": "^7.7.3" }, "devDependencies": { - "@eslint/js": "^9.36.0", + "@eslint/js": "^9.37.0", "@vercel/ncc": "^0.38.4", - "eslint": "^9.36.0", + "eslint": "^9.37.0", "prettier": "^3.6.2" } }, @@ -125,19 +125,22 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", - "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.0.tgz", + "integrity": "sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -172,9 +175,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz", - "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==", + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.37.0.tgz", + "integrity": "sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==", "dev": true, "license": "MIT", "engines": { @@ -195,13 +198,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.2", + "@eslint/core": "^0.16.0", "levn": "^0.4.1" }, "engines": { @@ -652,20 +655,20 @@ } }, "node_modules/eslint": { - "version": "9.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz", - "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.37.0.tgz", + "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.1", - "@eslint/core": "^0.15.2", + "@eslint/config-helpers": "^0.4.0", + "@eslint/core": "^0.16.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.36.0", - "@eslint/plugin-kit": "^0.3.5", + "@eslint/js": "9.37.0", + "@eslint/plugin-kit": "^0.4.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -1228,9 +1231,9 @@ } }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", "bin": { "semver": "bin/semver.js" diff --git a/package.json b/package.json index b8264fa..9279883 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,12 @@ "dependencies": { "@actions/core": "^1.11.1", "@actions/github": "^6.0.1", - "semver": "^7.7.2" + "semver": "^7.7.3" }, "devDependencies": { - "@eslint/js": "^9.36.0", + "@eslint/js": "^9.37.0", "@vercel/ncc": "^0.38.4", - "eslint": "^9.36.0", + "eslint": "^9.37.0", "prettier": "^3.6.2" } } diff --git a/src/api.js b/src/api.js new file mode 100644 index 0000000..9e74f30 --- /dev/null +++ b/src/api.js @@ -0,0 +1,64 @@ +const github = require('@actions/github') + +class Api { + /** + * GitHub Api + * @param {String} token + */ + constructor(token) { + this.octokit = github.getOctokit(token) + } + + /** + * List Releases + * @return {Promise|Undefined>} + */ + async listReleases() { + const response = await this.octokit.rest.repos.listReleases({ + ...github.context.repo, + per_page: 2, + }) + return response.data + } + + /** + * Delete Release + * @param {string} release_id + * @return {Promise} + */ + async deleteRelease(release_id) { + const response = await this.octokit.rest.repos.deleteRelease({ + ...github.context.repo, + release_id, + }) + return response.status + } + + /** + * Get Latest Release + * @param {Object} data + * @return {Promise|Undefined>} + */ + async generateReleaseNotes(data) { + const response = await this.octokit.rest.repos.generateReleaseNotes({ + ...github.context.repo, + ...data, + }) + return response.data + } + + /** + * Upload Release Asset + * @param {Object} data + * @return {Promise|Undefined>} + */ + async createRelease(data) { + const response = await this.octokit.rest.repos.createRelease({ + ...github.context.repo, + ...data, + }) + return response.data + } +} + +module.exports = Api diff --git a/src/index.js b/src/index.js index 000058d..a15182c 100644 --- a/src/index.js +++ b/src/index.js @@ -90,7 +90,6 @@ async function processRelease(inputs) { console.log('previous.draft:', previous?.draft) console.log('latest.tag_name:', latest?.tag_name) console.log('previous.tag_name:', previous?.tag_name) - // if (latest.draft && latest.body.includes(script_id)) { if (latest.draft && latest.author.id === bot_id && latest.body.includes(script_id)) { core.info(`⛔ Deleting Latest Draft: \u001b[31;1m${latest.tag_name}`) const response = await octokit.rest.repos.deleteRelease({ @@ -106,14 +105,23 @@ async function processRelease(inputs) { throw new Error(`Unable to parse ${inputs.semver} from ${latest.tag_name}`) } + const notes = await octokit.rest.repos.generateReleaseNotes({ + ...github.context.repo, + tag_name, + previous_tag_name: latest.tag_name, + }) + console.log('notes.status:', notes.status) + console.log('notes.data:', notes.data) + core.info(`Creating New Draft: \u001b[33;1m${tag_name}`) const response = await octokit.rest.repos.createRelease({ ...github.context.repo, tag_name, draft: true, prerelease: inputs.prerelease, - generate_release_notes: true, - body: `\n\n\n\n${script_id}`, + generate_release_notes: false, + name: notes.data.name, + body: notes.data.body, }) console.log('response.status:', response.status) return response From 690e52cb7f95038085d746717059e291038a4e4d Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Wed, 8 Oct 2025 15:29:58 -0700 Subject: [PATCH 2/3] Restore Release Body --- commit-checklist.json | 4 ++++ dist/index.js | 2 +- src/index.js | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 commit-checklist.json diff --git a/commit-checklist.json b/commit-checklist.json new file mode 100644 index 0000000..2dd6851 --- /dev/null +++ b/commit-checklist.json @@ -0,0 +1,4 @@ +[ + { "value": "Run Build", "fileMask": "*src\\*.js" }, + { "value": "Check main in action.yml", "fileMask": "*action.yml" } +] diff --git a/dist/index.js b/dist/index.js index 65450b4..a668892 100644 --- a/dist/index.js +++ b/dist/index.js @@ -34672,7 +34672,7 @@ async function processRelease(inputs) { prerelease: inputs.prerelease, generate_release_notes: false, name: notes.data.name, - body: notes.data.body, + body: `\n\n\n\n${script_id}\n${notes.data.body}`, }) console.log('response.status:', response.status) return response diff --git a/src/index.js b/src/index.js index a15182c..7261833 100644 --- a/src/index.js +++ b/src/index.js @@ -121,7 +121,7 @@ async function processRelease(inputs) { prerelease: inputs.prerelease, generate_release_notes: false, name: notes.data.name, - body: notes.data.body, + body: `\n\n\n\n${script_id}\n${notes.data.body}`, }) console.log('response.status:', response.status) return response From 13de2722ab62511ac6b7214f2e3807115c01d73e Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Wed, 8 Oct 2025 15:32:35 -0700 Subject: [PATCH 3/3] Update Release Body --- dist/index.js | 2 +- src/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index a668892..2cb1ee8 100644 --- a/dist/index.js +++ b/dist/index.js @@ -34672,7 +34672,7 @@ async function processRelease(inputs) { prerelease: inputs.prerelease, generate_release_notes: false, name: notes.data.name, - body: `\n\n\n\n${script_id}\n${notes.data.body}`, + body: `\n\n\n${script_id}\n\n${notes.data.body}`, }) console.log('response.status:', response.status) return response diff --git a/src/index.js b/src/index.js index 7261833..2f02b04 100644 --- a/src/index.js +++ b/src/index.js @@ -121,7 +121,7 @@ async function processRelease(inputs) { prerelease: inputs.prerelease, generate_release_notes: false, name: notes.data.name, - body: `\n\n\n\n${script_id}\n${notes.data.body}`, + body: `\n\n\n${script_id}\n\n${notes.data.body}`, }) console.log('response.status:', response.status) return response