Melakukan integrasi dengan CI/CD

CodeMender dapat memindai setiap permintaan pull di pipeline continuous integration dan continuous delivery (CI/CD) Anda. Pemeriksaan gagal saat CodeMender menemukan kerentanan dengan tingkat keparahan CRITICAL atau HIGH dalam kode yang diubah oleh permintaan pull. Temuan dalam kode yang tidak diubah oleh permintaan pull akan muncul dalam laporan, tetapi tidak akan menyebabkan pemeriksaan gagal.

Dokumen ini menunjukkan cara melakukan hal berikut:

  • Pindai permintaan pull dengan GitHub Actions, dan minta CodeMender membuka permintaan pull dengan perbaikan.
  • Memindai permintaan pull dengan Cloud Build.
  • Pindai perubahan Anda sebelum setiap commit dengan hook pra-commit Git.

Cara kerja pemindaian permintaan pull

Untuk memindai permintaan pull, jalankan cm find dengan flag --diff dan cabang dasar permintaan pull:

cm find . --diff=origin/main

Sebagai respons terhadap perintah ini, CodeMender akan melakukan hal berikut:

  1. Membandingkan cabang pull request dengan cabang dasar, dan memindai file sumber yang diubah serta file yang bergantung langsung padanya, seperti pemanggil dan pengimpor.
  2. Membedakan kerentanan baru yang diperkenalkan atau diekspos oleh permintaan pull dari temuan yang sudah ada, yang diberi label [LEGACY / UNTOUCHED]. Pemeriksaan CI Anda hanya memblokir kerentanan yang disebabkan oleh permintaan penarikan.
  3. Keluar dengan status 1 jika temuan yang disebabkan oleh permintaan pull cocok dengan tingkat keparahan di --fail-on. Defaultnya adalah CRITICAL,HIGH.

Untuk mengetahui informasi selengkapnya tentang perbandingan --diff dengan mode pemindaian lainnya, lihat Mode penemuan CodeMender.

Sebelum memulai

CodeMender tersedia untuk sejumlah kecil pelanggan dalam Pratinjau Publik. Hubungi tim penjualan Anda untuk mendapatkan akses.

  1. Login ke akun Google Cloud Anda. Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud 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

  3. 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.

  4. Verify that billing is enabled for your Google Cloud project.

  5. 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

  6. Install the Google Cloud CLI.

  7. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

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

    gcloud init
  9. In the Google Cloud console, on the project selector page, select or create a Google Cloud 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

  10. 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.

  11. Verify that billing is enabled for your Google Cloud project.

  12. 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

  13. Install the Google Cloud CLI.

  14. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

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

    gcloud init

Pastikan rilis CLI CodeMender Anda mendukung pemindaian pull request. Pipeline dalam dokumen ini mendownload rilis stabil terbaru setiap kali dijalankan. Untuk memeriksa penginstalan lokal, jalankan cm find --help dan cari tanda --diff. Untuk mengupdate CLI, jalankan cm update. Untuk mengetahui informasi selengkapnya, lihat Menginstal dan mengonfigurasi CLI.

Peran yang diperlukan

Untuk mendapatkan izin yang Anda perlukan untuk menyiapkan integrasi CI/CD untuk CodeMender, minta administrator Anda untuk memberi Anda peran IAM berikut di project Anda:

Untuk mengetahui informasi selengkapnya tentang pemberian peran, lihat Mengelola akses ke project, folder, dan organisasi.

Anda mungkin juga bisa mendapatkan izin yang diperlukan melalui peran khusus atau peran bawaan lainnya.

Untuk memastikan bahwa akun layanan CI/CD memiliki izin yang diperlukan untuk menjalankan CodeMender di pipeline CI/CD, minta administrator untuk memberikan peran IAM berikut kepada akun layanan CI/CD:

Untuk mengetahui informasi selengkapnya tentang pemberian peran, lihat Mengelola akses ke project, folder, dan organisasi.

Administrator Anda mungkin juga dapat memberikan izin yang diperlukan kepada akun layanan CI/CD melalui peran khusus atau peran yang telah ditetapkan lainnya.

Pertimbangan keamanan

