fix: 模块通知邮件路由修复 - 改用 Commit Comment 通知推送者本人,不再通知仓库所有者
v2.0 改动: 1. notify-module-received.js: 改用 Commit Comment API(替代 Issue API) - 邮件只发给推送者本人(@github.actor),不再通知仓库所有者 - 通知中包含模块自检结果(通过/未通过 + 详细报告) 2. generate-module-doc.yml: 新增模块自检步骤(检查 README、package.json、src/ 等) 3. bingshuo-deploy-agent.yml: 新增 workflow_run 触发,模块推送后自动启动冰朔人格体 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
ee837894ef
commit
d120b776c4
|
|
@ -4,6 +4,7 @@ name: "🧊 冰朔人格体 · 自动部署诊断"
|
||||||
# 1. 手动触发(workflow_dispatch)
|
# 1. 手动触发(workflow_dispatch)
|
||||||
# 2. Issue 评论包含触发关键词
|
# 2. Issue 评论包含触发关键词
|
||||||
# 3. 新 Issue 带有 bingshuo-deploy 标签
|
# 3. 新 Issue 带有 bingshuo-deploy 标签
|
||||||
|
# 4. 合作者推送模块后,模块文档工作流完成时自动触发
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
|
|
@ -27,6 +28,11 @@ on:
|
||||||
issues:
|
issues:
|
||||||
types: [opened]
|
types: [opened]
|
||||||
|
|
||||||
|
# 合作者推送模块后,模块文档工作流完成时自动触发冰朔人格体部署诊断
|
||||||
|
workflow_run:
|
||||||
|
workflows: ["铸渊 · HoloLake Era 模块文档自动生成"]
|
||||||
|
types: [completed]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
issues: write
|
issues: write
|
||||||
|
|
@ -42,6 +48,7 @@ jobs:
|
||||||
# 3. 新 Issue 带有 bingshuo-deploy 标签
|
# 3. 新 Issue 带有 bingshuo-deploy 标签
|
||||||
if: |
|
if: |
|
||||||
github.event_name == 'workflow_dispatch' ||
|
github.event_name == 'workflow_dispatch' ||
|
||||||
|
github.event_name == 'workflow_run' ||
|
||||||
(github.event_name == 'issue_comment' && (
|
(github.event_name == 'issue_comment' && (
|
||||||
contains(github.event.comment.body, '启动冰朔人格体') ||
|
contains(github.event.comment.body, '启动冰朔人格体') ||
|
||||||
contains(github.event.comment.body, '冰朔人格体') ||
|
contains(github.event.comment.body, '冰朔人格体') ||
|
||||||
|
|
|
||||||
|
|
@ -57,14 +57,13 @@ jobs:
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
notify-collaborator:
|
check-and-notify:
|
||||||
name: 📧 通知合作者模块已收到
|
name: 🔍 模块自检 + 📧 通知推送者
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# 仅 push 事件触发(workflow_dispatch 为手动,不发通知)
|
# 仅 push 事件触发(workflow_dispatch 为手动,不发通知)
|
||||||
if: github.event_name == 'push'
|
if: github.event_name == 'push'
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: write
|
||||||
issues: write
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
|
@ -88,7 +87,59 @@ jobs:
|
||||||
echo "EOF" >> $GITHUB_OUTPUT
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
echo "📄 改动文件:$FILES"
|
echo "📄 改动文件:$FILES"
|
||||||
|
|
||||||
- name: 发送模块收讫通知
|
- name: 🔍 模块自检
|
||||||
|
id: check
|
||||||
|
run: |
|
||||||
|
CHANGED_FILES="${{ steps.changed.outputs.files }}"
|
||||||
|
MODULES="m01-login m03-personality m05-user-center m06-ticket m07-dialogue-ui m10-cloud m11-module m12-kanban m15-cloud-drive dingtalk-bot backend-integration status-board"
|
||||||
|
|
||||||
|
RESULT="pass"
|
||||||
|
DETAILS=""
|
||||||
|
|
||||||
|
for mod in $MODULES; do
|
||||||
|
# 只检查本次有改动的模块
|
||||||
|
if echo "$CHANGED_FILES" | grep -q "^${mod}/"; then
|
||||||
|
echo "🔍 检查模块: $mod"
|
||||||
|
|
||||||
|
if [ -d "$mod" ]; then
|
||||||
|
if [ ! -f "$mod/README.md" ]; then
|
||||||
|
DETAILS="${DETAILS}❌ ${mod} 缺少 README.md(必须提供)"$'\n'
|
||||||
|
RESULT="fail"
|
||||||
|
fi
|
||||||
|
if [ ! -f "$mod/package.json" ]; then
|
||||||
|
DETAILS="${DETAILS}⚠️ ${mod} 缺少 package.json(建议补充)"$'\n'
|
||||||
|
fi
|
||||||
|
if [ ! -d "$mod/src" ]; then
|
||||||
|
DETAILS="${DETAILS}⚠️ ${mod} 缺少 src/ 目录(建议补充)"$'\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查 package.json 格式是否正确
|
||||||
|
if [ -f "$mod/package.json" ]; then
|
||||||
|
if ! node -e "JSON.parse(require('fs').readFileSync('$mod/package.json','utf8'))" 2>/dev/null; then
|
||||||
|
DETAILS="${DETAILS}❌ ${mod}/package.json 格式错误(JSON 解析失败)"$'\n'
|
||||||
|
RESULT="fail"
|
||||||
|
else
|
||||||
|
DETAILS="${DETAILS}✅ ${mod} 结构检查通过"$'\n'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
DETAILS="${DETAILS}✅ ${mod} 基本结构检查通过"$'\n'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$DETAILS" ]; then
|
||||||
|
DETAILS="✅ 所有模块检查通过"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "test_result=$RESULT" >> $GITHUB_OUTPUT
|
||||||
|
# 使用 heredoc 方式输出多行详情
|
||||||
|
echo "test_details<<EOF" >> $GITHUB_OUTPUT
|
||||||
|
echo "$DETAILS" >> $GITHUB_OUTPUT
|
||||||
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
|
echo "🔍 自检结果: $RESULT"
|
||||||
|
|
||||||
|
- name: 📧 发送模块收讫通知(Commit Comment → 推送者本人)
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
GITHUB_REPO: ${{ github.repository }}
|
GITHUB_REPO: ${{ github.repository }}
|
||||||
|
|
@ -96,5 +147,7 @@ jobs:
|
||||||
CHANGED_FILES: ${{ steps.changed.outputs.files }}
|
CHANGED_FILES: ${{ steps.changed.outputs.files }}
|
||||||
COMMIT_SHA: ${{ github.sha }}
|
COMMIT_SHA: ${{ github.sha }}
|
||||||
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
|
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
|
||||||
|
TEST_RESULT: ${{ steps.check.outputs.test_result }}
|
||||||
|
TEST_DETAILS: ${{ steps.check.outputs.test_details }}
|
||||||
run: node scripts/notify-module-received.js
|
run: node scripts/notify-module-received.js
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
// scripts/notify-module-received.js
|
// scripts/notify-module-received.js
|
||||||
// 铸渊 · 模块收讫通知系统
|
// 铸渊 · 模块收讫通知系统 v2.0
|
||||||
// 当合作者上传模块后,自动创建 GitHub Issue @提及 → GitHub 自动发邮件给对方
|
// 当合作者上传模块后,通过 Commit Comment @推送者 → GitHub 自动发邮件给推送者
|
||||||
|
//
|
||||||
|
// v2.0 改动:
|
||||||
|
// - 改用 Commit Comment(而非 Issue)通知,邮件只发给推送者本人,不再通知仓库所有者
|
||||||
|
// - 通知中包含模块自检结果(通过/未通过 + 详细报告)
|
||||||
|
// - 直接使用 github.actor 作为 @提及目标,无需 collaborators.json 中填写 github_username
|
||||||
//
|
//
|
||||||
// 环境变量(由 GitHub Actions 注入):
|
// 环境变量(由 GitHub Actions 注入):
|
||||||
// GITHUB_TOKEN — 仓库 token(自动注入)
|
// GITHUB_TOKEN — 仓库 token(自动注入)
|
||||||
// GITHUB_REPO — 格式: owner/repo(如 qinfendebingshuo/guanghulab)
|
// GITHUB_REPO — 格式: owner/repo(如 qinfendebingshuo/guanghulab)
|
||||||
// PUSHER_LOGIN — github.actor,即推送者的 GitHub 用户名
|
// PUSHER_LOGIN — github.actor,即推送者的 GitHub 用户名
|
||||||
// CHANGED_FILES — 本次 push 中改动的文件列表(换行分隔)
|
// CHANGED_FILES — 本次 push 中改动的文件列表(换行分隔)
|
||||||
// COMMIT_SHA — 本次 commit SHA(前8位)
|
// COMMIT_SHA — 本次 commit 完整 SHA
|
||||||
// COMMIT_MESSAGE — 本次 commit 消息
|
// COMMIT_MESSAGE — 本次 commit 消息
|
||||||
|
// TEST_RESULT — 自检结果:pass / fail
|
||||||
|
// TEST_DETAILS — 自检详细报告
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const https = require('https');
|
const https = require('https');
|
||||||
|
|
@ -18,8 +25,11 @@ const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
|
||||||
const GITHUB_REPO = process.env.GITHUB_REPO || '';
|
const GITHUB_REPO = process.env.GITHUB_REPO || '';
|
||||||
const PUSHER_LOGIN = (process.env.PUSHER_LOGIN || '').trim();
|
const PUSHER_LOGIN = (process.env.PUSHER_LOGIN || '').trim();
|
||||||
const CHANGED_FILES = (process.env.CHANGED_FILES || '').trim();
|
const CHANGED_FILES = (process.env.CHANGED_FILES || '').trim();
|
||||||
const COMMIT_SHA = (process.env.COMMIT_SHA || '').slice(0, 8);
|
const COMMIT_SHA = (process.env.COMMIT_SHA || '').trim();
|
||||||
|
const COMMIT_SHA_SHORT = COMMIT_SHA.slice(0, 8);
|
||||||
const COMMIT_MSG = (process.env.COMMIT_MESSAGE || '').split('\n')[0].slice(0, 80);
|
const COMMIT_MSG = (process.env.COMMIT_MESSAGE || '').split('\n')[0].slice(0, 80);
|
||||||
|
const TEST_RESULT = (process.env.TEST_RESULT || 'unknown').trim();
|
||||||
|
const TEST_DETAILS = (process.env.TEST_DETAILS || '').trim();
|
||||||
|
|
||||||
if (!GITHUB_TOKEN || !GITHUB_REPO) {
|
if (!GITHUB_TOKEN || !GITHUB_REPO) {
|
||||||
console.error('❌ 缺少 GITHUB_TOKEN 或 GITHUB_REPO');
|
console.error('❌ 缺少 GITHUB_TOKEN 或 GITHUB_REPO');
|
||||||
|
|
@ -31,6 +41,11 @@ if (!PUSHER_LOGIN) {
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!COMMIT_SHA) {
|
||||||
|
console.log('⚠️ 未获取到 Commit SHA,跳过通知');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
const [OWNER, REPO] = GITHUB_REPO.split('/');
|
const [OWNER, REPO] = GITHUB_REPO.split('/');
|
||||||
|
|
||||||
// ========== 加载合作者配置 ==========
|
// ========== 加载合作者配置 ==========
|
||||||
|
|
@ -39,8 +54,7 @@ try {
|
||||||
const config = JSON.parse(fs.readFileSync('.github/brain/collaborators.json', 'utf8'));
|
const config = JSON.parse(fs.readFileSync('.github/brain/collaborators.json', 'utf8'));
|
||||||
collaborators = config.collaborators || [];
|
collaborators = config.collaborators || [];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('❌ 无法读取 collaborators.json:', e.message);
|
console.log('⚠️ 无法读取 collaborators.json,将使用 GitHub 用户名:', e.message);
|
||||||
process.exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 按推送者 GitHub 用户名查找合作者 ==========
|
// ========== 按推送者 GitHub 用户名查找合作者 ==========
|
||||||
|
|
@ -76,71 +90,80 @@ function detectChangedModules(changedFilesStr) {
|
||||||
return Array.from(moduleDirs);
|
return Array.from(moduleDirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 构建通知 Issue 内容 ==========
|
// ========== 构建通知内容(Commit Comment 格式)==========
|
||||||
function buildIssueContent(collab, changedModules, allFiles) {
|
function buildNotificationContent(collab, changedModules, allFiles) {
|
||||||
const now = new Date().toISOString().replace('T', ' ').slice(0, 16) + ' UTC';
|
const now = new Date().toISOString().replace('T', ' ').slice(0, 16) + ' UTC';
|
||||||
const mention = collab && collab.github_username ? `@${collab.github_username}` : `@${PUSHER_LOGIN}`;
|
|
||||||
const devLabel = collab ? `${collab.dev_id} · ${collab.emoji} ${collab.name}` : PUSHER_LOGIN;
|
const devLabel = collab ? `${collab.dev_id} · ${collab.emoji} ${collab.name}` : PUSHER_LOGIN;
|
||||||
|
|
||||||
const moduleListStr = changedModules.length > 0
|
const moduleListStr = changedModules.length > 0
|
||||||
? changedModules.map(m => `- \`${m}/\``).join('\n')
|
? changedModules.map(m => `- \`${m}/\``).join('\n')
|
||||||
: '- (系统自动检测,请核对)';
|
: '- (未检测到标准模块目录)';
|
||||||
|
|
||||||
const fileLines = allFiles.split('\n').filter(Boolean);
|
const fileLines = allFiles.split('\n').filter(Boolean);
|
||||||
const fileListStr = fileLines.slice(0, 20).map(f => ` - \`${f}\``).join('\n');
|
const fileListStr = fileLines.slice(0, 20).map(f => ` - \`${f}\``).join('\n');
|
||||||
const extraNote = fileLines.length > 20 ? `\n - ...(共 ${fileLines.length} 个文件)` : '';
|
const extraNote = fileLines.length > 20 ? `\n - ...(共 ${fileLines.length} 个文件)` : '';
|
||||||
|
|
||||||
const title = `📦 铸渊收讫 · [${collab ? collab.dev_id : 'DEV-???'}] ${collab ? collab.name : PUSHER_LOGIN} 模块已收到`;
|
const isPass = TEST_RESULT === 'pass';
|
||||||
|
const statusEmoji = isPass ? '✅' : '❌';
|
||||||
|
const statusText = isPass ? '自检通过' : '自检未通过';
|
||||||
|
|
||||||
const body = `## 铸渊收讫通知
|
let body = `## 📦 光湖自动化系统 · 模块收讫回执\n\n`;
|
||||||
|
body += `@${PUSHER_LOGIN} 你好!\n\n`;
|
||||||
|
|
||||||
${mention} 你好!🎉
|
if (isPass) {
|
||||||
|
body += `🎉 **你上传的模块已收到,自检通过!**\n\n`;
|
||||||
|
} else {
|
||||||
|
body += `⚠️ **你上传的模块已收到,但自检发现以下问题,请修改后重新上传:**\n\n`;
|
||||||
|
}
|
||||||
|
|
||||||
铸渊(自动化系统)已确认收到你上传的模块。
|
body += `---\n\n`;
|
||||||
|
body += `### 📋 收讫详情\n\n`;
|
||||||
|
body += `| 字段 | 内容 |\n`;
|
||||||
|
body += `|------|------|\n`;
|
||||||
|
body += `| **合作者** | ${devLabel} |\n`;
|
||||||
|
body += `| **GitHub 账号** | @${PUSHER_LOGIN} |\n`;
|
||||||
|
body += `| **收到时间** | ${now} |\n`;
|
||||||
|
body += `| **Commit** | \`${COMMIT_SHA_SHORT}\` |\n`;
|
||||||
|
body += `| **提交说明** | ${COMMIT_MSG || '(无)'} |\n`;
|
||||||
|
body += `| **自检结果** | ${statusEmoji} ${statusText} |\n\n`;
|
||||||
|
|
||||||
---
|
body += `### 📦 涉及模块\n\n${moduleListStr}\n\n`;
|
||||||
|
body += `### 📄 上传文件清单\n\n${fileListStr}${extraNote}\n\n`;
|
||||||
|
|
||||||
### 📋 收讫详情
|
// 自检报告
|
||||||
|
body += `### ${statusEmoji} 自检报告\n\n`;
|
||||||
|
if (TEST_DETAILS) {
|
||||||
|
body += `\`\`\`\n${TEST_DETAILS}\n\`\`\`\n\n`;
|
||||||
|
} else {
|
||||||
|
body += isPass ? '所有检查项目通过。\n\n' : '(未获取到详细检查报告)\n\n';
|
||||||
|
}
|
||||||
|
|
||||||
| 字段 | 内容 |
|
if (!isPass) {
|
||||||
|------|------|
|
body += `### 📌 修改指南\n\n`;
|
||||||
| **合作者** | ${devLabel} |
|
body += `1. 请根据以上自检报告修改相关文件\n`;
|
||||||
| **GitHub 账号** | @${PUSHER_LOGIN} |
|
body += `2. 修改完成后重新推送到仓库\n`;
|
||||||
| **收到时间** | ${now} |
|
body += `3. 铸渊将自动重新检查并发送新的回执\n\n`;
|
||||||
| **Commit** | \`${COMMIT_SHA}\` |
|
} else {
|
||||||
| **提交说明** | ${COMMIT_MSG || '(无)'} |
|
body += `### 📌 下一步\n\n`;
|
||||||
|
body += `1. 模块结构检查已通过,无需额外操作\n`;
|
||||||
|
body += `2. 铸渊将自动更新 [部署模块总文档](https://github.com/${GITHUB_REPO}/blob/main/docs/HoloLake-Era-OS-Modules.md)\n`;
|
||||||
|
body += `3. 如需修改,请继续推送即可\n\n`;
|
||||||
|
}
|
||||||
|
|
||||||
### 📦 涉及模块
|
body += `---\n`;
|
||||||
|
body += `*—— 光湖自动化系统 · 铸渊(ZhùYuān)· ${now}*`;
|
||||||
|
|
||||||
${moduleListStr}
|
return body;
|
||||||
|
|
||||||
### 📄 上传文件清单
|
|
||||||
|
|
||||||
${fileListStr}${extraNote}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 📌 下一步
|
|
||||||
|
|
||||||
1. **铸渊将自动更新** [HoloLake Era 操作系统部署模块](https://github.com/${GITHUB_REPO}/blob/main/docs/HoloLake-Era-OS-Modules.md) 总文档
|
|
||||||
2. **模块结构检查** 已自动运行,请确认 CI 状态绿灯
|
|
||||||
3. 如需补充 \`SYSLOG.md\`、\`package.json\` 或 \`src/\` 目录,请继续推送
|
|
||||||
|
|
||||||
> 💡 如有问题,请直接在本 Issue 回复,铸渊会收到通知。
|
|
||||||
|
|
||||||
---
|
|
||||||
*—— 铸渊(ZhùYuān)· 光湖自动化系统 · 自动通知 #${now}*`;
|
|
||||||
|
|
||||||
return { title, body };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 调用 GitHub API 创建 Issue ==========
|
// ========== 调用 GitHub API 创建 Commit Comment ==========
|
||||||
function createIssue(title, body) {
|
// Commit Comment 只通知 commit 作者 + @提及的用户,不通知仓库所有者
|
||||||
|
function createCommitComment(body) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const payload = JSON.stringify({ title, body, labels: ['模块收讫'] });
|
const payload = JSON.stringify({ body });
|
||||||
const options = {
|
const options = {
|
||||||
hostname: 'api.github.com',
|
hostname: 'api.github.com',
|
||||||
path: `/repos/${OWNER}/${REPO}/issues`,
|
path: `/repos/${OWNER}/${REPO}/commits/${COMMIT_SHA}/comments`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${GITHUB_TOKEN}`,
|
'Authorization': `Bearer ${GITHUB_TOKEN}`,
|
||||||
|
|
@ -157,8 +180,7 @@ function createIssue(title, body) {
|
||||||
res.on('data', chunk => { data += chunk; });
|
res.on('data', chunk => { data += chunk; });
|
||||||
res.on('end', () => {
|
res.on('end', () => {
|
||||||
if (res.statusCode === 201) {
|
if (res.statusCode === 201) {
|
||||||
const issue = JSON.parse(data);
|
resolve(JSON.parse(data));
|
||||||
resolve(issue);
|
|
||||||
} else {
|
} else {
|
||||||
reject(new Error(`GitHub API 返回 ${res.statusCode}: ${data}`));
|
reject(new Error(`GitHub API 返回 ${res.statusCode}: ${data}`));
|
||||||
}
|
}
|
||||||
|
|
@ -171,55 +193,15 @@ function createIssue(title, body) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 确保标签存在(不存在则自动创建)==========
|
|
||||||
function ensureLabel() {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const labelPayload = JSON.stringify({
|
|
||||||
name: '模块收讫',
|
|
||||||
color: '0075ca',
|
|
||||||
description: '铸渊自动通知:合作者模块收讫确认',
|
|
||||||
});
|
|
||||||
const options = {
|
|
||||||
hostname: 'api.github.com',
|
|
||||||
path: `/repos/${OWNER}/${REPO}/labels`,
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Authorization': `Bearer ${GITHUB_TOKEN}`,
|
|
||||||
'Accept': 'application/vnd.github+json',
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Content-Length': Buffer.byteLength(labelPayload),
|
|
||||||
'User-Agent': 'ZhuyuanBot/1.0',
|
|
||||||
'X-GitHub-Api-Version': '2022-11-28',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const req = https.request(options, res => {
|
|
||||||
let data = '';
|
|
||||||
res.on('data', c => { data += c; });
|
|
||||||
res.on('end', () => {
|
|
||||||
// 201 = created, 422 = already exists,都算OK
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.on('error', () => resolve()); // 标签创建失败不阻断主流程
|
|
||||||
req.write(labelPayload);
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 主流程 ==========
|
// ========== 主流程 ==========
|
||||||
async function main() {
|
async function main() {
|
||||||
console.log(`👤 推送者:${PUSHER_LOGIN}`);
|
console.log(`👤 推送者:${PUSHER_LOGIN}`);
|
||||||
console.log(`📁 改动文件:${CHANGED_FILES ? CHANGED_FILES.split('\n').length : 0} 个`);
|
console.log(`📁 改动文件:${CHANGED_FILES ? CHANGED_FILES.split('\n').length : 0} 个`);
|
||||||
|
console.log(`🔍 自检结果:${TEST_RESULT}`);
|
||||||
|
|
||||||
const collab = findCollaborator(PUSHER_LOGIN);
|
const collab = findCollaborator(PUSHER_LOGIN);
|
||||||
if (collab) {
|
if (collab) {
|
||||||
console.log(`✅ 识别合作者:${collab.dev_id} · ${collab.name}`);
|
console.log(`✅ 识别合作者:${collab.dev_id} · ${collab.name}`);
|
||||||
if (!collab.github_username) {
|
|
||||||
console.log(`⚠️ ${collab.dev_id}(${collab.name})的 github_username 尚未填写`);
|
|
||||||
console.log(` 请在 .github/brain/collaborators.json 中补充,以便 @提及 生效`);
|
|
||||||
console.log(` 通知将仍然创建,但不会有 @提及 邮件通知`);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
console.log(`ℹ️ 未在 collaborators.json 中找到 "${PUSHER_LOGIN}" 的映射,将使用 GitHub 用户名通知`);
|
console.log(`ℹ️ 未在 collaborators.json 中找到 "${PUSHER_LOGIN}" 的映射,将使用 GitHub 用户名通知`);
|
||||||
}
|
}
|
||||||
|
|
@ -242,16 +224,14 @@ async function main() {
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确保标签存在
|
// 构建并发送通知(通过 Commit Comment,直接通知推送者本人)
|
||||||
await ensureLabel();
|
const body = buildNotificationContent(collab, changedModules, CHANGED_FILES);
|
||||||
|
console.log(`📝 创建 Commit Comment 通知(通知目标:@${PUSHER_LOGIN})...`);
|
||||||
|
|
||||||
// 构建并发送通知
|
const comment = await createCommitComment(body);
|
||||||
const { title, body } = buildIssueContent(collab, changedModules, CHANGED_FILES);
|
console.log(`✅ Commit Comment 已创建:${comment.html_url}`);
|
||||||
console.log(`📝 创建通知 Issue:${title}`);
|
console.log(`📧 GitHub 将自动发送邮件通知给 @${PUSHER_LOGIN}(推送者本人)`);
|
||||||
|
console.log(`📧 仓库所有者将不会收到此通知`);
|
||||||
const issue = await createIssue(title, body);
|
|
||||||
console.log(`✅ Issue 已创建:#${issue.number} → ${issue.html_url}`);
|
|
||||||
console.log(`📧 GitHub 将自动发送邮件通知给 @${collab?.github_username || PUSHER_LOGIN}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main().catch(err => {
|
main().catch(err => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue