mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-12-12 01:42:19 +00:00
[core] auto create release notes with every push on develop (#3985)
and remove CHANGELOG.md logic. This is my attempt to create a draft release instead of editing a changelog, see discussion on discord. Logic: - new github workflow `.github/workflows/release-notes.yaml` - runs with every push on `develop` (so after PR's are merged) - collects the commits on `develop` which are newer than the latest tag - searches the commit messages for keywords defined in an array and group the messages into categories (this is a first shot, we will update this ...) - creates markdown content - looks for an untagged and unpublished draft release with name `unreleased`, if it exists, it will be deleted - creates an untagged and unpublished draft release with name `unreleased` with markdown content created above Example created on my fork (this caused having `MagicMirrorOrg` in the PR-Links): <img width="952" height="1804" alt="grafik" src="https://github.com/user-attachments/assets/38687bed-f5da-4dcb-93eb-242c317769df" /> Please review this PR, it is a draft release at the moment because I got problems in my fork where I tested this: The created draft release is not visible at the moment (they are visible via api). AFAIS this is a queue problem on GitHub, maybe I flooded their queue while testing ... So I will test this tomorrow again before removing `draft` here.
This commit is contained in:
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,6 +1,6 @@
|
|||||||
Hello and thank you for wanting to contribute to the MagicMirror² project!
|
Hello and thank you for wanting to contribute to the MagicMirror² project!
|
||||||
|
|
||||||
**Please make sure that you have followed these 4 rules before submitting your Pull Request:**
|
**Please make sure that you have followed these 3 rules before submitting your Pull Request:**
|
||||||
|
|
||||||
> 1. Base your pull requests against the `develop` branch.
|
> 1. Base your pull requests against the `develop` branch.
|
||||||
> 2. Include these infos in the description:
|
> 2. Include these infos in the description:
|
||||||
@@ -12,8 +12,6 @@ Hello and thank you for wanting to contribute to the MagicMirror² project!
|
|||||||
>
|
>
|
||||||
> 3. Please run `node --run lint:prettier` before submitting so that
|
> 3. Please run `node --run lint:prettier` before submitting so that
|
||||||
> style issues are fixed.
|
> style issues are fixed.
|
||||||
> 4. Don't forget to add an entry about your changes to
|
|
||||||
> the CHANGELOG.md file.
|
|
||||||
|
|
||||||
**Note**: Sometimes the development moves very fast. It is highly
|
**Note**: Sometimes the development moves very fast. It is highly
|
||||||
recommended that you update your branch of `develop` before creating a
|
recommended that you update your branch of `develop` before creating a
|
||||||
|
|||||||
2
.github/dependabot.yaml
vendored
2
.github/dependabot.yaml
vendored
@@ -6,7 +6,6 @@ updates:
|
|||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
target-branch: "develop"
|
target-branch: "develop"
|
||||||
labels:
|
labels:
|
||||||
- "Skip Changelog"
|
|
||||||
- "dependencies"
|
- "dependencies"
|
||||||
|
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: "npm"
|
||||||
@@ -15,6 +14,5 @@ updates:
|
|||||||
interval: "monthly"
|
interval: "monthly"
|
||||||
target-branch: "develop"
|
target-branch: "develop"
|
||||||
labels:
|
labels:
|
||||||
- "Skip Changelog"
|
|
||||||
- "dependencies"
|
- "dependencies"
|
||||||
- "javascript"
|
- "javascript"
|
||||||
|
|||||||
10
.github/workflows/enforce-pullrequest-rules.yaml
vendored
10
.github/workflows/enforce-pullrequest-rules.yaml
vendored
@@ -1,6 +1,5 @@
|
|||||||
# This workflow enforces on every pull request:
|
# This workflow enforces on every pull request that the PR is not based against master,
|
||||||
# - the update of our CHANGELOG.md file, see: https://github.com/dangoslen/changelog-enforcer
|
# taken from https://github.com/oppia/oppia-android/pull/2832/files
|
||||||
# - that the PR is not based against master, taken from https://github.com/oppia/oppia-android/pull/2832/files
|
|
||||||
|
|
||||||
name: "Enforce Pull-Request Rules"
|
name: "Enforce Pull-Request Rules"
|
||||||
|
|
||||||
@@ -13,11 +12,6 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- name: "Enforce changelog"
|
|
||||||
uses: dangoslen/changelog-enforcer@v3
|
|
||||||
with:
|
|
||||||
changeLogPath: "CHANGELOG.md"
|
|
||||||
skipLabels: "Skip Changelog"
|
|
||||||
- name: "Enforce develop branch"
|
- name: "Enforce develop branch"
|
||||||
if: ${{ github.event.pull_request.base.ref == 'master' && !contains(github.event.pull_request.labels.*.name, 'mastermerge') }}
|
if: ${{ github.event.pull_request.base.ref == 'master' && !contains(github.event.pull_request.labels.*.name, 'mastermerge') }}
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
33
.github/workflows/release-notes.yaml
vendored
Normal file
33
.github/workflows/release-notes.yaml
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# This workflow writes a draft release on GitHub named `unreleased` after every push on develop
|
||||||
|
|
||||||
|
name: "Create Release Notes"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [develop]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release-notes:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 15
|
||||||
|
steps:
|
||||||
|
- name: "Checkout code"
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
fetch-depth: "0"
|
||||||
|
- name: "Use Node.js"
|
||||||
|
uses: actions/setup-node@v6
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
cache: "npm"
|
||||||
|
- name: "Create Markdown content"
|
||||||
|
run: |
|
||||||
|
export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
|
||||||
|
node js/releasenotes.js
|
||||||
54
CHANGELOG.md
54
CHANGELOG.md
@@ -7,58 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/#donate) With your help we can continue to improve the MagicMirror².
|
❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/#donate) With your help we can continue to improve the MagicMirror².
|
||||||
|
|
||||||
## [2.34.0] - unreleased
|
## Obsolete
|
||||||
|
|
||||||
planned for 2026-01-01
|
This file is no longer being updated. Release notes are now automatically generated via a GitHub action.
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- [weather] feat: add configurable forecast date format option (#3918)
|
|
||||||
- [core] Add new `server:watch` script to run MagicMirror² server-only with automatic restarts when files (defined in `config.watchTargets`) change (#3920)
|
|
||||||
- [weather] add error handling to fetch functions including cors (#3791)
|
|
||||||
- [l10n] Add Portuguese (Portugal & Brazil) translations for alert module, Refine Portuguese (Portugal) translations
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
|
|
||||||
- [weather] Removed deprecated `ukmetoffice` datapoint provider (#3842, #3952)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- [core] refactor: replace `module-alias` dependency with internal alias resolver (#3893)
|
|
||||||
- [check_config] refactor: improve error handling (#3927)
|
|
||||||
- [calendar] test: remove "Recurring event per timezone" test (#3929)
|
|
||||||
- [calendar] chore: remove `requiresVersion: "2.1.0"` (#3932)
|
|
||||||
- [tests] migrate from `jest` to `vitest` (#3940, #3941)
|
|
||||||
- [ci] Add concurrency to automated tests workflow to cancel outdated runs (#3943)
|
|
||||||
- [tests] replace `node-libgpiod` with `serialport` in electron-rebuild workflow (#3945)
|
|
||||||
- [calendar] hide repeatingCountTitle if the event count is zero (#3949)
|
|
||||||
- [weatherprovider] update override warning wording (#3914)
|
|
||||||
- [core] configure cspell to check default modules only and fix typos (#3955)
|
|
||||||
- [core] refactor: replace `XMLHttpRequest` with `fetch` in `translator.js` (#3950)
|
|
||||||
- [tests] migrate e2e tests to Playwright (#3950)
|
|
||||||
- [calendar] refactor: migrate CalendarFetcher to ES6 class and improve error handling (#3958)
|
|
||||||
- [gitignore] cleanup/simplify .gitignore (#3952, #3954, #3968, #3969)
|
|
||||||
- [compliments] refactor: optimize `loadComplimentFile` method and add unit tests(#3969)
|
|
||||||
- [core] chore: simplify Wayland start script (#3974)
|
|
||||||
- [calendar] refactor: simplify recurring event handling and event exclusion logic (#3976)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- feat: add ESlint rule `no-sparse-arrays` for config check to fix #3910 (#3911)
|
|
||||||
- fixed eslint warnings shown in #3911 and updated npm publish docs (#3913)
|
|
||||||
- [core] refactor: replace `express-ipfilter` with lightweight custom middleware (#3917) - This fixes security issue [CVE-2023-42282](https://github.com/advisories/GHSA-78xj-cgh5-2h22), which is not very likely to be exploitable in MagicMirror² setups, but still should be fixed.
|
|
||||||
- fixed the Environment Canada weather URL (#3912) and now converts a windspeed of 'calm' to 0
|
|
||||||
- fixed problems with daylight-saving-time in weather provider `openmeto` (#3930, #3931)
|
|
||||||
- [newsfeed] fixed header layout issue introduced with prettier njk linting (#3946)
|
|
||||||
- [weather] fixed windy icon not showing up in pirateweather (#3957)
|
|
||||||
- [compliments] fixed duplicate query param "?" when constructing refresh url (#3967)
|
|
||||||
- [compliments] fixed compliments remote file minimum delay to be 15 minutes (#3970)
|
|
||||||
- [calendar] prevent excessive fetching with smart refresh strategy (#3976)
|
|
||||||
|
|
||||||
### Updated
|
|
||||||
|
|
||||||
- [core] Update dependencies incl. electron to v39 (#3909, #3916, #3921, #3925, #3934, #3982)
|
|
||||||
- [logger] Add prefixes to most Log messages (#3923, #3926)
|
|
||||||
|
|
||||||
## [2.33.0] - 2025-10-01
|
## [2.33.0] - 2025-10-01
|
||||||
|
|
||||||
@@ -1877,7 +1828,6 @@ It includes (but is not limited to) the following features:
|
|||||||
|
|
||||||
This was part of the blogpost: [https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the](https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the)
|
This was part of the blogpost: [https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the](https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the)
|
||||||
|
|
||||||
[2.34.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.33.0...develop
|
|
||||||
[2.33.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.32.0...v2.33.0
|
[2.33.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.32.0...v2.33.0
|
||||||
[2.32.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.31.0...v2.32.0
|
[2.32.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.31.0...v2.32.0
|
||||||
[2.31.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.30.0...v2.31.0
|
[2.31.0]: https://github.com/MagicMirrorOrg/MagicMirror/compare/v2.30.0...v2.31.0
|
||||||
|
|||||||
@@ -34,29 +34,28 @@ Are done by
|
|||||||
- [ ] create `prep-release` branch from `develop`
|
- [ ] create `prep-release` branch from `develop`
|
||||||
- [ ] update `package.json` and `package-lock.json` to reflect correct version number `2.xx.0`
|
- [ ] update `package.json` and `package-lock.json` to reflect correct version number `2.xx.0`
|
||||||
- [ ] test `prep-release` branch
|
- [ ] test `prep-release` branch
|
||||||
- [ ] update `CHANGELOG.md`
|
|
||||||
- [ ] add all contributor names: `...`
|
|
||||||
- [ ] add min. node version: > ⚠️ This release needs nodejs version `v22.20.0` or higher
|
|
||||||
- [ ] check release link at the bottom of the file
|
|
||||||
- [ ] commit and push all changes
|
- [ ] commit and push all changes
|
||||||
- [ ] create pull request from `prep-release` to `develop` branch with title `Prepare Release 2.xx.0`
|
- [ ] create pull request from `prep-release` to `develop` branch with title `Prepare Release 2.xx.0`
|
||||||
- [ ] after successful test run via github actions: merge pull request to `develop`
|
- [ ] after successful test run via github actions: merge pull request to `develop`
|
||||||
|
- [ ] review the content of the automatically generated draft release named `unreleased`
|
||||||
|
- [ ] check contributor names
|
||||||
|
- [ ] check auto generated min. node version and adjust it for better readability if necessary
|
||||||
|
- [ ] check if all elements are assigned to the correct category
|
||||||
|
- [ ] change release name to `v2.xx.0`
|
||||||
- [ ] after successful test run via github actions: create pull request from `develop` to `master` branch
|
- [ ] after successful test run via github actions: create pull request from `develop` to `master` branch
|
||||||
- [ ] add label `mastermerge`
|
- [ ] add label `mastermerge`
|
||||||
- [ ] title of the PR is `Release 2.xx.0`
|
- [ ] title of the PR is `Release 2.xx.0`
|
||||||
- [ ] description of the PR is the section of the `CHANGELOG.md`
|
- [ ] description of the PR is the body of the draft release with name `v2.xx.0`
|
||||||
- [ ] after PR tests run without issues, merge PR
|
- [ ] after PR tests run without issues, merge PR
|
||||||
- [ ] create new release with
|
- [ ] edit draft release with name `v2.xx.0`
|
||||||
- [ ] corresponding version tag `v2.xx.0`
|
- [ ] set corresponding version tag `v2.xx.0` (with `Select tag` and then `Create new tag`)
|
||||||
- [ ] a release name: `...`
|
- [ ] update release link in `Compare to previous Release` by replacing `develop` with new tag `v2.xx.0`
|
||||||
- [ ] description of the release is the section of the `CHANGELOG.md`
|
- [ ] publish the release (button at the bottom)
|
||||||
|
|
||||||
### Draft new development release
|
### Draft new development release
|
||||||
|
|
||||||
- [ ] checkout `develop` branch
|
- [ ] checkout `develop` branch
|
||||||
- [ ] update `package.json` and `package-lock.json` to reflect correct version number `2.xx.0-develop`
|
- [ ] update `package.json` and `package-lock.json` to reflect correct version number `2.xx.0-develop`
|
||||||
- [ ] draft new section in `CHANGELOG.md`
|
|
||||||
- [ ] create new release link at the bottom of the file
|
|
||||||
- [ ] commit and push `develop` branch
|
- [ ] commit and push `develop` branch
|
||||||
- [ ] if new release will be in January, update the year in LICENSE.md
|
- [ ] if new release will be in January, update the year in LICENSE.md
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ function App () {
|
|||||||
const deprecatedOptions = deprecated.configs;
|
const deprecatedOptions = deprecated.configs;
|
||||||
const usedDeprecated = deprecatedOptions.filter((option) => userConfig.hasOwnProperty(option));
|
const usedDeprecated = deprecatedOptions.filter((option) => userConfig.hasOwnProperty(option));
|
||||||
if (usedDeprecated.length > 0) {
|
if (usedDeprecated.length > 0) {
|
||||||
Log.warn(`WARNING! Your config is using deprecated option(s): ${usedDeprecated.join(", ")}. Check README and CHANGELOG for more up-to-date ways of getting the same functionality.`);
|
Log.warn(`WARNING! Your config is using deprecated option(s): ${usedDeprecated.join(", ")}. Check README and Documentation for more up-to-date ways of getting the same functionality.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for deprecated module options
|
// check for deprecated module options
|
||||||
@@ -167,7 +167,7 @@ function App () {
|
|||||||
const deprecatedModuleOptions = deprecated[element.module];
|
const deprecatedModuleOptions = deprecated[element.module];
|
||||||
const usedDeprecatedModuleOptions = deprecatedModuleOptions.filter((option) => element.config.hasOwnProperty(option));
|
const usedDeprecatedModuleOptions = deprecatedModuleOptions.filter((option) => element.config.hasOwnProperty(option));
|
||||||
if (usedDeprecatedModuleOptions.length > 0) {
|
if (usedDeprecatedModuleOptions.length > 0) {
|
||||||
Log.warn(`WARNING! Your config for module ${element.module} is using deprecated option(s): ${usedDeprecatedModuleOptions.join(", ")}. Check README and CHANGELOG for more up-to-date ways of getting the same functionality.`);
|
Log.warn(`WARNING! Your config for module ${element.module} is using deprecated option(s): ${usedDeprecatedModuleOptions.join(", ")}. Check README and Documentation for more up-to-date ways of getting the same functionality.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
198
js/releasenotes.js
Normal file
198
js/releasenotes.js
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
/* eslint no-console: "off" */
|
||||||
|
const util = require("node:util");
|
||||||
|
const exec = util.promisify(require("node:child_process").exec);
|
||||||
|
const fs = require("node:fs");
|
||||||
|
|
||||||
|
const createReleaseNotes = async () => {
|
||||||
|
let repoName = "MagicMirrorOrg/MagicMirror";
|
||||||
|
if (process.env.GITHUB_REPOSITORY) {
|
||||||
|
repoName = process.env.GITHUB_REPOSITORY;
|
||||||
|
}
|
||||||
|
const baseUrl = `https://api.github.com/repos/${repoName}`;
|
||||||
|
|
||||||
|
const getOptions = (type) => {
|
||||||
|
if (process.env.GITHUB_TOKEN) {
|
||||||
|
return { method: `${type}`, headers: { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` } };
|
||||||
|
} else {
|
||||||
|
return { method: `${type}` };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const execShell = async (command) => {
|
||||||
|
const { stdout = "", stderr = "" } = await exec(command);
|
||||||
|
if (stderr) console.error(`Error in execShell executing command ${command}: ${stderr}`);
|
||||||
|
return stdout;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check Draft Release
|
||||||
|
const draftReleases = [];
|
||||||
|
const jsonReleases = await fetch(`${baseUrl}/releases`, getOptions("GET")).then((res) => res.json());
|
||||||
|
for (const rel of jsonReleases) {
|
||||||
|
if (rel.draft && rel.tag_name === "" && rel.published_at === null && rel.name === "unreleased") draftReleases.push(rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
let draftReleaseId = 0;
|
||||||
|
if (draftReleases.length > 1) {
|
||||||
|
throw new Error("More than one draft release found, exiting.");
|
||||||
|
} else {
|
||||||
|
if (draftReleases[0]) draftReleaseId = draftReleases[0].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get last Git Tag
|
||||||
|
const gitTag = await execShell("git describe --tags `git rev-list --tags --max-count=1`");
|
||||||
|
const lastTag = gitTag.toString().replaceAll("\n", "");
|
||||||
|
console.info(`latest tag is ${lastTag}`);
|
||||||
|
|
||||||
|
// Get Git Commits
|
||||||
|
const gitOut = await execShell(`git log develop --pretty=format:"%H --- %s" --after="$(git log -1 --format=%aI ${lastTag})"`);
|
||||||
|
console.info(gitOut);
|
||||||
|
const commits = gitOut.toString().split("\n");
|
||||||
|
|
||||||
|
// Get Node engine version from package.json
|
||||||
|
const nodeVersion = JSON.parse(fs.readFileSync("package.json")).engines.node;
|
||||||
|
|
||||||
|
// Search strings
|
||||||
|
const labelArr = ["alert", "calendar", "clock", "compliments", "helloworld", "newsfeed", "updatenotification", "weather", "envcanada", "openmeteo", "openweathermap", "smhi", "ukmetoffice", "yr", "eslint", "bump", "dependencies", "deps", "logg", "translation", "test", "ci"];
|
||||||
|
|
||||||
|
// Map search strings to categories
|
||||||
|
const getFirstLabel = (text) => {
|
||||||
|
let res;
|
||||||
|
labelArr.every((item) => {
|
||||||
|
const labelIncl = text.includes(item);
|
||||||
|
if (labelIncl) {
|
||||||
|
switch (item) {
|
||||||
|
case "ci":
|
||||||
|
case "test":
|
||||||
|
res = "testing";
|
||||||
|
break;
|
||||||
|
case "logg":
|
||||||
|
res = "logging";
|
||||||
|
break;
|
||||||
|
case "eslint":
|
||||||
|
case "bump":
|
||||||
|
case "deps":
|
||||||
|
res = "dependencies";
|
||||||
|
break;
|
||||||
|
case "envcanada":
|
||||||
|
case "openmeteo":
|
||||||
|
case "openweathermap":
|
||||||
|
case "smhi":
|
||||||
|
case "ukmetoffice":
|
||||||
|
case "yr":
|
||||||
|
case "weather":
|
||||||
|
res = "modules/weather";
|
||||||
|
break;
|
||||||
|
case "alert":
|
||||||
|
res = "modules/alert";
|
||||||
|
break;
|
||||||
|
case "calendar":
|
||||||
|
res = "modules/calendar";
|
||||||
|
break;
|
||||||
|
case "clock":
|
||||||
|
res = "modules/clock";
|
||||||
|
break;
|
||||||
|
case "compliments":
|
||||||
|
res = "modules/compliments";
|
||||||
|
break;
|
||||||
|
case "helloworld":
|
||||||
|
res = "modules/helloworld";
|
||||||
|
break;
|
||||||
|
case "newsfeed":
|
||||||
|
res = "modules/newsfeed";
|
||||||
|
break;
|
||||||
|
case "updatenotification":
|
||||||
|
res = "modules/updatenotification";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!res) res = "core";
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
const grouped = {};
|
||||||
|
const contrib = [];
|
||||||
|
const sha = [];
|
||||||
|
|
||||||
|
// Loop through each Commit
|
||||||
|
for (const item of commits) {
|
||||||
|
|
||||||
|
const cm = item.trim();
|
||||||
|
// ignore `prepare release` line
|
||||||
|
if (cm.length > 0 && !cm.match(/^.* --- prepare .*-develop$/gi)) {
|
||||||
|
|
||||||
|
const [ref, title] = cm.split(" --- ");
|
||||||
|
|
||||||
|
const groupTitle = getFirstLabel(title.toLowerCase());
|
||||||
|
|
||||||
|
if (!grouped[groupTitle]) {
|
||||||
|
grouped[groupTitle] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
grouped[groupTitle].push(`- ${title}`);
|
||||||
|
|
||||||
|
sha.push(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// function to remove duplicates
|
||||||
|
const sortedArr = (arr) => {
|
||||||
|
return arr.filter((item,
|
||||||
|
index) => (arr.indexOf(item) === index && item !== "@dependabot[bot]")).sort(function (a, b) {
|
||||||
|
return a.toLowerCase().localeCompare(b.toLowerCase());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get Contributors logins
|
||||||
|
for (const ref of sha) {
|
||||||
|
const jsonRes = await fetch(`${baseUrl}/commits/${ref}`, getOptions("GET")).then((res) => res.json());
|
||||||
|
|
||||||
|
if (jsonRes && jsonRes.author && jsonRes.author.login) contrib.push(`@${jsonRes.author.login}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build Markdown content
|
||||||
|
let markdown = "## Release Notes\n";
|
||||||
|
|
||||||
|
markdown += `Thanks to: ${sortedArr(contrib).join(", ")}\n`;
|
||||||
|
markdown += `> ⚠️ This release needs nodejs version ${nodeVersion}\n`;
|
||||||
|
markdown += "\n";
|
||||||
|
markdown += `[Compare to previous Release ${lastTag}](https://github.com/${repoName}/compare/${lastTag}...develop)\n\n`;
|
||||||
|
|
||||||
|
const sorted = Object.keys(grouped)
|
||||||
|
.sort() // Sort the keys alphabetically
|
||||||
|
.reduce((obj, key) => {
|
||||||
|
obj[key] = grouped[key]; // Rebuild the object with sorted keys
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
for (const group in sorted) {
|
||||||
|
markdown += `\n### [${group}]\n`;
|
||||||
|
markdown += `${sorted[group].join("\n")}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.info(markdown);
|
||||||
|
|
||||||
|
// Create Github Release
|
||||||
|
if (process.env.GITHUB_TOKEN) {
|
||||||
|
if (draftReleaseId > 0) {
|
||||||
|
// delete release
|
||||||
|
await fetch(`${baseUrl}/releases/${draftReleaseId}`, getOptions("DELETE"));
|
||||||
|
console.info(`Old Release with id ${draftReleaseId} deleted.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const relContent = getOptions("POST");
|
||||||
|
relContent.body = JSON.stringify(
|
||||||
|
{ tag_name: "", name: "unreleased", body: `${markdown}`, draft: true }
|
||||||
|
);
|
||||||
|
const createRelease = await fetch(`${baseUrl}/releases`, relContent).then((res) => res.json());
|
||||||
|
console.info(`New release created with id ${createRelease.id}, GitHub-Url: ${createRelease.html_url}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
createReleaseNotes();
|
||||||
Reference in New Issue
Block a user