refactor: complete Python-first local runtime migration #47
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: pr-labeler | |
| on: | |
| pull_request_target: | |
| types: | |
| - opened | |
| - reopened | |
| - synchronize | |
| - edited | |
| - ready_for_review | |
| jobs: | |
| label-pr: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| steps: | |
| - name: Apply area labels (paths) | |
| uses: actions/labeler@v6 | |
| with: | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| configuration-path: .github/labeler.yml | |
| sync-labels: false | |
| - name: Apply type label (title prefix) | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const pullNumber = context.payload.pull_request?.number; | |
| if (!pullNumber) { | |
| core.info('No pull_request number found in event payload; skipping'); | |
| return; | |
| } | |
| const { data: pr } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: pullNumber, | |
| }); | |
| const title = pr.title ?? ''; | |
| const normalizedTitle = title.trim().toLowerCase(); | |
| const prefixToLabel = [ | |
| ['feat:', 'enhancement'], | |
| ['fix:', 'bug'], | |
| ['docs:', 'docs'], | |
| ['refactor:', 'refactor'], | |
| ['test:', 'test'], | |
| ]; | |
| const matchedRule = prefixToLabel.find(([prefix]) => normalizedTitle.startsWith(prefix)); | |
| if (!matchedRule) { | |
| core.info(`No supported title prefix found for PR #${pullNumber}`); | |
| return; | |
| } | |
| const [, mappedLabel] = matchedRule; | |
| const typeLabels = new Set(prefixToLabel.map(([, label]) => label)); | |
| const currentLabels = (pr.labels ?? []).map((label) => label.name); | |
| if (currentLabels.includes(mappedLabel)) { | |
| core.info(`Label "${mappedLabel}" already exists on PR #${pullNumber}`); | |
| return; | |
| } | |
| const alwaysAreaLabels = new Set(['plugin', 'mcp', 'indexer', 'core', 'api', 'ops']); | |
| const prFiles = await github.paginate(github.rest.pulls.listFiles, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: pullNumber, | |
| per_page: 100, | |
| }); | |
| const docsIsArea = prFiles.some( | |
| (file) => file.filename === 'README.md' || file.filename.startsWith('docs/'), | |
| ); | |
| const areaLabels = new Set([...alwaysAreaLabels, ...(docsIsArea ? ['docs'] : [])]); | |
| const existingTypeLabel = currentLabels.find((label) => typeLabels.has(label) && !areaLabels.has(label)); | |
| if (existingTypeLabel) { | |
| core.info( | |
| `Type label "${existingTypeLabel}" already exists on PR #${pullNumber}; skipping to avoid overriding manual labels`, | |
| ); | |
| return; | |
| } | |
| await github.rest.issues.addLabels({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: pullNumber, | |
| labels: [mappedLabel], | |
| }); | |
| core.info(`Applied "${mappedLabel}" from title prefix "${matchedRule[0]}"`); |