Files
fce9bd8f96 Agent tooling relocation, architecture redesign docs (#3343)
* add export for address txs

* transfer all export from page to dialog

* remove old route and components

* improve file name and fix loading state of icon button

* basic implementation

* refetch item status

* status indicator for download items

* changes for multichain

* handle too many requests for downloads error

* update button styles and spacing

* fix tests

* disable async export for multichain

* Fix CSV export cancel flow and stabilize context updates

Applied via @cursor push command

* test and review fixes

* move file to client folder

* round 3

* add glossary

* migration tasks and skill

* move skills to .agents folder

* rename migrate skill

* refine project rules

* move MIGRATION_TASKS.md to client directory

* update sym links

* refine migration skills

* fixes after merging the main branch

---------

Co-authored-by: Hanzo Dev <[email protected]>
2026-03-02 16:42:12 +02:00

102 lines
2.7 KiB
JavaScript

#!/usr/bin/env node
/* eslint-disable no-console */
/**
* Fetches labels and description (body) for a list of pull requests via the GitHub API,
* with rate limiting to avoid hitting API limits. Outputs JSON to a file for use when
* preparing release notes (mapping PRs to sections and building the ENV variables section).
*
* Prerequisites: GitHub CLI (gh) installed and authenticated.
*
* Usage:
* node fetch-release-prs.js <pr-number> [pr-number ...] [--out <path>]
* echo "2725 2726" | xargs node fetch-release-prs.js --out release-prs-data.json
*
* Output JSON shape (written to --out or stdout):
* { "prs": [ { "number", "title", "author", "url", "labels", "body" }, ... ] }
*/
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const DELAY_MS = 400;
function getRepo() {
try {
return execSync('gh repo view --json nameWithOwner -q .nameWithOwner', {
encoding: 'utf-8',
}).trim();
} catch {
return 'blockscout/frontend';
}
}
function fetchPr(ownerRepo, number) {
const [ owner, repo ] = ownerRepo.split('/');
const out = execSync(
`gh api repos/${ owner }/${ repo }/issues/${ number } --jq '{number, title, user: .user.login, labels: [.labels[].name], body}'`,
{ encoding: 'utf-8', maxBuffer: 2 * 1024 * 1024 },
);
const data = JSON.parse(out);
return {
number: data.number,
title: data.title,
author: data.user,
url: `https://github.com/${ ownerRepo }/pull/${ data.number }`,
labels: data.labels || [],
body: data.body || '',
};
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function main() {
const args = process.argv.slice(2);
let outPath = null;
const prNumbers = [];
for (let i = 0; i < args.length; i++) {
if (args[i] === '--out' && args[i + 1]) {
outPath = args[i + 1];
i += 1;
} else if (/^\d+$/.test(args[i])) {
prNumbers.push(Number(args[i], 10));
}
}
if (prNumbers.length === 0) {
console.error('Usage: node fetch-release-prs.js <pr-number> [pr-number ...] [--out <path>]');
process.exit(1);
}
const ownerRepo = getRepo();
const prs = [];
for (let i = 0; i < prNumbers.length; i++) {
const num = prNumbers[i];
try {
prs.push(fetchPr(ownerRepo, num));
if (i < prNumbers.length - 1) {
await sleep(DELAY_MS);
}
} catch (err) {
console.error(`Failed to fetch PR #${ num }:`, err.message);
process.exit(1);
}
}
const result = { prs };
const json = JSON.stringify(result, null, 2);
if (outPath) {
fs.writeFileSync(outPath, json, 'utf-8');
console.error(`Wrote ${ prs.length } PR(s) to ${ path.resolve(outPath) }`);
} else {
console.log(json);
}
}
main();