From 8aec33b1c7b1c702fb0b683bd0901c9bec3145f9 Mon Sep 17 00:00:00 2001 From: kmilo Date: Wed, 7 Oct 2026 00:32:19 -0400 Subject: [PATCH 1/2] feat: enhance pip-audit workflow to output JSON summaries and improve vulnerability reporting Signed-off-by: kmilo --- .github/workflows/scan.yml | 59 +++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index 7d8379f..7f3ad2e 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -45,8 +45,59 @@ jobs: - name: Install pip-audit run: python -m pip install pip-audit - - name: Audit requirements.txt - run: pip-audit -r requirements.txt + - name: Audit requirements.txt (JSON) + run: | + pip-audit -r requirements.txt --format json --output audit-requirements.json + + - name: Audit installed environment (JSON) + run: | + pip-audit --format json --output audit-env.json + + - name: Publish pip-audit summary to run summary + env: + GITHUB_STEP_SUMMARY: ${{ github.step_summary }} + run: | + python - <<'PY' + import json, os, pathlib + + def summarize(path): + p = pathlib.Path(path) + if not p.exists(): + return 0 + try: + d = json.loads(p.read_text()) + if isinstance(d, list): + return len(d) + if isinstance(d, dict): + for k in ('vulns','vulnerabilities','results'): + if k in d and isinstance(d[k], list): + return len(d[k]) + # Fallback: count top-level list-like values + total = 0 + for v in d.values(): + if isinstance(v, list): + total += len(v) + return total + except Exception: + return 0 - - name: Audit installed environment - run: pip-audit + req = summarize('audit-requirements.json') + env = summarize('audit-env.json') + summary = f"## pip-audit summary\n- requirements.txt vulnerabilities: {req}\n- installed environment vulnerabilities: {env}\n" + print(summary) + target = os.environ.get('GITHUB_STEP_SUMMARY') + if target: + with open(target, 'a') as fh: + fh.write(summary) + else: + # Fallback to printing if summary file not available in older runners + print('GITHUB_STEP_SUMMARY not set; summary printed above') + PY + + - name: Upload pip-audit JSON artifacts + uses: actions/upload-artifact@v4 + with: + name: pip-audit-results + path: | + audit-requirements.json + audit-env.json From 874ea6d38e1077c77648703d94ae5013e28d7fc3 Mon Sep 17 00:00:00 2001 From: kmilo Date: Wed, 7 Oct 2026 00:32:25 -0400 Subject: [PATCH 2/2] fix: improve fallback mechanism for scheduled vulnerability scan Signed-off-by: kmilo --- .github/workflows/scheduled-scan.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scheduled-scan.yml b/.github/workflows/scheduled-scan.yml index 38d5d6d..54b6608 100644 --- a/.github/workflows/scheduled-scan.yml +++ b/.github/workflows/scheduled-scan.yml @@ -24,13 +24,26 @@ jobs: env: GH_TOKEN: ${{ github.token }} run: | - tag="$(gh api "repos/${GITHUB_REPOSITORY}/releases/latest" --jq '.tag_name')" + # Attempt to get the latest release tag from GitHub Releases API + tag="$(gh api "repos/${GITHUB_REPOSITORY}/releases/latest" --jq '.tag_name' 2>/dev/null || echo "")" + + # If no release (or API failed), try the repository tags list via the API if [ -z "${tag}" ] || [ "${tag}" = "null" ]; then - echo "::error::No releases found in ${GITHUB_REPOSITORY}" - exit 1 + tag="$(gh api "repos/${GITHUB_REPOSITORY}/tags" --jq '.[0].name' 2>/dev/null || echo "")" + fi + + # If still empty, log warning and use main branch as a safe default + if [ -z "${tag}" ]; then + echo "::warning::No releases or tags found in ${GITHUB_REPOSITORY}, using main branch for scan" + tag="main" fi + echo "value=${tag}" >> "${GITHUB_OUTPUT}" + concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + scan-release: name: Scan ${{ needs.latest-release-version.outputs.tag_name }} needs: latest-release-version