name: "Extra Security Scan"

on:
  push:
    branches:
      - "**"

permissions:
  contents: read

jobs:
  gitleaks:
    name: Gitleaks Secret Scan
    runs-on: ubuntu-latest

    permissions:
      contents: read

    steps:
      - name: Checkout full history
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
        with:
          fetch-depth: 0
          persist-credentials: false

      - name: Run Gitleaks
        uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITLEAKS_ENABLE_SUMMARY: "true"
          GITLEAKS_ENABLE_UPLOAD_ARTIFACT: "true"
          # 如果仓库属于 GitHub Organization，需要在 Settings -> Secrets 里加 GITLEAKS_LICENSE
          # GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}

  osv:
    name: OSV Dependency Scan
    uses: google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@9a498708959aeaef5ef730655706c5a1df1edbc2

    permissions:
      contents: read
      actions: read
      security-events: write

    with:
      scan-args: |-
        --recursive
        ./
      upload-sarif: true
      fail-on-vuln: true

  pnpm-audit:
    name: pnpm audit
    runs-on: ubuntu-latest

    permissions:
      contents: read

    steps:
      - name: Checkout repository
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
        with:
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
        with:
          node-version: 22

      - name: Run pnpm audit
        shell: bash
        run: |
          if [ ! -f pnpm-lock.yaml ]; then
            echo "pnpm-lock.yaml not found, skip pnpm audit."
            exit 0
          fi

          corepack enable
          corepack prepare pnpm@10 --activate
          pnpm audit --audit-level=high

  semgrep:
    name: Semgrep CE Scan
    runs-on: ubuntu-latest

    permissions:
      contents: read
      security-events: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
        with:
          persist-credentials: false

      - name: Run Semgrep CE
        shell: bash
        run: |
          docker run --rm \
            -v "${PWD}:/src" \
            -w /src \
            semgrep/semgrep:latest \
            semgrep scan --config p/default --sarif --output semgrep.sarif . || true

          if [ ! -f semgrep.sarif ]; then
            cat > semgrep.sarif <<'EOF'
          {
            "version": "2.1.0",
            "$schema": "https://json.schemastore.org/sarif-2.1.0.json",
            "runs": [
              {
                "tool": {
                  "driver": {
                    "name": "Semgrep",
                    "informationUri": "https://semgrep.dev",
                    "rules": []
                  }
                },
                "results": []
              }
            ]
          }
          EOF
          fi

      - name: Upload Semgrep SARIF
        uses: github/codeql-action/upload-sarif@411bbbe57033eedfc1a82d68c01345aa96c737d7
        with:
          sarif_file: semgrep.sarif
          category: semgrep

  actionlint:
    name: GitHub Actions Syntax Scan
    runs-on: ubuntu-latest

    permissions:
      contents: read

    steps:
      - name: Checkout repository
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
        with:
          persist-credentials: false

      - name: Run actionlint
        shell: bash
        run: |
          docker run --rm \
            -v "${PWD}:/repo" \
            -w /repo \
            rhysd/actionlint:latest

  zizmor:
    name: GitHub Actions Security Scan
    runs-on: ubuntu-latest

    permissions:
      contents: read
      actions: read
      security-events: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
        with:
          persist-credentials: false

      - name: Run zizmor
        uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa
        with:
          persona: auditor
          min-severity: medium
          min-confidence: medium

  scorecard:
    name: OpenSSF Scorecard
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'

    permissions:
      contents: read
      security-events: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
        with:
          persist-credentials: false

      - name: Run OpenSSF Scorecard
        uses: ossf/scorecard-action@99c09fe975337306107572b4fdf4db224cf8e2f2
        with:
          results_file: scorecard.sarif
          results_format: sarif
          publish_results: false

      - name: Upload Scorecard SARIF
        uses: github/codeql-action/upload-sarif@411bbbe57033eedfc1a82d68c01345aa96c737d7
        with:
          sarif_file: scorecard.sarif
          category: openssf-scorecard
