Integrar com CI/CD

O CodeMender pode verificar cada solicitação de envio no pipeline de integração e entrega contínua (CI/CD). A verificação falha quando o CodeMender encontra uma vulnerabilidade com gravidade CRITICAL ou HIGH no código que a solicitação de extração muda. As descobertas no código que não foram alteradas pela solicitação de envio aparecem no relatório, mas não causam falha na verificação.

Esta página mostra como fazer o seguinte:

  • Verifique as solicitações de pull com o GitHub Actions e faça com que o CodeMender abra uma solicitação de envio com correções.
  • Verificar solicitações de pull com o Cloud Build.
  • Verifique as mudanças antes de cada commit com um hook de pré-commit do Git.

Como funcionam as verificações de solicitação de envio

Para verificar uma solicitação de envio, execute cm find com a flag --diff e a ramificação base da solicitação de pull:

cm find . --diff=origin/main

Em resposta a esse comando, o CodeMender faz o seguinte:

  1. Compara a ramificação da solicitação de envio com a ramificação de base e verifica os arquivos de origem modificados, além dos arquivos que dependem diretamente deles, como chamadores e importadores.
  2. Distingue novas vulnerabilidades introduzidas ou expostas pela solicitação de envio de descobertas preexistentes, que são rotuladas como [LEGACY / UNTOUCHED]. A verificação de CI bloqueia apenas vulnerabilidades causadas pela solicitação de extração.
  3. Sai com o status 1 quando uma descoberta causada pela solicitação de envio corresponde a uma gravidade em --fail-on. O padrão é CRITICAL,HIGH.

Para mais informações sobre como o --diff se compara a outros modos de verificação, consulte Modos de localização do CodeMender.

Antes de começar

O CodeMender está disponível para um grupo limitado de clientes no Acesso antecipado. Entre em contato com sua equipe de vendas para ter acesso.

  1. In the Cloud de Confiance console, on the project selector page, select or create a Cloud de Confiance project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. If you're using an existing project for this guide, verify that you have the permissions required to complete this guide. If you created a new project, then you already have the required permissions.

  3. Verify that billing is enabled for your Cloud de Confiance project.

  4. Enable the Agent Platform API and Cloud Resource Manager API APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  5. Install the Google Cloud CLI.

  6. Configure the gcloud CLI to use your federated identity.

    For more information, see Sign in to the gcloud CLI with your federated identity.

  7. To initialize the gcloud CLI, run the following command:

    gcloud init

Confira se a versão da CLI do CodeMender é compatível com verificações de solicitação de envio. Os pipelines neste documento baixam a versão estável mais recente sempre que são executados. Para verificar uma instalação local, execute cm find --help e procure a flag --diff. Para atualizar a CLI, execute cm update. Para mais informações, consulte Instalar e configurar a CLI.

Funções exigidas

Para receber as permissões necessárias para configurar integrações de CI/CD para o CodeMender, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto:

Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias usando papéis personalizados ou outros papéis predefinidos.

Para garantir que a conta de serviço de CI/CD tenha as permissões necessárias para executar o CodeMender em um pipeline de CI/CD, peça ao administrador para conceder os seguintes papéis do IAM à conta de serviço de CI/CD:

Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

O administrador também pode conceder à conta de serviço de CI/CD as permissões necessárias por meio de papéis personalizados ou outros papéis predefinidos.

Considerações sobre segurança

Quando você executa o CodeMender em um fluxo de trabalho do GitHub Actions, um gatilho de build do Cloud Build ou um hook de pré-commit do Git, o CodeMender é executado sem pedir confirmação. Antes de configurar essas integrações, considere o seguinte:

  • Solicitações de confirmação: a flag --yes desativa as solicitações de confirmação dos comandos do agente e gravações de arquivos. A flag --bypass-warning ignora o aviso de que o agente pode modificar arquivos e executar comandos no sistema. Antes de usar essas flags, leia os termos de prévia no início deste documento, incluindo os termos sobre a desativação da confirmação humana.
  • Sandbox: os pipelines desativam o sandbox do CodeMender com --sandbox=false. Os comandos executados pelo agente, como builds e testes ao corrigir uma descoberta, têm o mesmo acesso que o job, incluindo as credenciais e o acesso à rede doCloud de Confiance by S3NS . O sandbox do Linux usa namespaces de usuário, que alguns ambientes de CI, como contêineres sem privilégios, não oferecem suporte. Desative o sandbox apenas em ambientes isolados e descartáveis. Se o ambiente de CI for compatível com a sandbox, remova --sandbox=false.
  • Executores: execute o fluxo de trabalho do GitHub Actions em executores hospedados no GitHub, como ubuntu-24.04, que executam cada job em uma nova máquina virtual. Não use executores autohospedados que sejam reutilizados entre jobs.
  • Código não confiável: o código em uma solicitação de envio pode conter texto que tenta direcionar o agente. O fluxo de trabalho do GitHub Actions verifica apenas solicitações de pull de ramificações no mesmo repositório, que só podem ser criadas por usuários com acesso de gravação. No Cloud Build, use o controle de comentários para que um proprietário ou colaborador precise aprovar builds para solicitações de pull de outros colaboradores.
  • Acesso: conceda a cada conta de serviço apenas os papéis necessários do Identity and Access Management (IAM) para o pipeline.

