@@ -156,6 +156,276 @@ jobs:
156156 <img src='https://img.shields.io/badge/Subscribe-blog.armbian.com-red?style=for-the-badge&logo=rss' alt='Subscribe to Blog'/></a>" >> summary.md
157157 echo "<p><br>Stay up to date with the latest Armbian news, development highlights, and tips — delivered straight to your inbox." >> summary.md
158158
159+ - name : " Generate HTML digest table"
160+ shell : bash
161+ run : |
162+ cat > out/digest.html <<'HTMLEOF'
163+ <!DOCTYPE html>
164+ <html lang="en">
165+ <head>
166+ <meta charset="UTF-8">
167+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
168+ <title>${LABEL} - Armbian PR Digest</title>
169+ <style>
170+ :root {
171+ --bg-primary: #0d1117;
172+ --bg-secondary: #161b22;
173+ --bg-tertiary: #21262d;
174+ --border-color: #30363d;
175+ --text-primary: #c9d1d9;
176+ --text-secondary: #8b949e;
177+ --text-muted: #6e7681;
178+ --accent: #58a6ff;
179+ --accent-hover: #79c0ff;
180+ --success: #3fb950;
181+ --armbian-orange: #f88a29;
182+ --armbian-blue: #007bff;
183+ }
184+ * { margin: 0; padding: 0; box-sizing: border-box; }
185+ body {
186+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
187+ background: var(--bg-primary);
188+ color: var(--text-primary);
189+ line-height: 1.6;
190+ padding: 20px;
191+ }
192+ .container {
193+ max-width: 1200px;
194+ margin: 0 auto;
195+ }
196+ header {
197+ text-align: center;
198+ padding: 40px 20px;
199+ border-bottom: 1px solid var(--border-color);
200+ margin-bottom: 30px;
201+ }
202+ h1 {
203+ font-size: 2.5rem;
204+ margin-bottom: 10px;
205+ background: linear-gradient(135deg, var(--armbian-orange), var(--armbian-blue));
206+ -webkit-background-clip: text;
207+ -webkit-text-fill-color: transparent;
208+ background-clip: text;
209+ }
210+ .subtitle {
211+ color: var(--text-secondary);
212+ font-size: 1.1rem;
213+ }
214+ .meta {
215+ display: flex;
216+ justify-content: center;
217+ gap: 20px;
218+ flex-wrap: wrap;
219+ margin-bottom: 20px;
220+ }
221+ .meta-item {
222+ background: var(--bg-secondary);
223+ padding: 8px 16px;
224+ border-radius: 6px;
225+ font-size: 0.9rem;
226+ }
227+ .table-container {
228+ background: var(--bg-secondary);
229+ border-radius: 12px;
230+ overflow: hidden;
231+ border: 1px solid var(--border-color);
232+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
233+ }
234+ table {
235+ width: 100%;
236+ border-collapse: collapse;
237+ }
238+ thead {
239+ background: var(--bg-tertiary);
240+ }
241+ th {
242+ padding: 16px;
243+ text-align: left;
244+ font-weight: 600;
245+ color: var(--text-primary);
246+ border-bottom: 2px solid var(--border-color);
247+ font-size: 0.85rem;
248+ text-transform: uppercase;
249+ letter-spacing: 0.5px;
250+ }
251+ td {
252+ padding: 14px 16px;
253+ border-bottom: 1px solid var(--border-color);
254+ vertical-align: middle;
255+ }
256+ tr:last-child td {
257+ border-bottom: none;
258+ }
259+ tr:hover {
260+ background: var(--bg-tertiary);
261+ }
262+ .pr-title {
263+ font-weight: 500;
264+ color: var(--text-primary);
265+ margin-bottom: 6px;
266+ }
267+ .pr-meta {
268+ display: flex;
269+ gap: 8px;
270+ flex-wrap: wrap;
271+ align-items: center;
272+ }
273+ .badge {
274+ display: inline-block;
275+ padding: 3px 10px;
276+ border-radius: 12px;
277+ font-size: 0.75rem;
278+ font-weight: 500;
279+ }
280+ .badge-repo {
281+ background: rgba(88, 166, 255, 0.15);
282+ color: var(--accent);
283+ border: 1px solid rgba(88, 166, 255, 0.3);
284+ }
285+ .badge-author {
286+ background: rgba(248, 138, 41, 0.15);
287+ color: var(--armbian-orange);
288+ border: 1px solid rgba(248, 138, 41, 0.3);
289+ }
290+ .pr-link {
291+ color: var(--accent);
292+ text-decoration: none;
293+ font-size: 0.9rem;
294+ display: inline-flex;
295+ align-items: center;
296+ }
297+ .pr-link:hover {
298+ color: var(--accent-hover);
299+ text-decoration: underline;
300+ }
301+ .pr-link::before {
302+ content: "→";
303+ margin-right: 6px;
304+ }
305+ .no-prs {
306+ text-align: center;
307+ padding: 60px 20px;
308+ color: var(--text-muted);
309+ font-size: 1.1rem;
310+ }
311+ .no-prs-icon {
312+ font-size: 3rem;
313+ margin-bottom: 16px;
314+ opacity: 0.5;
315+ }
316+ footer {
317+ margin-top: 40px;
318+ text-align: center;
319+ padding: 30px 20px;
320+ border-top: 1px solid var(--border-color);
321+ color: var(--text-secondary);
322+ }
323+ .footer-link {
324+ color: var(--accent);
325+ text-decoration: none;
326+ font-weight: 500;
327+ }
328+ .footer-link:hover {
329+ text-decoration: underline;
330+ }
331+ .generated-time {
332+ margin-top: 10px;
333+ font-size: 0.85rem;
334+ color: var(--text-muted);
335+ }
336+ @media (max-width: 768px) {
337+ .meta {
338+ flex-direction: column;
339+ }
340+ .pr-meta {
341+ flex-direction: column;
342+ gap: 6px;
343+ }
344+ th, td {
345+ padding: 12px;
346+ }
347+ }
348+ </style>
349+ </head>
350+ <body>
351+ <div class="container">
352+ <header>
353+ <h1>${LABEL}</h1>
354+ <p class="subtitle">Armbian Pull Request Digest</p>
355+ <div class="meta">
356+ <div class="meta-item">📅 Period: ${PERIOD}</div>
357+ <div class="meta-item">📅 From: ${SINCE_UTC}</div>
358+ <div class="meta-item">📅 Until: ${UNTIL_UTC}</div>
359+ </div>
360+ </header>
361+ HTMLEOF
362+
363+ # Generate table rows
364+ if [[ ! -s out/pr-digest.tsv ]]; then
365+ cat >> out/digest.html <<'EOF'
366+ <div class="table-container">
367+ <div class="no-prs">
368+ <div class="no-prs-icon">📭</div>
369+ <p>No merged PRs in this period.</p>
370+ </div>
371+ </div>
372+ EOF
373+ else
374+ cat >> out/digest.html <<'EOF'
375+ <div class="table-container">
376+ <table>
377+ <thead>
378+ <tr>
379+ <th width="50%">Pull Request</th>
380+ <th>Author</th>
381+ <th>Repository</th>
382+ <th>Link</th>
383+ </tr>
384+ </thead>
385+ <tbody>
386+ EOF
387+
388+ while IFS=$'\t' read -r title author repo num pr_url; do
389+ repo_name="${repo##*/}"
390+ cat >> out/digest.html <<EOF
391+ <tr>
392+ <td>
393+ <div class="pr-title">${title}</div>
394+ <div class="pr-meta">
395+ <span class="badge badge-repo">${repo_name}</span>
396+ </div>
397+ </td>
398+ <td><span class="badge badge-author">@${author}</span></td>
399+ <td>${repo_name}</td>
400+ <td><a class="pr-link" href="${pr_url}" target="_blank">View PR #${num}</a></td>
401+ </tr>
402+ EOF
403+ done < out/pr-digest.tsv
404+
405+ cat >> out/digest.html <<'EOF'
406+ </tbody>
407+ </table>
408+ </div>
409+ EOF
410+ fi
411+
412+ cat >> out/digest.html <<'EOF'
413+ <footer>
414+ <a class="footer-link" href="https://blog.armbian.com/#/portal/signup" target="_blank">
415+ 📬 Subscribe to Armbian Blog
416+ </a>
417+ <p style="margin-top: 15px; font-size: 0.9rem; color: var(--text-muted);">
418+ Stay up to date with the latest Armbian news, development highlights, and tips.
419+ </p>
420+ <div class="generated-time">
421+ Generated: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
422+ </div>
423+ </footer>
424+ </div>
425+ </body>
426+ </html>
427+ HTMLEOF
428+
159429 - name : Upload raw data (artifacts)
160430 uses : actions/upload-artifact@v6
161431 with :
0 commit comments