diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml new file mode 100644 index 000000000..51db4e403 --- /dev/null +++ b/.github/workflows/validate-pr.yml @@ -0,0 +1,66 @@ +name: Validate PR Titles + +on: + pull_request: + types: [opened, edited, synchronize, reopened] + +permissions: + contents: read + pull-requests: write + +jobs: + validate-pr-title: + runs-on: ubuntu-latest + steps: + - name: Get PR Title + id: pr + uses: actions/github-script@v7 + with: + script: | + const title = context.payload.pull_request.title; + core.setOutput('title', title); + + - name: PR title must start with emoji + uses: actions/github-script@v7 + with: + script: | + const prTitle = '${{ steps.pr.outputs.title }}'; + + // Match either: + // 1. Unicode emoji at start (using Unicode properties) + // 2. GitHub emoji shortcode format (e.g. :fire:) + const emojiRegex = /^(?:[\p{Emoji_Presentation}\p{Extended_Pictographic}]|:[a-z0-9_+-]+:)/u; + + // Get all comments + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number + }); + + // Find our bot's validation comment if it exists + const botComment = comments.data.find(comment => + comment.user.type === 'Bot' && + comment.body.includes('Your PR title must start with an emoji!') + ); + + if (!emojiRegex.test(prTitle)) { + // Only add a comment if we haven't already + if (!botComment) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `⚠️ Your PR title must start with an emoji!\n\nExample valid titles:\n- ✨ Add new feature (or :sparkles: Add new feature)\n- 🐛 Fix login bug (or :bug: Fix login bug)\n- 📝 Update documentation (or :memo: Update documentation)\n\nNeed emoji suggestions? Check out [gitmoji.dev](https://gitmoji.dev) for a comprehensive list of Git-friendly emojis!\n\nPlease update your PR title and try again.` + }); + } + + core.setFailed(`PR title must start with an emoji! Current title: "${prTitle}". Use either Unicode emoji (🔥) or GitHub shortcode format (:fire:)`); + } else if (botComment) { + // If title is now valid and we have a comment, delete it + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id + }); + }