Skip to content

Commit 95a7a8d

Browse files
authored
Create documentation-style-review-enhanced.yml
1 parent d5fb6f3 commit 95a7a8d

File tree

1 file changed

+310
-0
lines changed

1 file changed

+310
-0
lines changed
Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
name: Enhanced Strapi Documentation Style Review
2+
3+
on:
4+
# Enable for real PRs when ready
5+
# pull_request:
6+
# types: [opened, synchronize, reopened]
7+
# paths:
8+
# - 'docusaurus/docs/**/*.md'
9+
# - 'docusaurus/docs/**/*.mdx'
10+
11+
# Manual trigger for testing
12+
workflow_dispatch:
13+
inputs:
14+
pr_number:
15+
description: 'PR number to validate'
16+
required: true
17+
type: string
18+
target_files:
19+
description: 'Specific files to validate (optional - leave empty to analyze entire PR)'
20+
required: false
21+
type: string
22+
enable_inline_comments:
23+
description: 'Enable inline comments (recommended)'
24+
required: false
25+
type: boolean
26+
default: true
27+
max_inline_comments:
28+
description: 'Maximum number of inline comments (default: 10)'
29+
required: false
30+
type: string
31+
default: '10'
32+
33+
jobs:
34+
validate-documentation:
35+
runs-on: ubuntu-latest
36+
permissions:
37+
contents: read
38+
issues: write
39+
pull-requests: write
40+
steps:
41+
- name: Checkout repository
42+
uses: actions/checkout@v4
43+
with:
44+
fetch-depth: 0
45+
46+
- name: Setup Node.js
47+
uses: actions/setup-node@v4
48+
with:
49+
node-version: '20'
50+
cache: 'yarn'
51+
cache-dependency-path: 'docusaurus/yarn.lock'
52+
53+
- name: Install dependencies
54+
run: |
55+
cd docusaurus
56+
yarn install
57+
58+
- name: Run Enhanced Documentation Validation
59+
id: validation
60+
run: |
61+
cd docusaurus
62+
63+
echo "🎯 Starting enhanced documentation validation..."
64+
65+
# Determine validation strategy
66+
if [ -n "${{ github.event.inputs.target_files }}" ]; then
67+
echo "📄 Validating specific files: ${{ github.event.inputs.target_files }}"
68+
69+
# Manual file validation (standard mode)
70+
node scripts/style-validation/validate-content-style.js \
71+
--verbose \
72+
${{ github.event.inputs.target_files }}
73+
74+
elif [ -n "${{ github.event.inputs.pr_number }}" ]; then
75+
echo "🔍 Validating PR #${{ github.event.inputs.pr_number }} with enhanced diff analysis"
76+
77+
# Use the new enhanced GitHub validation with inline comments
78+
node scripts/style-validation/validate-content-style-github.js \
79+
--pr ${{ github.event.inputs.pr_number }} \
80+
--repo strapi/documentation \
81+
--verbose
82+
83+
elif [ "${{ github.event_name }}" = "pull_request" ]; then
84+
echo "🔍 Auto-validating PR #${{ github.event.number }}"
85+
86+
# Auto-validation for real PRs
87+
node scripts/style-validation/validate-content-style-github.js \
88+
--pr ${{ github.event.number }} \
89+
--repo strapi/documentation \
90+
--verbose
91+
92+
else
93+
echo "❌ No validation target specified"
94+
echo '{"summary":{"filesProcessed":0,"totalIssues":0,"criticalIssues":0},"issues":{"errors":[],"warnings":[],"suggestions":[]}}' > style-check-results.json
95+
fi
96+
continue-on-error: true
97+
98+
- name: Post Enhanced PR Review with Inline Comments
99+
uses: actions/github-script@v7
100+
with:
101+
script: |
102+
const fs = require('fs');
103+
104+
// Get context information
105+
const prNumber = '${{ github.event.inputs.pr_number }}' || '${{ github.event.number }}' || '';
106+
const eventName = '${{ github.event_name }}';
107+
const enableInlineComments = '${{ github.event.inputs.enable_inline_comments }}' !== 'false';
108+
const maxInlineComments = parseInt('${{ github.event.inputs.max_inline_comments }}') || 10;
109+
110+
try {
111+
// Read validation results
112+
const resultsPath = 'docusaurus/style-check-results.json';
113+
114+
if (!fs.existsSync(resultsPath)) {
115+
console.log('❌ No results file found, validation may have failed');
116+
117+
const errorComment = '## ❌ Enhanced Documentation Review Failed\n\n' +
118+
'The enhanced validation system failed to run. Please check the Action logs.\n\n' +
119+
'**This might indicate:**\n' +
120+
'- Missing validation scripts\n' +
121+
'- Network issues fetching PR diff\n' +
122+
'- Configuration problems\n\n' +
123+
'*Please contact the documentation team for assistance.*';
124+
125+
if (prNumber) {
126+
await github.rest.issues.createComment({
127+
issue_number: parseInt(prNumber),
128+
owner: context.repo.owner,
129+
repo: context.repo.repo,
130+
body: errorComment
131+
});
132+
}
133+
return;
134+
}
135+
136+
const results = JSON.parse(fs.readFileSync(resultsPath, 'utf8'));
137+
138+
// Check for previous bot comments to determine if this is an update
139+
let isFollowUp = false;
140+
let previousResults = null;
141+
142+
try {
143+
if (prNumber) {
144+
const commentsResponse = await github.rest.issues.listComments({
145+
issue_number: parseInt(prNumber),
146+
owner: context.repo.owner,
147+
repo: context.repo.repo
148+
});
149+
150+
const botComments = commentsResponse.data.filter(comment =>
151+
comment.user.type === 'Bot' &&
152+
comment.body.includes('Thanks for contributing to Strapi\'s documentation')
153+
);
154+
155+
isFollowUp = botComments.length > 0;
156+
157+
// Try to extract previous results for comparison
158+
if (isFollowUp) {
159+
const lastComment = botComments[botComments.length - 1].body;
160+
const prevIssuesMatch = lastComment.match(/spotted (\d+) (?:small )?improvement/);
161+
if (prevIssuesMatch) {
162+
previousResults = { totalIssues: parseInt(prevIssuesMatch[1]) };
163+
}
164+
}
165+
}
166+
} catch (e) {
167+
console.log('Could not check for previous comments:', e.message);
168+
}
169+
170+
// Use the friendly comment from our enhanced validator
171+
let comment = results.githubComment || '## 👋 Thanks for contributing to Strapi\'s documentation!\n\nSomething went wrong generating the review comment.';
172+
173+
// Add progress indication if this is a follow-up
174+
if (isFollowUp && previousResults) {
175+
const change = results.summary.totalIssues - previousResults.totalIssues;
176+
let progressNote = '';
177+
178+
if (change < 0) {
179+
progressNote = `\n\n🎉 **Great progress!** You've resolved ${Math.abs(change)} issue${Math.abs(change) > 1 ? 's' : ''} since the last review!\n`;
180+
} else if (change > 0) {
181+
progressNote = `\n\n📝 **Update:** Found ${change} additional item${change > 1 ? 's' : ''} to review.\n`;
182+
} else if (results.summary.totalIssues === 0) {
183+
progressNote = `\n\n🎊 **Perfect!** All issues have been resolved!\n`;
184+
} else {
185+
progressNote = `\n\n🔄 **Updated review** with your latest changes.\n`;
186+
}
187+
188+
// Insert progress note before the resources section
189+
comment = comment.replace(/\*\*📚 Helpful Resources:\*\*/, progressNote + '**📚 Helpful Resources:**');
190+
}
191+
192+
// Add workflow context
193+
if (eventName === 'workflow_dispatch') {
194+
comment += `\n\n*🔧 Manually triggered validation for PR #${prNumber}*`;
195+
}
196+
197+
// Post the main comment
198+
if (prNumber) {
199+
await github.rest.issues.createComment({
200+
issue_number: parseInt(prNumber),
201+
owner: context.repo.owner,
202+
repo: context.repo.repo,
203+
body: comment
204+
});
205+
206+
console.log(`✅ Main comment posted to PR #${prNumber}`);
207+
}
208+
209+
// Post inline comments if enabled and available
210+
if (enableInlineComments && results.inlineComments && results.inlineComments.length > 0 && prNumber) {
211+
console.log(`💬 Posting ${results.inlineComments.length} inline comments...`);
212+
213+
try {
214+
// Get the latest commit SHA for the PR
215+
const prData = await github.rest.pulls.get({
216+
owner: context.repo.owner,
217+
repo: context.repo.repo,
218+
pull_number: parseInt(prNumber)
219+
});
220+
221+
const commitSha = prData.data.head.sha;
222+
223+
// Create a review with inline comments
224+
const review = await github.rest.pulls.createReview({
225+
owner: context.repo.owner,
226+
repo: context.repo.repo,
227+
pull_number: parseInt(prNumber),
228+
commit_id: commitSha,
229+
body: `## 📝 Detailed Style Review\n\nI've added specific suggestions directly on the lines that need attention. Each comment includes:\n- 🎯 The specific rule being applied\n- 💡 A suggested improvement\n- ✨ An example of the recommended approach\n\nThese suggestions will help make your documentation even more welcoming and clear for our global developer community!`,
230+
event: results.summary.criticalIssues > 0 ? 'REQUEST_CHANGES' : 'COMMENT',
231+
comments: results.inlineComments.map(comment => ({
232+
path: comment.path,
233+
line: comment.line,
234+
body: comment.body
235+
}))
236+
});
237+
238+
console.log(`✅ Posted review with ${results.inlineComments.length} inline comments`);
239+
240+
// If we had to truncate comments, add a note
241+
if (results.hasMoreIssues) {
242+
const truncationComment = `## 💙 More suggestions available!\n\n` +
243+
`I found ${results.remainingIssues} additional item${results.remainingIssues > 1 ? 's' : ''} to review. ` +
244+
`Once you address the current suggestions, I'll be happy to review again and share the remaining feedback!\n\n` +
245+
`This approach helps keep the review manageable and focused. Thanks for your patience! 😊`;
246+
247+
await github.rest.issues.createComment({
248+
issue_number: parseInt(prNumber),
249+
owner: context.repo.owner,
250+
repo: context.repo.repo,
251+
body: truncationComment
252+
});
253+
}
254+
255+
} catch (error) {
256+
console.error('Failed to post inline comments:', error);
257+
258+
// Fallback: post inline comments as a single comment
259+
let fallbackComment = '## 📝 Detailed Suggestions\n\n*Unable to post inline comments, here are the specific suggestions:*\n\n';
260+
261+
results.inlineComments.forEach((comment, index) => {
262+
fallbackComment += `### ${comment.path}:${comment.line}\n\n${comment.body}\n\n---\n\n`;
263+
});
264+
265+
await github.rest.issues.createComment({
266+
issue_number: parseInt(prNumber),
267+
owner: context.repo.owner,
268+
repo: context.repo.repo,
269+
body: fallbackComment
270+
});
271+
272+
console.log('✅ Posted fallback comment with suggestions');
273+
}
274+
}
275+
276+
// Set appropriate exit code
277+
if (results.issues.errors.length > 0) {
278+
core.setFailed(`Found ${results.issues.errors.length} critical errors that must be fixed before merging.`);
279+
} else {
280+
console.log(`✅ Enhanced validation completed successfully`);
281+
console.log(`📊 Results: ${results.summary.totalIssues} total issues, ${results.inlineComments?.length || 0} inline comments`);
282+
}
283+
284+
} catch (error) {
285+
console.error('❌ Error processing validation results:', error);
286+
287+
const errorMessage = '## ❌ Enhanced Documentation Review Error\n\n' +
288+
'There was an error processing the validation results.\n\n' +
289+
`**Error:** ${error.message}\n\n` +
290+
'Please check the GitHub Action logs for more details or contact the documentation team.';
291+
292+
if (prNumber) {
293+
await github.rest.issues.createComment({
294+
issue_number: parseInt(prNumber),
295+
owner: context.repo.owner,
296+
repo: context.repo.repo,
297+
body: errorMessage
298+
});
299+
}
300+
301+
core.setFailed(`Enhanced validation processing failed: ${error.message}`);
302+
}
303+
304+
- name: Upload Validation Results
305+
uses: actions/upload-artifact@v4
306+
if: always()
307+
with:
308+
name: style-validation-results
309+
path: docusaurus/style-check-results.json
310+
retention-days: 30

0 commit comments

Comments
 (0)