Saat Anda menjalankan CodeMender dalam alur kerja GitHub Actions, pemicu Cloud Build, atau hook pra-commit Git, CodeMender akan berjalan tanpa meminta konfirmasi. Sebelum menyiapkan integrasi ini, pertimbangkan hal berikut:

  • Perintah konfirmasi: Flag --yes menonaktifkan perintah yang meminta Anda mengonfirmasi perintah agen dan penulisan file. Flag --bypass-warning melewati peringatan bahwa agen dapat mengubah file dan menjalankan perintah di sistem Anda. Sebelum Anda menggunakan tanda ini, baca persyaratan Pratinjau di awal dokumen ini, termasuk persyaratan tentang menonaktifkan konfirmasi manusia.
  • Sandbox: Pipeline menonaktifkan sandbox CodeMender dengan --sandbox=false. Perintah yang dijalankan agen, seperti build dan pengujian saat memperbaiki temuan, memiliki akses yang sama dengan tugas, termasuk kredensialGoogle Cloud dan akses jaringannya. Sandbox Linux menggunakan namespace pengguna, yang tidak didukung oleh beberapa lingkungan CI, seperti container tanpa hak istimewa. Nonaktifkan sandbox hanya di lingkungan yang terisolasi dan sekali pakai. Jika lingkungan CI Anda mendukung sandbox, hapus --sandbox=false.
  • Runner: Jalankan alur kerja GitHub Actions di runner yang dihosting GitHub, seperti ubuntu-24.04, yang menjalankan setiap tugas di mesin virtual baru. Jangan gunakan pelari yang dihosting sendiri yang digunakan kembali di antara tugas.
  • Kode yang tidak tepercaya: Kode dalam permintaan pull dapat berisi teks yang mencoba mengarahkan agen. Alur kerja GitHub Actions hanya memindai permintaan pull dari cabang di repositori yang sama, yang hanya dapat dibuat oleh pengguna dengan akses tulis. Untuk Cloud Build, gunakan kontrol komentar sehingga pemilik atau kolaborator harus menyetujui build untuk pull request dari kontributor lain.
  • Akses: Beri setiap akun layanan hanya peran Identity and Access Management (IAM) yang diperlukan untuk pipeline-nya.

Memindai permintaan pull dengan GitHub Actions

Alur kerja di bagian ini memindai setiap permintaan pull di repositori di GitHub.com. Jika CodeMender menemukan kerentanan dengan tingkat keparahan CRITICAL atau HIGH dalam perubahan permintaan pull, alur kerja akan melakukan hal berikut:

  • Gagal dalam pemeriksaan pemindaian CodeMender.
  • Menjalankan cm fix untuk setiap temuan, dan membuka permintaan pull dengan perbaikan ke cabang permintaan pull.

Alur kerja ini juga mengupload temuan ke pemindaian kode GitHub.

Menyiapkan Workload Identity Federation

Alur kerja melakukan autentikasi ke Google Cloud dengan Workload Identity Federation, sehingga Anda tidak perlu menyimpan kunci akun layanan di GitHub. Jalankan perintah berikut dengan Google Cloud CLI:

  1. Tetapkan variabel shell untuk project dan repositori Anda:

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

    Ganti kode berikut:

    • PROJECT_ID: Google Cloud Project ID Anda.
    • GITHUB_ORG: nama organisasi GitHub Anda, atau nama pengguna GitHub Anda untuk repositori di akun pribadi.
    • REPOSITORY: nama repositori GitHub Anda.
  2. Aktifkan API yang digunakan Workload Identity Federation:

    gcloud services enable iam.googleapis.com \
        cloudresourcemanager.googleapis.com iamcredentials.googleapis.com \
        sts.googleapis.com --project="${PROJECT_ID}"
    
  3. Buat akun layanan untuk alur kerja, dan berikan peran IAM Pengguna Agent Platform (roles/aiplatform.user) kepadanya:

    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}.iam.gserviceaccount.com" \
        --role="roles/aiplatform.user"
    
  4. Membuat workload identity pool. Jika Anda sudah memiliki pool untuk GitHub Actions, lewati langkah ini, dan gunakan ID pool Anda, bukan github dalam langkah-langkah berikut.

    gcloud iam workload-identity-pools create github \
        --project="${PROJECT_ID}" \
        --location="global" \
        --display-name="GitHub Actions"
    
  5. Buat penyedia untuk GitHub di pool. Kondisi atribut hanya menerima token dari repositori yang dimiliki GITHUB_ORG.

    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. Izinkan alur kerja di repositori Anda menggunakan akun layanan:

    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}.iam.gserviceaccount.com" \
        --project="${PROJECT_ID}" \
        --role="roles/iam.workloadIdentityUser" \
        --member="principalSet://iam.googleapis.com/${POOL_ID}/attribute.repository/${REPO}"
    
  7. Mendapatkan nama lengkap penyedia. Anda akan memerlukannya di bagian berikutnya.

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

    Outputnya akan terlihat seperti berikut:

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

