name: PR Title Check on: pull_request_target: types: [opened, edited, reopened, synchronize] jobs: title-format: runs-on: ubuntu-latest permissions: pull-requests: write issues: write steps: - name: Validate PR title uses: actions/github-script@v8 with: script: | const title = (context.payload.pull_request.title || "").trim(); // allow only: // feat: xxx // feat(scope): xxx const pattern = /^(feat)(\([a-z0-9-]+\))?:\s.+$/i; const isValid = pattern.test(title); const isSameRepo = context.payload.pull_request.head.repo.full_name === context.payload.repository.full_name; if (!isValid) { if (isSameRepo) { try { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, body: [ "⚠️ PR title format check failed.", "Required formats:", "- `feat: xxx`", "- `feat(scope): xxx`", "Please update your PR title and push again." ].join("\n") }); } catch (e) { core.warning(`Failed to post PR title comment: ${e.message}`); } } else { core.warning("Fork PR: comment permission is restricted; skip posting review comment."); } } if (!isValid) { core.setFailed("Invalid PR title. Expected format: feat: xxx or feat(scope): xxx."); }