Spaces:
Sleeping
Sleeping
| 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); | |
| }); | |