Verificar solicitações de pull com o GitHub Actions

O fluxo de trabalho nesta seção verifica cada solicitação de envio em um repositório no GitHub.com. Quando o CodeMender encontra uma vulnerabilidade com gravidade CRITICAL ou HIGH nas mudanças da solicitação de envio, o fluxo de trabalho faz o seguinte:

  • Falha na verificação do CodeMender.
  • Executa cm fix para cada descoberta e abre uma solicitação de envio com as correções na ramificação da solicitação de envio.

O fluxo de trabalho também faz upload das descobertas para a verificação de código do GitHub.

Configurar a federação de identidade da carga de trabalho

O fluxo de trabalho é autenticado no Cloud de Confiance com a federação de identidade da carga de trabalho. Assim, você não armazena uma chave de conta de serviço no GitHub. Execute os seguintes comandos com a Google Cloud CLI:

  1. Defina variáveis de shell para seu projeto e repositório:

    PROJECT_ID="PROJECT_ID"
    GITHUB_ORG="GITHUB_ORG"
    REPO="GITHUB_ORG/REPOSITORY"
    

    Substitua:

    • PROJECT_ID: o ID do projeto Cloud de Confiance .
    • GITHUB_ORG: o nome da sua organização do GitHub ou seu nome de usuário do GitHub para um repositório em uma conta pessoal.
    • REPOSITORY: o nome do repositório do GitHub.
  2. Ative as APIs que a federação de identidade da carga de trabalho usa:

    gcloud services enable iam.googleapis.com \
        cloudresourcemanager.googleapis.com iamcredentials.googleapis.com \
        sts.googleapis.com --project="${PROJECT_ID}"
    
  3. Crie uma conta de serviço para o fluxo de trabalho e conceda a ela o papel do IAM de usuário da plataforma do agente (roles/aiplatform.user):

    gcloud iam service-accounts create codemender-ci \
        --project="${PROJECT_ID}" \
        --display-name="CodeMender CI"
    
    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
        --member="serviceAccount:codemender-ci@${PROJECT_ID}.s3ns.iam.gserviceaccount.com" \
        --role="roles/aiplatform.user"
    
  4. Crie um pool de identidade da carga de trabalho. Se você já tiver um pool para o GitHub Actions, pule esta etapa e use o ID do pool em vez de github nas etapas a seguir.

    gcloud iam workload-identity-pools create github \
        --project="${PROJECT_ID}" \
        --location="global" \
        --display-name="GitHub Actions"
    
  5. Crie um provedor para o GitHub no pool. A condição de atributo aceita tokens apenas de repositórios que o GITHUB_ORG possui.

    gcloud iam workload-identity-pools providers create-oidc codemender \
        --project="${PROJECT_ID}" \
        --location="global" \
        --workload-identity-pool="github" \
        --display-name="CodeMender" \
        --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
        --attribute-condition="assertion.repository_owner == '${GITHUB_ORG}'" \
        --issuer-uri="https://token.actions.githubusercontent.com"
    
  6. Permita que os fluxos de trabalho no seu repositório usem a conta de serviço:

    POOL_ID=$(gcloud iam workload-identity-pools describe github \
        --project="${PROJECT_ID}" \
        --location="global" \
        --format="value(name)")
    
    gcloud iam service-accounts add-iam-policy-binding \
        "codemender-ci@${PROJECT_ID}.s3ns.iam.gserviceaccount.com" \
        --project="${PROJECT_ID}" \
        --role="roles/iam.workloadIdentityUser" \
        --member="principalSet://iam.googleapis.com/${POOL_ID}/attribute.repository/${REPO}"
    
  7. Acesse o nome completo do provedor. Você precisará dele na próxima seção.

    gcloud iam workload-identity-pools providers describe codemender \
        --project="${PROJECT_ID}" \
        --location="global" \
        --workload-identity-pool="github" \
        --format="value(name)"
    

    A saída será assim:

    projects/123456789/locations/global/workloadIdentityPools/github/providers/codemender
    

