From 73d5888e61adbba094ca4841b545708411e6bce3 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 08:49:41 +0200 Subject: [PATCH 01/12] Refactor GitHub Actions workflow for entropy scan Step 1 --- .github/workflows/entropy-beauty-scan.yml | 95 +++++------------------ 1 file changed, 20 insertions(+), 75 deletions(-) diff --git a/.github/workflows/entropy-beauty-scan.yml b/.github/workflows/entropy-beauty-scan.yml index 0c9056bdca..ebf7eb580a 100644 --- a/.github/workflows/entropy-beauty-scan.yml +++ b/.github/workflows/entropy-beauty-scan.yml @@ -1,11 +1,13 @@ name: Entropy Beauty + TruffleHog Scan -on: [push, release, pull_request_target] +on: + push: + release: + pull_request: permissions: - contents: read - pull-requests: write - issues: write # must be at workflow level for push/merge events + contents: read # minimal for analysis + # no write permissions here jobs: scan: @@ -14,37 +16,20 @@ jobs: - name: Checkout code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.sha }} - fetch-depth: ${{ github.event_name == 'pull_request_target' && 1 || 2 }} - allow-unsafe-pr-checkout: ${{ github.event_name == 'pull_request_target' }} - - - name: Fetch PR base commit (needed for accurate diff) - if: github.event_name == 'pull_request_target' - run: git fetch origin ${{ github.event.pull_request.base.sha }} --depth=1 - - - name: Cache pip manually - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-entropy-${{ hashFiles('.github/workflows/compute-entropy.py') }} - restore-keys: | - ${{ runner.os }}-pip-entropy- + # For pull_request this is the PR head – safe because we have no write token + fetch-depth: 0 # or 2 if you prefer - name: Setup Python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.12' - - name: Install Python dependencies (only when needed) - run: | - python -m pip install --upgrade pip - # No extra packages needed — compute-entropy.py uses only stdlib - - name: Run TruffleHog uses: trufflesecurity/trufflehog@6f3c981e7b77f235fd2702dd74af25fc4b72bf11 # v3.96.0 with: path: . extra_args: --results=verified,unknown --filter-entropy=3.5 --json + # Optional: continue-on-error: true if you don't want the job to fail on findings - name: Compute mid-4 beauty entropy env: @@ -53,63 +38,25 @@ jobs: HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} run: python .github/workflows/compute-entropy.py - - name: Post summary comment (PR only) - if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target' - uses: actions/github-script@v9 + - name: Upload scan results + uses: actions/upload-artifact@v4 with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const fs = require('fs'); - - // Read TruffleHog output — it prints one JSON object per line (NDJSON) - let findings = []; - if (fs.existsSync('trufflehog.json')) { - try { - const lines = fs.readFileSync('trufflehog.json', 'utf8').trim().split('\n'); - findings = lines.map(line => { - try { return JSON.parse(line); } catch(e) { return null; } - }).filter(Boolean); - } catch(e) {} - } else { - console.log("No trufflehog.json found, using empty findings"); - } + name: scan-results + path: | + /tmp/beauty.json + trufflehog.json # if TruffleHog wrote it; adjust if needed + retention-days: 1 - const beauty = JSON.parse(fs.readFileSync('/tmp/beauty.json', 'utf8')); - - let body = `## 🐷 TruffleHog + Entropy Beauty Scan\n\n`; - body += `**Average entropy of changed code:** ${beauty.average_entropy} bits/char\n`; - body += `**Verdict:** ${beauty.verdict}\n\n`; - - if (beauty.files && beauty.files.length) { - body += `**Changed files entropy:**\n\`\`\`\n${beauty.files.join('\n')}\n\`\`\`\n\n`; - } - - if (findings.length > 0) { - body += `⚠️ **TruffleHog found ${findings.length} potential issue(s)**\n`; - } else { - body += `✅ No secrets or suspicious high-entropy strings found.\n`; - } - - body += `\n*Mid-4 beauty heuristic in action — powered by our entropy chats! 😊*`; - - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body: body - }); - - # ── Create issue on push ONLY if suspicious (entropy outside 4.3–5.1) ── + # ── Create issue on push/release (trusted events) ── - name: Create issue on suspicious push if: github.event_name == 'push' || github.event_name == 'release' - uses: actions/github-script@v9 + uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs'); const beauty = JSON.parse(fs.readFileSync('/tmp/beauty.json', 'utf8')); - // Only create issue if it's NOT beautiful mid-4 if (beauty.average_entropy >= 4.3 && beauty.average_entropy <= 5.1) { console.log("✅ Mid-4 beauty — no issue created"); return; @@ -138,14 +85,12 @@ jobs: body += `✅ No secrets or suspicious high-entropy strings found.\n`; } - body += `\n*Triggered by push to \`${context.sha}\` — mid-4 beauty heuristic*`; + body += `\n*Triggered by ${context.eventName} to \`${context.sha}\` — mid-4 beauty heuristic*`; await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, - title: `🚨 Suspicious entropy detected in recent push (${beauty.average_entropy})`, + title: `🚨 Suspicious entropy detected in recent ${context.eventName} (${beauty.average_entropy})`, body: body, labels: ['entropy', 'security', 'review-needed'] }); - - console.log("⚠️ Created issue because entropy was outside mid-4 range"); From da18d911a9f9f659d6177a76940041c80f4790fe Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 08:50:59 +0200 Subject: [PATCH 02/12] Add GitHub Actions workflow for entropy beauty comments part 2 --- .github/workflows/entropy-beauty-comment.yml | 79 ++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .github/workflows/entropy-beauty-comment.yml diff --git a/.github/workflows/entropy-beauty-comment.yml b/.github/workflows/entropy-beauty-comment.yml new file mode 100644 index 0000000000..a9d9d0ce3c --- /dev/null +++ b/.github/workflows/entropy-beauty-comment.yml @@ -0,0 +1,79 @@ +name: Post Entropy Beauty Comment + +on: + workflow_run: + workflows: ["Entropy Beauty + TruffleHog Scan"] + types: + - completed + +permissions: + contents: read + pull-requests: write + issues: write + +jobs: + comment: + # Only for successful PR runs + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-latest + steps: + - name: Download scan results + uses: actions/download-artifact@v4 + with: + name: scan-results + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + path: results + + - name: Post summary comment + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + const path = require('path'); + + const beauty = JSON.parse(fs.readFileSync(path.join('results', 'beauty.json'), 'utf8')); + + let findings = []; + const thPath = path.join('results', 'trufflehog.json'); + if (fs.existsSync(thPath)) { + try { + const lines = fs.readFileSync(thPath, 'utf8').trim().split('\n'); + findings = lines.map(line => { + try { return JSON.parse(line); } catch(e) { return null; } + }).filter(Boolean); + } catch(e) {} + } + + let body = `## 🐷 TruffleHog + Entropy Beauty Scan\n\n`; + body += `**Average entropy of changed code:** ${beauty.average_entropy} bits/char\n`; + body += `**Verdict:** ${beauty.verdict}\n\n`; + + if (beauty.files && beauty.files.length) { + body += `**Changed files entropy:**\n\`\`\`\n${beauty.files.join('\n')}\n\`\`\`\n\n`; + } + + if (findings.length > 0) { + body += `⚠️ **TruffleHog found ${findings.length} potential issue(s)**\n`; + } else { + body += `✅ No secrets or suspicious high-entropy strings found.\n`; + } + + body += `\n*Mid-4 beauty heuristic in action — powered by our entropy chats! 😊*`; + + // Get the PR number from the workflow_run payload + const pr = github.event.workflow_run.pull_requests[0]; + if (!pr) { + console.log("No associated PR found"); + return; + } + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: body + }); From f76256289b9296671354bd3f22877499facaca50 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 08:52:07 +0200 Subject: [PATCH 03/12] Update event name check for pull request handling part 3 --- .github/workflows/compute-entropy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/compute-entropy.py b/.github/workflows/compute-entropy.py index 44a11770a7..9abe8bb9a1 100644 --- a/.github/workflows/compute-entropy.py +++ b/.github/workflows/compute-entropy.py @@ -21,7 +21,7 @@ def shannon_entropy(text: str) -> float: head_sha = os.environ.get("HEAD_SHA", "").strip() or "HEAD" try: - if event_name == "pull_request_target" and base_sha: + if event_name in ("pull_request", "pull_request_target") and base_sha: # PR case: we checked out the PR head and fetched the base commit changed_files = subprocess.check_output( ["git", "diff", "--name-only", base_sha, head_sha], @@ -78,4 +78,4 @@ def shannon_entropy(text: str) -> float: }, f, indent=2) print(f"Average entropy: {avg}") -print(verdict) \ No newline at end of file +print(verdict) From 2fa7901bcafe7b8c31b8fdcee6cbd4272f6121cb Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 08:59:18 +0200 Subject: [PATCH 04/12] Update persist-credentials setting in workflow --- .github/workflows/entropy-beauty-scan.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/entropy-beauty-scan.yml b/.github/workflows/entropy-beauty-scan.yml index ebf7eb580a..ead7498b39 100644 --- a/.github/workflows/entropy-beauty-scan.yml +++ b/.github/workflows/entropy-beauty-scan.yml @@ -18,6 +18,7 @@ jobs: with: # For pull_request this is the PR head – safe because we have no write token fetch-depth: 0 # or 2 if you prefer + persist-credentials: false - name: Setup Python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 From 0342ee7bc5a74b3cd7c7aa9bc4181630fda84489 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 09:01:34 +0200 Subject: [PATCH 05/12] Update github-script action version in workflow --- .github/workflows/entropy-beauty-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/entropy-beauty-scan.yml b/.github/workflows/entropy-beauty-scan.yml index ead7498b39..099ce34ab0 100644 --- a/.github/workflows/entropy-beauty-scan.yml +++ b/.github/workflows/entropy-beauty-scan.yml @@ -51,7 +51,7 @@ jobs: # ── Create issue on push/release (trusted events) ── - name: Create issue on suspicious push if: github.event_name == 'push' || github.event_name == 'release' - uses: actions/github-script@v7 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | From 735bc8fabee23a415d0402b0efb8f2fd14d8cd0e Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 09:02:42 +0200 Subject: [PATCH 06/12] Update entropy-beauty-comment.yml --- .github/workflows/entropy-beauty-comment.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/entropy-beauty-comment.yml b/.github/workflows/entropy-beauty-comment.yml index a9d9d0ce3c..8281262dd6 100644 --- a/.github/workflows/entropy-beauty-comment.yml +++ b/.github/workflows/entropy-beauty-comment.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download scan results - uses: actions/download-artifact@v4 + uses: actions/download-artifact@fa0a91b85d4f404e444e005971372dc801d16 # v4.1.8 with: name: scan-results run-id: ${{ github.event.workflow_run.id }} @@ -28,7 +28,7 @@ jobs: path: results - name: Post summary comment - uses: actions/github-script@v7 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | From 669482aaa721c087ae231a700771fbe275835b71 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 09:06:49 +0200 Subject: [PATCH 07/12] Update upload-artifact action version in workflow --- .github/workflows/entropy-beauty-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/entropy-beauty-scan.yml b/.github/workflows/entropy-beauty-scan.yml index 099ce34ab0..18854b8fb2 100644 --- a/.github/workflows/entropy-beauty-scan.yml +++ b/.github/workflows/entropy-beauty-scan.yml @@ -40,7 +40,7 @@ jobs: run: python .github/workflows/compute-entropy.py - name: Upload scan results - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v4.3.0 with: name: scan-results path: | From d41fd17517c0aec9c3da939d7e347260678ccbec Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 09:15:37 +0200 Subject: [PATCH 08/12] Update TruffleHog integration in workflow Replaced TruffleHog action with a Docker command to run it. Redirect output to be not leak secrets. --- .github/workflows/entropy-beauty-scan.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/entropy-beauty-scan.yml b/.github/workflows/entropy-beauty-scan.yml index 18854b8fb2..a1dc497e6d 100644 --- a/.github/workflows/entropy-beauty-scan.yml +++ b/.github/workflows/entropy-beauty-scan.yml @@ -26,11 +26,16 @@ jobs: python-version: '3.12' - name: Run TruffleHog - uses: trufflesecurity/trufflehog@6f3c981e7b77f235fd2702dd74af25fc4b72bf11 # v3.96.0 - with: - path: . - extra_args: --results=verified,unknown --filter-entropy=3.5 --json - # Optional: continue-on-error: true if you don't want the job to fail on findings + run: | + docker run --rm \ + -v "$PWD:/pwd" \ + trufflesecurity/trufflehog:3.96.0 \ + git file:///pwd \ + --results=verified,unknown \ + --filter-entropy=3.5 \ + --json \ + --no-update \ + > trufflehog.json 2>/dev/null || true - name: Compute mid-4 beauty entropy env: From 0370b015081d9d6a881eaed22d0770a2370c16e7 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 09:19:51 +0200 Subject: [PATCH 09/12] Handle missing trufflehog.json in scan workflow --- .github/workflows/entropy-beauty-scan.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/entropy-beauty-scan.yml b/.github/workflows/entropy-beauty-scan.yml index a1dc497e6d..749f3910b1 100644 --- a/.github/workflows/entropy-beauty-scan.yml +++ b/.github/workflows/entropy-beauty-scan.yml @@ -76,6 +76,9 @@ jobs: try { return JSON.parse(line); } catch(e) { return null; } }).filter(Boolean); } catch(e) {} + } else { + core.setFailed("trufflehog.json was not produced — secret scan did not run correctly"); + return; } let body = `**Average entropy:** ${beauty.average_entropy} bits/char\n\n`; From eba5c695b36f5dbcf7be6cc695e83e40cab6be2f Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 09:23:39 +0200 Subject: [PATCH 10/12] Refactor entropy-beauty-scan workflow for summary upload Refactor GitHub Actions workflow to create a sanitized summary of scan results and upload it. Adjust permissions and job structure for issue creation based on scan findings. --- .github/workflows/entropy-beauty-scan.yml | 92 +++++++++++++++-------- 1 file changed, 62 insertions(+), 30 deletions(-) diff --git a/.github/workflows/entropy-beauty-scan.yml b/.github/workflows/entropy-beauty-scan.yml index 749f3910b1..0e616fea7d 100644 --- a/.github/workflows/entropy-beauty-scan.yml +++ b/.github/workflows/entropy-beauty-scan.yml @@ -6,8 +6,7 @@ on: pull_request: permissions: - contents: read # minimal for analysis - # no write permissions here + contents: read jobs: scan: @@ -16,8 +15,7 @@ jobs: - name: Checkout code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - # For pull_request this is the PR head – safe because we have no write token - fetch-depth: 0 # or 2 if you prefer + fetch-depth: 0 persist-credentials: false - name: Setup Python @@ -44,43 +42,77 @@ jobs: HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} run: python .github/workflows/compute-entropy.py - - name: Upload scan results - uses: actions/upload-artifact@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v4.3.0 + - name: Create sanitized summary (never include Raw secrets) + run: | + python3 << 'EOF' + import json, os + from pathlib import Path + + findings = [] + if Path("trufflehog.json").exists(): + for line in Path("trufflehog.json").read_text().splitlines(): + line = line.strip() + if not line: + continue + try: + f = json.loads(line) + findings.append({ + "detector": f.get("DetectorName"), + "verified": f.get("Verified"), + "file": f.get("SourceMetadata", {}).get("Data", {}).get("Git", {}).get("file"), + "line": f.get("SourceMetadata", {}).get("Data", {}).get("Git", {}).get("line"), + }) + except Exception: + pass + + beauty = {} + if Path("/tmp/beauty.json").exists(): + beauty = json.loads(Path("/tmp/beauty.json").read_text()) + + summary = { + "beauty": beauty, + "findings_count": len(findings), + "findings": findings, # safe fields only + } + Path("scan-summary.json").write_text(json.dumps(summary, indent=2)) + print(f"Sanitized summary written ({len(findings)} findings)") + EOF + + - name: Upload sanitized results only + uses: actions/upload-artifact@v4 with: name: scan-results - path: | - /tmp/beauty.json - trufflehog.json # if TruffleHog wrote it; adjust if needed + path: scan-summary.json retention-days: 1 - # ── Create issue on push/release (trusted events) ── - - name: Create issue on suspicious push - if: github.event_name == 'push' || github.event_name == 'release' - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + # Separate job that only runs on trusted events and has write permission + create-issue: + needs: scan + if: github.event_name == 'push' || github.event_name == 'release' + runs-on: ubuntu-latest + permissions: + contents: read + issues: write + steps: + - name: Download summary + uses: actions/download-artifact@v4 + with: + name: scan-results + + - name: Create issue on suspicious entropy + uses: actions/github-script@v7 with: - github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs'); - const beauty = JSON.parse(fs.readFileSync('/tmp/beauty.json', 'utf8')); + const summary = JSON.parse(fs.readFileSync('scan-summary.json', 'utf8')); + const beauty = summary.beauty || {}; + const findingsCount = summary.findings_count || 0; if (beauty.average_entropy >= 4.3 && beauty.average_entropy <= 5.1) { console.log("✅ Mid-4 beauty — no issue created"); return; } - let findings = []; - if (fs.existsSync('trufflehog.json')) { - try { - const lines = fs.readFileSync('trufflehog.json', 'utf8').trim().split('\n'); - findings = lines.map(line => { - try { return JSON.parse(line); } catch(e) { return null; } - }).filter(Boolean); - } catch(e) {} - } else { - core.setFailed("trufflehog.json was not produced — secret scan did not run correctly"); - return; - } - let body = `**Average entropy:** ${beauty.average_entropy} bits/char\n\n`; body += `**Verdict:** ${beauty.verdict}\n\n`; @@ -88,8 +120,8 @@ jobs: body += `**Changed files:**\n\`\`\`\n${beauty.files.join('\n')}\n\`\`\`\n\n`; } - if (findings.length > 0) { - body += `**TruffleHog found ${findings.length} potential issue(s)**\n`; + if (findingsCount > 0) { + body += `**TruffleHog found ${findingsCount} potential issue(s)**\n`; } else { body += `✅ No secrets or suspicious high-entropy strings found.\n`; } From ed3985c4207cab41af0b3f35e9779064354196a6 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 09:23:58 +0200 Subject: [PATCH 11/12] Refactor GitHub Actions workflow for scan results --- .github/workflows/entropy-beauty-comment.yml | 43 ++++++++------------ 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/.github/workflows/entropy-beauty-comment.yml b/.github/workflows/entropy-beauty-comment.yml index 8281262dd6..e0d7e9c904 100644 --- a/.github/workflows/entropy-beauty-comment.yml +++ b/.github/workflows/entropy-beauty-comment.yml @@ -3,51 +3,41 @@ name: Post Entropy Beauty Comment on: workflow_run: workflows: ["Entropy Beauty + TruffleHog Scan"] - types: - - completed + types: [completed] permissions: contents: read pull-requests: write - issues: write jobs: comment: - # Only for successful PR runs if: > github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' runs-on: ubuntu-latest steps: - name: Download scan results - uses: actions/download-artifact@fa0a91b85d4f404e444e005971372dc801d16 # v4.1.8 + uses: actions/download-artifact@v4 with: name: scan-results run-id: ${{ github.event.workflow_run.id }} github-token: ${{ secrets.GITHUB_TOKEN }} - path: results - name: Post summary comment - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + uses: actions/github-script@v7 with: - github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs'); - const path = require('path'); - - const beauty = JSON.parse(fs.readFileSync(path.join('results', 'beauty.json'), 'utf8')); - let findings = []; - const thPath = path.join('results', 'trufflehog.json'); - if (fs.existsSync(thPath)) { - try { - const lines = fs.readFileSync(thPath, 'utf8').trim().split('\n'); - findings = lines.map(line => { - try { return JSON.parse(line); } catch(e) { return null; } - }).filter(Boolean); - } catch(e) {} + if (!fs.existsSync('scan-summary.json')) { + core.setFailed('scan-summary.json missing — analysis did not produce results'); + return; } + const summary = JSON.parse(fs.readFileSync('scan-summary.json', 'utf8')); + const beauty = summary.beauty || {}; + const findingsCount = summary.findings_count || 0; + let body = `## 🐷 TruffleHog + Entropy Beauty Scan\n\n`; body += `**Average entropy of changed code:** ${beauty.average_entropy} bits/char\n`; body += `**Verdict:** ${beauty.verdict}\n\n`; @@ -56,24 +46,23 @@ jobs: body += `**Changed files entropy:**\n\`\`\`\n${beauty.files.join('\n')}\n\`\`\`\n\n`; } - if (findings.length > 0) { - body += `⚠️ **TruffleHog found ${findings.length} potential issue(s)**\n`; + if (findingsCount > 0) { + body += `⚠️ **TruffleHog found ${findingsCount} potential issue(s)**\n`; } else { body += `✅ No secrets or suspicious high-entropy strings found.\n`; } body += `\n*Mid-4 beauty heuristic in action — powered by our entropy chats! 😊*`; - // Get the PR number from the workflow_run payload - const pr = github.event.workflow_run.pull_requests[0]; - if (!pr) { - console.log("No associated PR found"); + const prs = github.event.workflow_run.pull_requests || []; + if (prs.length === 0) { + console.log('No associated PR found'); return; } await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, - issue_number: pr.number, + issue_number: prs[0].number, body: body }); From 504e9e6c04b58f61b3f406a888ee42794716e781 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 5 Aug 2026 09:39:39 +0200 Subject: [PATCH 12/12] Implement caching for TruffleHog Docker image Added caching for TruffleHog Docker image to optimize workflow. --- .github/workflows/entropy-beauty-scan.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/entropy-beauty-scan.yml b/.github/workflows/entropy-beauty-scan.yml index 0e616fea7d..16843d599c 100644 --- a/.github/workflows/entropy-beauty-scan.yml +++ b/.github/workflows/entropy-beauty-scan.yml @@ -23,6 +23,22 @@ jobs: with: python-version: '3.12' + - name: Cache TruffleHog Docker image + id: cache-trufflehog + uses: actions/cache@v4 + with: + path: /tmp/trufflehog-image.tar + key: trufflehog-3.96.0-${{ runner.os }} + + - name: Load TruffleHog image from cache + if: steps.cache-trufflehog.outputs.cache-hit == 'true' + run: docker load -i /tmp/trufflehog-image.tar + + - name: Pull TruffleHog image (cache miss) + if: steps.cache-trufflehog.outputs.cache-hit != 'true' + run: | + docker pull trufflesecurity/trufflehog:3.96.0 + docker save trufflesecurity/trufflehog:3.96.0 -o /tmp/trufflehog-image.tar - name: Run TruffleHog run: | docker run --rm \