Bump gitpython to 3.1.62 and soupsieve to 2.9.2 #1
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: Dependency Audit | |
| env: | |
| PYTHON_VERSION: "3.12" | |
| # This check is not a function of the code alone. pip-audit compares the locked | |
| # dependency set against advisory databases that publish continuously, so a | |
| # green run only describes the moment it ran -- the same commit can fail | |
| # tomorrow with nothing changed. That is why this runs on a schedule and not | |
| # only on pull requests: between 2026-09-09 (three GitPython advisories | |
| # published) and 2026-09-17 (the next push that happened to touch a path the | |
| # test workflow watches) the repository was shipping a known-vulnerable pin | |
| # with every check green. | |
| on: | |
| schedule: | |
| - cron: "17 6 * * *" | |
| pull_request: | |
| paths: | |
| - "pyproject.toml" | |
| - "uv.lock" | |
| - ".github/workflows/dependency-audit.yml" | |
| push: | |
| branches: [main] | |
| paths: | |
| - "pyproject.toml" | |
| - "uv.lock" | |
| - ".github/workflows/dependency-audit.yml" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: dependency-audit-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| dependency-audit: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| issues: write | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - name: 🐍 setup python | |
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: 🛠️ install uv | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install uv | |
| - name: 🛡️ pip-audit (known CVEs in the locked deps) | |
| id: audit | |
| run: | | |
| uv export --no-hashes --no-emit-project --format requirements-txt > /tmp/req-audit.txt | |
| set +e | |
| uvx pip-audit --strict --progress-spinner off --disable-pip --no-deps \ | |
| -r /tmp/req-audit.txt 2>&1 | tee /tmp/audit.log | |
| status=${PIPESTATUS[0]} | |
| set -e | |
| # Written before the exit so the issue step below can quote the table. | |
| { | |
| echo 'report<<AUDIT_REPORT_EOF' | |
| cat /tmp/audit.log | |
| echo 'AUDIT_REPORT_EOF' | |
| } >> "$GITHUB_OUTPUT" | |
| exit "$status" | |
| # A scheduled run has no pull request to turn red, so a failure here would | |
| # otherwise be visible only to someone reading the Actions tab. File it. | |
| - name: 📮 open or update the tracking issue | |
| if: always() && steps.audit.outcome == 'failure' && github.event_name == 'schedule' | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| env: | |
| AUDIT_REPORT: ${{ steps.audit.outputs.report }} | |
| with: | |
| script: | | |
| const marker = '<!-- dependency-audit-tracking-issue -->'; | |
| const title = 'Dependency audit: known vulnerabilities in the locked dependencies'; | |
| const runUrl = | |
| `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}` + | |
| `/actions/runs/${context.runId}`; | |
| const body = [ | |
| marker, | |
| '`pip-audit` found known vulnerabilities in the locked dependency set.', | |
| '', | |
| 'Bump the affected pins in `pyproject.toml`, run `uv lock`, and open a PR.', | |
| '', | |
| '```', | |
| process.env.AUDIT_REPORT.trim(), | |
| '```', | |
| '', | |
| `Run: ${runUrl}`, | |
| `Last checked: ${new Date().toISOString()}`, | |
| ].join('\n'); | |
| const existing = await github.paginate(github.rest.issues.listForRepo, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| per_page: 100, | |
| }); | |
| const tracking = existing.find( | |
| (issue) => !issue.pull_request && issue.body && issue.body.includes(marker), | |
| ); | |
| if (tracking) { | |
| await github.rest.issues.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: tracking.number, | |
| body, | |
| }); | |
| core.notice(`Updated tracking issue #${tracking.number}`); | |
| } else { | |
| const created = await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title, | |
| body, | |
| labels: ['dependencies'], | |
| }); | |
| core.notice(`Opened tracking issue #${created.data.number}`); | |
| } | |
| # Close the loop, so a stale issue does not outlive the problem. | |
| - name: ✅ close the tracking issue once the audit is clean | |
| if: always() && steps.audit.outcome == 'success' && github.event_name == 'schedule' | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| with: | |
| script: | | |
| const marker = '<!-- dependency-audit-tracking-issue -->'; | |
| const existing = await github.paginate(github.rest.issues.listForRepo, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| per_page: 100, | |
| }); | |
| const tracking = existing.find( | |
| (issue) => !issue.pull_request && issue.body && issue.body.includes(marker), | |
| ); | |
| if (!tracking) { | |
| return; | |
| } | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: tracking.number, | |
| body: 'The scheduled audit is clean again. Closing.', | |
| }); | |
| await github.rest.issues.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: tracking.number, | |
| state: 'closed', | |
| }); |