As mudanças na federação de identidade da carga de trabalho e no IAM podem levar até 5 minutos para entrar em vigor. Para mais informações, consulte Configurar a federação de identidade de cargas de trabalho com pipelines de implantação.

Adicionar secrets do repositório

No repositório, acesse Configurações > Chaves secretas e variáveis > Ações e adicione as seguintes chaves secretas do repositório:

Secret Valor
GCP_PROJECT_ID O ID do projeto.
GCP_WIF_PROVIDER O nome completo do provedor da seção anterior.
GCP_WIF_SERVICE_ACCOUNT codemender-ci@PROJECT_ID.s3ns.iam.gserviceaccount.com, em que PROJECT_ID é o ID do projeto.

Para mais informações, consulte Como usar secrets no GitHub Actions.

Configurar as definições do repositório

  1. Para permitir que o trabalho de correção automática abra solicitações de pull, acesse Configurações > Ações > Geral. Em Permissões de fluxo de trabalho, selecione Permitir que o GitHub Actions crie e aprove solicitações de pull e clique em Salvar. Um repositório em uma organização herda essa configuração da organização. Se não for possível mudar, peça ajuda a um proprietário da organização. Se você não usa a correção automática, pule esta etapa. Para mais informações, consulte Como gerenciar as configurações do GitHub Actions para um repositório.
  2. Verifique se a verificação de código do GitHub está disponível para o repositório. Para repositórios privados e internos, a verificação de código requer o GitHub Code Security. Se a verificação de código não estiver disponível, exclua a etapa Fazer upload de resultados para a verificação de código e as permissões security-events e actions do job de verificação. Caso contrário, o upload e o job de verificação vão falhar. Para mais informações, consulte Como fazer upload de um arquivo SARIF para o GitHub.

Adicionar o fluxo de trabalho

Confirme o seguinte fluxo de trabalho no repositório como .github/workflows/codemender.yml:

name: CodeMender

on:
  pull_request:

permissions: {}

defaults:
  run:
    shell: bash

env:
  CM_DOWNLOAD_URL: https://artifactregistry.googleapis.com/download/v1/projects/cmoc-prod/locations/us/repositories/codemender-cli-production/files/cm%3Astable%3Acm-linux-amd64.zip:download?alt=media

