C贸mo usar Bencher en GitHub Actions


on:
  push:
    branches: main

jobs:
  benchmark_with_bencher:
    name: Continuous Benchmarking with Bencher
    runs-on: ubuntu-latest
    env:
      BENCHER_PROJECT: save-walter-white
      BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }}
      BENCHER_TESTBED: ubuntu-latest
      BENCHER_ADAPTER: json
    steps:
      - uses: actions/checkout@v3
      - uses: bencherdev/bencher@main
      - name: Track Benchmarks with Bencher
        run: |
          bencher run \
          --branch main \
          --err \
          "bencher mock"
  1. Crea un archivo de workflow de GitHub Actions. (p.ej: .github/workflows/benchmark.yml)
  2. Ejecuta push en eventos para la branch main. Consulta la documentaci贸n de on de GitHub Actions para una visi贸n general completa. Tambi茅n puedes ver Pull Requests a continuaci贸n.
  3. Crea un trabajo de GitHub Actions. (p.ej: benchmark_with_bencher)
  4. El proyecto ya debe existir. Ajusta la opci贸n --project o la variable de entorno BENCHER_PROJECT al slug del proyecto o al UUID (p.ej: BENCHER_PROJECT: save-walter-white).
  5. El token de API ya debe existir. Agrega BENCHER_API_TOKEN como un secreto del Repositorio. (p.ej: Repo -> Configuraci贸n -> Secretos y variables -> Acciones -> Nuevo secreto del repositorio) Ajusta la opci贸n --token o variable de entorno BENCHER_API_TOKEN al token de API. (p.ej: BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }})
  6. Opcional: Ajusta la opci贸n --testbed o la variable de entorno BENCHER_TESTBED al slug de Testbed o al UUID. (p.ej: BENCHER_TESTBED: ubuntu-latest) El Testbed debe ya existir. Si esto no est谩 ajustado, entonces el Testbed localhost ser谩 usado.
  7. Opcional: Ajusta la opci贸n --adapter o la variable de entorno BENCHER_ADAPTER al nombre del adaptador deseado. (p.ej: BENCHER_ADAPTER: json) Si esto no est谩 ajustado, entonces el Adapter magic ser谩 usado. Consulta los adaptadores de harness de benchmark para obtener una visi贸n general completa.
  8. Verifica tu c贸digo fuente. (p.ej: uses: actions/checkout@v3)
  9. Instala la CLI de Bencher usando la Acci贸n de GitHub. (p.ej: uses: bencherdev/bencher@main)
  10. Monitorear tus benchmarks con el subcomando CLI de bencher run:
    1. Opcional: Ajusta la opci贸n --branch o la variable de entorno BENCHER_BRANCH al slug de la Branch o al UUID. (p.ej: --branch main) La Branch debe ya existir. Si esto no est谩 ajustado, entonces la Branch main ser谩 usada.
    2. Ajusta el comando para fallar si una Alerta es generada. (p.ej: --err) Para que una Alerta sea generada, un Umbral debe ya existir.
    3. Ejecuta tus benchmarks y genera un Reporte desde los resultados. (p.ej: "bencher mock")

Pull Requests

Para detectar la regresi贸n del rendimiento en los Pull Requests, necesitar谩s ejecutar tus benchmarks en PRs. Si solo esperas tener PRs desde las branch dentro del mismo repositorio entonces simplemente puedes modificar el ejemplo de arriba para tambi茅n ejecutar on en pull_request.

鈿狅笍 隆Esta soluci贸n solo funciona si todos los PRs son del mismo repositorio! Consulta Pull Requests desde Forks a continuaci贸n.

on:
  push:
    branches: main
  pull_request:

