From 518fccf557344c0098b55805dd19b2fe8bdd6701 Mon Sep 17 00:00:00 2001 From: Larry Chen Date: Wed, 28 Jan 2026 10:36:25 +0800 Subject: [PATCH 1/3] feat: trufflehog update existing comment in PR --- .github/actions/trufflehog-scan/action.yml | 63 +++++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/.github/actions/trufflehog-scan/action.yml b/.github/actions/trufflehog-scan/action.yml index 80f919b..69d809d 100644 --- a/.github/actions/trufflehog-scan/action.yml +++ b/.github/actions/trufflehog-scan/action.yml @@ -87,6 +87,9 @@ runs: if: inputs.post-pr-comment == 'true' && always() shell: bash run: | + # Marker for finding/updating existing comment + COMMENT_MARKER="" + # Determine if we're in a PR context PR_NUMBER="" if [ "${{ github.event_name }}" = "pull_request" ]; then @@ -143,14 +146,18 @@ runs: fi if [ "$SCAN_STATUS" == "clean" ]; then - REPORT="## 🔐 TruffleHog Secret Scan + REPORT="${COMMENT_MARKER} + ## 🔐 TruffleHog Secret Scan ✅ **No secrets or credentials found!** Your code has been scanned for 700+ types of secrets and credentials. All clear! 🎉 - 🔗 [View scan details]($JOB_URL)" + 🔗 [View scan details]($JOB_URL) + + 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${{ github.sha }}" elif [ "$SCAN_STATUS" == "detected" ]; then - REPORT="## 🔐 TruffleHog Secret Scan + REPORT="${COMMENT_MARKER} + ## 🔐 TruffleHog Secret Scan 🚨 **Potential secrets detected!** TruffleHog found potential secrets in your code changes. This could include: @@ -184,18 +191,60 @@ runs: - GitHub Secrets for CI/CD workflows - \`.env\` files (added to \`.gitignore\`) - 📖 [Learn more about TruffleHog](https://github.com/trufflesecurity/trufflehog)" + 📖 [Learn more about TruffleHog](https://github.com/trufflesecurity/trufflehog) + + 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${{ github.sha }}" else # Unknown status or error - REPORT="## 🔐 TruffleHog Secret Scan + REPORT="${COMMENT_MARKER} + ## 🔐 TruffleHog Secret Scan ⚠️ **Scan completed with warnings** The secret scan finished, but the status is unclear. Please review the logs for details. - 🔗 [View scan details]($JOB_URL)" + 🔗 [View scan details]($JOB_URL) + + 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${{ github.sha }}" + fi + + # Find existing comment from github-actions[bot] with our marker + EXISTING_COMMENT=$(gh api "/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \ + --jq '.[] | select(.user.login == "github-actions[bot]") | select(.body | contains("")) | {id, body}' \ + 2>/dev/null | head -1 || echo "") + + EXISTING_COMMENT_ID="" + PREVIOUS_STATUS="" + if [ -n "$EXISTING_COMMENT" ]; then + EXISTING_COMMENT_ID=$(echo "$EXISTING_COMMENT" | jq -r '.id' 2>/dev/null || echo "") + EXISTING_BODY=$(echo "$EXISTING_COMMENT" | jq -r '.body' 2>/dev/null || echo "") + + # Parse previous status from existing comment body + if echo "$EXISTING_BODY" | grep -q "No secrets or credentials found"; then + PREVIOUS_STATUS="clean" + elif echo "$EXISTING_BODY" | grep -q "Potential secrets detected"; then + PREVIOUS_STATUS="detected" + elif echo "$EXISTING_BODY" | grep -q "Scan completed with warnings"; then + PREVIOUS_STATUS="warning" + else + PREVIOUS_STATUS="unknown" + fi + echo "📊 Previous status: $PREVIOUS_STATUS | Current status: $SCAN_STATUS" fi - echo -e "$REPORT" | gh pr comment "$PR_NUMBER" --body-file=- + # Decide whether to update/create comment + if [ -n "$EXISTING_COMMENT_ID" ]; then + if [ "$PREVIOUS_STATUS" == "$SCAN_STATUS" ]; then + echo "⏭️ Status unchanged ($SCAN_STATUS), skipping comment update" + else + echo "📝 Status changed ($PREVIOUS_STATUS → $SCAN_STATUS), updating comment (ID: $EXISTING_COMMENT_ID)" + echo -e "$REPORT" | gh api "/repos/${{ github.repository }}/issues/comments/${EXISTING_COMMENT_ID}" \ + --method PATCH \ + --field body=@- + fi + else + echo "📝 Creating new comment (status: $SCAN_STATUS)" + echo -e "$REPORT" | gh pr comment "$PR_NUMBER" --body-file=- + fi env: GH_TOKEN: ${{ inputs.github-token }} From 72b04a68b982184854874c4e1512a754cadc8788 Mon Sep 17 00:00:00 2001 From: Larry Chen Date: Wed, 28 Jan 2026 11:15:48 +0800 Subject: [PATCH 2/3] feat: trufflehog update existing comment in PR, fix commit --- .github/actions/trufflehog-scan/action.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/actions/trufflehog-scan/action.yml b/.github/actions/trufflehog-scan/action.yml index 69d809d..dd963f5 100644 --- a/.github/actions/trufflehog-scan/action.yml +++ b/.github/actions/trufflehog-scan/action.yml @@ -145,6 +145,14 @@ runs: JOB_URL="$WORKFLOW_URL" fi + # Use the correct commit SHA (PR head commit for pull_request event, otherwise github.sha) + if [ "${{ github.event_name }}" = "pull_request" ]; then + COMMIT_SHA="${{ github.event.pull_request.head.sha }}" + else + COMMIT_SHA="${{ github.sha }}" + fi + SHORT_SHA="${COMMIT_SHA:0:7}" + if [ "$SCAN_STATUS" == "clean" ]; then REPORT="${COMMENT_MARKER} ## 🔐 TruffleHog Secret Scan @@ -154,7 +162,7 @@ runs: 🔗 [View scan details]($JOB_URL) - 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${{ github.sha }}" + 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${SHORT_SHA}" elif [ "$SCAN_STATUS" == "detected" ]; then REPORT="${COMMENT_MARKER} ## 🔐 TruffleHog Secret Scan @@ -193,7 +201,7 @@ runs: 📖 [Learn more about TruffleHog](https://github.com/trufflesecurity/trufflehog) - 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${{ github.sha }}" + 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${SHORT_SHA}" else # Unknown status or error REPORT="${COMMENT_MARKER} @@ -204,7 +212,7 @@ runs: 🔗 [View scan details]($JOB_URL) - 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${{ github.sha }}" + 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${SHORT_SHA}" fi # Find existing comment from github-actions[bot] with our marker From dfa35d9839f925b0a23e7d4815d1795185afdce8 Mon Sep 17 00:00:00 2001 From: Larry Chen Date: Wed, 28 Jan 2026 11:54:28 +0800 Subject: [PATCH 3/3] feat: trivy and codeql update existing comment in PR --- .github/actions/codeql-scan/action.yml | 69 ++++++++++++++++++++++++-- .github/actions/trivy-scan/action.yml | 69 ++++++++++++++++++++++++-- 2 files changed, 128 insertions(+), 10 deletions(-) diff --git a/.github/actions/codeql-scan/action.yml b/.github/actions/codeql-scan/action.yml index 06f3bd6..3c860b4 100644 --- a/.github/actions/codeql-scan/action.yml +++ b/.github/actions/codeql-scan/action.yml @@ -87,6 +87,9 @@ runs: if: inputs.post-pr-comment == 'true' shell: bash run: | + # Marker for finding/updating existing comment + COMMENT_MARKER="" + # Determine if we're in a PR context PR_NUMBER="" if [ "${{ github.event_name }}" = "pull_request" ]; then @@ -125,6 +128,21 @@ runs: # Parse SARIF for issue count and details TOTAL_ISSUES=$(jq '[.runs[].results // []] | add | length' "$SARIF_FILE" 2>/dev/null || echo "0") + # Determine current status + if [ "$TOTAL_ISSUES" -eq 0 ]; then + CURRENT_STATUS="clean" + else + CURRENT_STATUS="issues_found" + fi + + # Use the correct commit SHA (PR head commit for pull_request event, otherwise github.sha) + if [ "${{ github.event_name }}" = "pull_request" ]; then + COMMIT_SHA="${{ github.event.pull_request.head.sha }}" + else + COMMIT_SHA="${{ github.sha }}" + fi + SHORT_SHA="${COMMIT_SHA:0:7}" + # Determine footer message based on upload-sarif setting if [ "${{ inputs.upload-sarif }}" = "true" ]; then FOOTER="🔗 [View full details in Security tab](https://github.com/${{ github.repository }}/security/code-scanning)" @@ -133,17 +151,21 @@ runs: fi if [ "$TOTAL_ISSUES" -eq 0 ]; then - REPORT="## 🛡️ CodeQL Analysis + REPORT="${COMMENT_MARKER} + ## 🛡️ CodeQL Analysis ✅ No security issues found! - $FOOTER" + $FOOTER + + 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${SHORT_SHA}" else # Get severity breakdown ERRORS=$(jq '[.runs[].results // [] | .[] | select(.level == "error")] | length' "$SARIF_FILE" 2>/dev/null || echo "0") WARNINGS=$(jq '[.runs[].results // [] | .[] | select(.level == "warning")] | length' "$SARIF_FILE" 2>/dev/null || echo "0") NOTES=$(jq '[.runs[].results // [] | .[] | select(.level == "note")] | length' "$SARIF_FILE" 2>/dev/null || echo "0") - REPORT="## 🛡️ CodeQL Analysis + REPORT="${COMMENT_MARKER} + ## 🛡️ CodeQL Analysis 🚨 Found **$TOTAL_ISSUES** issue(s) **Severity Breakdown:** @@ -158,10 +180,47 @@ runs: - $FOOTER" + $FOOTER + + 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${SHORT_SHA}" fi - echo -e "$REPORT" | gh pr comment "$PR_NUMBER" --body-file=- + # Find existing comment from github-actions[bot] with our marker + EXISTING_COMMENT=$(gh api "/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \ + --jq '.[] | select(.user.login == "github-actions[bot]") | select(.body | contains("")) | {id, body}' \ + 2>/dev/null | head -1 || echo "") + + EXISTING_COMMENT_ID="" + PREVIOUS_STATUS="" + if [ -n "$EXISTING_COMMENT" ]; then + EXISTING_COMMENT_ID=$(echo "$EXISTING_COMMENT" | jq -r '.id' 2>/dev/null || echo "") + EXISTING_BODY=$(echo "$EXISTING_COMMENT" | jq -r '.body' 2>/dev/null || echo "") + + # Parse previous status from existing comment body + if echo "$EXISTING_BODY" | grep -q "No security issues found"; then + PREVIOUS_STATUS="clean" + elif echo "$EXISTING_BODY" | grep -q "Found \*\*"; then + PREVIOUS_STATUS="issues_found" + else + PREVIOUS_STATUS="unknown" + fi + echo "📊 Previous status: $PREVIOUS_STATUS | Current status: $CURRENT_STATUS" + fi + + # Decide whether to update/create comment + if [ -n "$EXISTING_COMMENT_ID" ]; then + if [ "$PREVIOUS_STATUS" == "$CURRENT_STATUS" ]; then + echo "⏭️ Status unchanged ($CURRENT_STATUS), skipping comment update" + else + echo "📝 Status changed ($PREVIOUS_STATUS → $CURRENT_STATUS), updating comment (ID: $EXISTING_COMMENT_ID)" + echo -e "$REPORT" | gh api "/repos/${{ github.repository }}/issues/comments/${EXISTING_COMMENT_ID}" \ + --method PATCH \ + --field body=@- + fi + else + echo "📝 Creating new comment (status: $CURRENT_STATUS)" + echo -e "$REPORT" | gh pr comment "$PR_NUMBER" --body-file=- + fi env: GH_TOKEN: ${{ inputs.github-token }} diff --git a/.github/actions/trivy-scan/action.yml b/.github/actions/trivy-scan/action.yml index ecabb72..a73ef67 100644 --- a/.github/actions/trivy-scan/action.yml +++ b/.github/actions/trivy-scan/action.yml @@ -100,6 +100,9 @@ runs: if: inputs.post-pr-comment == 'true' && steps.check_sarif.outputs.exists == 'true' shell: bash run: | + # Marker for finding/updating existing comment + COMMENT_MARKER="" + # Determine if we're in a PR context PR_NUMBER="" if [ "${{ github.event_name }}" = "pull_request" ]; then @@ -121,6 +124,21 @@ runs: # Parse SARIF for issue count and details TOTAL_ISSUES=$(jq '[.runs[].results // []] | add | length' "$SARIF_FILE" 2>/dev/null || echo "0") + # Determine current status + if [ "$TOTAL_ISSUES" -eq 0 ]; then + CURRENT_STATUS="clean" + else + CURRENT_STATUS="issues_found" + fi + + # Use the correct commit SHA (PR head commit for pull_request event, otherwise github.sha) + if [ "${{ github.event_name }}" = "pull_request" ]; then + COMMIT_SHA="${{ github.event.pull_request.head.sha }}" + else + COMMIT_SHA="${{ github.sha }}" + fi + SHORT_SHA="${COMMIT_SHA:0:7}" + # Determine footer message based on upload-sarif setting if [ "${{ inputs.upload-sarif }}" = "true" ]; then FOOTER="🔗 [View full details in Security tab](https://github.com/${{ github.repository }}/security/code-scanning)" @@ -129,17 +147,21 @@ runs: fi if [ "$TOTAL_ISSUES" -eq 0 ]; then - REPORT="## 🛡️ Vulnerability Scan + REPORT="${COMMENT_MARKER} + ## 🛡️ Vulnerability Scan ✅ No vulnerabilities found! - $FOOTER" + $FOOTER + + 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${SHORT_SHA}" else # Get severity breakdown CRITICAL=$(jq '[.runs[].results // [] | .[] | select(.level == "error")] | length' "$SARIF_FILE" 2>/dev/null || echo "0") HIGH=$(jq '[.runs[].results // [] | .[] | select(.level == "warning")] | length' "$SARIF_FILE" 2>/dev/null || echo "0") MEDIUM=$(jq '[.runs[].results // [] | .[] | select(.level == "note")] | length' "$SARIF_FILE" 2>/dev/null || echo "0") - REPORT="## 🛡️ Vulnerability Scan + REPORT="${COMMENT_MARKER} + ## 🛡️ Vulnerability Scan 🚨 Found **$TOTAL_ISSUES** vulnerability(ies) **Severity Breakdown:** @@ -154,10 +176,47 @@ runs: - $FOOTER" + $FOOTER + + 🕐 Last updated: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: ${SHORT_SHA}" + fi + + # Find existing comment from github-actions[bot] with our marker + EXISTING_COMMENT=$(gh api "/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \ + --jq '.[] | select(.user.login == "github-actions[bot]") | select(.body | contains("")) | {id, body}' \ + 2>/dev/null | head -1 || echo "") + + EXISTING_COMMENT_ID="" + PREVIOUS_STATUS="" + if [ -n "$EXISTING_COMMENT" ]; then + EXISTING_COMMENT_ID=$(echo "$EXISTING_COMMENT" | jq -r '.id' 2>/dev/null || echo "") + EXISTING_BODY=$(echo "$EXISTING_COMMENT" | jq -r '.body' 2>/dev/null || echo "") + + # Parse previous status from existing comment body + if echo "$EXISTING_BODY" | grep -q "No vulnerabilities found"; then + PREVIOUS_STATUS="clean" + elif echo "$EXISTING_BODY" | grep -q "Found \*\*"; then + PREVIOUS_STATUS="issues_found" + else + PREVIOUS_STATUS="unknown" + fi + echo "📊 Previous status: $PREVIOUS_STATUS | Current status: $CURRENT_STATUS" fi - echo -e "$REPORT" | gh pr comment "$PR_NUMBER" --body-file=- + # Decide whether to update/create comment + if [ -n "$EXISTING_COMMENT_ID" ]; then + if [ "$PREVIOUS_STATUS" == "$CURRENT_STATUS" ]; then + echo "⏭️ Status unchanged ($CURRENT_STATUS), skipping comment update" + else + echo "📝 Status changed ($PREVIOUS_STATUS → $CURRENT_STATUS), updating comment (ID: $EXISTING_COMMENT_ID)" + echo -e "$REPORT" | gh api "/repos/${{ github.repository }}/issues/comments/${EXISTING_COMMENT_ID}" \ + --method PATCH \ + --field body=@- + fi + else + echo "📝 Creating new comment (status: $CURRENT_STATUS)" + echo -e "$REPORT" | gh pr comment "$PR_NUMBER" --body-file=- + fi env: GH_TOKEN: ${{ inputs.github-token }}