diff --git a/.github/workflows/pr-auto-labeler.yml b/.github/workflows/pr-auto-labeler.yml new file mode 100644 index 0000000..044625c --- /dev/null +++ b/.github/workflows/pr-auto-labeler.yml @@ -0,0 +1,78 @@ +name: PR Auto-Labeler + +on: + workflow_call: + inputs: + label_mapping: + description: > + JSON object mapping regex patterns (matched against PR body) to label names. + Example: {"- \\[x\\] Bug fix": "bug fix", "- \\[x\\] New feature": "new feature"} + required: true + type: string + +defaults: + run: + shell: bash + +jobs: + label: + runs-on: ubuntu-latest + + permissions: + pull-requests: write + + steps: + - name: Auto-label PR based on checked boxes + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + env: + LABEL_MAPPING: ${{ inputs.label_mapping }} + with: + script: | + const body = context.payload.pull_request.body || ''; + const mapping = JSON.parse(process.env.LABEL_MAPPING); + + const toAdd = []; + const toRemove = []; + + for (const [pattern, label] of Object.entries(mapping)) { + const regex = new RegExp(pattern, 'i'); + if (regex.test(body)) { + toAdd.push(label); + } else { + toRemove.push(label); + } + } + + core.info(`Labels to add: ${toAdd.join(', ') || 'none'}`); + core.info(`Labels to remove: ${toRemove.join(', ') || 'none'}`); + + try { + if (toAdd.length) { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels: toAdd, + }); + } + + for (const label of toRemove) { + try { + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + name: label, + }); + } catch (e) { + if (e.status !== 404) throw e; + } + } + } catch (e) { + if (e.status === 403) { + core.warning('Insufficient permissions to modify labels. ' + + 'Ensure the caller workflow grants pull-requests: write.'); + } else { + throw e; + } + } diff --git a/.github/workflows/test-pr-auto-labeler.yml b/.github/workflows/test-pr-auto-labeler.yml new file mode 100644 index 0000000..634b9f6 --- /dev/null +++ b/.github/workflows/test-pr-auto-labeler.yml @@ -0,0 +1,24 @@ +on: + pull_request: + types: [opened, edited, reopened] + workflow_dispatch: + +permissions: + pull-requests: write + +jobs: + test-pr-auto-labeler: + uses: ./.github/workflows/pr-auto-labeler.yml + with: + label_mapping: >- + { + "- \\[x\\] Bug fix": "BugFix", + "- \\[x\\] New feature": "NewFeature", + "- \\[x\\] Breaking change": "BreakingChange", + "- \\[x\\] Refactor": "Refactor", + "- \\[x\\] Performance": "Performance", + "- \\[x\\] Tests": "Tests", + "- \\[x\\] Documentation update": "Documentation", + "- \\[x\\] Chore": "Chore", + "- \\[x\\] Release": "Release" + }