name: pip-audit on: schedule: - cron: "30 1 * * *" push: branches: [main] paths: [requirements.txt, scripts/filter_requirements.py] workflow_dispatch: jobs: audit: runs-on: ubuntu-latest outputs: report_b64: ${{ steps.audit.outputs.report_b64 }} steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" - name: Audit dependencies id: audit shell: bash run: | pip install pip-audit python3 scripts/filter_requirements.py requirements.txt requirements.audit.txt # Don't let a non-zero exit abort the step, so the report is saved first set +e pip-audit -r requirements.audit.txt --no-deps --disable-pip > audit.txt 2>&1 echo $? > audit.exit set -e cat audit.txt echo "report_b64=$(head -c 100000 audit.txt | base64 -w0)" >> "$GITHUB_OUTPUT" - name: Fail if the audit failed shell: bash run: exit "$(cat audit.exit)" notify: needs: audit if: ${{ always() && needs.audit.result == 'failure' }} runs-on: host steps: - name: Send mail via local postfix env: MAIL_FROM: ${{ vars.MAIL_FROM }} MAIL_TO: ${{ vars.MAIL_TO }} REPO: ${{ gitea.repository }} RUN_URL: ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_number }} REPORT_B64: ${{ needs.audit.outputs.report_b64 }} run: | python3 - <<'EOF' import base64, os, smtplib from email.message import EmailMessage b64 = os.environ.get("REPORT_B64", "") report = ( base64.b64decode(b64).decode("utf-8", errors="replace") if b64 else "(no audit output, the job failed before pip-audit finished)" ) msg = EmailMessage() msg["Subject"] = f"[pip-audit] Problem in {os.environ['REPO']}" msg["From"] = os.environ["MAIL_FROM"] msg["To"] = os.environ["MAIL_TO"] msg.set_content( f"pip-audit result for {os.environ['REPO']}:\n\n" f"{report}\n\n" f"Run: {os.environ['RUN_URL']}\n" ) with smtplib.SMTP("127.0.0.1", 25, timeout=30) as s: s.send_message(msg) EOF