Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions .github/workflows/dependency-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
name: Dependency Audit

env:
PYTHON_VERSION: "3.12"

# pip-audit compares the lockfile against advisory databases that publish
# continuously, so the result tracks the clock, not the commit. Hence the cron.
on:
schedule:
- cron: "17 6 * * *"
# Unfiltered: a required check behind a paths filter never reports on a
# pull request that misses the filter, which blocks the merge.
pull_request:
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 next step can quote it.
{
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 record it instead.
- 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}`);
}

- 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',
});
13 changes: 2 additions & 11 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,9 @@ on:
- "pyproject.toml"
- "uv.lock"
- ".github/workflows/python-tests.yml"
# Unfiltered: a required check behind a paths filter never reports on a
# pull request that misses the filter, which blocks the merge.
pull_request:
paths:
- "socketsecurity/**/*.py"
- "tests/unit/**/*.py"
- "tests/core/**/*.py"
- "pyproject.toml"
- "uv.lock"
- ".github/workflows/python-tests.yml"
workflow_dispatch:

permissions:
Expand Down Expand Up @@ -62,10 +57,6 @@ jobs:
from socketsecurity.config import CliConfig
print('import smoke OK')
"
- name: 🛡️ pip-audit (known CVEs in the locked deps)
run: |
uv export --no-hashes --no-emit-project --format requirements-txt > /tmp/req-audit.txt
uvx pip-audit --strict --progress-spinner off --disable-pip --no-deps -r /tmp/req-audit.txt

ruff:
runs-on: ubuntu-latest
Expand Down
8 changes: 2 additions & 6 deletions .github/workflows/version-check.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
name: Version Check
on:
# Unfiltered: a required check behind a paths filter never reports on a
# pull request that misses the filter, which blocks the merge.
pull_request:
types: [opened, synchronize, ready_for_review]
paths:
- 'socketsecurity/**'
- 'pyproject.toml'
- 'uv.lock'
# Included so a change to the check itself is exercised by its own PR.
- '.github/workflows/version-check.yml'

permissions:
contents: read
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## 2.9.5
Comment thread
lelia marked this conversation as resolved.

### Changed: bump pinned gitpython to 3.1.62 and soupsieve to 2.9.2

- Bumped `gitpython` from `3.1.59` to `3.1.62` (CVE-2026-87817, CVE-2026-87818,
CVE-2026-87819) and the transitive `soupsieve` pin from `2.8.4` to `2.9.2`
(GHSA-gjv8-xp57-g29c, GHSA-j934-xhv5-fg8f).
- Normalized the `gitpython` requirement to its lowercase PEP 503 name.

### Changed: audit the locked dependencies on a schedule

- `pip-audit` moved out of the Unit Tests workflow into a new Dependency Audit
workflow that also runs daily, so advisories published against unchanged pins
are reported on their own schedule rather than on the next push.

## 2.9.4

### Changed: bump pinned @coana-tech/cli to 15.10.46
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ build-backend = "hatchling.build"

[project]
name = "socketsecurity"
version = "2.9.4"
version = "2.9.5"
requires-python = ">= 3.11"
license = {"file" = "LICENSE"}
dependencies = [
"requests==2.34.2",
"mdutils==1.8.1",
"prettytable==3.18.0",
"GitPython==3.1.59",
"gitpython==3.1.62",
"packaging==26.3",
"python-dotenv==1.2.3",
"socketdev==3.6.0",
Expand Down
2 changes: 1 addition & 1 deletion socketsecurity/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__author__ = 'socket.dev'
__version__ = '2.9.4'
__version__ = '2.9.5'
USER_AGENT = f'SocketPythonCLI/{__version__}'
16 changes: 8 additions & 8 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading