Repository navigation
Security audit #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Security audit | |
| # Monthly pip-audit run for an unattended project. | |
| # | |
| # Why a separate workflow instead of a step in tests.yml: | |
| # - This repo isn't actively developed. Blocking PRs/pushes on every | |
| # newly disclosed CVE means a typo-fix PR can fail months later. | |
| # - Running monthly on a schedule keeps us informed without coupling | |
| # to user activity. Findings are surfaced as a GitHub issue so | |
| # they don't get lost in workflow logs. | |
| on: | |
| schedule: | |
| # 06:00 UTC on the 1st of every month. | |
| - cron: '0 6 1 * *' | |
| workflow_dispatch: # allow manual runs from the Actions tab | |
| permissions: | |
| contents: read | |
| issues: write | |
| jobs: | |
| audit: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install pip-audit | |
| run: | | |
| pip install --upgrade pip | |
| pip install pip-audit | |
| - name: Run pip-audit | |
| id: audit | |
| run: | | |
| # Capture output and exit code without failing the workflow — | |
| # a non-zero exit just means CVEs were found, which we want | |
| # to report, not error on. | |
| set +e | |
| pip-audit -r docker/requirements.txt > audit.txt 2>&1 | |
| echo "status=$?" >> "$GITHUB_OUTPUT" | |
| cat audit.txt | |
| exit 0 | |
| - name: Ensure security-audit label exists | |
| if: steps.audit.outputs.status != '0' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh label create security-audit \ | |
| --color "B60205" \ | |
| --description "Findings from the monthly pip-audit run" \ | |
| 2>/dev/null || true | |
| - name: Open or update audit issue | |
| if: steps.audit.outputs.status != '0' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| run_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" | |
| today="$(date -u +'%Y-%m-%d')" | |
| { | |
| echo "Monthly \`pip-audit\` run on $today found vulnerable dependencies." | |
| echo | |
| echo "Workflow run: $run_url" | |
| echo | |
| echo '```' | |
| cat audit.txt | |
| echo '```' | |
| echo | |
| echo "_Bump the affected packages in \`docker/requirements.txt\` and close this issue once the next run is clean._" | |
| } > body.md | |
| existing="$(gh issue list --label security-audit --state open --json number --jq '.[0].number')" | |
| if [ -n "$existing" ]; then | |
| gh issue comment "$existing" --body-file body.md | |
| else | |
| gh issue create \ | |
| --title "Security audit: vulnerable dependencies detected" \ | |
| --label security-audit \ | |
| --body-file body.md | |
| fi |