Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Validation Workflow for Pull Request Content #1233

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,9 @@ Thanks for submitting a pull request! Please provide enough information so that
**Does this PR introduce a breaking change?**

<!-- If this PR introduces a breaking change, please describe the impact and a migration path for existing applications. -->

# Checklist

Please ensure the following tasks are completed before submitting this pull request.

- [ ] Read, understood, and followed the [contributing guidelines](https://github.com/json-schema-org/website/blob/main/CONTRIBUTING.md).
116 changes: 116 additions & 0 deletions .github/workflows/pr-body-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: PR Body Validation

on:
pull_request_target:
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']
});
}
core.setFailed(`The following required information is missing or incomplete: ${missingItemsList}`);
} 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'
});
}
Loading