from __future__ import annotations from dataclasses import dataclass from pathlib import Path @dataclass class CICDConfig: provider: str schedule: str | None = None fail_on_critical: bool = True fail_on_high: bool = True fail_on_medium: bool = False comment_on_pr: bool = True include_licenses: bool = True include_outdated: bool = True include_unused: bool = False GITHUB_WORKFLOW_TEMPLATE = """name: DepAudit Security Scan on: schedule: - cron: '{schedule}' push: branches: [main, master] pull_request: branches: [main, master] jobs: depaudit: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install DepAudit run: | pip install depaudit-cli - name: Run DepAudit run: | depaudit . --format=json --output=depaudit-results.json continue-on-error: true - name: Upload results uses: actions/upload-artifact@v4 if: always() with: name: depaudit-results path: depaudit-results.json - name: Comment on PR if: github.event_name == 'pull_request' uses: actions/github-script@v7 with: script: | const fs = require('fs'); const results = JSON.parse(fs.readFileSync('depaudit-results.json', 'utf8')); const summary = results.summary || {{}}; const comment = ` ## DepAudit Security Scan Results **Vulnerabilities:** - Critical: ${{{{summary.total_vulnerabilities?.severity_breakdown?.critical || 0}}}} - High: ${{{{summary.total_vulnerabilities?.severity_breakdown?.high || 0}}}} - Medium: ${{{{summary.total_vulnerabilities?.severity_breakdown?.medium || 0}}}} - Low: ${{{{summary.total_vulnerabilities?.severity_breakdown?.low || 0}}}} **Outdated Packages:** ${{{{summary.total_outdated || 0}}}} **License Issues:** ${{{{summary.total_license_issues || 0}}}} `; github.rest.issues.createComment({{ issue_number: context.issue.number, body: comment }}); """ GITLAB_CI_TEMPLATE = """stages: - security depaudit: stage: security image: python:3.11-slim script: - pip install depaudit-cli - depaudit . --format=json --output=depaudit-results.json || true artifacts: reports: dotenv: depaudit-results.json rules: - if: $CI_PIPELINE_SOURCE == "schedule" - if: $CI_COMMIT_BRANCH == "main" - if: $CI_MERGE_REQUEST_IID """ def generate_github_workflow(config: CICDConfig) -> str: schedule = config.schedule or "0 0 * * 0" workflow = GITHUB_WORKFLOW_TEMPLATE.format(schedule=schedule) return workflow def generate_gitlab_ci(config: CICDConfig) -> str: return GITLAB_CI_TEMPLATE def generate_cicd_config( provider: str, output_dir: Path, config: CICDConfig | None = None, ) -> Path: if config is None: config = CICDConfig(provider=provider) if provider == "github": content = generate_github_workflow(config) output_path = output_dir / ".github" / "workflows" / "depaudit.yml" output_path.parent.mkdir(parents=True, exist_ok=True) output_path.write_text(content) elif provider == "gitlab": content = generate_gitlab_ci(config) output_path = output_dir / ".gitlab-ci.yml" output_path.write_text(content) else: raise ValueError(f"Unsupported CI/CD provider: {provider}") return output_path