jobs:
  scan:
    name: CodeMender scan
    # Workflows for fork and Dependabot pull requests can't read this
    # repository's secrets, so they can't authenticate to Google Cloud.
    if: >-
      github.event.pull_request.head.repo.full_name == github.repository &&
      github.actor != 'dependabot[bot]'
    runs-on: ubuntu-24.04
    timeout-minutes: 15
    permissions:
      contents: read
      id-token: write         # Workload Identity Federation
      security-events: write  # Upload SARIF to code scanning
      actions: read           # Upload SARIF from a private repository
    outputs:
      findings: ${{ steps.scan.outputs.findings }}
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0  # cm needs the base branch history
          persist-credentials: false

      - uses: google-github-actions/auth@v3
        with:
          project_id: ${{ secrets.GCP_PROJECT_ID }}
          workload_identity_provider: ${{ secrets.GCP_WIF_PROVIDER }}
          service_account: ${{ secrets.GCP_WIF_SERVICE_ACCOUNT }}

      - name: Install the CodeMender CLI
        run: |
          curl -fsSL -o "$RUNNER_TEMP/cm.zip" "$CM_DOWNLOAD_URL"
          unzip -q -o "$RUNNER_TEMP/cm.zip" -d "$RUNNER_TEMP/cm"
          echo "$RUNNER_TEMP/cm" >> "$GITHUB_PATH"

      - name: Scan the pull request
        id: scan
        env:
          BASE_REF: ${{ github.base_ref }}
          FAIL_ON: CRITICAL,HIGH
        run: |
          cm init
          status=0
          cm find . \
            --diff="origin/$BASE_REF" \
            --diff-workers=16 \
            --fail-on="$FAIL_ON" \
            --format=sarif \
            --output=codemender.sarif \
            --sandbox=false \
            --yes \
            --bypass-warning || status=$?

          # Save the findings that failed the scan for the autofix job. Like the
          # CI gate, skip findings labeled [LEGACY / UNTOUCHED]: they're in code
          # that the pull request didn't change.
          echo '[]' > "$RUNNER_TEMP/codemender-findings.json"
          if [ "$status" -ne 0 ]; then
            cm report --format=json --status=OPEN \
              | jq --arg fail_on "$FAIL_ON" '
                  ($fail_on | ascii_upcase | split(",")) as $severities
                  | [.[]
                     | select(.title | startswith("[LEGACY / UNTOUCHED]") | not)
                     | select(.severity | ascii_upcase | IN($severities[]))]' \
              > "$RUNNER_TEMP/codemender-findings.json"
          fi
          echo "findings=$(jq length "$RUNNER_TEMP/codemender-findings.json")" >> "$GITHUB_OUTPUT"
          exit "$status"

      - name: Upload results to code scanning
        if: ${{ !cancelled() && hashFiles('codemender.sarif') != '' }}
        uses: github/codeql-action/upload-sarif@v4
        with:
          sarif_file: codemender.sarif
          category: codemender

      - name: Save findings for autofix
        if: ${{ !cancelled() && steps.scan.outputs.findings > 0 }}
        uses: actions/upload-artifact@v7
        with:
          name: codemender-findings
          path: ${{ runner.temp }}/codemender-findings.json
          retention-days: 1

  autofix:
    name: CodeMender autofix
    needs: scan
    if: ${{ !cancelled() && needs.scan.outputs.findings > 0 }}
    runs-on: ubuntu-24.04
    timeout-minutes: 60
    permissions:
      contents: write        # Push the fix branch
      pull-requests: write   # Open the fix pull request
      id-token: write        # Workload Identity Federation
    steps:
      - uses: actions/checkout@v7
        with:
          ref: ${{ github.head_ref }}
          persist-credentials: false

      - uses: google-github-actions/auth@v3
        with:
          project_id: ${{ secrets.GCP_PROJECT_ID }}
          workload_identity_provider: ${{ secrets.GCP_WIF_PROVIDER }}
          service_account: ${{ secrets.GCP_WIF_SERVICE_ACCOUNT }}

      - name: Install the CodeMender CLI
        run: |
          curl -fsSL -o "$RUNNER_TEMP/cm.zip" "$CM_DOWNLOAD_URL"
          unzip -q -o "$RUNNER_TEMP/cm.zip" -d "$RUNNER_TEMP/cm"
          echo "$RUNNER_TEMP/cm" >> "$GITHUB_PATH"

      - uses: actions/download-artifact@v8
        with:
          name: codemender-findings
          path: ${{ runner.temp }}/codemender

      - name: Fix findings
        run: |
          # Keep CodeMender state and the auth action's credentials file out of
          # the commits, and out of the `git clean` that cm fix runs.
          printf '%s\n' .cm_project 'gha-creds-*.json' >> .git/info/exclude

          cm init
          # Fix in the repository root instead of each file's directory.
          printf 'project_paths:\n  - "%s"\n' "$GITHUB_WORKSPACE" \
            >> ~/.codemender/config.yaml
          cm report import -f "$RUNNER_TEMP/codemender/codemender-findings.json"

          git config user.name "github-actions[bot]"
          git config user.email \
            "41898282+github-actions[bot]@users.noreply.github.com"

          cm report --format=json --status=OPEN \
            | jq -r '.[] | [.finding_id, .title] | @tsv' \
            > "$RUNNER_TEMP/findings.tsv"
          while IFS=$'\t' read -r id title; do
            # cm fix exits 0 when it makes no edits, so also check for changes.
            if cm fix "$id" \
                 --sandbox=false --yes --bypass-warning < /dev/null &&
               ! git diff --quiet; then
              git commit -q -a -m "Fix $title" -m "CodeMender finding $id"
            else
              echo "::warning::CodeMender didn't fix \"$title\" ($id)."
            fi
            # Discard files the fix agent created, such as test output.
            git reset -q --hard
            git clean -q -fd
          done < "$RUNNER_TEMP/findings.tsv"

      - uses: peter-evans/create-pull-request@v8
        with:
          branch: codemender/fix-pr-${{ github.event.pull_request.number }}
          base: ${{ github.head_ref }}
          title: "CodeMender fixes for #${{ github.event.pull_request.number }}"
          body: |
            CodeMender generated these fixes for findings in #${{ github.event.pull_request.number }}.
            Review each commit before you merge this pull request into `${{ github.head_ref }}`.

Detalhes do fluxo de trabalho

O diagrama a seguir mostra como os jobs de verificação e correção automática de solicitação de envio interagem:

Uma solicitação de envio é verificada. Se não houver indícios de bloqueio, a verificação será aprovada. Caso contrário, a verificação falha, o CodeMender abre uma solicitação de envio de correção, e a fusão das correções verifica a solicitação de envio novamente.

