Label PR based on title #111
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Label PR based on title | |
on: | |
workflow_run: | |
workflows: ["Record PR number"] | |
types: | |
- completed | |
jobs: | |
upload: | |
runs-on: ubuntu-latest | |
# 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' }} | |
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' | |
uses: actions/github-script@v6 | |
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'); | |
39BC 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 | |
} | |
} |