sin-github-issues / scripts /render-github-app-vm-rollout.mjs
OpenCode
Deploy latest SIN-GitHub-Issues runtime
cd455f6
Raw
History Blame Contribute Delete
4.1 kB
#!/usr/bin/env node
import { readFile } from 'node:fs/promises';
import path from 'node:path';
const cwd = process.cwd();
function parseArgs(argv) {
const out = {};
for (let i = 0; i < argv.length; i += 1) {
const token = argv[i];
if (!token.startsWith('--')) continue;
const key = token.slice(2);
const next = argv[i + 1];
if (!next || next.startsWith('--')) {
out[key] = 'true';
continue;
}
out[key] = next;
i += 1;
}
return out;
}
function firstString(...values) {
for (const value of values) {
if (typeof value === 'string' && value.trim()) return value.trim();
}
return null;
}
function parseList(value) {
if (!value || typeof value !== 'string') return [];
return value.split(',').map((item) => item.trim()).filter(Boolean);
}
async function main() {
const args = parseArgs(process.argv.slice(2));
const configPath = path.resolve(cwd, args.config || process.env.SIN_GITHUB_APP_ROUTING_PATH || './config/github-app-routing.local.json');
const baseUrl = firstString(args['base-url'], 'https://<SET_VM_BASE_URL>');
const repo = firstString(args.repo, 'OpenSIN-AI/OpenSIN-backend');
const issueNumber = firstString(args['issue-number'], '<SET_TEST_ISSUE_NUMBER>');
const installationId = firstString(args['installation-id'], '<SET_INSTALLATION_ID>');
const selected = new Set(parseList(args.agents || args.agent));
const raw = await readFile(configPath, 'utf8');
const config = JSON.parse(raw);
const apps = Array.isArray(config.apps) ? config.apps : [];
const rolloutAgents = apps
.map((entry) => ({
agentSlug: firstString(entry.agentSlug, entry.preferredAgentSlug, entry.appSlug),
appSlug: firstString(entry.appSlug, entry.agentSlug, entry.preferredAgentSlug),
botName: firstString(entry.botName),
routePath: firstString(entry.routePath, entry.webhookPath, config.defaultWebhookPath, '/github/webhook'),
}))
.filter((entry) => entry.agentSlug && entry.appSlug)
.filter((entry) => selected.size === 0 || selected.has(entry.agentSlug) || selected.has(entry.appSlug));
const agentArgs = rolloutAgents.map((entry) => entry.appSlug).join(',');
const lines = [
'# GitHub App VM Rollout Checklist',
'',
'cd a2a/team-coding/A2A-SIN-GitHub-Issues',
'npm run build',
'npm run ops:github-app-routing:init',
`export SIN_GITHUB_APP_ROUTING_PATH=./config/github-app-routing.local.json`,
'export SIN_GITHUB_API_BASE_URL=https://api.github.com',
'',
'# Fill these VM env vars',
];
for (const entry of rolloutAgents) {
const prefix = String(entry.appSlug).toUpperCase().replace(/-/g, '_');
lines.push(`export ${prefix}_GITHUB_APP_ID=<SET_${prefix}_GITHUB_APP_ID>`);
lines.push(`export ${prefix}_GITHUB_APP_CLIENT_ID=<SET_${prefix}_GITHUB_APP_CLIENT_ID>`);
lines.push(`export ${prefix}_GITHUB_APP_PRIVATE_KEY_PEM='<SET_${prefix}_GITHUB_APP_PRIVATE_KEY_PEM>'`);
lines.push(`export ${prefix}_GITHUB_APP_WEBHOOK_SECRET=<SET_${prefix}_GITHUB_APP_WEBHOOK_SECRET>`);
lines.push('');
}
lines.push(`# Validate only the configured rollout targets`);
lines.push(`npm run ops:github-app-routing:check -- --configured-only true --agents ${agentArgs}`);
lines.push('');
lines.push('# Start the GitHub Issues A2A runtime');
lines.push('node dist/src/cli.js serve-a2a');
lines.push('');
lines.push('# In a second shell, run signed webhook smoke tests');
for (const entry of rolloutAgents) {
lines.push(`npm run ops:github-app-routing:smoke -- --agent ${entry.appSlug} --base-url ${baseUrl}`);
}
lines.push('');
lines.push('# Optional: live comment test as each bot identity');
for (const entry of rolloutAgents) {
lines.push(`npm run ops:github-app-comment -- --agent ${entry.agentSlug} --repo ${repo} --issue-number ${issueNumber} --installation-id ${installationId} --body "Hello from ${entry.botName}"`);
}
process.stdout.write(lines.join('\n') + '\n');
}
main().catch((error) => {
console.error(error instanceof Error ? error.message : String(error));
process.exit(1);
});