jobs:
  benchmark_with_bencher:
    name: Continuous Benchmarking with Bencher
    runs-on: ubuntu-latest
    env:
      BENCHER_PROJECT: save-walter-white
      BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }}
      BENCHER_TESTBED: ubuntu-latest
      BENCHER_ADAPTER: json
    steps:
      - uses: actions/checkout@v3
      - uses: bencherdev/bencher@main
      - name: Track Benchmarks with Bencher
        run: |
          bencher run \
          --if-branch "$GITHUB_REF_NAME" \
          --else-if-branch "$GITHUB_BASE_REF" \
          --else-if-branch main \
          --github-actions ${{ secrets.GITHUB_TOKEN }} \
          --err \
          "bencher mock"
  1. Ejecuta push en eventos para la branch main y en pull_request. Es importante limitar la ejecuci贸n en push solo a seleccionar las branch (p.ej: main) para prevenir pushs a las branch PR de ejecutar dos veces!
  2. En lugar de siempre utilizar la branch main, usa las variables de entorno por defecto de la Acci贸n de GitHub para:
    1. Usa los datos de la branch actual si ya existen. (p.ej: --if-branch "$GITHUB_REF_NAME")
    2. Crea un clon de los datos y umbrales de la branch objetivo de PR si ya existen. (p.ej: --else-if-branch "$GITHUB_BASE_REF")
    3. De lo contrario, crea un clon de los datos y umbrales de la branch main. (p.ej: --else-if-branch main)
    4. Hay varias opciones para ajustar la branch del proyecto. Consulta selecci贸n de branch para una visi贸n general completa.
  3. Ajusta el token de autenticaci贸n de GitHub API. (p.ej: --github-actions ${{ secrets.GITHUB_TOKEN }}) Cuando esta opci贸n se ajusta como parte de un pull request, entonces los resultados ser谩n adicionados al pull request como un comentario. Esto usa la variable de entorno GITHUB_TOKEN de GitHub Actions.
  4. Consulta la documentaci贸n de bencher run para una visi贸n general completa de todas las maneras de configurar el comentario de pull request con las opciones --ci-*.

Pull Requests from Forks

Si planeas aceptar pull requests desde forks, como es a menudo el caso en proyectos de c贸digo abierto p煤blicos, entonces necesitar谩s manejar las cosas un poco diferente. Por razones de seguridad, secretos como tu BENCHER_API_TOKEN y el GITHUB_TOKEN no est谩n disponibles en GitHub Actions para los PRs de fork. Es decir si un contribuyente externo abre un PR desde un fork el ejemplo de arriba no funcionar谩. Hay tres opciones para los PRs de fork:

Benchmark Fork PR desde Branch Objetivo

on:
  push:
    branches: main
  pull_request_target:

jobs:
  benchmark_main_with_bencher:
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    name: Benchmark main with Bencher
    runs-on: ubuntu-latest
    env:
      BENCHER_PROJECT: save-walter-white
      BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }}
      BENCHER_TESTBED: ubuntu-latest
      BENCHER_ADAPTER: json
    steps:
      - uses: actions/checkout@v3
      - uses: bencherdev/bencher@main
      - name: Track Benchmarks with Bencher
        run: |
          bencher run \
          --branch main \
          --err \
          "bencher mock"

  benchmark_pr_with_bencher:
    if: github.event_name == 'pull_request_target'
    name: Benchmark PR with Bencher
    runs-on: ubuntu-latest
    env:
      BENCHER_PROJECT: save-walter-white
      BENCHER_ADAPTER: json
      BENCHER_TESTBED: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.sha }}
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          persist-credentials: false
      - uses: bencherdev/bencher@main
      - name: Track Benchmarks with Bencher
        run: |
          bencher run \
          --if-branch "${{ github.event.pull_request.head.ref }}" \
          --else-if-branch "${{ github.event.pull_request.base.ref }}" \
          --else-if-branch main \
          --github-actions "${{ secrets.GITHUB_TOKEN }}" \
          --token "${{ secrets.BENCHER_API_TOKEN }}" \
          --err \
          "bencher mock"
  1. Ejecuta push en eventos para la branch main y on pull_request_target eventos.
  2. Crea un trabajo que solo se ejecuta para push en eventos para la branch main. Aparte de la condici贸n if, este trabajo es casi id茅ntico al ejemplo original de arriba.
  3. Crea un trabajo que solo se ejecuta para pull_request_target eventos.
    1. Verifica la branch del PR.
    2. Pasa todos los secretos directamente. Usa --token ${{ secrets.BENCHER_API_TOKEN }} en lugar de la variable de entorno BENCHER_API_TOKEN.
    3. Ejecuta y rastrea tus benchmarks de PR con bencher run.

