-
Notifications
You must be signed in to change notification settings - Fork 64
160 lines (132 loc) · 6.19 KB
/
vocs-config-reminder.yml
File metadata and controls
160 lines (132 loc) · 6.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
name: Sidebar Config Reminder
on:
pull_request_target:
types: [opened, synchronize]
branches:
- develop
permissions:
contents: read
pull-requests: write
jobs:
sidebar-reminder:
runs-on: ubuntu-latest
steps:
- name: Check for added, renamed, or removed documentation files
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.1.0
with:
script: |
// Sanitize filenames
const sanitizeFilename = (str) => {
if (typeof str !== 'string') return '';
return str
.replace(/[`\[\]()\\<>|_*~#]/g, '\\$&')
.replace(/[\n\r]/g, ' ')
.replace(/[\u200b-\u200f\u202a-\u202e\u2060\ufeff]/g, '')
.slice(0, 255);
};
// Allowed file statuses
const sanitizeStatus = (status) => {
const allowed = ['added', 'renamed', 'removed'];
return allowed.includes(status) ? status : 'unknown';
};
const { owner, repo } = context.repo;
const pull_number = context.payload.pull_request.number;
const eventAction = context.payload.action;
const MARKER = '<!-- vocs-config-reminder -->';
// Get files changed
const { data: allPrFiles } = await github.rest.pulls.listFiles({
owner,
repo,
pull_number,
per_page: 100
});
// Filter for added/renamed/removed .mdx files in docs/pages/
const currentDocFiles = allPrFiles.filter(file =>
['added', 'renamed', 'removed'].includes(file.status) &&
file.filename.startsWith('docs/pages/') &&
file.filename.endsWith('.mdx')
);
if (currentDocFiles.length === 0) {
console.log('No documentation files were added, renamed, or removed in this PR. Skipping.');
return;
}
// Find all previous bot comments with marker
const { data: comments } = await github.rest.issues.listComments({
owner,
repo,
issue_number: pull_number,
per_page: 100
});
// Only read comments from the bot with the marker
const previousComments = comments.filter(c =>
c.body.includes(MARKER) &&
c.user.login === 'github-actions[bot]'
);
// Extract previously seen files from bot past comments
const previouslySeenFiles = new Set();
for (const comment of previousComments) {
const dataMatch = comment.body.match(/<!-- VOCS_DATA:([\w+/=]+) -->/);
if (dataMatch) {
try {
const filenames = JSON.parse(Buffer.from(dataMatch[1], 'base64').toString('utf8'));
if (Array.isArray(filenames)) {
filenames.forEach(f => { if (typeof f === 'string') previouslySeenFiles.add(f); });
}
} catch (e) {
// Ignore corrupt data blocks
}
}
}
console.log(`Previously seen files: ${[...previouslySeenFiles].join(', ') || 'none'}`);
const newFiles = [];
const seenFiles = [];
for (const file of currentDocFiles) {
if (previouslySeenFiles.has(file.filename)) {
seenFiles.push(file);
} else {
newFiles.push(file);
}
}
// On PR open, all files are "new" (first comment)
// On synchronize, only post if there are actually new files
if (eventAction === 'synchronize' && newFiles.length === 0) {
console.log('No new documentation files in this push. Skipping comment.');
return;
}
console.log(`New files: ${newFiles.map(f => f.filename).join(', ') || 'none'}`);
console.log(`Previously seen files: ${seenFiles.map(f => f.filename).join(', ') || 'none'}`);
let fileListSection = '';
if (eventAction === 'opened') {
fileListSection = currentDocFiles.map(f => `- \`${sanitizeFilename(f.filename)}\` (${sanitizeStatus(f.status)})`).join('\n');
} else {
if (newFiles.length > 0) {
fileListSection += '**New in this push:**\n';
fileListSection += newFiles.map(f => `- \`${sanitizeFilename(f.filename)}\` (${sanitizeStatus(f.status)}) ← NEW`).join('\n');
}
if (seenFiles.length > 0) {
if (newFiles.length > 0) fileListSection += '\n\n';
fileListSection += '**Previously seen:**\n';
fileListSection += seenFiles.map(f => `- \`${sanitizeFilename(f.filename)}\` (${sanitizeStatus(f.status)})`).join('\n');
}
}
const rawFilenames = currentDocFiles.map(f => f.filename);
const dataBlock = `<!-- VOCS_DATA:${Buffer.from(JSON.stringify(rawFilenames)).toString('base64')} -->`;
const body = `### Sidebar Configuration Reminder
${MARKER}
${dataBlock}
${eventAction === 'opened' ? 'This PR includes added, renamed, or removed documentation files:' : 'Documentation files update:'}
${fileListSection}
Please ensure that:
- [ ] The sidebar in \`vocs.config.tsx\` has been updated to include these files
- [ ] New content has the \`dev: true\` parameter so it's marked as under development
- [ ] Sidebar links match the file paths - use the preview deployment to verify
See [Contributing Guide – Sidebar & Navigation](https://frameworks.securityalliance.org/contribute/contributing/#3-sidebar--navigation) for more details.
---
<sub>This is an automated reminder. If this PR doesn't need sidebar changes, you can ignore this message.</sub>`;
await github.rest.issues.createComment({
owner,
repo,
issue_number: pull_number,
body
});
console.log('Posted reminder comment.');