Repo-Backups, Gitea-Theme und Auto-Deploy
Deploy / check (push) Has been cancelled
Deploy / deploy (push) Has been cancelled

- Repo-Backups: nachts um 04:00 werden alle Gitea-Repos als git-Bundle
  gesichert — eine Datei pro Repo mit kompletter Historie, aus der sich
  direkt wieder klonen lässt. 14 Tage Rotation wie beim DB-Backup,
  Schalter und "Repos jetzt sichern" im System-Tab. Nutzt den bereits
  vorhandenen Gitea-Token; Dockerfile installiert dafür git mit.
- Gitea-Theme im D4RKST3R-Look (docs/gitea-theme/): Neon-Gelb/Orange auf
  Schwarz, gebaut gegen die Variablen von Gitea 1.26, Diff-Farben bleiben
  lesbar. Einbau-Anleitung liegt daneben.
- Auto-Deploy statt manuellem "Pull and redeploy": Workflow für Gitea
  Actions (prüft Server-Syntax und Frontend-Build, bevor deployed wird)
  plus dokumentierter Runner-loser Weg über den Portainer-Webhook.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 14:01:31 +02:00
co-authored by Claude Fable 5
parent c73b4e1074
commit b5617a9d18
10 changed files with 567 additions and 4 deletions
+17
View File
@@ -366,6 +366,7 @@ ${rssItems}
public_url: publicUrl(),
gitea_url: getSetting('gitea_url') ?? config.giteaUrl,
backup_enabled: getSetting('backup_enabled') !== '0',
repo_backup_enabled: getSetting('repo_backup_enabled') === '1',
backup_channel_id: getSetting('backup_channel_id') ?? '',
playtester_role_id: getSetting('playtester_role_id') ?? '',
starboard_channel_id: getSetting('starboard_channel_id') ?? '',
@@ -501,6 +502,9 @@ ${rssItems}
if (body.backup_enabled !== undefined) {
setSetting('backup_enabled', body.backup_enabled ? '1' : '0');
}
if (body.repo_backup_enabled !== undefined) {
setSetting('repo_backup_enabled', body.repo_backup_enabled ? '1' : '0');
}
if (body.sticky_roles_enabled !== undefined) {
setSetting('sticky_roles_enabled', body.sticky_roles_enabled ? '1' : '0');
}
@@ -1449,6 +1453,19 @@ ${rssItems}
return reply.code(502).send({ error: 'Backup fehlgeschlagen' });
}
}
// Alle Gitea-Repos als Bundle sichern (kann je nach Größe dauern)
if (target === 'repobackup') {
try {
const { runRepoBackup } = await import('../repo-backup.js');
const result = await runRepoBackup();
logAudit(getSessionUser(request), 'repo-backup gestartet', `${result.ok}/${result.repos} Repos`);
return { ok: true, ...result };
} catch (error) {
request.log.error({ err: error }, 'Repo-Backup fehlgeschlagen');
return reply.code(502).send({ error: `Repo-Backup: ${error.message?.slice(0, 120)}` });
}
}
const channelId =
target === 'commit' ? commitChannelId()
: target === 'devlog' ? devlogChannelId()