feat: complete release preparation, 10+ ad mediation, CI/CD, and docker deployment
Some checks failed
CI Pipeline / Code Quality & Typecheck (push) Waiting to run
CI Pipeline / Test Suite (macos-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (ubuntu-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (windows-latest) (push) Blocked by required conditions
CI Pipeline / Build Validation (admin) (push) Blocked by required conditions
CI Pipeline / Build Validation (desktop) (push) Blocked by required conditions
Deploy Landing Page / deploy (push) Blocked by required conditions
Deploy Landing Page / build (push) Waiting to run
Release & Packaging Pipeline / Build & Publish Admin Docker Image (push) Failing after 8s
Release & Code Signing CA Pipeline / build-and-sign-windows (push) Failing after 1m51s
Build macOS / Build & Package (macOS) (push) Failing after 4s
Build macOS / Build & Package (macOS)-1 (push) Failing after 5s
Release & Code Signing CA Pipeline / build-and-sign-macos (push) Failing after 3s
Release & Packaging Pipeline / Package macOS Desktop App (push) Failing after 4s
Release & Packaging Pipeline / Package Windows Desktop App (push) Failing after 2m28s
Release & Packaging Pipeline / Publish Official GitHub Release (push) Has been skipped
Some checks failed
CI Pipeline / Code Quality & Typecheck (push) Waiting to run
CI Pipeline / Test Suite (macos-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (ubuntu-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (windows-latest) (push) Blocked by required conditions
CI Pipeline / Build Validation (admin) (push) Blocked by required conditions
CI Pipeline / Build Validation (desktop) (push) Blocked by required conditions
Deploy Landing Page / deploy (push) Blocked by required conditions
Deploy Landing Page / build (push) Waiting to run
Release & Packaging Pipeline / Build & Publish Admin Docker Image (push) Failing after 8s
Release & Code Signing CA Pipeline / build-and-sign-windows (push) Failing after 1m51s
Build macOS / Build & Package (macOS) (push) Failing after 4s
Build macOS / Build & Package (macOS)-1 (push) Failing after 5s
Release & Code Signing CA Pipeline / build-and-sign-macos (push) Failing after 3s
Release & Packaging Pipeline / Package macOS Desktop App (push) Failing after 4s
Release & Packaging Pipeline / Package Windows Desktop App (push) Failing after 2m28s
Release & Packaging Pipeline / Publish Official GitHub Release (push) Has been skipped
This commit is contained in:
parent
5cd1de6859
commit
708e20f747
406 changed files with 42464 additions and 6199 deletions
52
scripts/ci/build-all.mjs
Normal file
52
scripts/ci/build-all.mjs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// scripts/ci/build-all.mjs
|
||||
// Local Full CI Pipeline Verification Runner
|
||||
|
||||
import { spawn } from 'node:child_process';
|
||||
import process from 'node:process';
|
||||
|
||||
function runStep(name, cmd, args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log(`\n==================================================`);
|
||||
console.log(`▶ STEP: ${name} (${cmd} ${args.join(' ')})`);
|
||||
console.log(`==================================================`);
|
||||
|
||||
const start = Date.now();
|
||||
const isWindows = process.platform === 'win32';
|
||||
const actualCmd = isWindows && cmd === 'npm' ? 'npm.cmd' : cmd;
|
||||
|
||||
const proc = spawn(actualCmd, args, { stdio: 'inherit', shell: isWindows });
|
||||
|
||||
proc.on('close', (code) => {
|
||||
const duration = ((Date.now() - start) / 1000).toFixed(2);
|
||||
if (code === 0) {
|
||||
console.log(`✔ SUCCESS: ${name} (took ${duration}s)`);
|
||||
resolve();
|
||||
} else {
|
||||
console.error(`✖ FAILED: ${name} (exit code ${code})`);
|
||||
reject(new Error(`Step failed: ${name}`));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const totalStart = Date.now();
|
||||
console.log('🚀 Starting Full CI/CD Build & Verification Pipeline...\n');
|
||||
|
||||
try {
|
||||
await runStep('Typecheck All Workspaces', 'npm', ['run', 'typecheck']);
|
||||
await runStep('Run Vitest Test Suites', 'npm', ['test']);
|
||||
await runStep('Build Desktop App (Renderer + Main + Preload)', 'npm', ['run', 'build', '--workspace=@d3ro/desktop']);
|
||||
await runStep('Build Admin Dashboard (Next.js 14)', 'npm', ['run', 'build', '--workspace=@d3ro/admin']);
|
||||
|
||||
const totalDuration = ((Date.now() - totalStart) / 1000).toFixed(2);
|
||||
console.log(`\n==================================================`);
|
||||
console.log(`🎉 ALL CI/CD STEPS PASSED SUCCESSFULLY! (Total: ${totalDuration}s)`);
|
||||
console.log(`==================================================\n`);
|
||||
} catch (err) {
|
||||
console.error(`\n❌ CI/CD Pipeline execution aborted: ${err.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
55
scripts/ci/generate-checksums.mjs
Normal file
55
scripts/ci/generate-checksums.mjs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// scripts/ci/generate-checksums.mjs
|
||||
// Computes SHA-256 hashes for all binaries in a release directory
|
||||
|
||||
import { createReadStream } from 'node:fs';
|
||||
import { readdir, writeFile, stat } from 'node:fs/promises';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { join, resolve } from 'node:path';
|
||||
|
||||
async function sha256File(filePath) {
|
||||
return new Promise((resolveHash, reject) => {
|
||||
const hash = createHash('sha256');
|
||||
const stream = createReadStream(filePath);
|
||||
stream.on('data', (chunk) => hash.update(chunk));
|
||||
stream.on('end', () => resolveHash(hash.digest('hex')));
|
||||
stream.on('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const targetDir = resolve(process.argv[2] || './apps/desktop/release');
|
||||
console.log(`Scanning release assets in: ${targetDir}`);
|
||||
|
||||
const lines = [];
|
||||
|
||||
async function scan(dir) {
|
||||
const entries = await readdir(dir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
const fullPath = join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
await scan(fullPath);
|
||||
} else if (/\.(exe|dmg|zip|blockmap|yml)$/i.test(entry.name) && !entry.name.includes('SHA256SUMS')) {
|
||||
const hash = await sha256File(fullPath);
|
||||
const relName = entry.name;
|
||||
lines.push(`${hash} ${relName}`);
|
||||
console.log(`✓ ${relName}: ${hash}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await scan(targetDir);
|
||||
if (lines.length > 0) {
|
||||
const outPath = join(targetDir, 'SHA256SUMS.txt');
|
||||
await writeFile(outPath, lines.join('\n') + '\n', 'utf8');
|
||||
console.log(`\nChecksums written to: ${outPath}`);
|
||||
} else {
|
||||
console.log('No matching release binaries found.');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error calculating checksums:', err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
56
scripts/ci/push-to-chanpaca-git.mjs
Normal file
56
scripts/ci/push-to-chanpaca-git.mjs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// scripts/ci/push-to-chanpaca-git.mjs
|
||||
// Pushes the monorepo to the user's git.chanpaca.net remote repository
|
||||
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { readFileSync, existsSync } from 'node:fs';
|
||||
|
||||
let user = 'yunchan';
|
||||
let pass = 'ONVI2v4J#y';
|
||||
let repo = 'd3ro-voice';
|
||||
|
||||
if (existsSync('.env')) {
|
||||
const envContent = readFileSync('.env', 'utf8');
|
||||
for (const line of envContent.split('\n')) {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed.startsWith('GIT_USERNAME=')) user = trimmed.split('=')[1].trim();
|
||||
if (trimmed.startsWith('GIT_PASSWORD=')) pass = trimmed.split('=')[1].trim();
|
||||
if (trimmed.startsWith('GIT_REPO_NAME=')) repo = trimmed.split('=')[1].trim();
|
||||
}
|
||||
}
|
||||
|
||||
const encodedPass = encodeURIComponent(pass);
|
||||
const remoteUrl = `https://${user}:${encodedPass}@git.chanpaca.net/${user}/${repo}.git`;
|
||||
|
||||
function run(cmd, args) {
|
||||
console.log(`▶ Running: ${cmd} ${args.join(' ')}`);
|
||||
const res = spawnSync(cmd, args, { stdio: 'inherit', shell: process.platform === 'win32' });
|
||||
if (res.status !== 0) {
|
||||
console.error(`Command failed with status ${res.status}`);
|
||||
}
|
||||
return res.status === 0;
|
||||
}
|
||||
|
||||
console.log('--- Configuring Git Remote for git.chanpaca.net ---');
|
||||
|
||||
// Check if chanpaca remote exists
|
||||
const remoteCheck = spawnSync('git', ['remote', 'get-url', 'chanpaca'], { encoding: 'utf8' });
|
||||
if (remoteCheck.status === 0) {
|
||||
run('git', ['remote', 'set-url', 'chanpaca', remoteUrl]);
|
||||
} else {
|
||||
run('git', ['remote', 'add', 'chanpaca', remoteUrl]);
|
||||
}
|
||||
|
||||
console.log('\n--- Staging and committing all changes ---');
|
||||
run('git', ['add', '-A']);
|
||||
run('git', ['commit', '-m', 'feat: add 10+ ad networks mediation, full CI/CD workflows, admin CRM, and production packaging']);
|
||||
|
||||
console.log('\n--- Pushing to git.chanpaca.net (main & tags) ---');
|
||||
const pushMain = run('git', ['push', '-u', 'chanpaca', 'HEAD:main', '--force']);
|
||||
const pushTags = run('git', ['push', 'chanpaca', '--tags']);
|
||||
|
||||
if (pushMain) {
|
||||
console.log('\n🎉 Successfully pushed full codebase to https://git.chanpaca.net/' + user + '/' + repo);
|
||||
} else {
|
||||
console.error('\n❌ Push to git.chanpaca.net failed.');
|
||||
process.exit(1);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue