Skip to content

Commit

Permalink
chore(ci): make export PR reusable
Browse files Browse the repository at this point in the history
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
  • Loading branch information
heitorlessa committed Jul 11, 2022
1 parent 2d4df8a commit 06965bb
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 193 deletions.
26 changes: 26 additions & 0 deletions .github/scripts/download_pr_artifact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module.exports = async ({github, context, core}) => {
const fs = require('fs');

const workflowRunId = process.env.WORKFLOW_ID;
core.info(`Listing artifacts for workflow run ${workflowRunId}`);

const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: workflowRunId,
});

const matchArtifact = artifacts.data.artifacts.filter(artifact => artifact.name == "pr")[0];

core.info(`Downloading artifacts for workflow run ${workflowRunId}`);
const artifact = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});

core.info("Saving artifact found", artifact);

fs.writeFileSync('pr.zip', Buffer.from(artifact.data));
}
28 changes: 28 additions & 0 deletions .github/scripts/label_missing_related_issue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = async ({github, context, core}) => {
const prBody = process.env.PR_BODY;
const prNumber = process.env.PR_NUMBER;
const blockLabel = process.env.BLOCK_LABEL;
const blockReasonLabel = process.env.BLOCK_REASON_LABEL;

const RELATED_ISSUE_REGEX = /Issue number:[^\d\r\n]+(?<issue>\d+)/;

const isMatch = RELATED_ISSUE_REGEX.exec(prBody);
if (isMatch == null) {
core.info(`No related issue found, maybe the author didn't use the template but there is one.`)

let msg = "No related issues found. Please ensure there is an open issue related to this change to avoid significant delays or closure.";
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
body: msg,
issue_number: prNumber,
});

return await github.rest.issues.addLabels({
issue_number: prNumber,
owner: context.repo.owner,
repo: context.repo.repo,
labels: [blockLabel, blockReasonLabel]
})
}
}
39 changes: 39 additions & 0 deletions .github/scripts/label_pr_based_on_title.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module.exports = async ({github, context, core}) => {
const pr_number = process.env.PR_NUMBER
const pr_title = process.env.PR_TITLE

console.log(pr_title)

const FEAT_REGEX = /feat(\((.+)\))?(\:.+)/
const BUG_REGEX = /(fix|bug)(\((.+)\))?(\:.+)/
const DOCS_REGEX = /(docs|doc)(\((.+)\))?(\:.+)/
const CHORE_REGEX = /(chore)(\((.+)\))?(\:.+)/
const DEPRECATED_REGEX = /(deprecated)(\((.+)\))?(\:.+)/
const REFACTOR_REGEX = /(refactor)(\((.+)\))?(\:.+)/

const labels = {
"feature": FEAT_REGEX,
"bug": BUG_REGEX,
"documentation": DOCS_REGEX,
"internal": CHORE_REGEX,
"enhancement": REFACTOR_REGEX,
"deprecated": DEPRECATED_REGEX,
}

for (const label in labels) {
const matcher = new RegExp(labels[label])
const isMatch = matcher.exec(pr_title)
if (isMatch != null) {
console.info(`Auto-labeling PR ${pr_number} with ${label}`)

await github.rest.issues.addLabels({
issue_number: pr_number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: [label]
})

break
}
}
}
8 changes: 4 additions & 4 deletions .github/scripts/label_related_issue.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module.exports = async ({github, context, core}) => {
const prBody = context.payload.body;
const prNumber = context.payload.number;
const prBody = process.env.PR_BODY;
const prNumber = process.env.PR_NUMBER;
const releaseLabel = process.env.RELEASE_LABEL;
const maintainersTeam = process.env.MAINTAINERS_TEAM

const maintainersTeam = process.env.MAINTAINERS_TEAM;
const RELATED_ISSUE_REGEX = /Issue number:[^\d\r\n]+(?<issue>\d+)/;

core.info(prBody);
const isMatch = RELATED_ISSUE_REGEX.exec(prBody);
if (!isMatch) {
core.setFailed(`Unable to find related issue for PR number ${prNumber}.\n\n Body details: ${prBody}`);
Expand Down
75 changes: 0 additions & 75 deletions .github/workflows/export_pr_details.yml

This file was deleted.

88 changes: 19 additions & 69 deletions .github/workflows/label_pr_on_title.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,86 +2,36 @@ name: Label PR based on title

on:
workflow_run:
workflows: ["Record PR number"]
workflows: ["Record PR details"]
types:
- completed

jobs:
upload:
runs-on: ubuntu-latest
get_pr_details:
# Guardrails to only ever run if PR recording workflow was indeed
# run in a PR event and ran successfully
if: >
${{ github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success' }}
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: ./.github/workflows/reusable_export_pr_details.yml
with:
record_pr_workflow_id: ${{ github.event.workflow_run.id }}
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
label_pr:
needs: get_pr_details
runs-on: ubuntu-latest
steps:
- name: 'Download artifact'
uses: actions/github-script@v6
# For security, we only download artifacts tied to the successful PR recording workflow
with:
script: |
const fs = require('fs');
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{github.event.workflow_run.id }},
});
const matchArtifact = artifacts.data.artifacts.filter(artifact => artifact.name == "pr")[0];
const artifact = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(artifact.data));
# NodeJS standard library doesn't provide ZIP capabilities; use system `unzip` command instead
- run: unzip pr.zip