Perubahan pada Workload Identity Federation dan IAM dapat memerlukan waktu hingga 5 menit untuk diterapkan. Untuk mengetahui informasi selengkapnya, lihat Mengonfigurasi Workload Identity Federation dengan pipeline deployment.

Menambahkan secret repositori

Di repositori Anda, buka Settings > Secrets and variables > Actions, lalu tambahkan secret repositori berikut:

Rahasia Nilai
GCP_PROJECT_ID Project ID Anda.
GCP_WIF_PROVIDER Nama lengkap penyedia dari bagian sebelumnya.
GCP_WIF_SERVICE_ACCOUNT codemender-ci@PROJECT_ID.iam.gserviceaccount.com, dengan PROJECT_ID adalah project ID Anda.

Untuk mengetahui informasi selengkapnya, lihat Menggunakan secret di GitHub Actions.

Mengonfigurasi setelan repositori

  1. Agar tugas perbaikan otomatis dapat membuka pull request, buka Setelan > Tindakan > Umum. Di bagian Workflow permissions, pilih Allow GitHub Actions to create and approve pull requests, lalu klik Save. Repositori di organisasi mewarisi setelan ini dari organisasi. Jika Anda tidak dapat mengubahnya, hubungi pemilik organisasi. Jika Anda tidak menggunakan perbaikan otomatis, lewati langkah ini. Untuk mengetahui informasi selengkapnya, lihat Mengelola setelan GitHub Actions untuk repositori.
  2. Pastikan pemindaian kode GitHub tersedia untuk repositori. Untuk repositori pribadi dan internal, pemindaian kode memerlukan GitHub Code Security. Jika pemindaian kode tidak tersedia, hapus langkah Upload hasil ke pemindaian kode dan izin security-events serta actions dari tugas pemindaian. Jika tidak, upload akan gagal, dan begitu juga tugas pemindaian. Untuk mengetahui informasi selengkapnya, lihat Mengupload file SARIF ke GitHub.

Tambahkan alur kerja

