150 lines
3.6 KiB
TypeScript
150 lines
3.6 KiB
TypeScript
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);
|
|
})();
|