diff --git a/.github/workflows/check-existing-prs.yml b/.github/workflows/check-existing-prs.yml index e10f734..a4fb6aa 100644 --- a/.github/workflows/check-existing-prs.yml +++ b/.github/workflows/check-existing-prs.yml @@ -36,8 +36,59 @@ jobs: script: | const axios = require('axios'); + // Define labels with colors + const LABELS = { + 'balance-ok': { + name: 'balance-ok', + color: '0e8a16', // green + description: 'BTC balance check passed' + }, + 'balance-insufficient': { + name: 'balance-insufficient', + color: 'd93f0b', // red + description: 'BTC balance is below required amount' + }, + 'invalid-address': { + name: 'invalid-address', + color: 'fbca04', // yellow + description: 'Invalid BTC address or wrong network' + } + }; + + // Create or update labels + async function ensureLabel(label) { + try { + await github.rest.issues.getLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + name: label.name + }); + } catch (error) { + if (error.status === 404) { + await github.rest.issues.createLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + name: label.name, + color: label.color, + description: label.description + }); + } + } + } + + // Ensure all labels exist + for (const label of Object.values(LABELS)) { + await ensureLabel(label); + } + async function checkBalance(btcAddress) { try { + // Check if address starts with 'bc1' (mainnet) or 'tb1' (testnet/signet) + const isMainnet = btcAddress.startsWith('bc1'); + if (isMainnet) { + throw new Error('Invalid network: Please use Signet address (tb1) instead of mainnet address (bc1)'); + } + console.log(`Checking balance for BTC address: ${btcAddress}`); const response = await axios.get(`https://mempool.space/signet/api/address/${btcAddress}`); const balanceInBTC = response.data.chain_stats.funded_txo_sum / 100000000; @@ -47,6 +98,12 @@ jobs: hasEnough: balanceInBTC >= 1 }; } catch (error) { + if (error.message.includes('Invalid network')) { + throw error; + } + if (error.response?.status === 400) { + throw new Error('Invalid address or wrong network. Please use a valid Signet (tb1) address'); + } console.error(`Error checking balance: ${error.message}`); throw error; } @@ -65,14 +122,12 @@ jobs: console.log(`\nProcessing PR #${pr.number}: ${pr.title}`); try { - // Get files in this PR const { data: files } = await github.rest.pulls.listFiles({ owner: context.repo.owner, repo: context.repo.repo, pull_number: pr.number }); - // Filter for validator JSON files const validatorFiles = files.filter(file => file.filename.includes('fiamma-testnet-1/bitvm2-staker-validators') && file.filename.endsWith('.json') @@ -89,7 +144,6 @@ jobs: console.log(`\nProcessing file: ${file.filename}`); try { - // Get raw content directly from the PR const response = await axios.get(file.raw_url); const content = response.data; @@ -97,39 +151,65 @@ jobs: try { validatorData = typeof content === 'string' ? JSON.parse(content) : content; } catch (error) { - console.error(`Invalid JSON in ${file.filename}:`, error.message); + const errorMessage = `❌ Invalid JSON format in ${file.filename}: ${error.message}`; + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: errorMessage + }); continue; } if (!validatorData.btcAddress) { - console.log(`No BTC address found in ${file.filename}`); + const errorMessage = `❌ No BTC address found in ${file.filename}`; + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: errorMessage + }); continue; } console.log(`Checking BTC address: ${validatorData.btcAddress}`); - const result = await checkBalance(validatorData.btcAddress); - - // Add comment to PR with results - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: pr.number, - body: `### BTC Balance Check Results for ${file.filename}\n\n` + - `- BTC Address: \`${validatorData.btcAddress}\`\n` + - `- Current Balance: ${result.balance} BTC\n` + - `- Required Balance: 1 BTC\n` + - `- Status: ${result.hasEnough ? '✅ PASSED' : '❌ FAILED'}` - }); - - // Add label based on balance check - const label = result.hasEnough ? 'balance-ok' : 'balance-insufficient'; - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: pr.number, - labels: [label] - }); - + try { + const result = await checkBalance(validatorData.btcAddress); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: `### BTC Balance Check Results for ${file.filename}\n\n` + + `- BTC Address: \`${validatorData.btcAddress}\`\n` + + `- Current Balance: ${result.balance} BTC\n` + + `- Required Balance: 1 BTC\n` + + `- Status: ${result.hasEnough ? '✅ PASSED' : '❌ FAILED'}` + }); + + const labelKey = result.hasEnough ? 'balance-ok' : 'balance-insufficient'; + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + labels: [LABELS[labelKey].name] + }); + } catch (error) { + if (error.message.includes('Invalid network') || error.message.includes('Invalid address')) { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + labels: [LABELS['invalid-address'].name] + }); + } + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: `❌ Error checking balance for ${file.filename}:\n${error.message}` + }); + } } catch (error) { console.error(`Error processing ${file.filename}:`, error); }