Skip to content

sdk-github-actions.yml

# Argus Security Scan — GitHub Actions
#
# Runs argus scan on push/PR, posts results as a PR comment,
# and uploads SARIF to GitHub Code Security.
#
# Prerequisites:
#   - argus.yml in the repository root (run: argus init)
#   - Docker available on the runner (default for ubuntu-latest)
#
# Customize:
#   - Adjust severity_threshold in argus.yml or via --severity-threshold flag
#   - Add/remove scanners in argus.yml
#   - Set fail_on_severity to control when the job fails

name: Argus Security Scan

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:

permissions:
  contents: read
  pull-requests: write
  security-events: write

jobs:
  security-scan:
    name: Security Scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Full history for gitleaks

      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install dependencies
        run: pip install pyyaml  # Will become: pip install argus-security

      - name: Run Argus scan
        id: scan
        run: |
          python -m argus scan \
            --format sarif --format json --format markdown \
            --output-dir ./argus-results \
            --output-vars ./argus-results/counts.env \
            --no-timestamp \
            || true

          # Forward scan counts as job outputs
          [ -f argus-results/counts.env ] && cat argus-results/counts.env >> "$GITHUB_OUTPUT"

      - name: Upload SARIF to Code Security
        if: always() && hashFiles('argus-results/argus-results.sarif') != ''
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: argus-results/argus-results.sarif
        continue-on-error: true

      - name: Upload scan artifacts
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: argus-results
          path: argus-results/
          retention-days: 30

      # Post results as PR comment
      - name: Comment PR with scan results
        if: github.event_name == 'pull_request' && always()
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const summaryPath = 'argus-results/argus-summary.md';

            if (!fs.existsSync(summaryPath)) {
              console.log('No summary file found, skipping PR comment');
              return;
            }

            const body = [
              '## 🔒 Argus Security Scan Results',
              '',
              `<!-- argus-scan-comment -->`,
              '',
              fs.readFileSync(summaryPath, 'utf8'),
              '',
              '---',
              `_Scanned at commit \`${context.sha.substring(0, 7)}\` by [Argus](https://github.com/huntridge-labs/argus)_`,
            ].join('\n');

            // Update existing comment or create new one
            const comments = await github.rest.issues.listComments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
            });

            const existing = comments.data.find(c =>
              c.body.includes('argus-scan-comment') &&
              (c.user.login === 'github-actions[bot]' || c.user.type === 'Bot')
            );

            if (existing) {
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: existing.id,
                body,
              });
            } else {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.issue.number,
                body,
              });
            }

      # Fail the job based on severity threshold
      - name: Check scan results
        if: always()
        run: |
          if [ "${{ steps.scan.outputs.passed }}" = "false" ]; then
            echo "::error::Security findings exceed severity threshold"
            exit 1
          fi