Lakukan commit alur kerja berikut ke repositori Anda sebagai .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 }}`.

Detail alur kerja

Diagram berikut menunjukkan cara kerja pemindaian pull request dan tugas perbaikan otomatis:

Permintaan pull dipindai. Jika tidak ada temuan pemblokiran, pemeriksaan akan lulus. Jika tidak, pemeriksaan akan gagal, CodeMender akan membuka permintaan pull perbaikan, dan penggabungan perbaikan akan memindai permintaan pull lagi.

Tugas pemindaian CodeMender melakukan hal berikut:

  1. Memeriksa permintaan pull dengan histori lengkapnya. Untuk permintaan pull, GitHub meng-checkout commit penggabungan dari branch permintaan pull ke dalam branch dasar.
  2. Melakukan autentikasi ke Google Cloud dan mendownload rilis stabil terbaru CodeMender CLI.
  3. Menjalankan cm find --diff terhadap cabang dasar. Tugas akan gagal jika CodeMender menemukan kerentanan dengan tingkat keparahan yang tercantum dalam FAIL_ON di perubahan permintaan pull.
  4. Mengupload laporan ke pemindaian kode GitHub, meskipun jika pemindaian gagal dalam tugas. Laporan ini mencakup temuan yang diberi label [LEGACY / UNTOUCHED]. Pemindaian kode juga menampilkan temuan dalam pemeriksaan pull request jika semua baris temuan ada dalam diff pull request.
  5. Menyimpan temuan yang menyebabkan tugas gagal untuk tugas perbaikan otomatis.

Tugas pemindaian tidak berjalan untuk pull request dari fork atau dari Dependabot, karena alur kerja untuk pull request tersebut tidak dapat membaca secret repositori. GitHub melaporkan tugas yang dilewati sebagai berhasil, sehingga pemeriksaan tidak memblokir permintaan pull ini, meskipun Anda menjadikannya pemeriksaan wajib. Tinjau sendiri pull request ini, atau pindai secara lokal dengan cm find --diff.

Tugas perbaikan otomatis CodeMender berjalan saat tugas pemindaian menyimpan temuan. Metode ini akan melakukan hal berikut:

  1. Memeriksa cabang permintaan pull.
  2. Menjalankan cm fix untuk setiap temuan, dan menerapkan setiap perbaikan secara terpisah. Jika CodeMender tidak memperbaiki temuan, tugas akan mencatat peringatan. Tugas hanya melakukan perubahan pada file yang sudah ada di repositori, dan menghapus file apa pun yang dibuat oleh agen perbaikan, seperti output pengujian.
  3. Membuka permintaan pull dari cabang codemender/fix-pr-NUMBER ke cabang permintaan pull, dengan NUMBER adalah nomor permintaan pull. Jika permintaan pull perbaikan sudah ada, tugas akan memperbaruinya. Jika CodeMender tidak memperbaiki temuan apa pun, atau jika tugas mencapai batas waktu 60 menit, tugas tidak akan membuka permintaan pull.

Meninjau dan menggabungkan perbaikan

GitHub tidak otomatis menjalankan alur kerja untuk permintaan pull yang dibuat alur kerja dengan GITHUB_TOKEN. Untuk memindai permintaan pull perbaikan, pengguna dengan akses tulis ke repositori mengklik Approve workflows to run di permintaan pull perbaikan.

Saat Anda menggabungkan permintaan pull perbaikan, branch permintaan pull akan berubah, dan alur kerja memindai permintaan pull asli lagi.

Menyesuaikan alur kerja

Anda dapat menyesuaikan alur kerja dengan cara berikut:

  • Untuk mengubah tingkat keparahan yang menyebabkan pemeriksaan gagal, pada langkah Pindai pull request, tetapkan FAIL_ON ke daftar tingkat keparahan yang dipisahkan koma tanpa spasi, seperti CRITICAL,HIGH,MEDIUM. Nilai yang valid adalah CRITICAL, HIGH, MEDIUM, dan LOW.
  • Untuk melaporkan temuan tanpa gagal dalam pemeriksaan, tetapkan FAIL_ON: "". Alur kerja tetap mengupload temuan ke pemindaian kode, tetapi tidak menjalankan tugas perbaikan otomatis.
  • Untuk memindai permintaan pull ke beberapa cabang saja, tambahkan filter branches ke pemicu pull_request. Alur kerja kemudian tidak memindai permintaan pull perbaikan, karena dasarnya adalah cabang permintaan pull:

    on:
      pull_request:
        branches: [main]
    
  • Untuk menonaktifkan perbaikan otomatis, hapus tugas autofix dan langkah Simpan temuan untuk perbaikan otomatis.

Memindai permintaan pull dengan Cloud Build

Build di bagian ini memindai setiap permintaan pull di repositori GitHub yang terhubung ke Cloud Build. Build dan pemeriksaan GitHub-nya gagal saat CodeMender menemukan kerentanan dengan tingkat keparahan CRITICAL atau HIGH dalam perubahan permintaan pull. Build tidak memperbaiki temuan.

Sebelum memulai, lakukan hal berikut:

  1. Hubungkan repositori Anda ke Cloud Build sebagai repositori generasi kedua. Untuk mengetahui informasi selengkapnya, lihat Menghubungkan ke repositori GitHub.
  2. Aktifkan Cloud Build API dan IAM API di project yang memiliki akses ke CodeMender. Build menggunakan CodeMender di project yang menjalankan build.

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

    Ganti PROJECT_ID dengan project ID Google Cloud Anda.

Membuat akun layanan

Buat akun layanan untuk build. Berikan peran IAM Agent Platform User (roles/aiplatform.user) agar dapat menggunakan CodeMender, dan peran Logs Writer (roles/logging.logWriter) agar dapat menulis log build:

SA="codemender-build@${PROJECT_ID}.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"

Untuk menyimpan laporan SARIF di bucket Cloud Storage, berikan juga akses akun layanan ke bucket:

BUCKET="BUCKET"

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

Ganti BUCKET dengan nama bucket Cloud Storage Anda.

Tambahkan konfigurasi build

Lakukan commit konfigurasi build berikut ke root repositori Anda sebagai 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

Buat pemicu

Buat pemicu yang menjalankan build untuk setiap permintaan pull ke 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}"

Ganti kode berikut:

  • REGION: region koneksi repositori Cloud Build Anda.
  • CONNECTION: nama koneksi repositori Cloud Build Anda.
  • REPOSITORY: nama repositori yang terhubung di Cloud Build.

Perhatikan opsi berikut:

  • --pull-request-pattern adalah ekspresi reguler untuk cabang dasar permintaan pull. Gunakan ^ dan $ untuk mencocokkan seluruh nama cabang.
  • Dengan --comment-control=COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY, build berjalan secara otomatis untuk permintaan pull dari pemilik dan kolaborator repositori. Untuk permintaan pull dari kontributor lain, build akan berjalan setelah pemilik atau kolaborator mengomentari /gcbrun permintaan pull.
  • Untuk menyimpan laporan SARIF dalam bucket, tambahkan --substitutions=_REPORT_BUCKET="${BUCKET}".

Anda juga dapat membuat pemicu di konsol Google Cloud . Untuk mengetahui informasi selengkapnya, lihat Membangun repositori dari GitHub.

Untuk menampilkan log build di GitHub, tambahkan --include-logs-with-status saat Anda membuat pemicu, dan berikan peran Logs Viewer (roles/logging.viewer) ke akun layanan. Siapa pun yang dapat melihat pemeriksaan di GitHub kemudian dapat membaca log build, termasuk temuan.

Cara kerja build

Build memiliki tiga langkah:

  1. install-codemender mendownload rilis stabil terbaru CodeMender CLI.
  2. fetch-history mengambil cabang dasar dan histori yang diperlukan CodeMender. Cloud Build hanya memeriksa commit yang memulai build. Langkah ini mengambil dari jarak jauh origin. Jika origin tidak dikonfigurasi, langkah ini akan mengambil dari GitHub tanpa kredensial, yang hanya berfungsi untuk repositori publik. Dalam hal ini, repositori pribadi memerlukan kredensial, seperti kunci SSH. Untuk mengetahui informasi selengkapnya, lihat Mengakses GitHub dari build menggunakan kunci SSH.
  3. scan menjalankan cm find --diff terhadap cabang dasar. Setelah pemindaian selesai, langkah ini akan mencetak semua temuan dalam log build. Jika Anda menyetel _REPORT_BUCKET, langkah ini juga menyalin laporan SARIF ke gs://BUCKET/codemender/BUILD_ID.sarif.

Untuk mengubah tingkat keparahan yang menyebabkan build gagal, edit --fail-on di langkah scan. Jika Anda menjalankan build tanpa pemicu permintaan pull, build akan gagal dengan pesan Run this build from a pull request trigger.

Memindai sebelum setiap commit

Hook pra-commit Git dapat memindai perubahan yang di-stage dan memblokir commit saat CodeMender menemukan kerentanan dengan tingkat keparahan CRITICAL atau HIGH. Developer dapat melewati hook, jadi gunakan hook selain pemindaian di CI, bukan sebagai penggantinya.

Setiap developer yang menggunakan hook memerlukan hal berikut:

  • CodeMender CLI, diinstal dan disiapkan seperti yang dijelaskan dalam Menginstal dan mengonfigurasi CLI, termasuk gcloud auth application-default login dan cm init. Hook membutuhkan cm di PATH.
  • Peran Pengguna Agent Platform (roles/aiplatform.user) dalam project dengan akses ke CodeMender. CodeMender menggunakan project dalam variabel lingkungan GOOGLE_CLOUD_PROJECT. Jika variabel tersebut tidak ditetapkan, CodeMender akan menggunakan project dari Kredensial Default Aplikasi Anda atau project default gcloud CLI Anda.

Untuk menambahkan hook, simpan skrip berikut sebagai .git/hooks/pre-commit di repositori Anda:

#!/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

Jadikan skrip dapat dieksekusi, lalu tambahkan .cm_project ke file .gitignore Anda, sehingga Anda tidak melakukan commit file yang dibuat CodeMender untuk melacak repositori:

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

Saat Anda menjalankan git commit, hook akan memindai file dengan perubahan yang di-stage. Pemindaian dapat memerlukan waktu beberapa menit. Hook tidak menonaktifkan sandbox CodeMender.

Untuk melakukan commit tanpa pemindaian, jalankan git commit --no-verify.

Tombol fitur pemindaian

Flag cm find berikut mengontrol pemindaian pull request. Untuk semua flag, jalankan cm find --help:

Flag Default Deskripsi
--diff[=REF] Nonaktif Memindai perubahan dibandingkan dengan REF, seperti origin/main. Tanpa REF, pemindaian perubahan yang belum di-commit pada file yang dilacak (dibandingkan dengan HEAD). Tidak dapat digunakan dengan --deep.
--staged Nonaktif Dengan --diff, hanya memindai perubahan yang dipentaskan.
--diff-depth DEPTH 1 Kedalaman penelusuran untuk analisis dampak (1 hingga 3, default: 1-hop).
--diff-workers COUNT 4 Jumlah file yang akan dipindai secara bersamaan, dari 1 hingga 16.
--diff-max-neighbors COUNT 10 Jumlah maksimum file dependen yang akan dipindai.
--fail-on SEVERITIES CRITICAL,HIGH Dengan --diff, tingkat keparahan yang membuat cm find keluar dengan status 1. Dengan nilai kosong, temuan tidak memengaruhi status keluar.
--fail-on-truncation Nonaktif Dengan --diff, keluar dengan status 1 jika CodeMender menemukan lebih banyak file dependen daripada yang diizinkan oleh --diff-max-neighbors.
--format FORMAT table Format laporan: table, json, atau sarif.
--output FILE Output standar File yang akan digunakan untuk menulis laporan.

Pemecahan masalah

Bagian ini menjelaskan cara menyelesaikan masalah umum saat menjalankan CodeMender di pipeline CI/CD.

Izin ditolak

Log menampilkan baris seperti berikut:

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

Pesan juga dapat menyertakan Permission 'aiplatform.interactions.create' denied. Periksa hal-hal berikut:

  • Project memiliki akses ke CodeMender.
  • Akun layanan atau pengguna memiliki peran Pengguna Agent Platform (roles/aiplatform.user) dalam project.
  • Agent Platform API diaktifkan di project.
  • CodeMender menggunakan project yang tepat. Di GitHub Actions, periksa rahasia GCP_PROJECT_ID. Cloud Build menggunakan project yang menjalankan build. Secara lokal, periksa variabel lingkungan GOOGLE_CLOUD_PROJECT, atau project default Anda jika variabel tidak ditetapkan.

Penyiapan resource sedang berlangsung

Jika log menampilkan Resource setup has just started. Please try again shortly. atau Resource setup is in progress. Please try again shortly., CodeMender sedang menyiapkan resource untuk project Anda, yang biasanya memerlukan waktu beberapa menit. Jalankan tugas lagi nanti.

Flag tidak dikenal: --diff

Jika cm find gagal dengan Error: unknown flag: --diff, rilis CLI Anda tidak mendukung pemindaian pull request. Jalankan cm update, atau download rilis terbaru.

Cabang dasar tidak ditemukan

Jika cm find gagal dengan error seperti berikut, cabang dasar tidak ada di 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.

Ambil cabang dasar dan historinya sebelum Anda menjalankan cm find. Di GitHub Actions, tetapkan fetch-depth: 0 di actions/checkout.

File tidak dipindai

Baris dengan ❌, seperti [1/1] ❌ src/app.py: start session failed, berarti CodeMender tidak dapat memindai file tersebut. Periksa error di baris, lalu jalankan tugas lagi.

Permintaan pull tanpa perbaikan

Jika alur kerja tidak membuka permintaan pull perbaikan, periksa hal berikut:

  • Jika tugas perbaikan otomatis gagal saat membuat permintaan pull, aktifkan Izinkan GitHub Actions membuat dan menyetujui permintaan pull. Untuk mengetahui informasi selengkapnya, lihat Mengonfigurasi setelan repositori.
  • Jika tugas perbaikan otomatis berhasil tanpa membuka permintaan pull, CodeMender tidak memperbaiki temuan apa pun. Log tugas menampilkan peringatan untuk setiap temuan yang tidak diperbaiki oleh CodeMender.

Upload pemindaian kode gagal

Jika langkah upload gagal dengan GitHub Code Security or GitHub Advanced Security must be enabled for this repository to use code scanning, aktifkan Keamanan Kode GitHub untuk repositori, atau hapus langkah upload. Untuk mengetahui informasi selengkapnya, lihat Mengonfigurasi setelan repositori.

Peringatan tidak dikonfirmasi

Jika cm gagal dengan warning not acknowledged. Please run interactively once to acknowledge or pass --bypass-warning, CodeMender memerlukan konfirmasi bahwa CodeMender tidak dapat memintanya di lingkungan non-interaktif. Tambahkan --bypass-warning ke perintah. Sebelum melakukannya, baca persyaratan Pratinjau di bagian atas halaman ini.

Untuk mendapatkan bantuan lebih lanjut, hubungi tim penjualan Anda.