Skip to content

Security and quality fixes for 2.2.4 #9

Security and quality fixes for 2.2.4

Security and quality fixes for 2.2.4 #9

Workflow file for this run

name: Dependency Security Scan
on:
schedule:
# Run every Monday at 08:00 UTC
- cron: '0 8 * * 1'
push:
paths:
- 'requirements.txt'
- '.github/workflows/security.yml'
pull_request:
paths:
- 'requirements.txt'
workflow_dispatch:
permissions:
contents: read
issues: write
jobs:
pip-audit:
name: pip-audit vulnerability scan
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pip-audit
pip install -r requirements.txt
- name: Run pip-audit
id: audit
run: |
pip-audit --format=json --output=audit-results.json --desc || true
pip-audit --desc 2>&1 | tee audit-report.txt
# Set output for downstream steps
if pip-audit --desc > /dev/null 2>&1; then
echo "has_vulnerabilities=false" >> "$GITHUB_OUTPUT"
else
echo "has_vulnerabilities=true" >> "$GITHUB_OUTPUT"
fi
- name: Upload audit results
if: always()
uses: actions/upload-artifact@v4
with:
name: pip-audit-results
path: |
audit-results.json
audit-report.txt
retention-days: 90
- name: Create issue on vulnerabilities
if: steps.audit.outputs.has_vulnerabilities == 'true' && github.event_name == 'schedule'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = fs.readFileSync('audit-report.txt', 'utf8');
const title = `[Security] Dependency vulnerabilities found - ${new Date().toISOString().split('T')[0]}`;
// Check for existing open issue to avoid duplicates
const existingIssues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'security,dependencies',
per_page: 5,
});
const duplicate = existingIssues.data.find(
issue => issue.title.startsWith('[Security] Dependency vulnerabilities found')
);
if (duplicate) {
// Update existing issue with new scan results
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: duplicate.number,
body: `## Updated Scan Results (${new Date().toISOString().split('T')[0]})\n\n\`\`\`\n${report}\n\`\`\``,
});
console.log(`Updated existing issue #${duplicate.number}`);
} else {
// Create new issue
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: `## Dependency Vulnerability Report\n\nAutomated scan found vulnerabilities in project dependencies.\n\n### pip-audit Results\n\n\`\`\`\n${report}\n\`\`\`\n\n### Recommended Actions\n\n1. Review each vulnerability and assess impact\n2. Update affected packages if patches are available\n3. If no patch exists, evaluate workarounds or alternative packages\n\n---\n*This issue was automatically created by the dependency security scan workflow.*`,
labels: ['security', 'dependencies'],
});
console.log('Created new security issue');
}
safety-check:
name: Safety vulnerability scan
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install safety
pip install -r requirements.txt
- name: Run Safety check
id: safety
run: |
safety check --output json > safety-results.json 2>&1 || true
safety check 2>&1 | tee safety-report.txt || true
- name: Upload Safety results
if: always()
uses: actions/upload-artifact@v4
with:
name: safety-results
path: |
safety-results.json
safety-report.txt
retention-days: 90