diff --git a/.github/workflows/apply-issue-labels-to-pr.yml b/.github/workflows/apply-issue-labels-to-pr.yml index bf35292598..c68e332a3c 100644 --- a/.github/workflows/apply-issue-labels-to-pr.yml +++ b/.github/workflows/apply-issue-labels-to-pr.yml @@ -1,27 +1,75 @@ name: "Apply issue labels to PR" on: - pull_request: - types: [opened] + pull_request_target: + types: + - opened + jobs: label_on_pr: runs-on: ubuntu-latest - + permissions: + contents: none + issues: read pull-requests: write - + steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Setup Node.js - uses: actions/setup-node@v2 - with: - node-version: 16 - - name: Apply labels from linked issue to PR - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_DATA: ${{ toJson(github.event.pull_request) }} - run: node ./.github/workflows/scripts/apply-issue-labels-to-pr.ts + uses: actions/github-script@v5 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + async function getLinkedIssues(owner, repo, prNumber) { + 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 variables = { + owner: owner, + repo: repo, + prNumber: prNumber, + }; + + const result = await github.graphql(query, variables); + return result.repository.pullRequest.closingIssuesReferences.nodes; + } + + const pr = context.payload.pull_request; + const linkedIssues = await getLinkedIssues( + context.repo.owner, + context.repo.repo, + pr.number + ); + + const labelsToAdd = new Set(); + for (const issue of linkedIssues) { + if (issue.labels && issue.labels.nodes) { + for (const label of issue.labels.nodes) { + labelsToAdd.add(label.name); + } + } + } + + if (labelsToAdd.size) { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + labels: Array.from(labelsToAdd), + }); + } diff --git a/.github/workflows/scripts/apply-issue-labels-to-pr.ts b/.github/workflows/scripts/apply-issue-labels-to-pr.ts deleted file mode 100644 index cfcfb25981..0000000000 --- a/.github/workflows/scripts/apply-issue-labels-to-pr.ts +++ /dev/null @@ -1,139 +0,0 @@ -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); -})();