From b94df97e71a2dfe16c4aa7bafe9ec75330bbcfc9 Mon Sep 17 00:00:00 2001 From: Thanh Nguyen Date: Sat, 23 May 2026 21:48:34 +0700 Subject: [PATCH] Add bounty command MVP --- dist/index.js | 42 ++++++++++++++++++++++++++++++++---------- src/index.ts | 46 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/dist/index.js b/dist/index.js index 70f224b..fc4142e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -10,9 +10,8 @@ const chalk_1 = __importDefault(require("chalk")); const config_1 = require("./config"); const program = new commander_1.Command(); const config = (0, config_1.loadConfig)(); -const token = config.githubToken || process.env.GITHUB_TOKEN; function createOctokit() { - const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN; + const token = config.githubToken || process.env.GITHUB_TOKEN || process.env.GH_TOKEN; return new rest_1.Octokit(token ? { auth: token } : {}); } function parseRepo(value) { @@ -55,6 +54,7 @@ function printSummary(request) { console.log(` Amount : ${request.amount} ${request.token}`); console.log(` Network : ${request.network}`); console.log(` Chain : ${request.chain}`); + console.log(` Status : ${request.status}`); } async function submitBountyRequest(request) { return { message: 'Contract submission is not wired up yet in this MVP.', payload: request }; @@ -70,19 +70,41 @@ program .action(async (options) => { const { owner, repo } = parseRepo(options.repo); const octokit = createOctokit(); - const { data: issues } = await octokit.issues.listForRepo({ - owner, - repo, - state: 'open', - }); + const { data: issues } = await octokit.issues.listForRepo({ owner, repo, state: 'open' }); console.log('Total issues found:', issues.length); if (issues.length === 0) { console.log('No open issues found.'); return; } console.log(`\nOpen issues in ${options.repo}:\n`); - issues.forEach((issue) => { - console.log(` #${issue.number} — ${issue.title}`); - }); + issues.forEach((issue) => console.log(` #${issue.number} — ${issue.title}`)); +}); +program + .command('bounty') + .description('Attach a Stellar USDC bounty request to a GitHub issue') + .requiredOption('-r, --repo ', 'target repository (org/repo)') + .requiredOption('-i, --issue ', 'target issue number') + .requiredOption('-a, --amount ', 'bounty amount in USDC') + .option('-t, --token ', 'bounty token', 'USDC') + .option('-n, --network ', 'Stellar network: testnet or mainnet', 'testnet') + .option('--dry-run', 'validate and print the request without submitting') + .action(async (options) => { + const repoInput = options.repo || config.defaultRepo; + if (!repoInput) + throw new Error('Repository is required. Use --repo owner/repo or set defaultRepo in .issueflow.'); + const { owner, repo } = parseRepo(repoInput); + const issueNumber = parseIssueNumber(options.issue); + const amount = parseAmount(options.amount); + const token = parseToken(options.token); + const network = parseNetwork(options.network); + const octokit = createOctokit(); + const { data: issue } = await octokit.issues.get({ owner, repo, issue_number: issueNumber }); + const request = createBountyRequest({ repository: repoInput, issueNumber, issueTitle: issue.title, amount, token, network, dryRun: Boolean(options.dryRun) }); + printSummary(request); + if (options.dryRun) + return; + const result = await submitBountyRequest(request); + console.log(chalk_1.default.yellow(`\n${result.message}`)); + console.log(chalk_1.default.green('Bounty request prepared successfully.')); }); program.parse(); diff --git a/src/index.ts b/src/index.ts index 0bbc158..bef986d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,10 +20,9 @@ interface BountyRequest { const program = new Command(); const config = loadConfig(); -const token = config.githubToken || process.env.GITHUB_TOKEN; function createOctokit(): Octokit { - const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN; + const token = config.githubToken || process.env.GITHUB_TOKEN || process.env.GH_TOKEN; return new Octokit(token ? { auth: token } : {}); } @@ -68,6 +67,7 @@ function printSummary(request: BountyRequest): void { console.log(` Amount : ${request.amount} ${request.token}`); console.log(` Network : ${request.network}`); console.log(` Chain : ${request.chain}`); + console.log(` Status : ${request.status}`); } async function submitBountyRequest(request: BountyRequest): Promise<{ message: string; payload: BountyRequest }> { @@ -86,20 +86,44 @@ program .action(async (options) => { const { owner, repo } = parseRepo(options.repo); const octokit = createOctokit(); - const { data: issues } = await octokit.issues.listForRepo({ - owner, - repo, - state: 'open', - }); + const { data: issues } = await octokit.issues.listForRepo({ owner, repo, state: 'open' }); console.log('Total issues found:', issues.length); if (issues.length === 0) { console.log('No open issues found.'); return; } console.log(`\nOpen issues in ${options.repo}:\n`); - issues.forEach((issue) => { - console.log(` #${issue.number} — ${issue.title}`); - }); + issues.forEach((issue) => console.log(` #${issue.number} — ${issue.title}`)); }); -program.parse(); \ No newline at end of file +program + .command('bounty') + .description('Attach a Stellar USDC bounty request to a GitHub issue') + .requiredOption('-r, --repo ', 'target repository (org/repo)') + .requiredOption('-i, --issue ', 'target issue number') + .requiredOption('-a, --amount ', 'bounty amount in USDC') + .option('-t, --token ', 'bounty token', 'USDC') + .option('-n, --network ', 'Stellar network: testnet or mainnet', 'testnet') + .option('--dry-run', 'validate and print the request without submitting') + .action(async (options) => { + const repoInput = options.repo || config.defaultRepo; + if (!repoInput) throw new Error('Repository is required. Use --repo owner/repo or set defaultRepo in .issueflow.'); + + const { owner, repo } = parseRepo(repoInput); + const issueNumber = parseIssueNumber(options.issue); + const amount = parseAmount(options.amount); + const token = parseToken(options.token); + const network = parseNetwork(options.network); + const octokit = createOctokit(); + const { data: issue } = await octokit.issues.get({ owner, repo, issue_number: issueNumber }); + const request = createBountyRequest({ repository: repoInput, issueNumber, issueTitle: issue.title, amount, token, network, dryRun: Boolean(options.dryRun) }); + + printSummary(request); + if (options.dryRun) return; + + const result = await submitBountyRequest(request); + console.log(chalk.yellow(`\n${result.message}`)); + console.log(chalk.green('Bounty request prepared successfully.')); + }); + +program.parse();