diff --git a/.github/workflows/release_please.yml b/.github/workflows/release_please.yml index 0d6e1b2e2..1588b02ce 100644 --- a/.github/workflows/release_please.yml +++ b/.github/workflows/release_please.yml @@ -50,10 +50,11 @@ jobs: MASTER_Z2M_VERSION=$(cat z2m-master/package.json | jq -r '.version') MASTER_ZHC_VERSION=$(cat z2m-master/package.json | jq -r '.dependencies."zigbee-herdsman-converters"') MASTER_ZH_VERSION=$(cat z2m-master/package.json | jq -r '.dependencies."zigbee-herdsman"') + MASTER_FRONTEND_VERSION=$(cat z2m-master/package.json | jq -r '.dependencies."zigbee2mqtt-frontend"') wget -q -O - https://raw.githubusercontent.com/Koenkk/zigbee2mqtt/release-please--branches--dev--components--release-please-action/CHANGELOG.md > z2m/CHANGELOG.md || true cd z2m npm ci - node scripts/generateChangelog.js $MASTER_Z2M_VERSION $MASTER_ZHC_VERSION $MASTER_ZH_VERSION >> ../changelog.md + node scripts/generateChangelog.js $MASTER_Z2M_VERSION $MASTER_ZHC_VERSION $MASTER_ZH_VERSION $MASTER_FRONTEND_VERSION >> ../changelog.md env: GH_TOKEN: ${{secrets.GH_TOKEN}} - name: Update changelog in release PR diff --git a/scripts/generateChangelog.js b/scripts/generateChangelog.js index 900720906..00d443b9b 100644 --- a/scripts/generateChangelog.js +++ b/scripts/generateChangelog.js @@ -8,6 +8,7 @@ const zhc = require('zigbee-herdsman-converters'); const z2mTillVersion = process.argv[2]; const zhcTillVersion = process.argv[3]; const zhTillVersion = process.argv[4]; +const frontendTillVersion = process.argv[5]; const changelogs = [ {tillVersion: z2mTillVersion, project: 'koenkk/zigbee2mqtt', @@ -16,16 +17,19 @@ const changelogs = [ contents: fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'zigbee-herdsman-converters', 'CHANGELOG.md'), 'utf-8').split('\n')}, {tillVersion: zhTillVersion, project: 'koenkk/zigbee-herdsman', contents: fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'zigbee-herdsman', 'CHANGELOG.md'), 'utf-8').split('\n')}, + {tillVersion: frontendTillVersion, project: 'nurikk/zigbee2mqtt-frontend', isFrontend: true, + contents: fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'zigbee2mqtt-frontend', 'CHANGELOG.md'), 'utf-8').split('\n')}, ]; const releaseRe = /## \[(.+)\]/; -const changes = {features: [], fixes: [], detect: [], add: [], error: []}; +const changes = {features: [], fixes: [], detect: [], add: [], error: [], frontend: []}; let context = null; const changeRe = [ /^\* (\*\*(.+):\*\*)?(.+)\((\[#\d+\]\(.+\))\) \(\[.+\]\(https:.+\/(.+)\)\)$/, /^\* (\*\*(.+):\*\*)?(.+)(https:\/\/github\.com.+) \(\[.+\]\(https:.+\/(.+)\)\)$/, /^\* (\*\*(.+):\*\*)?(.+)() \(\[.+\]\(https:.+\/(.+)\)\)$/, ]; +const frontendChangeRe = /^\* (\*\*.+:\*\* )()?(.+) \(\[.+\]\(https:.+\/()(.+)\)\)(.+)?$/; let commitUserLookup = {}; const commitUserFile = path.join(__dirname, 'commit-user-lookup.json'); @@ -36,7 +40,7 @@ if (fs.existsSync(commitUserFile)) { for (const changelog of changelogs) { for (const line of changelog.contents) { const releaseMatch = line.match(releaseRe); - const changeMatch = changeRe.map((re) => line.match(re)).find((e) => e); + const changeMatch = changelog.isFrontend ? line.match(frontendChangeRe) : changeRe.map((re) => line.match(re)).find((e) => e); if (releaseMatch) { if (releaseMatch[1] === changelog.tillVersion) { break; @@ -48,44 +52,51 @@ for (const changelog of changelogs) { } else if (line.startsWith('* **ignore:**')) { continue; } else if (changeMatch) { - let localContext = changeMatch[2] ? changeMatch[2] : context; + let localContext = changelog.isFrontend ? 'frontend' : (changeMatch[2] ? changeMatch[2] : context); if (!changes[localContext]) localContext = 'error'; - const commitUserKey = `${changelog.project}-${changeMatch[5]} `; + const commit = changeMatch[5]; + const commitUserKey = `${changelog.project}-${commit} `; let user = commitUserKey in commitUserLookup ? commitUserLookup[commitUserKey] : - execSync(`curl -s https://api.github.com/repos/${changelog.project}/commits/${changeMatch[5]} | jq -r '.author.login'`).toString().trim(); + execSync(`curl -s https://api.github.com/repos/${changelog.project}/commits/${commit} | jq -r '.author.login'`).toString().trim(); if (user !== 'null') commitUserLookup[commitUserKey] = user; const messages = []; let message = changeMatch[3].trim(); if (message.endsWith('.')) message = message.substring(0, message.length - 1); + message = message.charAt(0).toUpperCase() + message.slice(1); - const otherUser = message.match(/\[@(.+)\]\(https:\/\/github.com\/.+\)/) || message.match(/@(.+)/); - if (otherUser) { - user = otherUser[1]; - message = message.replace(otherUser[0], ''); - } - - if (localContext === 'add') { - for (const model of message.split(',')) { - const definition = zhc.definitions.find((d) => d.model === model.trim()); - if (definition) { - messages.push(`\`${definition.model}\` ${definition.vendor} ${definition.description}`); - } else { - changes['error'].push(`${line} (model '${model}' does not exist)`); - } - } - } else { + if (changelog.isFrontend) { + changes[localContext].push(`- [${commit.slice(0, 7)}](https://github.com/${changelog.project}/commit/${commit}) ${message} (@${user})`); messages.push(message); - } + } else { + const otherUser = message.match(/\[@(.+)\]\(https:\/\/github.com\/.+\)/) || message.match(/@(.+)/); + if (otherUser) { + user = otherUser[1]; + message = message.replace(otherUser[0], ''); + } - let issue = changeMatch[4].trim(); - if (issue && !issue.startsWith('[#')) issue = `[#${issue.split('/').pop()}](${issue})`; - if (!issue) { - issue = '_NO_ISSUE_'; - localContext = 'error'; - } + if (localContext === 'add') { + for (const model of message.split(',')) { + const definition = zhc.definitions.find((d) => d.model === model.trim()); + if (definition) { + messages.push(`\`${definition.model}\` ${definition.vendor} ${definition.description}`); + } else { + changes['error'].push(`${line} (model '${model}' does not exist)`); + } + } + } else { + messages.push(message); + } - messages.forEach((m) => changes[localContext].push(`- ${issue} ${m} (@${user})`)); + let issue = changeMatch[4].trim(); + if (issue && !issue.startsWith('[#')) issue = `[#${issue.split('/').pop()}](${issue})`; + if (!issue) { + issue = '_NO_ISSUE_'; + localContext = 'error'; + } + + messages.forEach((m) => changes[localContext].push(`- ${issue} ${m} (@${user})`)); + } } else if (line === '# Changelog' || line === '### ⚠ BREAKING CHANGES' || !line) { continue; } else { @@ -98,6 +109,7 @@ let result = ''; const names = [ ['features', 'Improvements'], ['fixes', 'Fixes'], + ['frontend', 'Frontend'], ['add', 'New supported devices'], ['detect', 'Fixed device detections'], ['error', 'Changelog generator error'],