O job verificação do CodeMender faz o seguinte:

  1. Confira a solicitação de envio com o histórico completo. Para solicitações de pull, o GitHub verifica um commit de mesclagem da ramificação da solicitação de envio na ramificação de base.
  2. Faz a autenticação no Cloud de Confiance e baixa a versão estável mais recente da CLI do CodeMender.
  3. Executa cm find --diff na ramificação de base. O job vai falhar se o CodeMender encontrar uma vulnerabilidade com uma gravidade listada em FAIL_ON nas mudanças da solicitação de pull.
  4. Faz upload do relatório para a verificação de código do GitHub, mesmo quando a verificação falha no job. O relatório inclui descobertas rotuladas como [LEGACY / UNTOUCHED]. A verificação de código também mostra uma descoberta nas verificações da solicitação de envio quando todas as linhas da descoberta estão no diff da solicitação de envio.
  5. Salva as descobertas que causaram a falha do job para o job de correção automática.

O job de verificação não é executado para solicitações de pull de bifurcações ou do Dependabot, porque os fluxos de trabalho dessas solicitações de pull não podem ler os secrets do repositório. O GitHub informa um job ignorado como bem-sucedido, de modo que a verificação não bloqueia essas solicitações de pull, mesmo que você a torne obrigatória. Revise essas solicitações de pull por conta própria ou verifique-as localmente com cm find --diff.

O job de correção automática do CodeMender é executado quando o job de verificação salva descobertas. Ele faz o seguinte:

  1. Verifica a ramificação da solicitação de envio.
  2. Executa cm fix para cada descoberta e confirma cada correção separadamente. Se o CodeMender não corrigir uma descoberta, o job vai registrar um aviso. O job confirma apenas as mudanças nos arquivos que já estão no repositório e descarta todos os arquivos criados pelo agente de correção, como a saída de teste.
  3. Abre uma solicitação de envio da ramificação codemender/fix-pr-NUMBER para a ramificação de solicitação de pull, em que NUMBER é o número da solicitação de envio. Se a solicitação de envio de correção já existir, o job vai atualizá-la. Se o CodeMender não corrigir nenhuma descoberta ou se o job atingir o tempo limite de 60 minutos, ele não abrirá uma solicitação de envio.

Revisar e mesclar correções

O GitHub não executa automaticamente fluxos de trabalho para solicitações de pull que um fluxo de trabalho cria com o GITHUB_TOKEN. Para verificar a solicitação de envio de correção, um usuário com acesso de gravação ao repositório clica em Aprovar fluxos de trabalho para execução na solicitação de pull de correção.

Quando você mescla a solicitação de envio de correção, a ramificação da solicitação de envio muda, e o fluxo de trabalho verifica a solicitação de envio original novamente.

Personalizar o fluxo de trabalho

É possível personalizar o fluxo de trabalho das seguintes maneiras:

  • Para mudar as gravidades que causam falha na verificação, na etapa Verificar a solicitação de pull, defina FAIL_ON como uma lista de gravidades separada por vírgulas sem espaços, como CRITICAL,HIGH,MEDIUM. Os valores válidos são CRITICAL, HIGH, MEDIUM e LOW.
  • Para informar as descobertas sem falhar na verificação, defina FAIL_ON: "". O fluxo de trabalho ainda faz upload de descobertas para a verificação de código, mas não executa o job de correção automática.
  • Para verificar solicitações de pull em apenas algumas ramificações, adicione um filtro branches ao acionador pull_request. O fluxo de trabalho não verifica as solicitações de pull de correção, porque a base delas é uma ramificação de solicitação de envio:

    on:
      pull_request:
        branches: [main]
    
  • Para desativar a correção automática, exclua o job autofix e a etapa Salvar descobertas para correção automática.

Verificar solicitações de pull com o Cloud Build

A versão nesta seção verifica cada solicitação de envio em um repositório do GitHub conectado ao Cloud Build. O build e a verificação do GitHub falham quando o CodeMender encontra uma vulnerabilidade com gravidade CRITICAL ou HIGH nas mudanças da solicitação de pull. O build não corrige as descobertas.

Antes de começar, faça o seguinte:

  1. Conecte seu repositório ao Cloud Build como um repositório de segunda geração. Para mais informações, consulte Conectar-se a um repositório do GitHub.
  2. Ative a API Cloud Build e a API IAM no projeto que tem acesso ao CodeMender. O build usa o CodeMender no projeto que executa o build.

    PROJECT_ID="PROJECT_ID"
    gcloud services enable cloudbuild.googleapis.com iam.googleapis.com \
        --project="${PROJECT_ID}"
    

    Substitua PROJECT_ID pelo ID do projeto do Cloud de Confiance.

