187 lines
5.4 KiB
TypeScript
187 lines
5.4 KiB
TypeScript
/**
|
|
* Script para backup COMPLETO do Arcádia Suite no GitHub
|
|
* Cria um arquivo tar.gz e faz upload como release
|
|
*/
|
|
|
|
import { Octokit } from '@octokit/rest';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
import { execSync } from 'child_process';
|
|
|
|
let connectionSettings: any;
|
|
|
|
async function getAccessToken() {
|
|
if (connectionSettings && connectionSettings.settings.expires_at && new Date(connectionSettings.settings.expires_at).getTime() > Date.now()) {
|
|
return connectionSettings.settings.access_token;
|
|
}
|
|
|
|
const hostname = process.env.REPLIT_CONNECTORS_HOSTNAME;
|
|
const xReplitToken = process.env.REPL_IDENTITY
|
|
? 'repl ' + process.env.REPL_IDENTITY
|
|
: process.env.WEB_REPL_RENEWAL
|
|
? 'depl ' + process.env.WEB_REPL_RENEWAL
|
|
: null;
|
|
|
|
if (!xReplitToken) throw new Error('Token não encontrado');
|
|
|
|
connectionSettings = await fetch(
|
|
'https://' + hostname + '/api/v2/connection?include_secrets=true&connector_names=github',
|
|
{
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'X_REPLIT_TOKEN': xReplitToken
|
|
}
|
|
}
|
|
).then(res => res.json()).then(data => data.items?.[0]);
|
|
|
|
const accessToken = connectionSettings?.settings?.access_token || connectionSettings.settings?.oauth?.credentials?.access_token;
|
|
if (!connectionSettings || !accessToken) throw new Error('GitHub não conectado');
|
|
return accessToken;
|
|
}
|
|
|
|
async function getGitHubClient() {
|
|
return new Octokit({ auth: await getAccessToken() });
|
|
}
|
|
|
|
const OWNER = 'JonasRodriguesPachceo';
|
|
const REPO = 'ArcadiaSuite-';
|
|
|
|
async function createFullBackup() {
|
|
console.log('🚀 Iniciando BACKUP COMPLETO do Arcádia Suite\n');
|
|
|
|
const projectRoot = process.cwd();
|
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
const backupName = `arcadia-suite-backup-${timestamp}`;
|
|
const tarFile = `/tmp/${backupName}.tar.gz`;
|
|
|
|
// Create exclusion list
|
|
const excludeFile = '/tmp/backup-exclude.txt';
|
|
const excludePatterns = [
|
|
'node_modules',
|
|
'.git',
|
|
'.cache',
|
|
'.upm',
|
|
'.config',
|
|
'.local',
|
|
'.npm',
|
|
'.nix-profile',
|
|
'.pythonlibs',
|
|
'__pycache__',
|
|
'*.pyc',
|
|
'.env',
|
|
'plus/vendor',
|
|
'plus/node_modules',
|
|
'plus/storage/logs/*',
|
|
'plus/storage/framework/cache/*',
|
|
'plus/storage/framework/sessions/*',
|
|
'plus/storage/framework/views/*',
|
|
'plus/bootstrap/cache/*',
|
|
'attached_assets',
|
|
'tmp',
|
|
'*.log',
|
|
'.breakpoints',
|
|
'package-lock.json',
|
|
'generated-icon.png',
|
|
];
|
|
|
|
fs.writeFileSync(excludeFile, excludePatterns.join('\n'));
|
|
|
|
console.log('📦 Criando arquivo de backup...');
|
|
console.log(' (Isso pode demorar alguns minutos)\n');
|
|
|
|
try {
|
|
// Create tar.gz excluding unnecessary files
|
|
execSync(`tar -czf ${tarFile} --exclude-from=${excludeFile} -C ${projectRoot} .`, {
|
|
stdio: 'inherit',
|
|
maxBuffer: 100 * 1024 * 1024
|
|
});
|
|
} catch (e) {
|
|
// tar may return warnings but still work
|
|
}
|
|
|
|
const stats = fs.statSync(tarFile);
|
|
const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);
|
|
console.log(`✅ Backup criado: ${sizeMB} MB\n`);
|
|
|
|
// Connect to GitHub
|
|
const octokit = await getGitHubClient();
|
|
const { data: user } = await octokit.users.getAuthenticated();
|
|
console.log(`✅ Autenticado como: ${user.login}`);
|
|
|
|
// Create a release
|
|
const tagName = `backup-${timestamp}`;
|
|
const releaseName = `Backup Completo - ${new Date().toLocaleDateString('pt-BR')} ${new Date().toLocaleTimeString('pt-BR')}`;
|
|
|
|
console.log('\n📤 Criando release no GitHub...');
|
|
|
|
const { data: release } = await octokit.repos.createRelease({
|
|
owner: OWNER,
|
|
repo: REPO,
|
|
tag_name: tagName,
|
|
name: releaseName,
|
|
body: `## Backup Completo do Arcádia Suite
|
|
|
|
**Data:** ${new Date().toLocaleString('pt-BR')}
|
|
**Tamanho:** ${sizeMB} MB
|
|
|
|
### Conteúdo incluído:
|
|
- ✅ Frontend React/TypeScript (client/)
|
|
- ✅ Backend Express/Node.js (server/)
|
|
- ✅ Schemas compartilhados (shared/)
|
|
- ✅ Laravel Plus ERP (plus/)
|
|
- ✅ Scripts Python (se houver)
|
|
- ✅ Documentação (docs/)
|
|
- ✅ Configurações do projeto
|
|
|
|
### Para restaurar:
|
|
\`\`\`bash
|
|
# Baixe o arquivo .tar.gz da release
|
|
tar -xzf arcadia-suite-backup-*.tar.gz
|
|
npm install
|
|
cd plus && composer install
|
|
\`\`\`
|
|
`,
|
|
draft: false,
|
|
prerelease: false
|
|
});
|
|
|
|
console.log(`✅ Release criada: ${release.html_url}\n`);
|
|
|
|
// Upload the backup file as release asset
|
|
console.log('📤 Fazendo upload do arquivo de backup...');
|
|
console.log(` (${sizeMB} MB - pode demorar)\n`);
|
|
|
|
const fileContent = fs.readFileSync(tarFile);
|
|
|
|
await octokit.repos.uploadReleaseAsset({
|
|
owner: OWNER,
|
|
repo: REPO,
|
|
release_id: release.id,
|
|
name: `${backupName}.tar.gz`,
|
|
// @ts-ignore
|
|
data: fileContent,
|
|
headers: {
|
|
'content-type': 'application/gzip',
|
|
'content-length': stats.size
|
|
}
|
|
});
|
|
|
|
// Cleanup
|
|
fs.unlinkSync(tarFile);
|
|
fs.unlinkSync(excludeFile);
|
|
|
|
console.log('\n' + '='.repeat(50));
|
|
console.log('🎉 BACKUP COMPLETO REALIZADO COM SUCESSO!');
|
|
console.log('='.repeat(50));
|
|
console.log(`\n📦 Tamanho: ${sizeMB} MB`);
|
|
console.log(`🔗 Release: ${release.html_url}`);
|
|
console.log(`📥 Download: https://github.com/${OWNER}/${REPO}/releases/tag/${tagName}`);
|
|
console.log('\nPara restaurar, baixe o .tar.gz e extraia com:');
|
|
console.log(' tar -xzf arcadia-suite-backup-*.tar.gz\n');
|
|
}
|
|
|
|
createFullBackup().catch(err => {
|
|
console.error('❌ Erro:', err.message);
|
|
process.exit(1);
|
|
});
|