const https = require("https"); async function applyLabelFromLinkedIssueToPR(pr, token) { // Get the labels from issues linked to the PR const query = ` query GetLinkedIssues($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { closingIssuesReferences(first: 10) { nodes { number labels(first: 10) { nodes { name } } } } } } } `; const graphqlData = JSON.stringify({ query, variables: { owner: pr.base.repo.owner.login, repo: pr.base.repo.name, prNumber: pr.number, }, }); const requestOptions = { hostname: "api.github.com", path: "/graphql", method: "POST", headers: { "Content-Type": "application/json", "Content-Length": graphqlData.length, Authorization: "Bearer " + token, "User-Agent": "Node.js", }, }; // Use the native Node.js request library to make the request let linkedIssues; linkedIssues = await new Promise((resolve, reject) => { const request = https.request(requestOptions, (response) => { let responseBody = ""; response.on("data", (chunk) => { responseBody += chunk; }); response.on("end", () => { resolve(JSON.parse(responseBody)?.data?.repository?.pullRequest?.closingIssuesReferences?.nodes); }); }); request.on("error", (error) => { reject(error); }); request.write(graphqlData); request.end(); }); if (!linkedIssues || linkedIssues.length === 0) { console.log("No issue linked."); return; } // Iterate over linked issues and apply labels to PR for (const issue of linkedIssues) { const labels = issue?.labels?.nodes?.map((label) => label.name); if (!labels || labels.length === 0) { console.log(`No labels found on the linked issue #${issue.number}.`); continue; } const labelsData = JSON.stringify({ labels: labels, }); const requestOptions = { hostname: "api.github.com", path: `/repos/${pr.base.repo.owner.login}/${pr.base.repo.name}/issues/${pr.number}/labels`, method: "POST", headers: { "Content-Type": "application/json", "Content-Length": labelsData.length, Authorization: "Bearer " + token, "User-Agent": "Node.js", }, }; let labelResult; labelResult = await new Promise((resolve, reject) => { const request = https.request(requestOptions, (response) => { let responseBody = ""; response.on("data", (chunk) => { responseBody += chunk; }); response.on("data", () => {}); response.on("end", () => { resolve(JSON.parse(responseBody)); }); }); request.on("error", (error) => { reject(error); }); request.write(labelsData); request.end(); }); if (labelResult.message) { console.log(`Error labelling PR: ${labelResult.message}`); continue; } console.log( `Applied labels: ${labels.join(", ")} to PR #${pr.number} from linked issue #${issue.number}` ); } } // Pass the PR data and GitHub token to the script (async () => { if (!process.env.PR_DATA) { console.log("No PR data found."); return; } const prData = JSON.parse(process.env.PR_DATA); const token = process.env.GITHUB_TOKEN; await applyLabelFromLinkedIssueToPR(prData, token); })();