- Added DOKUMENTASI-FILTER-PER-SITE.md (site isolation docs) - Fixed start-with-env.js to force-load .env.production - Fixed MONGODB_URI hostname from mongodb-netify to mongodb.prod.proit.id - Updated .gitignore to exclude sensitive scripts and credential files - Minor UI and labeling improvements
260 lines
9.8 KiB
JavaScript
260 lines
9.8 KiB
JavaScript
/**
|
||
* git-push-iso.js
|
||
* Push ke Gitea & GitHub menggunakan isomorphic-git (pure JS, tanpa system git)
|
||
*
|
||
* CARA KERJA:
|
||
* 1. Clone dari Gitea (untuk dapat history 75 commits)
|
||
* 2. Salin file proyek terbaru ke folder clone
|
||
* 3. Commit perubahan
|
||
* 4. Push ke Gitea
|
||
* 5. Push ke GitHub dengan remote tambahan
|
||
*/
|
||
|
||
const git = require('isomorphic-git');
|
||
const http = require('isomorphic-git/http/node');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const os = require('os');
|
||
|
||
// ─── CONFIG ────────────────────────────────────────────────────────────────
|
||
const PROJECT_DIR = path.resolve(__dirname);
|
||
|
||
// Gitea
|
||
const GITEA_URL = 'https://git.proit.id/rafif/Deep-Package-Inspection';
|
||
const GITEA_BRANCH = 'Proxy_Server_API_backone.cloud';
|
||
const GITEA_USER = 'rafif';
|
||
const GITEA_PASS = 'NetWorking.0';
|
||
|
||
// GitHub
|
||
const GITHUB_URL = 'https://github.com/Rafif-Riqullah-Siregar/BackOne-Deep-Package-Inspection';
|
||
const GITHUB_BRANCH = 'Proxy-Server-API-backone.cloud';
|
||
// GitHub token (diisi nanti, atau bisa kosong dulu untuk test)
|
||
const GITHUB_TOKEN = process.env.GITHUB_TOKEN || '';
|
||
|
||
// Commit message
|
||
const COMMIT_MSG = `feat(source2): push all latest files - device labeling, help system, proxy docs, database isolation fix
|
||
|
||
- Added DOKUMENTASI-FILTER-PER-SITE.md (site isolation docs)
|
||
- Fixed start-with-env.js to force-load .env.production
|
||
- Fixed MONGODB_URI hostname from mongodb-netify to mongodb.prod.proit.id
|
||
- Updated .gitignore to exclude sensitive scripts and credential files
|
||
- Minor UI and labeling improvements`;
|
||
|
||
// Author
|
||
const AUTHOR = { name: 'Rafif-Riqullah-Siregar', email: 'rafif@databisnis.id' };
|
||
|
||
// ─── GITIGNORE PATTERNS ──────────────────────────────────────────────────────
|
||
// File/folder yang TIDAK boleh di-push (dari .gitignore)
|
||
const EXCLUDED_PATTERNS = [
|
||
'node_modules',
|
||
'.next',
|
||
'.env',
|
||
'.env.local',
|
||
'.env.production',
|
||
'.env.development',
|
||
'coverage',
|
||
'build',
|
||
'out',
|
||
'.DS_Store',
|
||
'*.log',
|
||
'*.pem',
|
||
'.vercel',
|
||
'*.tsbuildinfo',
|
||
'next-env.d.ts',
|
||
'*.db', '*.db-shm', '*.db-wal', '*.sqlite',
|
||
'Laporan_*.docx',
|
||
'temp_docx',
|
||
'*.zip',
|
||
'AGENTS.md', 'CLAUDE.md', '.agents',
|
||
'docs', 'plans',
|
||
'temp.json', 'scratch',
|
||
// Sensitive scripts
|
||
'compare-netify-vs-dashboard.js',
|
||
'ssh-read-source1-proxy.js',
|
||
'check-frontend-uri-now.js',
|
||
'verify-final.js',
|
||
'check-frontend-uri.js',
|
||
'ssh-check-logs.js',
|
||
// Sensitive docs
|
||
'BUKTI-AKSES-MONGODB.txt',
|
||
'DOKUMENTASI-PROXY-NETIFY.md',
|
||
];
|
||
|
||
function shouldExclude(filePath) {
|
||
const parts = filePath.split(/[/\\]/);
|
||
for (const pattern of EXCLUDED_PATTERNS) {
|
||
for (const part of parts) {
|
||
if (pattern.startsWith('*')) {
|
||
const ext = pattern.slice(1);
|
||
if (part.endsWith(ext)) return true;
|
||
} else if (part === pattern || filePath.includes(pattern)) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
async function getGitFiles(dir, baseDir = dir) {
|
||
const files = [];
|
||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||
for (const entry of entries) {
|
||
const fullPath = path.join(dir, entry.name);
|
||
const relPath = path.relative(baseDir, fullPath).replace(/\\/g, '/');
|
||
if (shouldExclude(relPath) || entry.name === '.git') continue;
|
||
if (entry.isDirectory()) {
|
||
files.push(...await getGitFiles(fullPath, baseDir));
|
||
} else {
|
||
files.push(relPath);
|
||
}
|
||
}
|
||
return files;
|
||
}
|
||
|
||
async function main() {
|
||
console.log('╔══════════════════════════════════════════════════════════════╗');
|
||
console.log('║ GIT PUSH (isomorphic-git) → Gitea + GitHub ║');
|
||
console.log('╚══════════════════════════════════════════════════════════════╝\n');
|
||
|
||
// ─── STEP 1: Clone dari Gitea ke temp dir ──────────────────────────────────
|
||
const tmpDir = path.join(os.tmpdir(), `dpi-push-${Date.now()}`);
|
||
console.log(`[1] Cloning dari Gitea ke temp: ${tmpDir}`);
|
||
fs.mkdirSync(tmpDir, { recursive: true });
|
||
|
||
try {
|
||
await git.clone({
|
||
fs, http,
|
||
dir: tmpDir,
|
||
url: GITEA_URL,
|
||
ref: GITEA_BRANCH,
|
||
singleBranch: true,
|
||
depth: 10, // ambil 10 commit terakhir saja (cukup untuk push)
|
||
onAuth: () => ({ username: GITEA_USER, password: GITEA_PASS }),
|
||
onProgress: ({ phase, loaded, total }) => {
|
||
if (total) process.stdout.write(`\r ${phase}: ${loaded}/${total} `);
|
||
},
|
||
});
|
||
console.log(`\n ✅ Clone berhasil dari Gitea branch ${GITEA_BRANCH}`);
|
||
} catch (err) {
|
||
console.error(`\n ❌ Clone dari Gitea gagal: ${err.message}`);
|
||
console.log(' → Coba dengan username tanpa domain (tanpa @databisnis.id)');
|
||
process.exit(1);
|
||
}
|
||
|
||
// ─── STEP 2: Salin file project terbaru ke temp dir ────────────────────────
|
||
console.log(`\n[2] Menyalin file terbaru dari project ke clone...`);
|
||
const projectFiles = await getGitFiles(PROJECT_DIR);
|
||
let copied = 0;
|
||
for (const relPath of projectFiles) {
|
||
const src = path.join(PROJECT_DIR, relPath);
|
||
const dst = path.join(tmpDir, relPath);
|
||
fs.mkdirSync(path.dirname(dst), { recursive: true });
|
||
fs.copyFileSync(src, dst);
|
||
copied++;
|
||
}
|
||
console.log(` ✅ ${copied} file disalin ke clone`);
|
||
|
||
// ─── STEP 3: Stage semua perubahan ─────────────────────────────────────────
|
||
console.log(`\n[3] Staging semua perubahan...`);
|
||
const statusMatrix = await git.statusMatrix({ fs, dir: tmpDir });
|
||
let staged = 0;
|
||
for (const [filepath, head, workdir, stage] of statusMatrix) {
|
||
if (workdir !== stage) {
|
||
if (workdir === 0) {
|
||
// File dihapus
|
||
await git.remove({ fs, dir: tmpDir, filepath });
|
||
} else {
|
||
// File baru atau dimodifikasi
|
||
await git.add({ fs, dir: tmpDir, filepath });
|
||
}
|
||
staged++;
|
||
}
|
||
}
|
||
console.log(` ✅ ${staged} file di-stage`);
|
||
|
||
if (staged === 0) {
|
||
console.log(' ℹ️ Tidak ada perubahan yang perlu di-commit!');
|
||
return cleanup(tmpDir);
|
||
}
|
||
|
||
// ─── STEP 4: Commit ─────────────────────────────────────────────────────────
|
||
console.log(`\n[4] Membuat commit...`);
|
||
const sha = await git.commit({
|
||
fs,
|
||
dir: tmpDir,
|
||
author: AUTHOR,
|
||
committer: AUTHOR,
|
||
message: COMMIT_MSG,
|
||
});
|
||
console.log(` ✅ Commit dibuat: ${sha.slice(0, 8)}`);
|
||
|
||
// ─── STEP 5: Push ke Gitea ──────────────────────────────────────────────────
|
||
console.log(`\n[5] Push ke Gitea (${GITEA_URL})...`);
|
||
try {
|
||
await git.push({
|
||
fs, http,
|
||
dir: tmpDir,
|
||
remote: 'origin',
|
||
ref: GITEA_BRANCH,
|
||
onAuth: () => ({ username: GITEA_USER, password: GITEA_PASS }),
|
||
onProgress: ({ phase, loaded, total }) => {
|
||
if (total) process.stdout.write(`\r ${phase}: ${loaded}/${total} `);
|
||
},
|
||
});
|
||
console.log(`\n ✅ Push ke Gitea BERHASIL! Branch: ${GITEA_BRANCH}`);
|
||
} catch (err) {
|
||
console.error(`\n ❌ Push ke Gitea gagal: ${err.message}`);
|
||
}
|
||
|
||
// ─── STEP 6: Push ke GitHub ─────────────────────────────────────────────────
|
||
console.log(`\n[6] Push ke GitHub (${GITHUB_URL})...`);
|
||
|
||
// Tambah remote GitHub
|
||
const remotes = await git.listRemotes({ fs, dir: tmpDir });
|
||
const hasGithub = remotes.some(r => r.remote === 'github');
|
||
if (!hasGithub) {
|
||
await git.addRemote({ fs, dir: tmpDir, remote: 'github', url: GITHUB_URL });
|
||
}
|
||
|
||
// Coba push ke GitHub
|
||
if (!GITHUB_TOKEN) {
|
||
console.log(' ⚠️ GITHUB_TOKEN tidak di-set. GitHub push membutuhkan Personal Access Token.');
|
||
console.log(' → Set environment variable: $env:GITHUB_TOKEN = "ghp_XXXX"');
|
||
console.log(' → Lalu jalankan: node git-push-iso.js');
|
||
} else {
|
||
try {
|
||
await git.push({
|
||
fs, http,
|
||
dir: tmpDir,
|
||
remote: 'github',
|
||
ref: GITHUB_BRANCH,
|
||
remoteRef: GITHUB_BRANCH,
|
||
onAuth: () => ({ username: 'Rafif-Riqullah-Siregar', password: GITHUB_TOKEN }),
|
||
onProgress: ({ phase, loaded, total }) => {
|
||
if (total) process.stdout.write(`\r ${phase}: ${loaded}/${total} `);
|
||
},
|
||
});
|
||
console.log(`\n ✅ Push ke GitHub BERHASIL! Branch: ${GITHUB_BRANCH}`);
|
||
} catch (err) {
|
||
console.error(`\n ❌ Push ke GitHub gagal: ${err.message}`);
|
||
}
|
||
}
|
||
|
||
cleanup(tmpDir);
|
||
console.log('\n╔══════════════════════════════════════════════════════════════╗');
|
||
console.log('║ SELESAI ║');
|
||
console.log('╚══════════════════════════════════════════════════════════════╝');
|
||
}
|
||
|
||
function cleanup(tmpDir) {
|
||
try {
|
||
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||
console.log(`\n[cleanup] Temp dir dihapus: ${tmpDir}`);
|
||
} catch(e) {}
|
||
}
|
||
|
||
main().catch(err => {
|
||
console.error('\n[FATAL]', err.message);
|
||
process.exit(1);
|
||
});
|