Scanverra
CI/CD Integration

Guias

Integração CI/CD

Todo endpoint de scanner aceita uma chave de API, então qualquer um deles pode rodar como uma etapa de pipeline. Esta página explica o que significa a saída de cada ferramenta, como transformá-la em um gate de aprovação/reprovação, e traz exemplos funcionais para quatro plataformas de CI.

Base de pontuação por ferramenta

O que cada endpoint retorna e em qual valor basear seu limite.

FerramentaSaídaBaseGate integrado
Auditoria de site4 pontuações de 0 a 100: performance, seo, accessibility, bestPracticesPontuações brutas do Lighthouse. Convenção: ≥90 bom, 50-89 precisa melhorar, <50 ruim.Nenhum integrado — escolha seu próprio limite para cada pontuação.
Verificação de segurançariskScore de 0 a 100 (quanto maior, mais seguro)100 menos deduções ponderadas por gravidade e limitadas por categoria. Faixas de nota: A+ ≥90 … F <30.Nenhum integrado — escolha seu próprio limite.
Teste de navegadorArrays: jsErrors, brokenLinks, formIssues, imgIssues (cada um com severity: "error" | "warning")Sem pontuação agregada.Baseie o gate na contagem de problemas, por exemplo qualquer severity === "error".
Scanner de repositóriosscore de 0 a 100 + qualityGate: "passed" | "failed"100 menos deduções ponderadas por gravidade, limitadas por categoria.Integrado — reprova automaticamente com qualquer descoberta crítica ou score < 60.

Interrompendo o pipeline

A mecânica de CI é a mesma independentemente da plataforma: uma etapa que termina com código diferente de zero falha o job. Para realmente bloquear a mesclagem de um PR ou merge request, adicione esse job como uma verificação obrigatória/status check nas configurações de proteção de branch ou aprovação de merge request do seu host de repositório — uma etapa falha sozinha só aparece em vermelho, ela não impede uma mesclagem por si só.

Exemplos de pipeline

As mesmas quatro verificações — Auditoria, Verificação de segurança, Teste de navegador, Scanner de repositórios — escritas para quatro plataformas. Escolha seu sistema de CI abaixo.

name: Scanverra checks
on: [pull_request]

jobs:
  scanverra:
    runs-on: ubuntu-latest
    env:
      API_KEY: ${{ secrets.SCANVERRA_API_KEY }}
      TARGET_URL: https://staging.example.com   # your deployed preview URL
    steps:
      - name: Website Audit (perf/SEO/a11y)
        run: |
          RES=$(curl -sf -X POST https://www.scanverra.com/api/audit \
            -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
            -d "{\"url\":\"$TARGET_URL\"}")
          echo "$RES" | jq .
          PERF=$(echo "$RES" | jq '.scores.performance')
          A11Y=$(echo "$RES" | jq '.scores.accessibility')
          if (( $(echo "$PERF < 50" | bc -l) )) || (( $(echo "$A11Y < 90" | bc -l) )); then
            echo "::error::Audit failed thresholds (perf=$PERF, a11y=$A11Y)"
            exit 1
          fi

      - name: Security Scan
        run: |
          RES=$(curl -sf -X POST https://www.scanverra.com/api/security-scan \
            -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
            -d "{\"url\":\"$TARGET_URL\"}")
          RISK=$(echo "$RES" | jq '.riskScore')
          echo "riskScore=$RISK"
          [ "$RISK" -lt 70 ] && { echo "::error::Security risk score too low ($RISK)"; exit 1; }
          true

      - name: Browser Test (JS errors, broken links)
        run: |
          RES=$(curl -sf -X POST https://www.scanverra.com/api/browser-test \
            -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
            -d "{\"url\":\"$TARGET_URL\"}")
          ERRORS=$(echo "$RES" | jq '[.jsErrors[]? | select(.severity=="error")] | length')
          [ "$ERRORS" -gt 0 ] && { echo "::error::$ERRORS JS errors found"; exit 1; }
          true

      - name: Repo Scan (SAST, secrets, deps, quality gate)
        run: |
          SCAN_ID=$(curl -sf -X POST https://www.scanverra.com/api/repo/scan \
            -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
            -d '{"owner":"your-org","repo":"your-repo","branch":"${{ github.head_ref }}"}' | jq -r .scanId)

          for i in $(seq 1 30); do
            RESULT=$(curl -sf "https://www.scanverra.com/api/repo/result?id=$SCAN_ID" -H "X-API-Key: $API_KEY")
            STATUS=$(echo "$RESULT" | jq -r .status)
            [ "$STATUS" != "running" ] && break
            sleep 10
          done

          echo "$RESULT" | jq '{score, qualityGate}'
          GATE=$(echo "$RESULT" | jq -r .qualityGate)
          [ "$GATE" = "failed" ] && { echo "::error::Repo quality gate failed"; exit 1; }
          true

Onde armazenar a chave de API como um segredo, por plataforma:

  • GitHub Actions: secret do repositório — Settings → Secrets and variables → Actions.
  • GitLab CI: variável de CI/CD mascarada — Settings → CI/CD → Variables.
  • Azure Pipelines: variável secreta de pipeline (ícone de cadeado) ou um Variable Group em Pipelines → Library.
  • Jenkins: credencial Secret text — Manage Jenkins → Credentials — referenciada via credentials(). A imagem do agente também precisa ter curl, jq e bc instalados; os runners ubuntu-latest hospedados pelo GitHub e pela Azure já os incluem, mas a imagem alpine do GitLab não (daí a etapa apk add).

A etapa do Scanner de repositórios precisa que sua conta do GitHub/Bitbucket/Azure esteja conectada previamente nas configurações da Scanverra — a varredura roda usando o token armazenado ali, não um passado por requisição.

Nota sobre cota: uma chave de API do plano Free tem cota limitada da mesma forma que uma conta web Free — as execuções de CI ainda contam para o seu limite mensal de varreduras e podem esgotá-lo rapidamente se você escanear a cada PR. Chaves de API dos planos Pro, Team e Enterprise não têm limite. Veja Limites e comportamento.

Somente o Scanner de repositórios retorna um campo qualityGate pronto para uso. Para as outras três ferramentas, defina seus próprios limites antecipadamente e mantenha-os consistentes entre os ambientes (por exemplo, não compare a pontuação de segurança de uma URL de staging com um limite ajustado para produção).