Discord.js机器人多GitHub仓库同步更新实现问题求助
Discord.js机器人多GitHub仓库同步更新实现问题求助
我刚接触GitHub,最近在给我的Discord.js机器人开发一套多仓库同步更新的系统,目前规划了三个仓库来实现不同的功能:
authCodeRepoUrl:存放机器人的核心业务代码(比如命令、事件逻辑等),这个仓库需要每次都拉取最新的远程代码覆盖本地authDataRepoUrl:专门存储机器人的.json数据文件,需要对比本地和远程文件的更新时间,实现双向同步(哪边文件更新就以哪边为准同步)authBackupRepoUrl:用来备份机器人的整个运行文件夹,这样我在任意设备都能查看完整的文件状态
我自己尝试写了实现代码,遇到问题后找AI帮忙调试,但不确定是不是真的解决了问题,所以来这里求助各位大佬(提前说声抱歉)。
我的实现代码如下:
const { exec } = require('child_process'); const path = require('path'); const fs = require('fs'); require('dotenv').config(); const os = require('os'); const codeRepoUrl = process.env.CODE_REPO_URL; const dataRepoUrl = process.env.DATA_REPO_URL; const backupRepoUrl = process.env.BACKUP_REPO_URL; const token = process.env.GITHUB_PAT; const allowedHost = 'ncpi'; const currentHost = os.hostname(); if (!codeRepoUrl || !dataRepoUrl || !backupRepoUrl || !token) { console.error('[ERROR] CODE_REPO_URL, DATA_REPO_URL, BACKUP_REPO_URL, or GITHUB_PAT is not set in .env'); process.exit(1); } const codeRepoPath = path.join(__dirname, './'); const dataRepoPath = path.join(__dirname, 'Data'); const logFilePath = path.join(dataRepoPath, 'sync_log.txt'); const authCodeRepoUrl = codeRepoUrl.replace('https://', `https://${token}@`); const authDataRepoUrl = dataRepoUrl.replace('https://', `https://${token}@`); const authBackupRepoUrl = backupRepoUrl.replace('https://', `https://${token}@`); // Git操作辅助函数 function execPromise(command) { return new Promise((resolve, reject) => { exec(command, (error, stdout, stderr) => { if (error) { reject(stderr || stdout); } else { resolve(stdout); } }); }); } async function getDefaultBranch(repoPath) { try { const branchName = await execPromise(`git -C ${repoPath} symbolic-ref --short HEAD`); return branchName.trim(); } catch { return 'main'; } } async function syncDataRepo() { try { console.log('[INFO] Syncing data repository...'); if (!fs.existsSync(dataRepoPath)) { console.log('[INFO] Cloning data repository...'); await execPromise(`git clone ${authDataRepoUrl} ${dataRepoPath}`); } else { console.log('[INFO] Pulling latest changes for the data repository...'); await execPromise(`git -C ${dataRepoPath} pull`); } await execPromise(`git -C ${dataRepoPath} branch --set-upstream-to=origin/main main`); const localChanges = await execPromise(`git -C ${dataRepoPath} status --porcelain`); if (localChanges.trim().length > 0) { console.log('[INFO] Local changes detected. Pushing to remote repository...'); await execPromise( `git -C ${dataRepoPath} add . && git -C ${dataRepoPath} commit -m "Auto-sync: ${new Date().toISOString()}" && git -C ${dataRepoPath} push` ); } console.log('[INFO] Data repository synchronized.'); logSyncSuccess(); } catch (error) { console.error('[ERROR] Failed to synchronize data repository:', error); } } function logSyncSuccess() { const timestamp = `[SUCCESS] Data repository synchronized at: ${new Date().toISOString()}\n\n`; try { fs.appendFileSync(logFilePath, timestamp, 'utf8'); console.log('[INFO] Sync timestamp logged.'); } catch (err) { console.error('[ERROR] Failed to write sync log:', err); } } async function syncCodeRepo() { if (currentHost !== allowedHost) { console.log('[INFO] Code synchronization skipped: Not running on the allowed device.'); return; } try { console.log('[INFO] Syncing code repository...'); const branchName = await getDefaultBranch(codeRepoPath); if (!fs.existsSync(path.join(codeRepoPath, '.git'))) { console.log('[INFO] Cloning code repository...'); await execPromise(`git clone ${authCodeRepoUrl} ${codeRepoPath}`); } else { console.log('[INFO] Pulling latest changes for the code repository...'); try { await execPromise(`git -C ${codeRepoPath} remote add origin ${authCodeRepoUrl}`); } catch (error) { if (!error.includes('remote origin already exists')) { throw error; } } await execPromise(`git -C ${codeRepoPath} pull origin ${branchName}`); } await execPromise(`git -C ${codeRepoPath} branch --set-upstream-to=origin/${branchName} ${branchName}`); console.log('[INFO] Code repository synchronized.'); } catch (error) { console.error('[ERROR] Failed to synchronize code repository:', error); } } async function backupToRemoteRepo() { if (currentHost !== allowedHost) { console.log('[INFO] Backup skipped: Not running on the allowed device.'); return; } try { console.log('[INFO] Backing up directly to remote repository...'); const branchName = 'main'; if (!fs.existsSync(path.join(codeRepoPath, '.git'))) { console.log('[INFO] Initializing repository for backup...'); await execPromise(`git -C ${codeRepoPath} init`); await execPromise(`git -C ${codeRepoPath} checkout -b ${branchName}`); await execPromise(`git -C ${codeRepoPath} remote add origin ${authBackupRepoUrl}`); } await execPromise(`git -C ${codeRepoPath} config user.email "email censored"`); await execPromise(`git -C ${codeRepoPath} config user.name "github user censored"`); await execPromise(`git -C ${codeRepoPath} add .`); await execPromise(`git -C ${codeRepoPath} commit -m "Backup: ${new Date().toISOString()}"`); await execPromise(`git -C ${codeRepoPath} push origin ${branchName} --force`); console.log('[INFO] Backup to remote repository completed.'); } catch (error) { console.error('[ERROR] Failed to backup to remote repository:', error); } } async function checkAndUpdate() { console.log('[INFO] Starting update process...'); await syncCodeRepo(); await syncDataRepo(); await backupToRemoteRepo(); console.log('[INFO] Update process completed.'); scheduleNextSync(); } function scheduleNextSync() { const now = new Date(); const minutes = now.getMinutes(); const nextInterval = 10 - (minutes % 10); const delay = nextInterval * 60 * 1000; console.log(`[INFO] Next sync scheduled in ${nextInterval} minutes (${new Date(now.getTime() + delay).toLocaleTimeString()}).`); setTimeout(() => { checkAndUpdate().then(scheduleRecurringSync); }, delay); } function scheduleRecurringSync() { console.log('[INFO] Scheduling recurring sync every 10 minutes.'); setInterval(checkAndUpdate, 10 * 60 * 1000); } module.exports = { checkAndUpdate };
运行代码后出现了以下错误日志:
0| [ERROR] Failed to synchronize data repository: There is no tracking information for the current branch. 0| Please specify which branch you want to merge with. 0| See git-pull(1) for details. 0| git pull <remote> <branch> 0| If you wish to set tracking information for this branch you can do so with: 0| git branch --set-upstream-to=<remote>/<branch> master 0| [INFO] Backing up directly to remote repository... 0| [ERROR] Failed to backup to remote repository: error: src refspec main does not match any 0| error: failed to push some refs to 'https://github.com/censored/censored' 0| [INFO] Update process completed. 0| [INFO] Next sync scheduled in 10 minutes (04:10:37). 0| [INFO] Bot and data repositories are up-to-date. Starting bot... 0| [INFO] Starting update process... 0| [INFO] Syncing code repository... 0| [INFO] Pulling latest changes for the code repository... 0| [ERROR] Failed to synchronize code repository: fatal: couldn't find remote ref master 0| [INFO] Syncing data repository... 0| [INFO] Pulling latest changes for the data repository... 0| [ERROR] Failed to synchronize data repository: There is no tracking information for the current branch. 0| Please specify which branch you want to merge with. 0| See git-pull(1) for details. 0| git pull <remote> <branch> 0| If you wish to set tracking information for this branch you can do so with: 0| git branch --set-upstream-to=<remote>/<branch> master 0| [INFO] Backing up directly to remote repository... 0| [ERROR] Failed to backup to remote repository: On branch master 0| nothing to commit, working tree clean 0| [INFO] Update process completed. 0| [INFO] Next sync scheduled in 10 minutes (04:20:39). 0| [INFO] Scheduling recurring sync every 10 minutes.
真心希望能得到大家的帮助,我真的很想让这个同步系统正常运行,提前谢谢各位了!
备注:内容来源于stack exchange,提问作者Blaxyy
相关产品推荐
相关产品推荐

