diff --git a/.github/workflows/bring-it.yaml b/.github/workflows/bring-it.yaml
index fc25b03..ef5fc91 100644
--- a/.github/workflows/bring-it.yaml
+++ b/.github/workflows/bring-it.yaml
@@ -36,7 +36,7 @@ jobs:
uses: airkro/bring-it@actions
with:
npm-token: ${{ secrets.NPM_TOKEN }}
- publish-command: npx @bring-it/npm@0.3.9 npm
+ publish-command: node packages/cli/dist/cli.mjs npm
custom-command: |
cd packages
mkdir -p cli/dist
diff --git a/package.json b/package.json
index 4a3f9aa..045867a 100644
--- a/package.json
+++ b/package.json
@@ -29,9 +29,12 @@
"@nice-move/prettier-config": "^0.10.0",
"best-shot": "^0.5.0",
"eslint": "^8.56.0",
- "garou": "^0.6.20",
+ "garou": "^0.6.22",
"prettier": "^3.1.1"
},
+ "peerDependencies": {
+ "@bring-it/utils": "workspace:*"
+ },
"engines": {
"node": "^18.0.0 || ^20.0.0",
"npm": ">=9.4.0"
@@ -39,7 +42,7 @@
"packageManager": "pnpm@8.12.1",
"pnpm": {
"overrides": {
- "cpu-features": "npm:garou@0.0.0"
+ "cpu-features": "npm:cheetor@0.0.0"
}
},
"eslintConfig": {
diff --git a/packages/notify/lib/utils.mjs b/packages/notify/lib/utils.mjs
index 93508b7..c02d1ef 100644
--- a/packages/notify/lib/utils.mjs
+++ b/packages/notify/lib/utils.mjs
@@ -1,3 +1,10 @@
+import { createRequire } from 'node:module';
+
+import { sync } from 'conventional-commits-parser';
+import { clean } from 'fast-clean';
+import gitlog from 'gitlog';
+import groupBy from 'lodash/groupBy.js';
+import sortBy from 'lodash/sortBy.js';
import { toMarkdown } from 'mdast-util-to-markdown';
import semverPrerelease from 'semver/functions/prerelease.js';
@@ -10,6 +17,7 @@ const {
DEPOT_NAME,
GIT_COMMIT_SHORT,
GIT_COMMIT,
+ GIT_PREVIOUS_COMMIT,
GIT_HTTP_URL,
JOB_ID,
npm_package_version = '未知',
@@ -17,6 +25,18 @@ const {
PROJECT_WEB_URL,
} = process.env;
+function getVersion({ isLatest, version }) {
+ let name = npm_package_version;
+
+ if (version !== true) {
+ try {
+ name = createRequire(import.meta.url)(`${version}/package.json`).version;
+ } catch {}
+ }
+
+ return isLatest ? ['latest', name].join(' / ') : name;
+}
+
export function dingtalk({ markdown, title, token }) {
console.log({ title });
@@ -31,9 +51,14 @@ export function dingtalk({ markdown, title, token }) {
markdown: {
title,
text: markdown
- .trim()
- // eslint-disable-next-line unicorn/prefer-string-replace-all
- .replace(/\n\n/g, '\n\n
\n\n'),
+ .split('更新历史:')
+ .map((text, i) =>
+ i === 0
+ ? text.replaceAll('\n\n', '\n\n
\n\n')
+ : text.replaceAll('\n\n##', '\n\n
\n\n##'),
+ )
+ .join('更新历史:')
+ .trim(),
},
},
});
@@ -43,6 +68,126 @@ function isTest() {
return BRANCH_NAME !== 'master' || semverPrerelease(npm_package_version);
}
+const configs = {
+ feat: {
+ label: '功能变化',
+ level: 0,
+ },
+ fix: {
+ label: '功能修复',
+ level: 1,
+ },
+ perf: {
+ label: '性能优化',
+ level: 2,
+ },
+ refactor: {
+ label: '重构',
+ level: 3,
+ },
+ revert: {
+ label: '回滚',
+ level: 4,
+ },
+ chore: {
+ label: '杂项',
+ level: 5,
+ },
+ style: {
+ label: '代码风格',
+ level: 6,
+ },
+ test: {
+ label: '测试',
+ level: 7,
+ },
+ build: {
+ label: '编译配置',
+ level: 8,
+ },
+ ci: {
+ label: '自动化',
+ level: 9,
+ },
+ docs: {
+ label: '补充文档',
+ level: 10,
+ },
+};
+
+function getCommits() {
+ const io =
+ GIT_COMMIT === GIT_PREVIOUS_COMMIT
+ ? []
+ : sortBy(
+ Object.entries(
+ groupBy(
+ gitlog
+ .default({
+ repo: '.',
+ since: GIT_PREVIOUS_COMMIT,
+ until: GIT_COMMIT,
+ fields: ['hash', 'abbrevHash', 'subject'],
+ })
+ .map(({ abbrevHash, hash, subject }) => ({
+ hash,
+ abbrevHash,
+ message: sync(subject),
+ subject,
+ })),
+ ({ message }) => message.type,
+ ),
+ ),
+ ([type]) => configs[type].level,
+ ).flatMap(([type, list]) => [
+ {
+ type: 'heading',
+ depth: 4,
+ children: [
+ {
+ type: 'text',
+ value: configs[type]?.label || type,
+ },
+ ],
+ },
+ {
+ type: 'list',
+ spread: false,
+ children: list.map(({ hash, subject }) => ({
+ type: 'listItem',
+ children: [
+ {
+ type: 'link',
+ url: `${PROJECT_WEB_URL}/d/${DEPOT_NAME}/git/commit/${hash}`,
+ children: [
+ {
+ type: 'text',
+ value: subject,
+ },
+ ],
+ },
+ ],
+ })),
+ },
+ ]);
+
+ return io.length > 0
+ ? [
+ {
+ type: 'heading',
+ depth: 3,
+ children: [
+ {
+ type: 'text',
+ value: '更新历史:',
+ },
+ ],
+ },
+ ...io,
+ ]
+ : io;
+}
+
export function createContent({
project = '未命名项目',
type,
@@ -50,10 +195,11 @@ export function createContent({
banner,
isLatest = false,
image,
+ version = true,
}) {
return toMarkdown({
type: 'root',
- children: [
+ children: clean([
banner
? {
type: 'paragraph',
@@ -67,7 +213,7 @@ export function createContent({
: undefined,
{
type: 'heading',
- depth: 3,
+ depth: 2,
children: [
{
type: 'text',
@@ -122,8 +268,13 @@ export function createContent({
type: 'listItem',
children: [
{
- type: 'text',
- value: `发布类型:${type}`,
+ type: 'paragraph',
+ children: [
+ {
+ type: 'text',
+ value: `发布类型:${type}`,
+ },
+ ],
},
],
}
@@ -139,25 +290,23 @@ export function createContent({
],
}
: undefined,
- {
- type: 'listItem',
- children: [
- {
- type: 'paragraph',
+ version
+ ? {
+ type: 'listItem',
children: [
{
- type: 'text',
- value: `版本编号:${
- isLatest
- ? ['latest', npm_package_version].join(' / ')
- : npm_package_version
- }`,
+ type: 'paragraph',
+ children: [
+ {
+ type: 'text',
+ value: `版本编号:${getVersion({ isLatest, version })}`,
+ },
+ ],
},
],
- },
- ],
- },
- ].filter(Boolean),
+ }
+ : undefined,
+ ],
},
{
type: 'paragraph',
@@ -254,7 +403,13 @@ export function createContent({
children: [
{
type: 'text',
- value: GIT_COMMIT_SHORT,
+ value:
+ GIT_COMMIT === GIT_PREVIOUS_COMMIT
+ ? GIT_COMMIT_SHORT
+ : [
+ GIT_PREVIOUS_COMMIT.slice(0, 7),
+ GIT_COMMIT_SHORT,
+ ].join('...'),
},
],
},
@@ -289,8 +444,9 @@ export function createContent({
],
}
: undefined,
- ].filter(Boolean),
+ ],
},
- ].filter(Boolean),
+ ...getCommits(),
+ ]),
});
}
diff --git a/packages/notify/package.json b/packages/notify/package.json
index 5b74c71..4918c21 100644
--- a/packages/notify/package.json
+++ b/packages/notify/package.json
@@ -1,6 +1,6 @@
{
"name": "@bring-it/notify",
- "version": "0.2.0",
+ "version": "0.2.1",
"description": "Send releases notifications",
"license": "MIT",
"author": {
@@ -37,6 +37,10 @@
"prepublishOnly": "pnpm run build"
},
"devDependencies": {
+ "conventional-commits-parser": "^5.0.0",
+ "fast-clean": "^1.3.2",
+ "gitlog": "^4.0.8",
+ "lodash": "^4.17.21",
"mdast-util-to-markdown": "^2.1.0",
"semver": "^7.5.4"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 054450a..ae4fc99 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -5,11 +5,15 @@ settings:
excludeLinksFromLockfile: false
overrides:
- cpu-features: npm:garou@0.0.0
+ cpu-features: npm:cheetor@0.0.0
importers:
.:
+ dependencies:
+ '@bring-it/utils':
+ specifier: workspace:*
+ version: link:packages/utils
devDependencies:
'@nice-move/cli':
specifier: ^0.11.3
@@ -27,8 +31,8 @@ importers:
specifier: ^8.56.0
version: 8.56.0
garou:
- specifier: ^0.6.20
- version: 0.6.20(eslint@8.56.0)(typescript@5.3.3)
+ specifier: ^0.6.22
+ version: 0.6.22(eslint@8.56.0)(typescript@5.3.3)
prettier:
specifier: ^3.1.1
version: 3.1.1
@@ -52,6 +56,18 @@ importers:
specifier: workspace:^
version: link:../cli
devDependencies:
+ conventional-commits-parser:
+ specifier: ^5.0.0
+ version: 5.0.0
+ fast-clean:
+ specifier: ^1.3.2
+ version: 1.3.2
+ gitlog:
+ specifier: ^4.0.8
+ version: 4.0.8
+ lodash:
+ specifier: ^4.17.21
+ version: 4.17.21
mdast-util-to-markdown:
specifier: ^2.1.0
version: 2.1.0
@@ -933,6 +949,14 @@ packages:
resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==}
dev: true
+ /JSONStream@1.3.5:
+ resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
+ hasBin: true
+ dependencies:
+ jsonparse: 1.3.1
+ through: 2.3.8
+ dev: true
+
/acorn-import-assertions@1.9.0(acorn@8.11.2):
resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==}
peerDependencies:
@@ -1208,6 +1232,12 @@ packages:
resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
dev: true
+ /cheetor@0.0.0:
+ resolution: {integrity: sha512-dFpFG4lIUa6GISraG69KSFiSE+bzatlow4oG3VqIoMG6MQdl1O8MpxOe4MSS31rOpO+VhJdRAzMoV5wun0soHA==}
+ requiresBuild: true
+ dev: true
+ optional: true
+
/cheetor@0.13.0:
resolution: {integrity: sha512-1QADgHQtO2oZksh/y6MK8yth40dpeWtlg0qSKMkvdpsWT2UHCT5uAw/yCDgi4vCFChMsmhgOlUsZ+O3kjKhDgg==}
engines: {node: ^14.17.0 || >=16.13.0}
@@ -1277,6 +1307,17 @@ packages:
resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
dev: true
+ /conventional-commits-parser@5.0.0:
+ resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==}
+ engines: {node: '>=16'}
+ hasBin: true
+ dependencies:
+ JSONStream: 1.3.5
+ is-text-path: 2.0.0
+ meow: 12.1.1
+ split2: 4.2.0
+ dev: true
+
/convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
dev: true
@@ -1873,6 +1914,10 @@ packages:
strip-final-newline: 3.0.0
dev: true
+ /fast-clean@1.3.2:
+ resolution: {integrity: sha512-MnlLEHYSfVtvbk9zAZS8DWyF9ZHE/0cvh+pI6I9WNN13k7Asi6OZHpPeuCl9kFiNk7WnZJKvnTsFe/lB+//OSA==}
+ dev: true
+
/fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: true
@@ -1970,20 +2015,13 @@ packages:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
dev: true
- /garou@0.0.0:
- resolution: {integrity: sha512-jxk51p6LStuG4TuejYyNxlZCRT31KwIN5tcwDHtRWS43Pq99KeVoCVdyKkAK+/jUBlLVEjX18aXgdJyBJWhdVQ==}
- deprecated: Use latest version
- requiresBuild: true
- dev: true
- optional: true
-
- /garou@0.6.20(eslint@8.56.0)(typescript@5.3.3):
- resolution: {integrity: sha512-WDB47SrWQbBJoYDPfrMJ/bMfw0IFB+2sgHkwXkRhFzfcfGjEMLQi/LZSM3dV6Fs9BKte/1hlhGV5UYDQ07tHwA==}
+ /garou@0.6.22(eslint@8.56.0)(typescript@5.3.3):
+ resolution: {integrity: sha512-p/hDC+7HjlAstuAAP5gWwojJyfDrsOPhEoXHqKq74nLu5mnppR9SoV1bDeODu8xbYtZAfR2AJnp47LYk6odUig==}
engines: {node: '>=20.0.0 || ^16.15.0 || ^18.12.0'}
hasBin: true
peerDependencies:
- eslint: ^8.55.0
- typescript: ^5.2.2
+ eslint: ^8.56.0
+ typescript: ^5.3.3
peerDependenciesMeta:
typescript:
optional: true
@@ -2040,6 +2078,16 @@ packages:
resolve-pkg-maps: 1.0.0
dev: true
+ /gitlog@4.0.8:
+ resolution: {integrity: sha512-FcTLP7Rc0H1vWXD+J/aj5JS1uiCEBblcYXlcacRAT73N26OMYFFzrBXYmDozmWlV2K7zwK5PrH16/nuRNhqSlQ==}
+ engines: {node: '>= 10.x'}
+ dependencies:
+ debug: 4.3.4
+ tslib: 2.6.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
/glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -2383,6 +2431,13 @@ packages:
has-symbols: 1.0.3
dev: true
+ /is-text-path@2.0.0:
+ resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==}
+ engines: {node: '>=8'}
+ dependencies:
+ text-extensions: 2.4.0
+ dev: true
+
/is-typed-array@1.1.12:
resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==}
engines: {node: '>= 0.4'}
@@ -2488,6 +2543,11 @@ packages:
hasBin: true
dev: true
+ /jsonparse@1.3.1:
+ resolution: {integrity: sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=}
+ engines: {'0': node >= 0.2.0}
+ dev: true
+
/keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
dependencies:
@@ -2616,6 +2676,11 @@ packages:
'@types/mdast': 4.0.3
dev: true
+ /meow@12.1.1:
+ resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==}
+ engines: {node: '>=16.10'}
+ dev: true
+
/merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
dev: true
@@ -3286,6 +3351,11 @@ packages:
resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==}
dev: true
+ /split2@4.2.0:
+ resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
+ engines: {node: '>= 10.x'}
+ dev: true
+
/ssh-config@4.4.1:
resolution: {integrity: sha512-3VKB9wiwWbwVGjM8T5/nkIrijenIYhKXOHrcCH4cOlAX6d+hD4lMFJtJp3UF1KaUDIMtccg1MmwqoTCX7CoVzw==}
dev: true
@@ -3298,7 +3368,7 @@ packages:
asn1: 0.2.6
bcrypt-pbkdf: 1.0.2
optionalDependencies:
- cpu-features: /garou@0.0.0
+ cpu-features: /cheetor@0.0.0
nan: 2.18.0
dev: true
@@ -3437,10 +3507,19 @@ packages:
source-map-support: 0.5.21
dev: true
+ /text-extensions@2.4.0:
+ resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==}
+ engines: {node: '>=8'}
+ dev: true
+
/text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true
+ /through@2.3.8:
+ resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=}
+ dev: true
+
/to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
@@ -3470,6 +3549,10 @@ packages:
strip-bom: 3.0.0
dev: true
+ /tslib@2.6.2:
+ resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
+ dev: true
+
/tweetnacl@0.14.5:
resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==}
dev: true