Criar uma conta de serviço

Crie uma conta de serviço para o build. Conceda a ele o papel do IAM de usuário da Agent Platform (roles/aiplatform.user) para usar o CodeMender e o papel de gravador de registros (roles/logging.logWriter) para gravar registros de build:

SA="codemender-build@${PROJECT_ID}.s3ns.iam.gserviceaccount.com"

gcloud iam service-accounts create codemender-build \
    --project="${PROJECT_ID}" \
    --display-name="CodeMender Cloud Build"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:${SA}" \
    --role="roles/aiplatform.user"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:${SA}" \
    --role="roles/logging.logWriter"

Para salvar relatórios SARIF em um bucket do Cloud Storage, conceda à conta de serviço acesso ao bucket:

BUCKET="BUCKET"

gcloud storage buckets add-iam-policy-binding "gs://${BUCKET}" \
    --member="serviceAccount:${SA}" \
    --role="roles/storage.objectUser"

Substitua BUCKET pelo nome do bucket do Cloud Storage.

Adicionar a configuração do build

Confirme a seguinte configuração de build na raiz do repositório como cloudbuild.yaml:

# Scans a pull request with CodeMender. The build fails when CodeMender finds
# a CRITICAL or HIGH vulnerability in the pull request's changes.
steps:
  - id: install-codemender
    name: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
    script: |
      #!/usr/bin/env bash
      set -euo pipefail
      curl -fsSL -o /tmp/cm.zip "$_CM_DOWNLOAD_URL"
      python3 -m zipfile -e /tmp/cm.zip /workspace/.codemender-cli
      chmod +x /workspace/.codemender-cli/cm

  - id: fetch-history
    name: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
    script: |
      #!/usr/bin/env bash
      set -euo pipefail
      : "${_BASE_BRANCH:?Run this build from a pull request trigger.}"
      # Triggers check out only the pull request's commit. CodeMender needs the
      # history back to where the pull request branched from the base branch.
      # Fetch from origin, or from GitHub if origin isn't configured.
      refspec="+refs/heads/$_BASE_BRANCH:refs/remotes/origin/$_BASE_BRANCH"
      git fetch --quiet --unshallow origin "$refspec" ||
        git fetch --quiet --unshallow \
          "https://github.com/$REPO_FULL_NAME.git" "$refspec"
      merge_base=$(git merge-base HEAD "origin/$_BASE_BRANCH")
      echo "Merge base with $_BASE_BRANCH: $merge_base"

  - id: scan
    name: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
    script: |
      #!/usr/bin/env bash
      set -uo pipefail
      export PATH="/workspace/.codemender-cli:$PATH"
      # The project that has access to CodeMender.
      export GOOGLE_CLOUD_PROJECT="$PROJECT_ID"
      cm init || exit 1
      status=0
      cm find . \
        --diff="origin/$_BASE_BRANCH" \
        --diff-workers=16 \
        --fail-on=CRITICAL,HIGH \
        --format=sarif \
        --output=codemender.sarif \
        --sandbox=false \
        --yes \
        --bypass-warning || status=$?

      # cm find writes the SARIF report when the scan completes.
      if [ -f codemender.sarif ]; then
        # cm find doesn't print finding details, so print them here.
        cm report --status=OPEN --format=md
        if [ -n "${_REPORT_BUCKET:-}" ]; then
          gcloud storage cp codemender.sarif \
            "gs://$_REPORT_BUCKET/codemender/$BUILD_ID.sarif" || status=1
        fi
      fi
      exit "$status"

substitutions:
  _CM_DOWNLOAD_URL: https://artifactregistry.googleapis.com/download/v1/projects/cmoc-prod/locations/us/repositories/codemender-cli-production/files/cm%3Astable%3Acm-linux-amd64.zip:download?alt=media
  _REPORT_BUCKET: ''  # Optional: a bucket to save the SARIF report in.

timeout: 1200s
options:
  automapSubstitutions: true
  logging: CLOUD_LOGGING_ONLY

Criar o gatilho

Crie um gatilho que execute o build para cada solicitação de envio em main:

REGION="REGION"
CONNECTION="CONNECTION"
REPOSITORY="REPOSITORY"

