Add HTML digest table artifact to release summary workflow#218
Add HTML digest table artifact to release summary workflow#218igorpecovnik wants to merge 1 commit intomainfrom
Conversation
WalkthroughA new workflow step was added to Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- Add "Generate HTML digest table" step that creates out/digest.html - Implement dark theme design matching GitHub's aesthetic - Add responsive table layout with color-coded badges - Include header with period metadata and footer with blog subscription - Handle empty state when no PRs were merged during period Signed-off-by: Igor Pecovnik <igor@armbian.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/reporting-release-summary.yml:
- Line 414: The anchor element with class "pr-link" using target="_blank" should
be hardened by adding rel="noopener noreferrer"; locate the <a class="pr-link"
href="${pr_url}" target="_blank">View PR #${num}</a> occurrences (also the
similar occurrence at the other location) and add rel="noopener noreferrer" to
the tag so external links opened in new tabs do not expose window.opener.
- Around line 402-415: The loop injects unescaped TSV fields (title, author,
repo_name, pr_url, num) directly into HTML—create a small shell helper like
escape_html() that replaces &, <, >, ", and ' (e.g. using printf '%s' "$1" | sed
-e 's/&/\&/g' -e 's/</\</g' -e 's/>/\>/g' -e 's/"/\"/g' -e
"s/'/\'/g"), call it before the heredoc to produce safe variables
(escaped_title="$(escape_html "$title")", escaped_author=...,
escaped_repo="$(escape_html "$repo_name")", escaped_pr_url="$(escape_html
"$pr_url")", escaped_num="$(escape_html "$num")"), and use those escaped_*
variables inside the here-doc to prevent HTML injection/XSS.
- Around line 176-183: Heredocs using single-quoted delimiters (e.g.,
<<'HTMLEOF' and <<'EOF') prevent shell variable and command expansion so
${LABEL}, ${PERIOD}, ${SINCE_UTC}, ${UNTIL_UTC}, @${author}, ${repo_name},
${pr_url}, ${num}, and $(date ...) are written literally; remove the single
quotes from the heredoc delimiters (change <<'HTMLEOF' -> <<HTMLEOF and <<'EOF'
-> <<EOF) for the heredoc blocks that produce the HTML (delimiters named HTMLEOF
and EOF at the locations referenced) so the variables and command substitutions
are expanded when the file is written.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 87fb8eb7-d04b-4deb-b64c-052c52c49cec
📒 Files selected for processing (1)
.github/workflows/reporting-release-summary.yml
| cat > out/digest.html <<'HTMLEOF' | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>${LABEL} - Armbian PR Digest</title> | ||
| <style> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find the file and check its size
wc -l .github/workflows/reporting-release-summary.ymlRepository: armbian/armbian.github.io
Length of output: 120
🏁 Script executed:
# Read lines 176-183 (first mentioned range)
sed -n '176,183p' .github/workflows/reporting-release-summary.ymlRepository: armbian/armbian.github.io
Length of output: 384
🏁 Script executed:
# Read lines 367-373 (second mentioned range)
sed -n '367,373p' .github/workflows/reporting-release-summary.ymlRepository: armbian/armbian.github.io
Length of output: 483
🏁 Script executed:
# Read lines 426-436 (third mentioned range)
sed -n '426,436p' .github/workflows/reporting-release-summary.ymlRepository: armbian/armbian.github.io
Length of output: 711
🏁 Script executed:
# Check the closing delimiters for both heredocs
sed -n '420,428p' .github/workflows/reporting-release-summary.ymlRepository: armbian/armbian.github.io
Length of output: 365
🏁 Script executed:
# Check where HTMLEOF closes
grep -n "^HTMLEOF" .github/workflows/reporting-release-summary.ymlRepository: armbian/armbian.github.io
Length of output: 51
🏁 Script executed:
# Check where EOF closes
grep -n "^EOF" .github/workflows/reporting-release-summary.ymlRepository: armbian/armbian.github.io
Length of output: 51
🏁 Script executed:
# Search for closing delimiters without anchoring to line start (may have whitespace)
grep -n "HTMLEOF" .github/workflows/reporting-release-summary.ymlRepository: armbian/armbian.github.io
Length of output: 160
🏁 Script executed:
# Find where the second heredoc ends
sed -n '426,440p' .github/workflows/reporting-release-summary.yml | cat -nRepository: armbian/armbian.github.io
Length of output: 901
🏁 Script executed:
# Get broader context around line 426
sed -n '410,445p' .github/workflows/reporting-release-summary.yml | cat -nRepository: armbian/armbian.github.io
Length of output: 1768
Remove quotes from heredoc delimiters to enable variable and command expansion.
Lines 176, 426 use single-quoted heredocs (<<'HTMLEOF' and <<'EOF'), which suppress expansion of ${LABEL}, ${PERIOD}, ${SINCE_UTC}, ${UNTIL_UTC}, @${author}, ${repo_name}, ${pr_url}, ${num}, and $(date ...). These will be written literally to the HTML output instead of being evaluated.
Suggested fix
- cat > out/digest.html <<'HTMLEOF'
+ cat > out/digest.html <<HTMLEOF- cat >> out/digest.html <<'EOF'
+ cat >> out/digest.html <<EOFAlso applies to: 367-373, 426-436
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/reporting-release-summary.yml around lines 176 - 183,
Heredocs using single-quoted delimiters (e.g., <<'HTMLEOF' and <<'EOF') prevent
shell variable and command expansion so ${LABEL}, ${PERIOD}, ${SINCE_UTC},
${UNTIL_UTC}, @${author}, ${repo_name}, ${pr_url}, ${num}, and $(date ...) are
written literally; remove the single quotes from the heredoc delimiters (change
<<'HTMLEOF' -> <<HTMLEOF and <<'EOF' -> <<EOF) for the heredoc blocks that
produce the HTML (delimiters named HTMLEOF and EOF at the locations referenced)
so the variables and command substitutions are expanded when the file is
written.
| while IFS=$'\t' read -r title author repo num pr_url; do | ||
| repo_name="${repo##*/}" | ||
| cat >> out/digest.html <<EOF | ||
| <tr> | ||
| <td> | ||
| <div class="pr-title">${title}</div> | ||
| <div class="pr-meta"> | ||
| <span class="badge badge-repo">${repo_name}</span> | ||
| </div> | ||
| </td> | ||
| <td><span class="badge badge-author">@${author}</span></td> | ||
| <td>${repo_name}</td> | ||
| <td><a class="pr-link" href="${pr_url}" target="_blank">View PR #${num}</a></td> | ||
| </tr> |
There was a problem hiding this comment.
Escape TSV fields before injecting into HTML.
title, author, and repo values are inserted raw into HTML. Please HTML-escape these fields before rendering to avoid markup injection/XSS in the artifact.
🔒 Suggested fix
+ html_escape() {
+ sed -e 's/&/\&/g' \
+ -e 's/</\</g' \
+ -e 's/>/\>/g' \
+ -e 's/"/\"/g' \
+ -e "s/'/\'/g"
+ }
...
while IFS=$'\t' read -r title author repo num pr_url; do
repo_name="${repo##*/}"
+ title_esc="$(printf '%s' "$title" | html_escape)"
+ author_esc="$(printf '%s' "$author" | html_escape)"
+ repo_name_esc="$(printf '%s' "$repo_name" | html_escape)"
cat >> out/digest.html <<EOF
<tr>
<td>
- <div class="pr-title">${title}</div>
+ <div class="pr-title">${title_esc}</div>
<div class="pr-meta">
- <span class="badge badge-repo">${repo_name}</span>
+ <span class="badge badge-repo">${repo_name_esc}</span>
</div>
</td>
- <td><span class="badge badge-author">@${author}</span></td>
- <td>${repo_name}</td>
+ <td><span class="badge badge-author">@${author_esc}</span></td>
+ <td>${repo_name_esc}</td>
<td><a class="pr-link" href="${pr_url}" target="_blank">View PR #${num}</a></td>
</tr>
EOF
done < out/pr-digest.tsv📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| while IFS=$'\t' read -r title author repo num pr_url; do | |
| repo_name="${repo##*/}" | |
| cat >> out/digest.html <<EOF | |
| <tr> | |
| <td> | |
| <div class="pr-title">${title}</div> | |
| <div class="pr-meta"> | |
| <span class="badge badge-repo">${repo_name}</span> | |
| </div> | |
| </td> | |
| <td><span class="badge badge-author">@${author}</span></td> | |
| <td>${repo_name}</td> | |
| <td><a class="pr-link" href="${pr_url}" target="_blank">View PR #${num}</a></td> | |
| </tr> | |
| html_escape() { | |
| sed -e 's/&/\&/g' \ | |
| -e 's/</\</g' \ | |
| -e 's/>/\>/g' \ | |
| -e 's/"/\"/g' \ | |
| -e "s/'/\'/g" | |
| } | |
| while IFS=$'\t' read -r title author repo num pr_url; do | |
| repo_name="${repo##*/}" | |
| title_esc="$(printf '%s' "$title" | html_escape)" | |
| author_esc="$(printf '%s' "$author" | html_escape)" | |
| repo_name_esc="$(printf '%s' "$repo_name" | html_escape)" | |
| cat >> out/digest.html <<EOF | |
| <tr> | |
| <td> | |
| <div class="pr-title">${title_esc}</div> | |
| <div class="pr-meta"> | |
| <span class="badge badge-repo">${repo_name_esc}</span> | |
| </div> | |
| </td> | |
| <td><span class="badge badge-author">@${author_esc}</span></td> | |
| <td>${repo_name_esc}</td> | |
| <td><a class="pr-link" href="${pr_url}" target="_blank">View PR #${num}</a></td> | |
| </tr> | |
| EOF | |
| done < out/pr-digest.tsv |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/reporting-release-summary.yml around lines 402 - 415, The
loop injects unescaped TSV fields (title, author, repo_name, pr_url, num)
directly into HTML—create a small shell helper like escape_html() that replaces
&, <, >, ", and ' (e.g. using printf '%s' "$1" | sed -e 's/&/\&/g' -e
's/</\</g' -e 's/>/\>/g' -e 's/"/\"/g' -e "s/'/\'/g"), call it
before the heredoc to produce safe variables (escaped_title="$(escape_html
"$title")", escaped_author=..., escaped_repo="$(escape_html "$repo_name")",
escaped_pr_url="$(escape_html "$pr_url")", escaped_num="$(escape_html "$num")"),
and use those escaped_* variables inside the here-doc to prevent HTML
injection/XSS.
| </td> | ||
| <td><span class="badge badge-author">@${author}</span></td> | ||
| <td>${repo_name}</td> | ||
| <td><a class="pr-link" href="${pr_url}" target="_blank">View PR #${num}</a></td> |
There was a problem hiding this comment.
Harden external links opened in new tabs.
For target="_blank" links, add rel="noopener noreferrer".
💡 Suggested fix
- <td><a class="pr-link" href="${pr_url}" target="_blank">View PR #${num}</a></td>
+ <td><a class="pr-link" href="${pr_url}" target="_blank" rel="noopener noreferrer">View PR #${num}</a></td>
...
- <a class="footer-link" href="https://blog.armbian.com/#/portal/signup" target="_blank">
+ <a class="footer-link" href="https://blog.armbian.com/#/portal/signup" target="_blank" rel="noopener noreferrer">Also applies to: 428-428
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/reporting-release-summary.yml at line 414, The anchor
element with class "pr-link" using target="_blank" should be hardened by adding
rel="noopener noreferrer"; locate the <a class="pr-link" href="${pr_url}"
target="_blank">View PR #${num}</a> occurrences (also the similar occurrence at
the other location) and add rel="noopener noreferrer" to the tag so external
links opened in new tabs do not expose window.opener.
Summary
out/digest.htmlartifact with modern dark theme designTest plan