name: ๐Ÿงผ PR on: merge_group: types: - checks_requested pull_request: types: - demilestoned - edited - milestoned - opened - synchronize permissions: {} jobs: validate-description: name: Validate Description runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/github-script@v8 with: script: | if (context.eventName === 'merge_group') { // Ignore merge_group events return; } const body = context.payload.pull_request.body || ''; const errors = []; // Check for ## Description section const descMatch = body.match(/^## Description:\s*\n([\s\S]*?)(?:^## |\Z)/m); if (!descMatch || descMatch[1].trim().length < 20) { errors.push('โŒ Missing or short `## Description:` section.'); } // Check all five boxes are checked const requiredBoxes = [ /- \[x\] I have added screenshots for all UI updates/i, /- \[x\] I process any text displayed to the user through translateText\(\) and I\'ve added it to the en\.json file/i, /- \[x\] I have added relevant tests to the test directory/i, /- \[x\] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced/i, ]; for (const box of requiredBoxes) { if (!box.test(body)) { errors.push('โŒ One or more checklist items are not checked.'); break; } } if (errors.length > 0) { core.setFailed(errors.join('\n')); } else { console.log('โœ… PR description and checklist look good.'); } has-milestone: name: Has Milestone runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/github-script@v8 with: script: | if (context.eventName === 'merge_group') { // Ignore merge_group events } else if (context.eventName === 'pull_request') { // Get the pull request data const milestone = context.payload.pull_request.milestone; if (!milestone) { core.setFailed('โŒ Reviewer must assign a Milestone to this Pull request before merging.'); return; } console.log(`โœ… Milestone found: ${milestone.title}`); } else { core.setFailed(`โŒ Unknown event type ${context.eventName}.`); }