const simpleGit = require('simple-git'); // const path = require('path'); const axios = require('axios'); const DINGTALK_WEBHOOK = 'https://oapi.dingtalk.com/robot/send?access_token=54b7c152d185a3b6220b444d366490ecf45876c7fa64e3bf4ab55fc9d1d5190e' const SECRET = 'SEC058cffe27061581bde3d42b4a610179c04cdc296f4e7dee1af510803c49af5a0' // 钉钉消息格式 // const message = { // msgtype: 'markdown', // markdown: { // title: '前端项目构建通知', // text: `### 前端项目构建完成\n` + // `- 项目: ${process.env.npm_package_name}\n` + // `- 版本: ${process.env.npm_package_version}\n` + // `- 环境: ${process.env.NODE_ENV || 'production'}\n` + // `- 时间: ${new Date().toLocaleString()}\n` + // `- 状态: 成功 ✅\n\n` // } // }; const message2 = { 'at': { 'atMobiles': [ '13717881619' ], 'atUserIds': [ ], 'isAtAll': false }, 'text': { 'content': '大数据平台前端页面打包上传完成,请发版!\n' }, 'msgtype': 'text' } function send(webhook, data) { axios.post(webhook, data) .then(response => { if (response.data.errcode !== 0) { console.error('发送钉钉通知失败', response.data); process.exit(1); } else { console.log('钉钉通知发送成功'); } }) .catch(error => { console.error('发送钉钉通知时出错', error.message); process.exit(1); }); } function sendDingTalk() { if (SECRET) { const timestamp = Date.now(); const sign = generateSign(SECRET, timestamp); send(`${DINGTALK_WEBHOOK}×tamp=${timestamp}&sign=${sign}`, message2); } else { send(DINGTALK_WEBHOOK, message2); } } // 生成加签 function generateSign(secret, timestamp) { const crypto = require('crypto'); const str = timestamp + '\n' + secret; const hmac = crypto.createHmac('sha256', secret); hmac.update(str); return encodeURIComponent(hmac.digest('base64')); } // ==================== 配置参数 ==================== const CONFIG = { // 仓库2的本地路径(即项目A的 dist 目录,必填) repo2LocalPath: 'F:\\project\\bigdata_vue_frond', // 假设 dist 是项目A的输出目录 // 仓库2的远程地址(必填,如 GitHub 私有仓库用 HTTPS 或 SSH) repo2Remote: 'http://code.nyzhwlw.com:10202/bd_vue_org/bigdata_vue_frond.git', // 仓库2的目标分支(必填,如 main、gh-pages) targetBranch: 'master', // 提交信息(可选,默认动态生成) commitMsg: `Auto commit: ${new Date().toLocaleString()}` }; // ================================================== // 初始化 Git 实例(指向仓库2的本地路径) const git = simpleGit({ baseDir: CONFIG.repo2LocalPath, maxConcurrentProcesses: 1 }); /** * 主函数:执行全流程 */ async function main() { try { // 步骤 1:检查仓库2的本地路径是否存在且是 Git 仓库 if (!await isGitRepository(CONFIG.repo2LocalPath)) { throw new Error(`❌ 仓库2的本地路径不存在或不是 Git 仓库:${CONFIG.repo2LocalPath}`); } // 步骤 2:切换到仓库2目录并拉取最新代码 await pullLatestCode(); // 步骤 3:检测仓库2中是否有新变更(由项目A打包生成) const hasChanges = await checkForChanges(); if (!hasChanges) { console.log('\x1b[33mℹ️ 无变更需要提交,跳过操作。\x1b[0m'); return; } // 步骤 4:提交并推送至仓库2 await commitAndPush(); console.log('\x1b[32m✅ 操作成功!\x1b[0m'); console.log(`仓库2的 ${CONFIG.targetBranch} 分支已更新。`); // 发送到钉钉 sendDingTalk() } catch (error) { console.error('\x1b[31m❌ 操作失败!\x1b[0m'); console.error(error.message); process.exit(1); } } /** * 检查路径是否是 Git 仓库(通过 .git 目录判断) */ async function isGitRepository(dirPath) { try { await simpleGit(dirPath).checkIsRepo(); return true; } catch (e) { return false; } } /** * 拉取仓库2的远程最新代码 */ async function pullLatestCode() { console.log('🔄 正在拉取仓库2的远程最新代码...'); await git.pull('origin', CONFIG.targetBranch); } /** * 检测仓库2中是否有新变更(由项目A打包生成) */ async function checkForChanges() { console.log('🔍 检测仓库2中是否有新变更...'); const status = await git.status(); return status.files.length > 0; // 有文件变更则返回 true } /** * 提交并推送至仓库2的远程 */ async function commitAndPush() { console.log('🔄 提交并推送变更到仓库2...'); // 添加所有变更文件 await git.add('./*'); // 提交(确保有变更) const status = await git.status(); if (!status.files.length) { throw new Error('❌ 无变更需要提交(可能仓库2内容与远程一致)'); } await git.commit(CONFIG.commitMsg); // 推送至远程分支(-u 关联本地与远程分支) await git.push('-u', 'origin', CONFIG.targetBranch); } // 执行主函数 main();