Skip to content

Commit e98aecd

Browse files
committed
feat: add pip file scanning
.#9 nofusscomputing/centurion_erp#209 fixes #9
1 parent dcc1dd9 commit e98aecd

File tree

1 file changed

+224
-0
lines changed

1 file changed

+224
-0
lines changed

.github/workflows/python.yaml

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,227 @@ jobs:
379379
echo "[Debug] PWD[${PWD}]";
380380
echo "[Debug] ****************************";
381381
git push
382+
383+
384+
vulnerability-scan:
385+
name: PIP file Scan (requirements.txt)
386+
runs-on: ubuntu-latest
387+
steps:
388+
389+
390+
- uses: actions/checkout@v4
391+
392+
393+
- name: Run Trivy vulnerability scanner against requirements.txt
394+
uses: aquasecurity/trivy-action@0.20.0
395+
with:
396+
scan-type: 'fs'
397+
ignore-unfixed: false
398+
format: 'sarif'
399+
output: 'trivy-results.sarif'
400+
severity: 'LOW,MEDIUM,HIGH,CRITICAL'
401+
scan-ref: requirements.txt
402+
exit-code: 0
403+
404+
405+
- name: Upload requirements.txt scan results to GitHub Security tab
406+
uses: github/codeql-action/upload-sarif@v3
407+
with:
408+
sarif_file: 'trivy-results.sarif'
409+
410+
411+
- name: Run Trivy vulnerability scanner against requirements.txt (json Report)
412+
uses: aquasecurity/trivy-action@0.20.0
413+
with:
414+
scan-type: 'fs'
415+
ignore-unfixed: false
416+
format: 'json'
417+
output: 'scan-results.json'
418+
severity: 'LOW,MEDIUM,HIGH,CRITICAL'
419+
scan-ref: requirements.txt
420+
exit-code: 0
421+
422+
423+
- name: Upload scan results (json Report)
424+
uses: actions/upload-artifact@v4
425+
with:
426+
name: python-scan-results-json
427+
path: scan-results.json
428+
429+
430+
431+
vulnerability-report:
432+
name: Create Reports
433+
needs:
434+
- vulnerability-scan
435+
runs-on: ubuntu-latest
436+
steps:
437+
438+
439+
- name: Fetch scan results (json Report)
440+
uses: actions/download-artifact@v4
441+
with:
442+
name: python-scan-results-json
443+
444+
445+
- name: Create Vulnerabilities (Critical/High)
446+
run: |
447+
echo "[Debug] jq -r '.Results'=$(jq -r '.Results' scan-results.json)";
448+
449+
if [ "$(jq -r '.Results' scan-results.json)" ]; then
450+
451+
not_empty="$(jq -r '.Results[] | .Vulnerabilities[]' scan-results.json)";
452+
453+
else
454+
455+
not_empty="";
456+
457+
fi
458+
459+
echo "[Debug] not_empty=${not_empty}";
460+
461+
jq -r '
462+
[
463+
"# Python Scan Results (requirements.txt)",
464+
"",
465+
"**Scan Date:** _" + ( .CreatedAt // "" ) + "_",
466+
"**File:** _" + ( .ArtifactName // "" ) + "_",
467+
""
468+
] | join("\n")
469+
' scan-results.json > vulnerability-report.md
470+
471+
if [ "$not_empty" ]; then
472+
jq -r '
473+
def hr(severity):
474+
if severity == "HIGH" or severity == "CRITICAL" then true else false end;
475+
def to_md:
476+
"| " + (.VulnerabilityID // "") + " | " + (.PkgName // "") + " | " + (.InstalledVersion // "") + " | " + (.Severity // "") + " | " + (.Title // "") + " |";
477+
[
478+
"## High and Critical Vulnerabilities",
479+
"",
480+
"| Vulnerability ID | Package | Version | Severity | Description |",
481+
"| --------- | ----- | ----- | ----- | -------|",
482+
(.Results[] | .Vulnerabilities[] | select(hr(.Severity)) | to_md),
483+
""
484+
] | join("\n")
485+
' scan-results.json >> vulnerability-report.md
486+
487+
else
488+
489+
echo "**Nothing Found**" >> vulnerability-report.md
490+
491+
fi;
492+
493+
494+
495+
- name: Create Full Vulnerabilities
496+
run: |
497+
echo "[Debug] jq -r '.Results'=$(jq -r '.Results' scan-results.json)";
498+
499+
if [ "$(jq -r '.Results' scan-results.json)" ]; then
500+
501+
not_empty="$(jq -r '.Results[] | .Vulnerabilities[]' scan-results.json)";
502+
503+
else
504+
505+
not_empty="";
506+
507+
fi
508+
509+
echo "[Debug] not_empty=${not_empty}";
510+
511+
512+
jq -r '
513+
[
514+
"# Full Scan Results",
515+
"",
516+
"**Scan Date:** _" + ( .CreatedAt // "" ) + "_",
517+
"**File:** _" + ( .ArtifactName // "" ) + "_",
518+
""
519+
] | join("\n")
520+
' scan-results.json > full-vulnerability-report.md
521+
522+
if [ "$not_empty" ]; then
523+
jq -r '
524+
def hr(severity):
525+
if severity == "HIGH" or severity == "CRITICAL" then true else true end;
526+
def to_md:
527+
"| " + (.VulnerabilityID // "") + " | " + (.PkgName // "") + " | " + (.InstalledVersion // "") + " | " + (.Severity // "") + " | " + (.Title // "") + " |";
528+
[
529+
"## Vulnerabilities",
530+
"",
531+
"| Vulnerability ID | Package | Version | Severity | Description |",
532+
"| --------- | ----- | ----- | ----- | -------|",
533+
(.Results[] | .Vulnerabilities[] | select(.Severity) | to_md),
534+
""
535+
] | join("\n")
536+
' scan-results.json >> full-vulnerability-report.md
537+
538+
else
539+
540+
echo "**Nothing Found**" >> full-vulnerability-report.md
541+
542+
fi;
543+
544+
545+
- name: Upload scan results
546+
uses: actions/upload-artifact@v4
547+
with:
548+
name: python-vulnerability-report
549+
path: vulnerability-report.md
550+
551+
552+
- name: Upload scan results
553+
uses: actions/upload-artifact@v4
554+
with:
555+
name: python-vulnerability-report-full
556+
path: full-vulnerability-report.md
557+
558+
559+
- uses: dtinth/markdown-report-action@v1
560+
with:
561+
name: Python Vulnerability Report
562+
title: Python Vulnerability Report
563+
body-file: full-vulnerability-report.md
564+
565+
566+
567+
pull-request-report-comment:
568+
if: ${{ github.ref_type != 'tag' }}
569+
needs:
570+
- vulnerability-scan
571+
- vulnerability-report
572+
runs-on: ubuntu-latest
573+
name: Comment on Pull Request (Python Scan)
574+
steps:
575+
576+
577+
- name: Find Current Pull Request
578+
uses: jwalton/gh-find-current-pr@v1
579+
id: finder
580+
581+
582+
- name: Fetch Vulnerability Report
583+
if: ${{ steps.finder.outputs.pr != '' }}
584+
uses: actions/download-artifact@v4
585+
with:
586+
name: python-vulnerability-report
587+
588+
589+
- name: Capture scan results
590+
if: ${{ steps.finder.outputs.pr != '' }}
591+
run: |
592+
content=$(cat vulnerability-report.md | head -c 65000)
593+
echo "report<<EOF" >> $GITHUB_ENV
594+
echo "$content" >> $GITHUB_ENV
595+
echo "EOF" >> $GITHUB_ENV
596+
597+
598+
- name: Comment scan results on PR
599+
if: ${{ steps.finder.outputs.pr != '' }}
600+
uses: marocchino/sticky-pull-request-comment@v2
601+
with:
602+
number: ${{ steps.finder.outputs.pr }}
603+
header: Python requirements.txt Scan Results
604+
message: |
605+
${{ env.report }}

0 commit comments

Comments
 (0)