Page 1 of 1

Wie gehe ich mit der GitHub-Aktualisierung richtig um?

Posted: 11 Jan 2025, 07:17
by Guest
Ich bin relativ neu bei Github und habe versucht, ein System für meinen Discord.js-Bot zu programmieren, das den Code des Bots mit meinen privaten Repositories aktualisiert. Für dieses System habe ich 3 Repositorys. Das erste authCodeRepoUrl ist das Repository, das ich für den allgemeinen Code des Bots (Befehle, Ereignisse usw.) erstellt habe, daher sollte immer der neueste Code aus diesem Repository heruntergeladen werden. Die zweite ist authDataRepoUrl, die für die Daten gedacht ist, die mein Bot in .json-Dateien speichert. Er sollte prüfen, welche Datei neuer ist, und abhängig davon entweder lokale oder Remote-Datendateien ändern. Mit dem dritten authBackupRepoUrl sichere ich den gesamten Ordner von jedem Gerät im Repository, sodass ich den Ordner immer überprüfen kann.
Jetzt habe ich versucht, dies zu tun und Als ich Probleme hatte, habe ich eine KI gebeten, mir bei der Behebung der Probleme zu helfen, aber ich bin mir nicht sicher, ob das wirklich geholfen hat, deshalb möchte ich hier um Hilfe bitten (Entschuldigung im Voraus).
Mein Code sieht so aus:

Code: Select all

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}@`);

// Hilfsfunktionen für Git-Operationen
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 };

Dies sind die Protokolldaten, die kommen, wenn ich den Code ausprobiere:

Code: Select all

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 

0| If you wish to set tracking information for this branch you can do so with:
0|     git branch --set-upstream-to=/
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 

0| If you wish to set tracking information for this branch you can do so with:
0|     git branch --set-upstream-to=/
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.
Ich freue mich über jede Hilfe, ich möchte wirklich nur, dass es funktioniert.
Vielen Dank im Voraus.