Skip to content

Commit eec5167

Browse files
author
Fr4gm3nt3d_sh
committed
Update .github/workflows/llmcodereview.yml
1 parent 134ce02 commit eec5167

File tree

1 file changed

+137
-112
lines changed

1 file changed

+137
-112
lines changed

.github/workflows/llmcodereview.yml

Lines changed: 137 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,32 @@ jobs:
6464
6565
const result = await model.generateContent(prompt);
6666
const report = result.response.text();
67+
68+
// Escape HTML to prevent XSS
69+
const escapeHtml = (text) => {
70+
const map = {
71+
'&': '&',
72+
'<': '&lt;',
73+
'>': '&gt;',
74+
'"': '&quot;',
75+
"'": '&#039;'
76+
};
77+
return text.replace(/[&<>"']/g, m => map[m]);
78+
};
79+
80+
// Convert markdown to HTML safely
81+
const markdownToHtml = (md) => {
82+
let html = escapeHtml(md);
83+
html = html.replace(/^### (.*?)$/gm, '<h3>$1</h3>');
84+
html = html.replace(/^## (.*?)$/gm, '<h2>$1</h2>');
85+
html = html.replace(/^# (.*?)$/gm, '<h1>$1</h1>');
86+
html = html.replace(/\n\n/g, '</p><p>');
87+
html = html.replace(/^- (.*?)$/gm, '<li>$1</li>');
88+
html = html.replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>');
89+
html = html.replace(/\`(.*?)\`/g, '<code>$1</code>');
90+
html = '<p>' + html + '</p>';
91+
return html;
92+
};
6793
6894
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
6995
const reportName = `report-${timestamp}.html`;
@@ -75,221 +101,221 @@ jobs:
75101
<meta charset="UTF-8">
76102
<meta name="viewport" content="width=device-width, initial-scale=1.0">
77103
<title>Gemini Code Review</title>
78-
<link rel="stylesheet" href="/style.css">
104+
<link rel="stylesheet" href="../style.css">
79105
<style>
80-
.container {
81-
max-width: 900px;
82-
margin: 2rem auto;
106+
.report-container {
107+
max-width: 800px;
108+
margin: 1.5rem auto;
83109
background: var(--bg-light);
84-
border-radius: 8px;
110+
border-radius: 6px;
85111
border: 1px solid var(--border);
86112
overflow: hidden;
87113
}
88-
.header {
114+
.report-header {
89115
background: var(--bg);
90116
color: var(--text);
91-
padding: 3rem 2rem;
117+
padding: 2rem 1.5rem;
92118
text-align: center;
93119
border-bottom: 1px solid var(--border);
94120
}
95-
.header h1 {
96-
font-size: 2.5rem;
97-
margin-bottom: 0.5rem;
121+
.report-header h1 {
122+
font-size: 1.8rem;
123+
margin-bottom: 0.3rem;
98124
font-weight: 700;
99125
color: var(--primary);
100126
}
101-
.header p {
102-
font-size: 1rem;
127+
.report-header p {
128+
font-size: 0.9rem;
103129
color: var(--text-muted);
104130
}
105-
.timestamp {
106-
font-size: 0.85rem;
107-
margin-top: 1rem;
131+
.report-timestamp {
132+
font-size: 0.75rem;
133+
margin-top: 0.5rem;
108134
color: var(--text-muted);
109135
}
110-
.content {
111-
padding: 2.5rem;
136+
.report-content {
137+
padding: 1.5rem;
138+
font-size: 0.95rem;
112139
}
113-
.content h2 {
140+
.report-content h2 {
114141
color: var(--primary);
115-
margin-top: 2rem;
116-
margin-bottom: 1rem;
117-
font-size: 1.5rem;
118-
border-left: 3px solid var(--primary);
119-
padding-left: 1rem;
120-
}
121-
.content h3 {
122-
color: var(--secondary);
123142
margin-top: 1.5rem;
124143
margin-bottom: 0.8rem;
125-
font-size: 1.2rem;
144+
font-size: 1.3rem;
145+
border-left: 3px solid var(--primary);
146+
padding-left: 0.8rem;
126147
}
127-
.content h4 {
128-
color: var(--text-muted);
129-
margin-top: 1rem;
130-
margin-bottom: 0.5rem;
131-
font-size: 1rem;
148+
.report-content h3 {
149+
color: var(--secondary);
150+
margin-top: 1rem;
151+
margin-bottom: 0.5rem;
152+
font-size: 1.1rem;
132153
}
133-
.content p {
134-
margin-bottom: 1rem;
154+
.report-content p {
155+
margin-bottom: 0.8rem;
135156
color: var(--text);
136157
}
137-
.content ul, .content ol {
138-
margin-left: 2rem;
139-
margin-bottom: 1rem;
158+
.report-content ul {
159+
margin-left: 1.5rem;
160+
margin-bottom: 0.8rem;
140161
}
141-
.content li {
142-
margin-bottom: 0.5rem;
162+
.report-content li {
163+
margin-bottom: 0.3rem;
143164
color: var(--text);
144165
}
145-
.content code {
166+
.report-content code {
146167
background: var(--bg);
147-
padding: 0.2rem 0.5rem;
148-
border-radius: 4px;
168+
padding: 0.15rem 0.4rem;
169+
border-radius: 3px;
149170
font-family: 'Courier New', monospace;
150171
color: var(--secondary);
151-
font-size: 0.9em;
172+
font-size: 0.85em;
152173
}
153-
.content pre {
174+
.report-content pre {
154175
background: var(--bg-dark);
155176
color: var(--text);
156-
padding: 1.5rem;
157-
border-radius: 6px;
177+
padding: 1rem;
178+
border-radius: 4px;
158179
overflow-x: auto;
159-
margin: 1rem 0;
180+
margin: 0.8rem 0;
160181
font-family: 'Courier New', monospace;
161-
font-size: 0.85rem;
182+
font-size: 0.8rem;
162183
border: 1px solid var(--border);
163184
}
164-
.content pre code {
165-
background: none;
166-
padding: 0;
167-
color: inherit;
168-
}
169-
.footer {
185+
.report-footer {
170186
background: var(--bg);
171-
padding: 1.5rem;
187+
padding: 1rem;
172188
text-align: center;
173189
color: var(--text-muted);
174190
border-top: 1px solid var(--border);
175-
font-size: 0.9rem;
191+
font-size: 0.8rem;
176192
}
177-
.footer a {
193+
.report-footer a {
178194
color: var(--primary);
179195
text-decoration: none;
180196
}
181-
.footer a:hover {
197+
.report-footer a:hover {
182198
color: var(--secondary);
183199
}
184-
@media (max-width: 768px) {
185-
.header h1 { font-size: 1.8rem; }
186-
.content { padding: 1.5rem; }
187-
}
188200
</style>
189201
</head>
190202
<body>
191-
<div class="container">
192-
<div class="header">
203+
<div class="report-container">
204+
<div class="report-header">
193205
<h1>🔍 Code Review</h1>
194-
<p>Gemini Analysis Report</p>
195-
<p class="timestamp">${date.toUTCString()}</p>
206+
<p>Gemini Analysis</p>
207+
<p class="report-timestamp">${date.toUTCString()}</p>
196208
</div>
197-
<div class="content">
198-
${report}
209+
<div class="report-content">
210+
${markdownToHtml(report)}
199211
</div>
200-
<div class="footer">
212+
<div class="report-footer">
201213
<p><a href="index.html">← Back to Reports</a></p>
202214
</div>
203215
</div>
204216
</body>
205217
</html>`;
206218
207-
fs.writeFileSync(reportName, html);
219+
// Create reports directory if it doesn't exist
220+
if (!fs.existsSync("reports")) {
221+
fs.mkdirSync("reports", { recursive: true });
222+
}
208223
224+
fs.writeFileSync(\`reports/\${reportName}\`, html);
225+
226+
// Create or update index.html for reports
227+
let indexPath = "reports/index.html";
209228
let index = "";
210-
let reportsHTML = "";
211-
212-
if (fs.existsSync("report.html")) {
213-
index = fs.readFileSync("report.html", "utf8");
229+
230+
if (fs.existsSync(indexPath)) {
231+
index = fs.readFileSync(indexPath, "utf8");
214232
} else {
215-
index = `<!DOCTYPE html>
233+
index = \`<!DOCTYPE html>
216234
<html lang="en" data-theme="dark">
217235
<head>
218236
<meta charset="UTF-8">
219237
<meta name="viewport" content="width=device-width, initial-scale=1.0">
220238
<title>Code Reviews</title>
221-
<link rel="stylesheet" href="/style.css">
239+
<link rel="stylesheet" href="../style.css">
222240
<style>
223-
.reports-container {
224-
max-width: 1200px;
225-
margin: 2rem auto;
226-
padding: 0 2rem;
241+
.reviews-container {
242+
max-width: 900px;
243+
margin: 1.5rem auto;
244+
padding: 0 1rem;
227245
}
228-
.reports-header {
246+
.reviews-header {
229247
text-align: center;
230-
margin-bottom: 3rem;
248+
margin-bottom: 2rem;
231249
}
232-
.reports-header h1 {
233-
font-size: 2.5rem;
250+
.reviews-header h1 {
251+
font-size: 2rem;
234252
color: var(--primary);
235-
margin-bottom: 0.5rem;
253+
margin-bottom: 0.3rem;
236254
}
237-
.reports-header p {
255+
.reviews-header p {
238256
color: var(--text-muted);
239-
font-size: 1rem;
257+
font-size: 0.95rem;
240258
}
241-
.reports-grid {
259+
.reviews-grid {
242260
display: grid;
243-
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
244-
gap: 1.5rem;
261+
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
262+
gap: 1rem;
245263
}
246-
.report-card {
264+
.review-card {
247265
background: var(--bg-light);
248266
border: 1px solid var(--border);
249-
border-radius: 8px;
250-
padding: 1.5rem;
267+
border-radius: 6px;
268+
padding: 1.2rem;
251269
text-decoration: none;
252270
color: inherit;
253271
display: flex;
254272
flex-direction: column;
255273
transition: all 0.3s ease;
256274
}
257-
.report-card:hover {
275+
.review-card:hover {
258276
border-color: var(--primary);
259277
background: var(--bg);
260278
}
261-
.report-card h2 {
279+
.review-card h3 {
262280
color: var(--primary);
263-
margin-bottom: 0.5rem;
264-
font-size: 1.2rem;
281+
margin-bottom: 0.3rem;
282+
font-size: 1rem;
265283
}
266-
.report-card .date {
284+
.review-card .date {
267285
color: var(--text-muted);
268-
font-size: 0.85rem;
286+
font-size: 0.8rem;
269287
}
270288
@media (max-width: 768px) {
271-
.reports-header h1 { font-size: 1.8rem; }
272-
.reports-grid {
289+
.reviews-header h1 { font-size: 1.5rem; }
290+
.reviews-grid {
273291
grid-template-columns: 1fr;
274292
}
275293
}
276294
</style>
277295
</head>
278296
<body>
279-
<div class="reports-container">
280-
<div class="reports-header">
297+
<div class="reviews-container">
298+
<div class="reviews-header">
281299
<h1>Code Reviews</h1>
282300
<p>Gemini-powered analysis reports</p>
283301
</div>
284-
<div class="reports-grid" id="reports"></div>
302+
<div class="reviews-grid" id="reviews"></div>
285303
</div>
286304
</body>
287-
</html>`;
305+
</html>\`;
288306
}
289307
290-
const button = `<a href="./${reportName}" class="report-card"><h2>📝 Report</h2><p class="date">${date.toUTCString()}</p></a>`;
291-
index = index.replace('<div class="reports-grid" id="reports">', `<div class="reports-grid" id="reports">\n ${button}`);
292-
fs.writeFileSync("report.html", index);
308+
// Get all existing reports
309+
const files = fs.readdirSync("reports").filter(f => f.startsWith("report-") && f.endsWith(".html"));
310+
files.sort().reverse();
311+
312+
let cardsHtml = files.map(file => {
313+
const displayName = file.replace("report-", "").replace(".html", "").replace(/[T-]/g, " ").trim();
314+
return \`<a href="./ file\\" class="review-card"><h3>📝 Review</h3><p class="date">\${displayName}</p></a>\`;
315+
}).join("\\n ");
316+
317+
index = index.replace('<div class="reviews-grid" id="reviews"></div>', \`<div class="reviews-grid">\${cardsHtml}</div>\`);
318+
fs.writeFileSync(indexPath, index);
293319
294320
console.log("=== Gemini Code Review Complete ===");
295321
console.log(report);
@@ -302,15 +328,14 @@ jobs:
302328
run: |
303329
git config user.name "gemini-bot"
304330
git config user.email "gemini@actions"
305-
git add report*.html report.html
331+
git add reports/
306332
git commit -m "Add Gemini code report" || echo "No changes to commit"
307333
mkdir -p /tmp/pages-repo
308334
cd /tmp/pages-repo
309335
git clone https://x-access-token:${GH_PAGES_PAT}@github.com/Mod-Sauce/mod-sauce.github.io.git .
310-
cp -r $GITHUB_WORKSPACE/report*.html .
311-
cp $GITHUB_WORKSPACE/report.html .
336+
cp -r $GITHUB_WORKSPACE/reports .
312337
git config user.name "gemini-bot"
313338
git config user.email "gemini@actions"
314-
git add report*.html report.html
339+
git add reports/
315340
git commit -m "Add Gemini code report" || echo "No changes to commit"
316341
git push origin main

0 commit comments

Comments
 (0)