name: Validate PR title on: pull_request: types: [opened, edited, reopened] branches: - main - 'next-*_*_*' - 'fix-v*' permissions: {} jobs: validate-pr-title: name: 'Validate PR title' runs-on: ubuntu-latest permissions: contents: read pull-requests: read steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Validate PR title uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | const fs = require('fs'); const path = require('path'); const prTitle = context.payload.pull_request.title; const match = prTitle.match(/^([\p{Emoji}\uFE0F\u200d]+)(?:\(([a-z-]+)\)\s*)? ([^ ].+)$/u); if (match === null) { core.setFailed('❌ Invalid format'); return; } const [, emoji, packageName, description] = match; if (packageName !== undefined) { const packagesDir = path.join(process.env.GITHUB_WORKSPACE, 'packages'); const packages = fs.readdirSync(packagesDir, { withFileTypes: true }) .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name) .filter(name => name !== 'fast-check'); if (!packages.includes(packageName)) { core.setFailed('❌ Invalid package name'); return; } } if (!description.trim()) { core.setFailed('❌ Missing description'); return; } console.log('✅ Valid PR title');