diff --git a/.github/release.yml b/.github/release.yml index 21e093324e..72e8208ad1 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -1,3 +1,8 @@ +# This configuration is used by Craft to categorize changelog entries based on +# PR labels. To avoid some manual work, there is a PR labeling GitHub action in +# .github/workflows/pr-labeler.yml that adds a changelog label to PRs based on +# the title. + changelog: exclude: labels: diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml new file mode 100644 index 0000000000..c489de30d4 --- /dev/null +++ b/.github/workflows/pr-labeler.yml @@ -0,0 +1,72 @@ +# This action adds changelog labels to PRs that are then used by the release +# notes generator in Craft. The configuration for which labels map to what +# changelog categories can be found in .github/release.yml. + +name: Label PR for Changelog + +on: + pull_request: + types: [opened, edited] + +permissions: + pull-requests: write + +jobs: + label: + runs-on: ubuntu-latest + steps: + - name: Add changelog label + uses: actions/github-script@v7 + with: + script: | + const title = context.payload.pull_request.title.toLowerCase(); + const prNumber = context.payload.pull_request.number; + + // Get current labels + const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + }); + + // Check if a Changelog label already exists + const hasChangelogLabel = currentLabels.some(label => + label.name.startsWith('Changelog:') || label.name === 'skip-changelog' + ); + + if (hasChangelogLabel) { + console.log('PR already has a Changelog label, skipping'); + return; + } + + // Determine which label to apply + let newLabel = null; + + if (title.includes('deprecate')) { + newLabel = 'Changelog: Deprecation'; + } else if (title.startsWith('feat')) { + newLabel = 'Changelog: Feature'; + } else if (title.startsWith('fix') || title.startsWith('bugfix')) { + newLabel = 'Changelog: Bugfix'; + } else if (title.startsWith('docs')) { + newLabel = 'Changelog: Docs'; + } else if (title.startsWith('ref') || title.startsWith('test')) { + newLabel = 'Changelog: Internal'; + } else if (title.startsWith('ci') || title.startsWith('build')) { + newLabel = 'skip-changelog'; + } + + // Apply the new label if one was determined + if (newLabel) { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + labels: [newLabel], + }); + + console.log(`Applied label: ${newLabel}`); + } else { + console.log('No matching label pattern found in PR title, please add manually'); + } +