Skip to content

Commit 06965bb

Browse files
committed
chore(ci): make export PR reusable
Signed-off-by: heitorlessa <[email protected]>
1 parent 2d4df8a commit 06965bb

10 files changed

+234
-193
lines changed
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module.exports = async ({github, context, core}) => {
2+
const fs = require('fs');
3+
4+
const workflowRunId = process.env.WORKFLOW_ID;
5+
core.info(`Listing artifacts for workflow run ${workflowRunId}`);
6+
7+
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
8+
owner: context.repo.owner,
9+
repo: context.repo.repo,
10+
run_id: workflowRunId,
11+
});
12+
13+
const matchArtifact = artifacts.data.artifacts.filter(artifact => artifact.name == "pr")[0];
14+
15+
core.info(`Downloading artifacts for workflow run ${workflowRunId}`);
16+
const artifact = await github.rest.actions.downloadArtifact({
17+
owner: context.repo.owner,
18+
repo: context.repo.repo,
19+
artifact_id: matchArtifact.id,
20+
archive_format: 'zip',
21+
});
22+
23+
core.info("Saving artifact found", artifact);
24+
25+
fs.writeFileSync('pr.zip', Buffer.from(artifact.data));
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module.exports = async ({github, context, core}) => {
2+
const prBody = process.env.PR_BODY;
3+
const prNumber = process.env.PR_NUMBER;
4+
const blockLabel = process.env.BLOCK_LABEL;
5+
const blockReasonLabel = process.env.BLOCK_REASON_LABEL;
6+
7+
const RELATED_ISSUE_REGEX = /Issue number:[^\d\r\n]+(?<issue>\d+)/;
8+
9+
const isMatch = RELATED_ISSUE_REGEX.exec(prBody);
10+
if (isMatch == null) {
11+
core.info(`No related issue found, maybe the author didn't use the template but there is one.`)
12+
13+
let msg = "No related issues found. Please ensure there is an open issue related to this change to avoid significant delays or closure.";
14+
await github.rest.issues.createComment({
15+
owner: context.repo.owner,
16+
repo: context.repo.repo,
17+
body: msg,
18+
issue_number: prNumber,
19+
});
20+
21+
return await github.rest.issues.addLabels({
22+
issue_number: prNumber,
23+
owner: context.repo.owner,
24+
repo: context.repo.repo,
25+
labels: [blockLabel, blockReasonLabel]
26+
})
27+
}
28+
}
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
module.exports = async ({github, context, core}) => {
2+
const pr_number = process.env.PR_NUMBER
3+
const pr_title = process.env.PR_TITLE
4+
5+
console.log(pr_title)
6+
7+
const FEAT_REGEX = /feat(\((.+)\))?(\:.+)/
8+
const BUG_REGEX = /(fix|bug)(\((.+)\))?(\:.+)/
9+
const DOCS_REGEX = /(docs|doc)(\((.+)\))?(\:.+)/
10+
const CHORE_REGEX = /(chore)(\((.+)\))?(\:.+)/
11+
const DEPRECATED_REGEX = /(deprecated)(\((.+)\))?(\:.+)/
12+
const REFACTOR_REGEX = /(refactor)(\((.+)\))?(\:.+)/
13+
14+
const labels = {
15+
"feature": FEAT_REGEX,
16+
"bug": BUG_REGEX,
17+
"documentation": DOCS_REGEX,
18+
"internal": CHORE_REGEX,
19+
"enhancement": REFACTOR_REGEX,
20+
"deprecated": DEPRECATED_REGEX,
21+
}
22+
23+
for (const label in labels) {
24+
const matcher = new RegExp(labels[label])
25+
const isMatch = matcher.exec(pr_title)
26+
if (isMatch != null) {
27+
console.info(`Auto-labeling PR ${pr_number} with ${label}`)
28+
29+
await github.rest.issues.addLabels({
30+
issue_number: pr_number,
31+
owner: context.repo.owner,
32+
repo: context.repo.repo,
33+
labels: [label]
34+
})
35+
36+
break
37+
}
38+
}
39+
}