Esta configuraci贸n funciona porque pull_request_target se ejecuta en el contexto de la branch objetivo del PR, donde los secretos como tu BENCHER_API_TOKEN y el GITHUB_TOKEN est谩n disponibles. Por lo tanto, este flujo de trabajo solo funcionar谩 si existe en la branch objetivo. Evita configurar cualquier secreto como variable de entorno, como BENCHER_API_TOKEN. En su lugar, pasa expl铆citamente el token de API a bencher run. (p.ej: --token ${{ secrets.BENCHER_API_TOKEN }}) Consulta esta rese帽a del laboratorio de seguridad de GitHub y este post de blog sobre c贸mo prevenir peticiones pwn para una visi贸n general completa.

Benchmark Fork PR desde Branch Objetivo con Revisores Requeridos

on:
  push:
    branches: main
  pull_request_target:

jobs:
  benchmark_main_with_bencher:
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    name: Benchmark main with Bencher
    runs-on: ubuntu-latest
    env:
      BENCHER_PROJECT: save-walter-white
      BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }}
      BENCHER_TESTBED: ubuntu-latest
      BENCHER_ADAPTER: json
    steps:
      - uses: actions/checkout@v3
      - uses: bencherdev/bencher@main
      - name: Track Benchmarks with Bencher
        run: |
          bencher run \
          --branch main \
          --err \
          "bencher mock"

  benchmark_pr_requires_review:
    if: github.event_name == 'pull_request_target'
    environment:
      ${{ (github.event.pull_request.head.repo.full_name == github.repository && 'internal') || 'external' }}
    runs-on: ubuntu-latest
    steps:
      - run: true

  benchmark_pr_with_bencher:
    needs: benchmark_pr_requires_review
    name: Benchmark PR with Bencher
    runs-on: ubuntu-latest
    env:
      BENCHER_PROJECT: save-walter-white
      BENCHER_ADAPTER: json
      BENCHER_TESTBED: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.sha }}
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          persist-credentials: false
      - uses: bencherdev/bencher@main
      - name: Track Benchmarks with Bencher
        run: |
          bencher run \
          --if-branch "${{ github.event.pull_request.head.ref }}" \
          --else-if-branch "${{ github.event.pull_request.base.ref }}" \
          --else-if-branch main \
          --github-actions "${{ secrets.GITHUB_TOKEN }}" \
          --token "${{ secrets.BENCHER_API_TOKEN }}" \
          --err \
          "bencher mock"

Esta configuraci贸n es exactamente la misma que Benchmark Fork PR desde Branch Objetivo con el requisito adicional de aprobaci贸n de un revisor obligatorio antes de cada ejecuci贸n de PR de fork. Los pull requests del mismo repositorio no requieren aprobaci贸n. Para configurar esto, necesitas crear dos Ambientes de Acci贸n de GitHub (p.ej: Repo -> Configuraci贸n -> Ambientes -> Nuevo ambiente). El ambiente internal no debe tener ninguna Regla de protecci贸n de despliegue. Sin embargo, el ambiente external debe tener Revisores requeridos ajustado a aquellos de confianza para revisar PR de fork antes del benchmarking.

Benchmark Fork PR y Subir desde Branch por Defecto

name: Run and Cache Benchmarks

on: pull_request

jobs:
  benchmark:
    name: Run Benchmarks
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Mock Benchmark
        run: echo '{"bencher::mock_0": { "latency": { "value": 1.0 }}}' &> benchmark_results.txt
      - uses: actions/upload-artifact@v3
        with:
          name: benchmark_results.txt
          path: ./benchmark_results.txt
      - uses: actions/upload-artifact@v3
        with:
          name: pr_event.json
          path: ${{ env.GITHUB_EVENT_PATH }}
name: Track Benchmarks

on:
  workflow_run:
    workflows: [Run and Cache Benchmarks]
    types:
      - completed

