# Per ADR-0015 (CI/CD on Gitea Actions). Weekly full-tree security
# scans plus a Lighthouse run against the production environment when
# its URL is configured. Complements the per-PR ci.yml workflow with
# broader / longer-running checks that don't fit the per-PR budget.

name: Security and perf — scheduled

on:
  schedule:
    # Mondays, 04:00 UTC — outside business hours; before the week starts.
    - cron: '0 4 * * 1'
  workflow_dispatch:

jobs:
  full-tree-scan:
    runs-on: [self-hosted, on-prem]
    # Step ordering mirrors ci.yml: scanners run before `pnpm install`
    # so the working tree is not polluted with node_modules content
    # (READMEs / fixtures of upstream packages contain demo
    # secrets that gitleaks false-positives on by the hundreds).
    # The deep-history gitleaks scan here doesn't strictly need it
    # (history doesn't contain node_modules), but consistency with
    # ci.yml keeps the two workflows reading the same way.
    steps:
      # fetch-depth: 0 → full history. The per-PR gitleaks scan is
      # shallow + working-tree-only; this scheduled job is where we
      # do the deep history scan that catches secrets ever committed
      # (and not just what's currently checked in).
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - uses: pnpm/action-setup@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: '.nvmrc'
          cache: 'pnpm'
      # Full-tree Trivy (no skip-dirs, no severity filter — the per-PR
      # gate filters by severity for speed; this run wants the full
      # surface for the security feed). Manual install + curl, same
      # pattern as ci.yml — see the rationale there.
      - name: Install Trivy
        env:
          # renovate: datasource=github-releases depName=aquasecurity/trivy
          TRIVY_VERSION: '0.70.0'
          GITHUB_TOKEN: ${{ secrets.GITHUBCOM_TOKEN }}
        run: |
          curl -sfL \
            -H "Authorization: Bearer ${GITHUB_TOKEN}" \
            -o /tmp/trivy.tar.gz \
            "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz"
          tar -xzf /tmp/trivy.tar.gz -C /usr/local/bin trivy
          trivy --version
      - name: Run Trivy
        run: |
          trivy fs \
            --scanners vuln \
            --ignore-unfixed \
            .
      # Deep gitleaks scan (full git history). Same install pattern as
      # ci.yml. `--redact` masks any matched secret in the log so we
      # don't leak it via CI logs themselves.
      - name: Install gitleaks
        env:
          # renovate: datasource=github-releases depName=gitleaks/gitleaks
          GITLEAKS_VERSION: '8.30.1'
          GITHUB_TOKEN: ${{ secrets.GITHUBCOM_TOKEN }}
        run: |
          curl -sfL \
            -H "Authorization: Bearer ${GITHUB_TOKEN}" \
            -o /tmp/gitleaks.tar.gz \
            "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
          tar -xzf /tmp/gitleaks.tar.gz -C /usr/local/bin gitleaks
          gitleaks version
      - name: Run gitleaks (full history)
        run: |
          gitleaks detect \
            --source . \
            --redact \
            --exit-code 1
      # npm-advisory check (against pnpm-lock.yaml). Run last so
      # `pnpm install` does not pollute the working tree before the
      # scanners above.
      - run: pnpm install --frozen-lockfile
      - run: pnpm audit

  lighthouse-prod:
    # Skipped silently if the prod URL hasn't been configured yet.
    if: vars.LHCI_PROD_URL != ''
    runs-on: [self-hosted, on-prem]
    steps:
      - uses: actions/checkout@v6
      - uses: pnpm/action-setup@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: '.nvmrc'
          cache: 'pnpm'
      - run: pnpm install --frozen-lockfile
      - run: pnpm exec lhci collect --url=${{ vars.LHCI_PROD_URL }} --numberOfRuns=3
      - run: pnpm exec lhci assert --config=./lighthouserc.js
      - uses: actions/upload-artifact@v7
        if: always()
        with:
          name: lighthouseci-prod-report
          path: .lighthouseci/
          retention-days: 90