.github/scripts/label_related_issue.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
module.exports = async ({github, context, core}) => {
2-
const prBody = context.payload.body;
3-
const prNumber = context.payload.number;
2+
const prBody = process.env.PR_BODY;
3+
const prNumber = process.env.PR_NUMBER;
44
const releaseLabel = process.env.RELEASE_LABEL;
5-
const maintainersTeam = process.env.MAINTAINERS_TEAM
6-
5+
const maintainersTeam = process.env.MAINTAINERS_TEAM;
76
const RELATED_ISSUE_REGEX = /Issue number:[^\d\r\n]+(?<issue>\d+)/;
87

8+
core.info(prBody);
99
const isMatch = RELATED_ISSUE_REGEX.exec(prBody);
1010
if (!isMatch) {
1111
core.setFailed(`Unable to find related issue for PR number ${prNumber}.\n\n Body details: ${prBody}`);

.github/workflows/export_pr_details.yml

-75
This file was deleted.

.github/workflows/label_pr_on_title.yml

+19-69
Original file line numberDiff line numberDiff line change
@@ -2,86 +2,36 @@ name: Label PR based on title
22

33
on:
44
workflow_run:
5-
workflows: ["Record PR number"]
5+
workflows: ["Record PR details"]
66
types:
77
- completed
88

99
jobs:
10-
upload:
11-
runs-on: ubuntu-latest
10+
get_pr_details:
1211
# Guardrails to only ever run if PR recording workflow was indeed
1312
# run in a PR event and ran successfully
14-
if: >
15-
${{ github.event.workflow_run.event == 'pull_request' &&
16-
github.event.workflow_run.conclusion == 'success' }}
13+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
14+
uses: ./.github/workflows/reusable_export_pr_details.yml
15+
with:
16+
record_pr_workflow_id: ${{ github.event.workflow_run.id }}
17+
secrets:
18+
token: ${{ secrets.GITHUB_TOKEN }}
19+
label_pr:
20+
needs: get_pr_details
21+
runs-on: ubuntu-latest
1722
steps:
18-
- name: 'Download artifact'
19-
uses: actions/github-script@v6
20-
# For security, we only download artifacts tied to the successful PR recording workflow
21-
with:
22-
script: |
23-
const fs = require('fs');
24-
25-
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
26-
owner: context.repo.owner,
27-
repo: context.repo.repo,
28-
run_id: ${{github.event.workflow_run.id }},
29-
});
30-
31-
const matchArtifact = artifacts.data.artifacts.filter(artifact => artifact.name == "pr")[0];
32-
33-
const artifact = await github.rest.actions.downloadArtifact({
34-
owner: context.repo.owner,
35-
repo: context.repo.repo,
36-
artifact_id: matchArtifact.id,
37-
archive_format: 'zip',
38-
});
39-
40-
fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(artifact.data));
41-
# NodeJS standard library doesn't provide ZIP capabilities; use system `unzip` command instead
42-
- run: unzip pr.zip
43-
44-
- name: 'Label PR based on title'
23+
- name: Checkout repository
24+
uses: actions/checkout@v3
25+
- name: "Label PR based on title"
4526
uses: actions/github-script@v6
27+
env:
28+
PR_NUMBER: ${{ needs.get_pr_details.outputs.prNumber }}
29+
PR_TITLE: ${{ needs.get_pr_details.outputs.prTitle }}
4630
with:
4731
github-token: ${{ secrets.GITHUB_TOKEN }}
4832
# This safely runs in our base repo, not on fork
4933
# thus allowing us to provide a write access token to label based on PR title
5034
# and label PR based on semantic title accordingly
5135
script: |
52-
const fs = require('fs');
53-
const pr_number = Number(fs.readFileSync('./number'));
54-
const pr_title = fs.readFileSync('./title', 'utf-8').trim();
55-
56-
const FEAT_REGEX = /feat(\((.+)\))?(\:.+)/
57-
const BUG_REGEX = /(fix|bug)(\((.+)\))?(\:.+)/
58-
const DOCS_REGEX = /(docs|doc)(\((.+)\))?(\:.+)/
59-
const CHORE_REGEX = /(chore)(\((.+)\))?(\:.+)/
60-
const DEPRECATED_REGEX = /(deprecated)(\((.+)\))?(\:.+)/
61-
const REFACTOR_REGEX = /(refactor)(\((.+)\))?(\:.+)/
62-
63-
const labels = {
64-
"feature": FEAT_REGEX,
65-
"bug": BUG_REGEX,
66-
"documentation": DOCS_REGEX,
67-
"internal": CHORE_REGEX,
68-
"enhancement": REFACTOR_REGEX,
69-
"deprecated": DEPRECATED_REGEX,
70-
}
71-
72-
for (const label in labels) {
73-
const matcher = new RegExp(labels[label])
74-
const isMatch = matcher.exec(pr_title)
75-
if (isMatch != null) {
76-
console.info(`Auto-labeling PR ${pr_number} with ${label}`)
77-
78-
await github.rest.issues.addLabels({
79-
issue_number: pr_number,
80-
owner: context.repo.owner,
81-
repo: context.repo.repo,
82-
labels: [label]
83-
})
84-
85-
break
86-
}
87-
}
36+
const script = require('.github/scripts/label_pr_based_on_title.js')
37+
await script({github, context, core})

.github/workflows/on_merged_pr.yml

+19-8
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
1-
# Maintenance: Verify why we're having permissions issues even with write scope, then re-enable it.
2-
# logs: https://github.com/awslabs/aws-lambda-powertools-python/runs/7030238348?check_suite_focus=true
1+
name: On PR merge
32

43
on:
5-
pull_request:
4+
workflow_run:
5+
workflows: ["Record PR details"]
66
types:
7-
- closed
7+
- completed
88

99
env:
1010
RELEASE_LABEL: "pending-release"
1111
MAINTAINERS_TEAM: "@awslabs/aws-lambda-powertools-python"
1212

1313
jobs:
14+
get_pr_details:
15+
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
16+
uses: ./.github/workflows/reusable_export_pr_details.yml
17+
with:
18+
record_pr_workflow_id: ${{ github.event.workflow_run.id }}
19+
secrets:
20+
token: ${{ secrets.GITHUB_TOKEN }}
1421
release_label_on_merge:
15-
if: github.event.pull_request.merged == true && github.event.pull_request.user.login != 'dependabot[bot]'
22+
needs: get_pr_details
23+
# Maintenance: Conditional isn't working as expected
24+
if: |
25+
needs.get_pr_details.outputs.prAuthor != 'dependabot[bot]'
26+
&& needs.get_pr_details.outputs.prIsMerged == true
1627
runs-on: ubuntu-latest
17-
permissions:
18-
issues: write # required for new scoped token
19-
pull-requests: write # required for new scoped token
2028
steps:
2129
- uses: actions/checkout@v3
2230
- name: "Label PR related issue for release"
2331
uses: actions/github-script@v6
32+
env:
33+
PR_NUMBER: ${{ needs.get_pr_details.outputs.prNumber }}
34+
PR_BODY: ${{ needs.get_pr_details.outputs.prBody }}
2435
with:
2536
github-token: ${{ secrets.GITHUB_TOKEN }}
2637
script: |

0 commit comments

Comments
 (0)