- name: 'Label PR based on title'
- name: Checkout repository
uses: actions/checkout@v3
- name: "Label PR based on title"
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ needs.get_pr_details.outputs.prNumber }}
PR_TITLE: ${{ needs.get_pr_details.outputs.prTitle }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
# This safely runs in our base repo, not on fork
# thus allowing us to provide a write access token to label based on PR title
# and label PR based on semantic title accordingly
script: |
const fs = require('fs');
const pr_number = Number(fs.readFileSync('./number'));
const pr_title = fs.readFileSync('./title', 'utf-8').trim();
const FEAT_REGEX = /feat(\((.+)\))?(\:.+)/
const BUG_REGEX = /(fix|bug)(\((.+)\))?(\:.+)/
const DOCS_REGEX = /(docs|doc)(\((.+)\))?(\:.+)/
const CHORE_REGEX = /(chore)(\((.+)\))?(\:.+)/
const DEPRECATED_REGEX = /(deprecated)(\((.+)\))?(\:.+)/
const REFACTOR_REGEX = /(refactor)(\((.+)\))?(\:.+)/
const labels = {
"feature": FEAT_REGEX,
"bug": BUG_REGEX,
"documentation": DOCS_REGEX,
"internal": CHORE_REGEX,
"enhancement": REFACTOR_REGEX,
"deprecated": DEPRECATED_REGEX,
}
for (const label in labels) {
const matcher = new RegExp(labels[label])
const isMatch = matcher.exec(pr_title)
if (isMatch != null) {
console.info(`Auto-labeling PR ${pr_number} with ${label}`)
await github.rest.issues.addLabels({
issue_number: pr_number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: [label]
})
break
}
}
const script = require('.github/scripts/label_pr_based_on_title.js')
await script({github, context, core})
27 changes: 19 additions & 8 deletions .github/workflows/on_merged_pr.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
# Maintenance: Verify why we're having permissions issues even with write scope, then re-enable it.
# logs: https://github.com/awslabs/aws-lambda-powertools-python/runs/7030238348?check_suite_focus=true
name: On PR merge

on:
pull_request:
workflow_run:
workflows: ["Record PR details"]
types:
- closed
- completed

env:
RELEASE_LABEL: "pending-release"
MAINTAINERS_TEAM: "@awslabs/aws-lambda-powertools-python"

jobs:
get_pr_details:
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
uses: ./.github/workflows/reusable_export_pr_details.yml
with:
record_pr_workflow_id: ${{ github.event.workflow_run.id }}
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
release_label_on_merge:
if: github.event.pull_request.merged == true && github.event.pull_request.user.login != 'dependabot[bot]'
needs: get_pr_details
# Maintenance: Conditional isn't working as expected
if: |
needs.get_pr_details.outputs.prAuthor != 'dependabot[bot]'
&& needs.get_pr_details.outputs.prIsMerged == true
runs-on: ubuntu-latest
permissions:
issues: write # required for new scoped token
pull-requests: write # required for new scoped token
steps:
- uses: actions/checkout@v3
- name: "Label PR related issue for release"
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ needs.get_pr_details.outputs.prNumber }}
PR_BODY: ${{ needs.get_pr_details.outputs.prBody }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
Expand Down
Loading

0 comments on commit 06965bb

Please sign in to comment.