gcloud builds triggers create github \
    --project="${PROJECT_ID}" \
    --region="${REGION}" \
    --name="codemender-scan" \
    --repository="projects/${PROJECT_ID}/locations/${REGION}/connections/${CONNECTION}/repositories/${REPOSITORY}" \
    --pull-request-pattern='^main$' \
    --comment-control=COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY \
    --build-config=cloudbuild.yaml \
    --service-account="projects/${PROJECT_ID}/serviceAccounts/${SA}"

Substitua:

  • REGION: a região da conexão do repositório do Cloud Build.
  • CONNECTION: o nome da conexão do repositório do Cloud Build.
  • REPOSITORY: o nome do repositório conectado no Cloud Build.

Observe as seguintes opções:

  • --pull-request-pattern é uma expressão regular para a ramificação base da solicitação de envio. Use ^ e $ para corresponder ao nome completo da ramificação.
  • Com o --comment-control=COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY, o build é executado automaticamente para solicitações de pull de proprietários e colaboradores do repositório. Para solicitações de pull de outros colaboradores, o build é executado depois que um proprietário ou colaborador comenta /gcbrun na solicitação de envio.
  • Para salvar relatórios SARIF em um bucket, adicione --substitutions=_REPORT_BUCKET="${BUCKET}".

Também é possível criar o gatilho no console do Cloud de Confiance . Para mais informações, consulte Como criar repositórios do GitHub.

Para mostrar os registros de build no GitHub, adicione --include-logs-with-status ao criar o gatilho e conceda à conta de serviço o papel de Visualizador de registros (roles/logging.viewer). Qualquer pessoa que possa visualizar a verificação no GitHub poderá ler os registros de build, incluindo as descobertas.

Como o build funciona

A versão tem três etapas:

  1. install-codemender baixa a versão estável mais recente da CLI do CodeMender.
  2. fetch-history busca a ramificação base e o histórico de que o CodeMender precisa. O Cloud Build faz o check-out apenas do commit que iniciou o build. A etapa busca do origin remoto. Se origin não estiver configurado, a etapa vai buscar no GitHub sem credenciais, o que funciona apenas para repositórios públicos. Nesse caso, um repositório particular precisa de credenciais, como uma chave SSH. Para mais informações, consulte Como acessar o GitHub de um build usando chaves SSH.
  3. scan executa cm find --diff na ramificação de base. Quando a verificação é concluída, a etapa imprime todas as descobertas no registro de build. Se você definir _REPORT_BUCKET, a etapa também vai copiar o relatório SARIF para gs://BUCKET/codemender/BUILD_ID.sarif.

Para mudar as gravidades que falham na build, edite --fail-on na etapa scan. Se você executar o build sem um gatilho de solicitação de envio, ele vai falhar com a mensagem Run this build from a pull request trigger.

Verificar antes de cada commit

Um hook de pré-confirmação do Git pode verificar as mudanças preparadas e bloquear a confirmação quando o CodeMender encontrar uma vulnerabilidade com gravidade CRITICAL ou HIGH. Os desenvolvedores podem pular o hook. Portanto, use-o além da verificação na CI, não em vez dela.

Cada desenvolvedor que usa o hook precisa do seguinte:

  • A CLI do CodeMender, instalada e configurada conforme descrito em Instalar e configurar a CLI, incluindo gcloud auth application-default login e cm init. O hook precisa de cm no PATH.
  • O papel de usuário da Agent Platform (roles/aiplatform.user) em um projeto com acesso ao CodeMender. O CodeMender usa o projeto na variável de ambiente GOOGLE_CLOUD_PROJECT. Se essa variável não estiver definida, o CodeMender usará o projeto das suas Application Default Credentials ou o projeto padrão da CLI gcloud.

Para adicionar o hook, salve o script a seguir como .git/hooks/pre-commit no seu repositório:

#!/bin/sh
# Scans staged changes with CodeMender before each commit.
if ! cm find . --diff --staged --fail-on=CRITICAL,HIGH \
    --yes --bypass-warning; then
  echo "CodeMender blocked this commit. To see the findings, run:" >&2
  echo "  cm report --status=OPEN" >&2
  echo "To commit anyway, run git commit --no-verify." >&2
  exit 1
fi

Torne o script executável e adicione .cm_project ao arquivo .gitignore para não confirmar o arquivo que o CodeMender cria para rastrear o repositório:

chmod +x .git/hooks/pre-commit
echo .cm_project >> .gitignore

Quando você executa git commit, o hook verifica os arquivos com mudanças preparadas. A verificação pode levar alguns minutos. O hook não desativa o sandbox do CodeMender.

Para fazer commit sem a verificação, execute git commit --no-verify.

Sinalizações de verificação

