From b6732661274c9e2b8cfd0810ba2727371d8820f6 Mon Sep 17 00:00:00 2001 From: Roland Date: Mon, 13 Apr 2026 15:19:22 +0200 Subject: [PATCH] Refs: #83 getting ready to do a run on github --- .github/workflows/release.yml | 25 ++------ package.json | 6 +- release-notes.mjs | 109 ++++++++++++++++++++++++++++++++++ version-bump.mjs | 2 +- 4 files changed, 118 insertions(+), 24 deletions(-) create mode 100644 release-notes.mjs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 781c5bb..1766341 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,8 +15,6 @@ jobs: steps: - name: Checkout repo uses: actions/checkout@v4 - with: - fetch-depth: 0 # IMPORTANT for release notes - name: Setup Node uses: actions/setup-node@v4 @@ -33,29 +31,16 @@ jobs: - name: Build plugin run: npm run build - - name: Sync versions (manifest + versions.json) - run: npm run version - - - name: Commit version updates - run: | - git config user.name "github-actions" - git config user.email "github-actions@github.com" - git add manifest.json versions.json - git commit -m "chore: sync versions" || echo "No changes" - git push - - - name: Generate changelog - id: changelog - run: | - echo "## Changes" > CHANGELOG.md - git log $(git describe --tags --abbrev=0 HEAD^)..HEAD --pretty=format:"- %s" >> CHANGELOG.md + - name: Read release title + id: release_title + run: echo "value=$(cat release_title.txt)" >> "$GITHUB_OUTPUT" - name: Create Release (Draft) uses: softprops/action-gh-release@v2 with: draft: true - name: Release ${{ github.ref_name }} - body_path: CHANGELOG.md + name: ${{ steps.release_title.outputs.value }} + body_path: release_changelog.txt files: | main.js manifest.json diff --git a/package.json b/package.json index 837efc7..5aee07e 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,9 @@ "test": "vitest", "test:run": "vitest run", "test:coverage": "vitest run --coverage", - "patch": "node version-bump.mjs patch", - "minor": "node version-bump.mjs minor", - "major": "node version-bump.mjs major" + "patch": "node release-notes.mjs patch && node version-bump.mjs patch", + "minor": "node release-notes.mjs minor && node version-bump.mjs minor", + "major": "node release-notes.mjs major && node version-bump.mjs major" }, "keywords": [ "obsidian", diff --git a/release-notes.mjs b/release-notes.mjs new file mode 100644 index 0000000..dd1b076 --- /dev/null +++ b/release-notes.mjs @@ -0,0 +1,109 @@ +import { execSync } from "child_process"; +import { writeFileSync } from "fs"; + +function run(command) { + return execSync(command, { encoding: "utf8" }).trim(); +} + +function tryRun(command) { + try { + return run(command); + } catch { + return ""; + } +} + +function bumpVersion(version, bumpType) { + const [major, minor, patch] = version.split(".").map(Number); + + if (![major, minor, patch].every(Number.isInteger)) { + throw new Error(`Invalid version: ${version}`); + } + + if (bumpType === "major") { + return `${major + 1}.0.0`; + } + + if (bumpType === "minor") { + return `${major}.${minor + 1}.0`; + } + + if (bumpType === "patch") { + return `${major}.${minor}.${patch + 1}`; + } + + throw new Error(`Invalid bump type: ${bumpType}`); +} + +function getLastTag() { + const tagsRaw = tryRun("git tag --sort=-version:refname"); + const tags = tagsRaw ? tagsRaw.split("\n").filter(Boolean) : []; + return tags[0] || ""; +} + +function getCommitSubjects(fromRef, toRef = "HEAD") { + const log = tryRun(`git log ${fromRef}..${toRef} --pretty=format:%s`); + return log ? log.split("\n").filter(Boolean) : []; +} + +function extractTickets(messages) { + const tickets = new Set(); + + for (const message of messages) { + const matches = message.match(/#[0-9]+/g) || []; + for (const match of matches) { + tickets.add(match); + } + } + + return [...tickets].sort((a, b) => Number(a.slice(1)) - Number(b.slice(1))); +} + +function filterMessages(messages) { + return messages.filter((message) => { + const lower = message.toLowerCase(); + + if (lower.startsWith("version bump:")) { + return false; + } + + return true; + }); +} + +const bumpType = process.argv[2]; + +if (!["patch", "minor", "major"].includes(bumpType)) { + console.error("Usage: node release-notes.mjs [patch|minor|major]"); + process.exit(1); +} + +const lastTag = getLastTag(); + +if (!lastTag) { + console.error("No tags found. Cannot generate release notes."); + process.exit(1); +} + +const nextVersion = bumpVersion(lastTag, bumpType); +const allMessages = getCommitSubjects(lastTag, "HEAD"); +const messages = filterMessages(allMessages); +const tickets = extractTickets(messages); + +let title = `Releasing ${nextVersion} ${bumpType}`; +if (tickets.length > 0) { + title += ` including ${tickets.join(" ")}`; +} + +let changelog = "## Changes\n"; + +if (messages.length > 0) { + changelog += messages.map((message) => `- ${message}`).join("\n"); +} else { + changelog += "- No changes recorded"; +} + +writeFileSync("release_title.txt", `${title}\n`); +writeFileSync("release_changelog.txt", `${changelog}\n`); + +console.log("Generated release_title.txt and release_changelog.txt"); diff --git a/version-bump.mjs b/version-bump.mjs index 36f69af..54b7745 100644 --- a/version-bump.mjs +++ b/version-bump.mjs @@ -45,4 +45,4 @@ execSync(`git commit -m "version bump: ${version}"`, { execSync(`git tag ${version}`, { stdio: "inherit" }); -console.log(`🚀 Released ${version} ready for push `); +console.log(`🚀 Released ${version} ready for push \n git push --follow-tags`);