feat: 公告栏改为追加式更新 + 每日自动清空缓存
Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
ab7afe4794
commit
92a1c53840
|
|
@ -0,0 +1 @@
|
|||
{"date":"","records":[]}
|
||||
|
|
@ -22,6 +22,24 @@ jobs:
|
|||
with:
|
||||
node-version: '20'
|
||||
|
||||
# ── Step 0: 清空公告栏缓存(每日重置) ──
|
||||
- name: 清空公告栏缓存
|
||||
run: |
|
||||
CACHE_FILE=".github/brain/bulletin-board-today.json"
|
||||
TODAY=$(TZ="Asia/Shanghai" date +%Y-%m-%d)
|
||||
if [ -f "$CACHE_FILE" ]; then
|
||||
CACHE_DATE=$(jq -r '.date // ""' "$CACHE_FILE" 2>/dev/null || echo "")
|
||||
if [ "$CACHE_DATE" != "$TODAY" ]; then
|
||||
echo '{"date":"","records":[]}' > "$CACHE_FILE"
|
||||
echo "✅ 公告栏缓存已清空(旧日期: $CACHE_DATE)"
|
||||
else
|
||||
echo "📌 公告栏缓存日期匹配今天 ($TODAY),无需清空"
|
||||
fi
|
||||
else
|
||||
echo '{"date":"","records":[]}' > "$CACHE_FILE"
|
||||
echo "✅ 创建新的公告栏缓存文件"
|
||||
fi
|
||||
|
||||
# ── Step 1: 检查 brain/ 目录完整性 ──
|
||||
- name: 检查 brain/ 目录完整性
|
||||
id: brain_check
|
||||
|
|
@ -96,7 +114,7 @@ jobs:
|
|||
run: |
|
||||
git config user.name "铸渊 Maintenance Agent"
|
||||
git config user.email "actions@guanghulab.com"
|
||||
git add brain/system-health.json
|
||||
git add brain/system-health.json .github/brain/bulletin-board-today.json
|
||||
if git diff --cached --quiet; then
|
||||
echo "📌 无变更需要提交"
|
||||
else
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ jobs:
|
|||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add README.md
|
||||
git add README.md .github/brain/bulletin-board-today.json
|
||||
if git diff --cached --quiet; then
|
||||
echo "📢 公告区无变化,跳过提交"
|
||||
else
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ const MEMORY_PATH = path.join(__dirname, '..', '.github', 'brain', 'memory.json'
|
|||
const PERSONA_MEMORY_PATH = path.join(__dirname, '..', '.github', 'persona-brain', 'memory.json');
|
||||
const DEV_STATUS_PATH = path.join(__dirname, '..', '.github', 'persona-brain', 'dev-status.json');
|
||||
const COLLABORATORS_PATH = path.join(__dirname, '..', '.github', 'brain', 'collaborators.json');
|
||||
const BULLETIN_CACHE_PATH = path.join(__dirname, '..', '.github', 'brain', 'bulletin-board-today.json');
|
||||
|
||||
const MAX_BINGSHUO_ENTRIES = 15;
|
||||
const MAX_COLLAB_ENTRIES = 20;
|
||||
|
|
@ -101,6 +102,21 @@ function formatTime(ts) {
|
|||
return `${get('month')}-${get('day')} ${get('hour')}:${get('minute')}`;
|
||||
}
|
||||
|
||||
function formatTimeShort(ts) {
|
||||
if (!ts) return '—';
|
||||
const d = new Date(ts);
|
||||
if (isNaN(d.getTime())) return '—';
|
||||
const fmt = new Intl.DateTimeFormat('zh-CN', {
|
||||
timeZone: 'Asia/Shanghai',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false,
|
||||
});
|
||||
const parts = fmt.formatToParts(d);
|
||||
const get = (type) => (parts.find(p => p.type === type) || {}).value || '';
|
||||
return `${get('hour')}:${get('minute')}`;
|
||||
}
|
||||
|
||||
function todayDateStr() {
|
||||
const fmt = new Intl.DateTimeFormat('zh-CN', {
|
||||
timeZone: 'Asia/Shanghai',
|
||||
|
|
@ -149,6 +165,54 @@ function loadMemoryEvents() {
|
|||
return events;
|
||||
}
|
||||
|
||||
/* ── 公告栏缓存(当日追加式) ─────────────────────────── */
|
||||
|
||||
function loadBulletinCache() {
|
||||
const today = todayDateStr();
|
||||
try {
|
||||
if (fs.existsSync(BULLETIN_CACHE_PATH)) {
|
||||
const cache = JSON.parse(fs.readFileSync(BULLETIN_CACHE_PATH, 'utf8'));
|
||||
if (cache.date === today) {
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(`⚠️ 公告栏缓存读取失败: ${err.message}`);
|
||||
}
|
||||
return { date: today, records: [] };
|
||||
}
|
||||
|
||||
function saveBulletinCache(cache) {
|
||||
try {
|
||||
fs.writeFileSync(BULLETIN_CACHE_PATH, JSON.stringify(cache, null, 2), 'utf8');
|
||||
} catch (err) {
|
||||
console.log(`⚠️ 公告栏缓存写入失败: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function appendToCache(cache, newEntries) {
|
||||
const existingKeys = new Set(cache.records.map(r => r.key));
|
||||
let added = 0;
|
||||
for (const e of newEntries) {
|
||||
const key = `${e.actor}|${e.module || '—'}|${formatTimeShort(e.ts)}`;
|
||||
if (!existingKeys.has(key)) {
|
||||
existingKeys.add(key);
|
||||
cache.records.push({
|
||||
key,
|
||||
ts: e.ts,
|
||||
actor: e.actor,
|
||||
module: e.module || '—',
|
||||
result: e.result,
|
||||
icon: e.icon,
|
||||
sortKey: e.sortKey,
|
||||
});
|
||||
added++;
|
||||
}
|
||||
}
|
||||
cache.records.sort((a, b) => a.sortKey - b.sortKey);
|
||||
return added;
|
||||
}
|
||||
|
||||
/* ── 分类事件为冰朔/合作者 ─────────────────────────── */
|
||||
|
||||
function classifyEvents(events) {
|
||||
|
|
@ -474,26 +538,19 @@ function buildBingshuoAlert(issues) {
|
|||
return alert;
|
||||
}
|
||||
|
||||
/* ── 生成合作者公告表格 ─────────────────────────── */
|
||||
/* ── 生成合作者公告表格(追加式,从缓存构建) ─────────────────────────── */
|
||||
|
||||
function buildCollabBulletin(entries) {
|
||||
const sorted = [...entries].sort((a, b) => b.sortKey - a.sortKey);
|
||||
const seen = new Set();
|
||||
const unique = [];
|
||||
for (const e of sorted) {
|
||||
const key = `${e.actor}|${e.module}|${formatTime(e.ts)}`;
|
||||
if (!seen.has(key)) { seen.add(key); unique.push(e); }
|
||||
}
|
||||
|
||||
const display = unique.slice(0, MAX_COLLAB_ENTRIES);
|
||||
function buildCollabBulletin(cacheRecords) {
|
||||
const today = todayDateStr();
|
||||
const display = cacheRecords.slice(0, MAX_COLLAB_ENTRIES);
|
||||
if (display.length === 0) {
|
||||
return '| 时间 | 合作者 | 模块 | 状态 |\n|------|--------|------|------|\n| 🕐 暂无记录 | — | — | 等待模块推送 |';
|
||||
return `👥 合作者公告栏(${today})\n\n| 时间 | 合作者 | 模块 | 状态 |\n|------|--------|------|------|\n| 🕐 暂无记录 | — | — | 等待模块推送 |`;
|
||||
}
|
||||
|
||||
const rows = display.map(e =>
|
||||
`| ${formatTime(e.ts)} | ${e.actor} | \`${e.module || '—'}/\` | ${e.icon} ${e.result === 'success' || e.result === 'passed' ? '上传成功' : e.result === 'failed' || e.result === 'failure' ? '❌ 上传失败' : '已更新'} |`
|
||||
`| ${formatTimeShort(e.ts)} | ${e.actor} | \`${e.module || '—'}/\` | ${e.icon} ${e.result === 'success' || e.result === 'passed' ? '上传成功' : e.result === 'failed' || e.result === 'failure' ? '❌ 上传失败' : '已更新'} |`
|
||||
);
|
||||
return `| 时间 | 合作者 | 模块 | 状态 |\n|------|--------|------|------|\n${rows.join('\n')}`;
|
||||
return `👥 合作者公告栏(${today})\n\n| 时间 | 合作者 | 模块 | 状态 |\n|------|--------|------|------|\n${rows.join('\n')}`;
|
||||
}
|
||||
|
||||
/* ── 生成合作者提醒 ─────────────────────────── */
|
||||
|
|
@ -687,18 +744,24 @@ async function main() {
|
|||
console.log(`\n📊 冰朔合计: ${allBingshuo.length} 条`);
|
||||
console.log(`📊 合作者合计: ${allCollab.length} 条\n`);
|
||||
|
||||
// 5. 检测需要干预的问题
|
||||
// 5. 合作者公告栏:追加式缓存
|
||||
const cache = loadBulletinCache();
|
||||
const addedCount = appendToCache(cache, allCollab);
|
||||
saveBulletinCache(cache);
|
||||
console.log(`📋 公告栏缓存: ${cache.records.length} 条记录(本次新增 ${addedCount} 条)`);
|
||||
|
||||
// 6. 检测需要干预的问题
|
||||
const { bingshuoIssues, collabIssuesByDev } = detectIssues(allBingshuo, allCollab);
|
||||
console.log(`🔴 冰朔待处理: ${bingshuoIssues.length} 条`);
|
||||
console.log(`🔴 合作者待处理: ${Object.keys(collabIssuesByDev).length} 人\n`);
|
||||
|
||||
// 6. 生成各区域内容
|
||||
// 7. 生成各区域内容
|
||||
const bingshuoBulletin = buildBingshuoBulletin(allBingshuo);
|
||||
const bingshuoAlert = buildBingshuoAlert(bingshuoIssues);
|
||||
const collabBulletin = buildCollabBulletin(allCollab);
|
||||
const collabBulletin = buildCollabBulletin(cache.records);
|
||||
const collabAlert = buildCollabAlert(collabIssuesByDev);
|
||||
|
||||
// 7. 更新 README.md
|
||||
// 8. 更新 README.md
|
||||
if (!fs.existsSync(README_PATH)) {
|
||||
console.error('❌ README.md 不存在');
|
||||
process.exit(1);
|
||||
|
|
@ -718,7 +781,7 @@ async function main() {
|
|||
console.log('✅ README.md 公告区已更新');
|
||||
}
|
||||
|
||||
// 8. 发送邮件(如有需要)
|
||||
// 9. 发送邮件(如有需要)
|
||||
if (bingshuoIssues.length > 0 || Object.keys(collabIssuesByDev).length > 0) {
|
||||
await sendAlertEmails(bingshuoIssues, collabIssuesByDev);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue