-
-
Notifications
You must be signed in to change notification settings - Fork 211
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5114356
commit 7b0cfc3
Showing
2 changed files
with
121 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
name: PR Body Validation | ||
|
||
on: | ||
pull_request: | ||
types: [opened, edited, synchronize, reopened] | ||
|
||
jobs: | ||
check-pr-content: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
pull-requests: write | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
|
||
- name: Check PR content | ||
uses: actions/github-script@v7 | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
script: | | ||
const pr = context.payload.pull_request; | ||
const prBody = pr.body || ''; | ||
let missingItems = []; | ||
// Helper function to extract content between section headers | ||
function extractSectionContent(content, sectionHeader) { | ||
const regex = new RegExp(`\\*\\*${sectionHeader}\\*\\*(.*?)(?=\\*\\*|$)`, 's'); | ||
const match = content.match(regex); | ||
if (!match) return ''; | ||
// Remove HTML comments and trim whitespace | ||
return match[1].replace(/<!--[\s\S]*?-->/g, '').trim(); | ||
} | ||
// Helper function to check if content is meaningful | ||
function hasMeaningfulContent(content) { | ||
// Remove HTML comments, markdown symbols, and extra whitespace | ||
const cleanContent = content | ||
.replace(/<!--[\s\S]*?-->/g, '') | ||
.replace(/[#*\[\]()_]/g, '') | ||
.trim(); | ||
return cleanContent.length >= 3; // Requiring at least 3 characters | ||
} | ||
// Check for issue links | ||
const issueRegex = /(closes|related to)\s+#\d+/i; | ||
if (!issueRegex.test(prBody)) { | ||
missingItems.push('issue reference'); | ||
} | ||
// Check for kind of change | ||
const changeContent = extractSectionContent(prBody, 'What kind of change does this PR introduce\\?'); | ||
if (!hasMeaningfulContent(changeContent)) { | ||
missingItems.push('kind of change description'); | ||
} | ||
// Check for breaking changes | ||
const breakingContent = extractSectionContent(prBody, 'Does this PR introduce a breaking change\\?'); | ||
if (!hasMeaningfulContent(breakingContent)) { | ||
missingItems.push('breaking changes information'); | ||
} | ||
// Check for unchecked items in checklist | ||
const checklistMatch = prBody.match(/# Checklist([\s\S]*?)(?=(?:#|$))/); | ||
if (checklistMatch && checklistMatch[1].includes('- [ ]')) { | ||
missingItems.push('completed checklist items'); | ||
} | ||
// Get current labels | ||
const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number | ||
}); | ||
const hasNeedsInfoLabel = currentLabels.some(label => label.name === 'needs-info'); | ||
if (missingItems.length > 0) { | ||
// If there are missing items, add comment and label | ||
const missingItemsList = missingItems.join(', '); | ||
const comment = `Hi @${pr.user.login}! Thanks a lot for your contribution! | ||
I noticed that the following required information is missing or incomplete: ${missingItemsList} | ||
Please update the PR description to include this information. You can find placeholders in the PR template for these items. | ||
Thanks a lot!`; | ||
await github.rest.issues.createComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number, | ||
body: comment | ||
}); | ||
// Add needs-info label if not already present | ||
if (!hasNeedsInfoLabel) { | ||
await github.rest.issues.addLabels({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number, | ||
labels: ['needs-info'] | ||
}); | ||
} | ||
} else if (hasNeedsInfoLabel) { | ||
// If all requirements are met and the needs-info label exists, remove it | ||
await github.rest.issues.removeLabel({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number, | ||
name: 'needs-info' | ||
}); | ||
} |