As flags cm find a seguir controlam as verificações de solicitação de envio. Para todas as flags, execute cm find --help:

Sinalização padrão Descrição
--diff[=REF] Desativado Verifica as mudanças em comparação com REF, como origin/main. Sem REF, verifica mudanças não confirmadas em arquivos rastreados (em comparação com HEAD). Não pode ser usado com --deep.
--staged Desativado Com --diff, verifica apenas as mudanças preparadas.
--diff-depth DEPTH 1 Profundidade de travessia para análise de impacto (1 a 3, padrão: 1 transmissão).
--diff-workers COUNT 4 O número de arquivos a serem verificados ao mesmo tempo, de 1 a 16.
--diff-max-neighbors COUNT 10 O número máximo de arquivos dependentes a serem verificados.
--fail-on SEVERITIES CRITICAL,HIGH Com --diff, as gravidades que fazem com que cm find saia com o status 1. Com um valor vazio, as descobertas não afetam o status de saída.
--fail-on-truncation Desativado Com --diff, sai com o status 1 se o CodeMender encontrar mais arquivos dependentes do que o permitido por --diff-max-neighbors.
--format FORMAT table O formato do relatório: table, json ou sarif.
--output FILE Saída padrão O arquivo em que o relatório será gravado.

Solução de problemas

Nesta seção, descrevemos como resolver problemas comuns ao executar o CodeMender em pipelines de CI/CD.

Permissão negada

O registro mostra uma linha como esta:

[1/1] ❌ src/app.py: start session failed: StartSession failed with HTTP 403 Forbidden.

A mensagem também pode incluir Permission 'aiplatform.interactions.create' denied. Verifique se:

  • O projeto tem acesso ao CodeMender.
  • A conta de serviço ou o usuário tem o papel de usuário da Agent Platform (roles/aiplatform.user) no projeto.
  • A API Agent Platform está ativada no projeto.
  • O CodeMender usa o projeto certo. No GitHub Actions, verifique o segredo GCP_PROJECT_ID. O Cloud Build usa o projeto que executa o build. Localmente, verifique a variável de ambiente GOOGLE_CLOUD_PROJECT ou o projeto padrão se a variável não estiver definida.

Configuração do recurso em andamento

Se o registro mostrar Resource setup has just started. Please try again shortly. ou Resource setup is in progress. Please try again shortly., o CodeMender está configurando recursos para seu projeto, o que geralmente leva alguns minutos. Execute o job novamente mais tarde.

Flag desconhecida: --diff

Se cm find falhar com Error: unknown flag: --diff, sua versão da CLI não vai oferecer suporte a verificações de solicitação de envio. Execute cm update ou faça o download da versão mais recente.

Branch de base não encontrado

Se cm find falhar com um erro como este, a ramificação de base não estará no checkout:

Error: retrieving VCS diff: git diff failed: exit status 128: fatal: ambiguous argument 'origin/main': unknown revision or path not in the working tree.

Busque a ramificação de base e o histórico dela antes de executar cm find. No GitHub Actions, defina fetch-depth: 0 em actions/checkout.

Arquivos não verificados

Uma linha com ❌, como [1/1] ❌ src/app.py: start session failed, significa que o CodeMender não conseguiu verificar esse arquivo. Verifique o erro na linha e execute o job de novo.

Nenhuma solicitação de envio de correção

Se o fluxo de trabalho não abrir uma solicitação de envio de correção, verifique o seguinte:

  • Se o job de correção automática falhar ao criar a solicitação de envio, ative a opção Permitir que as ações do GitHub criem e aprovem solicitações de pull. Para mais informações, consulte Configurar as definições do repositório.
  • Se o trabalho de correção automática for concluído sem abrir uma solicitação de envio, o CodeMender não corrigiu nenhuma descoberta. O registro do job mostra um aviso para cada descoberta que o CodeMender não corrigiu.

Falha no upload da verificação de código

Se a etapa de upload falhar com GitHub Code Security or GitHub Advanced Security must be enabled for this repository to use code scanning, ative a segurança de código do GitHub para o repositório ou exclua a etapa de upload. Para mais informações, consulte Definir as configurações do repositório.

Alerta não confirmado

Se cm falhar com warning not acknowledged. Please run interactively once to acknowledge or pass --bypass-warning, o CodeMender precisará de confirmação de que não pode pedir em um ambiente não interativo. Adicione --bypass-warning ao comando. Antes de fazer isso, leia os termos de pré-lançamento na parte de cima desta página.

Para receber mais ajuda, entre em contato com sua equipe de vendas.