jobs:
  track_with_bencher:
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    runs-on: ubuntu-latest
    env:
      BENCHER_PROJECT: save-walter-white
      BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }}
      BENCHER_ADAPTER: json
      BENCHER_TESTBED: ubuntu-latest
      BENCHMARK_RESULTS: benchmark_results.txt
      PR_EVENT: pr_event.json
    steps:
      - name: Download Benchmark Results
        uses: actions/github-script@v6
        with:
          script: |
            function downloadArtifact(artifactName) {
              let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
                owner: context.repo.owner,
                repo: context.repo.repo,
                run_id: context.payload.workflow_run.id,
              });
              let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
                return artifact.name == artifactName
              })[0];
              if (!matchArtifact) {
                core.setFailed(`Failed to find artifact: ${artifactName}`);
              }
              let download = await github.rest.actions.downloadArtifact({
                owner: context.repo.owner,
                repo: context.repo.repo,
                artifact_id: matchArtifact.id,
                archive_format: 'zip',
              });
              let fs = require('fs');
              fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/${artifactName}.zip`, Buffer.from(download.data));
            }
            downloadArtifact(process.env.BENCHMARK_RESULTS);
            downloadArtifact(process.env.PR_EVENT);
      - name: Unzip Benchmark Results
        run: |
          unzip $BENCHMARK_RESULTS.zip
          unzip $PR_EVENT.zip
      - name: Export PR Context
        uses: actions/github-script@v6
        with:
          script: |
            let fs = require('fs');
            let prEvent = JSON.parse(fs.readFileSync(process.env.PR_EVENT, {encoding: 'utf8'}));
            fs.appendFileSync(process.env.GITHUB_ENV, `PR_NUMBER=${prEvent.number}`);
            fs.appendFileSync(process.env.GITHUB_ENV, `PR_HEAD=${prEvent.pull_request.head.ref}`);
            fs.appendFileSync(process.env.GITHUB_ENV, `PR_BASE=${prEvent.pull_request.base.ref}`);
      - uses: bencherdev/bencher@main
          - name: Track Benchmarks with Bencher
            run: |
              bencher run \
              --if-branch "${{ env.PR_HEAD }}" \
              --else-if-branch "${{ env.PR_BASE }}" \
              --else-if-branch main \
              --github-actions "${{ secrets.GITHUB_TOKEN }}" \
              --ci-number "${{ env.PR_NUMBER }}" \
              --err \
              --file $BENCHMARK_RESULTS
  1. Crea un archivo de flujo de trabajo Run and Cache Benchmarks.
  2. Ejecuta tus benchmarks en pull_request eventos.
  3. Guarda los resultados de benchmark en un archivo y sube como archivo de artefacto.
  4. Sube el evento pull_request como un archivo de artefacto.
  5. Crea un segundo archivo de flujo de trabajo, Track Benchmarks.
  6. Encadena Track Benchmarks a Run and Cache Benchmarks con el evento workflow_run.
  7. Extrae los datos necesarios del evento pull_request almacenado en la cach茅.
  8. Rastrea los resultados de benchmark almacenados en la cach茅 con bencher run.
  9. Crea un tercer archivo de flujo de trabajo y usa el ejemplo inicial de arriba para ejecutar en push eventos a la branch main.

Esta configuraci贸n funciona porque workflow_run se ejecuta en el contexto de la branch por defecto del repositorio, donde los secretos como tu BENCHER_API_TOKEN y el GITHUB_TOKEN est谩n disponibles. Por lo tanto, estos flujos de trabajo solo se ejecutar谩n si existen en la branch por defecto. Consulta usando datos desde el flujo de trabajo que dispara para una visi贸n general completa. El n煤mero de pull request, la branch principal, y la branch base usadas en el flujo de trabajo inicial deben ser pasados expl铆citamente ya que no est谩n disponibles dentro de workflow_run.



馃惏 隆Felicidades! 隆Has aprendido c贸mo usar Bencher en GitHub Actions! 馃帀


Contin煤a: Visi贸n General de los Benchmarks 鉃

馃 Este documento fue generado autom谩ticamente por OpenAI GPT-4. Puede que no sea exacto y contenga errores. Si encuentra alg煤n error, abra un problema en GitHub.