Wie Bencher in GitHub-Aktionen verwendet wird


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. Erstellen Sie eine GitHub Actions workflow Datei. (z.B.: .github/workflows/benchmark.yml)
  2. F├╝hren Sie push Events zum main Zweig durch. Siehe GitHub Actions on Dokumentation f├╝r einen vollst├Ąndigen ├ťberblick. Siehe auch Pull Requests unten.
  3. Erstellen Sie eine GitHub Actions job. (z.B.: benchmark_with_bencher)
  4. Das Projekt muss bereits existieren. Setzen Sie das --project Flag oder die BENCHER_PROJECT Umgebungsvariable auf den Projektslug oder UUID (z.B.: BENCHER_PROJECT: save-walter-white).
  5. Das API-Token muss bereits existieren. F├╝gen Sie BENCHER_API_TOKEN als Repository Geheimnis hinzu. (z.B.: Repo -> Einstellungen -> Geheimnisse und Variablen -> Aktionen -> Neues Repository-Geheimnis) Setzen Sie das --token Flag oder die BENCHER_API_TOKEN Umgebungsvariable auf das API-Token. (z.B.: BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }})
  6. Optional: Setzen Sie das --testbed Flag oder die BENCHER_TESTBED Umgebungsvariable auf den Testbed Slug oder UUID. (z.B.: BENCHER_TESTBED: ubuntu-latest) Das Testbed muss bereits existieren. Wird dies nicht gesetzt, wird das localhost Testbed verwendet.
  7. Optional: Setzen Sie das --adapter Flag oder die BENCHER_ADAPTER Umgebungsvariable auf den gew├╝nschten Adapternamen. (z.B.: BENCHER_ADAPTER: json) Wird dies nicht gesetzt, wird der magic Adapter verwendet. Siehe Benchmark Harness Adapter f├╝r einen vollst├Ąndigen ├ťberblick.
  8. Checken Sie Ihren Quellcode aus. (z.B.: uses: actions/checkout@v3)
  9. Installieren Sie die Bencher CLI mit der GitHub Action. (z.B.: uses: bencherdev/bencher@main)
  10. Verfolgen Sie Ihre Benchmarks mit dem bencher run CLI-Unterbefehl:
    1. Optional: Setzen Sie das --branch Flag oder die BENCHER_BRANCH Umgebungsvariable auf den Branch Slug oder UUID. (z.B.: --branch main) Der Branch muss bereits existieren. Wird dies nicht gesetzt, wird der main Branch verwendet.
    2. Setzen Sie den Befehl zum Fehlschlagen, wenn ein Alarm generiert wird. (z.B.: --err) Damit ein Alarm generiert wird, muss bereits ein Threshold existieren.
    3. F├╝hren Sie Ihre Benchmarks durch und erzeugen Sie einen Bericht aus den Ergebnissen. (z.B.: "bencher mock")

Pull-Anfragen

Um eine Performance-Regression in Pull-Anfragen zu erkennen, m├╝ssen Sie Ihre Benchmarks bei den PRs durchf├╝hren. Wenn Sie nur erwarten, dass Sie PRs von Zweigen innerhalb des gleichen Repositories haben, k├Ânnen Sie das oben stehende Beispiel einfach ├Ąndern, um auch bei pull_request Events zu laufen.

ÔÜá´ŞĆ Diese L├Âsung funktioniert nur, wenn alle PRs aus dem gleichen Repository stammen! Siehe Pull-Anfragen von Forks unten.

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. F├╝hren Sie push Events zum main Zweig und auf pull_request Events aus. Es ist wichtig, das Laufen bei push nur auf die ausgew├Ąhlten Zweige zu beschr├Ąnken (z.B.: main), um zu verhindern, dass Pushes zu PR-Zweigen doppelt ausgef├╝hrt werden!
  2. Verwenden Sie statt dem main Zweig immer die standardm├Ą├čigen Umgebungsvariablen der GitHub-Aktion um:
    1. Die aktuellen Branch-Daten zu verwenden, wenn sie bereits existieren. (z.B.: --if-branch "$GITHUB_REF_NAME")
    2. Erstellen Sie einen Klon der PR-Zielbranch-Daten und Schwellenwert, wenn sie bereits existieren. (z.B.: --else-if-branch "$GITHUB_BASE_REF")
    3. Ansonsten erstellen Sie einen Klon der main Branch-Daten und Schwellenwerte. (z.B.: --else-if-branch main)
    4. Es gibt mehrere Optionen f├╝r die Einstellung des Projektbranches. Siehe Branch Auswahl f├╝r einen vollst├Ąndigen ├ťberblick.
  3. Setzen Sie das GitHub API Authentifizierungstoken. (z.B.: --github-actions ${{ secrets.GITHUB_TOKEN }}) Wenn diese Option als Teil einer Pull-Anfrage gesetzt ist, werden die Ergebnisse als Kommentar zur Pull-Anfrage hinzugef├╝gt. Dies verwendet die GitHub Actions GITHUB_TOKEN Umgebungsvariable.
  4. Siehe die bencher run Dokumentation f├╝r einen vollst├Ąndigen ├ťberblick ├╝ber alle M├Âglichkeiten zur Konfiguration des Pull-Anfragen-Kommentars mit den --ci-* Flags.

Pull-Anfragen von Forks

Wenn Sie planen, Pull-Anfragen von Forks anzunehmen, wie es oft der Fall bei ├Âffentlichen Open-Source-Projekten ist, m├╝ssen Sie die Dinge ein wenig anders behandeln. Aus Sicherheitsgr├╝nden stehen Geheimnisse wie Ihr BENCHER_API_TOKEN und das GITHUB_TOKEN nicht in GitHub-Aktionen f├╝r Fork-PRs zur Verf├╝gung. Das hei├čt, wenn ein externer Beitragender einen PR von einem Fork er├Âffnet, wird das obige Beispiel nicht funktionieren. Es gibt drei Optionen f├╝r Fork-PRs:

Benchmark Fork-PR vom Zielbranch

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. Lauf push Events zur main Zweig und zu pull_request_target Events.
  2. Erstellen Sie einen job der nur f├╝r push Events zum main Zweig l├Ąuft. Abgesehen von der if Bedingung ist dieser Job fast identisch mit dem urspr├╝nglichen Beispiel oben.
  3. Erstellen Sie einen job der nur f├╝r pull_request_target Events l├Ąuft.
    1. Checkout des Pull-Anfrage-Zweigs.
    2. ├ťbergeben Sie alle Geheimnisse direkt. Verwenden Sie --token ${{ secrets.BENCHER_API_TOKEN }} anstelle der BENCHER_API_TOKEN Umgebungsvariable.
    3. F├╝hren Sie Ihre Pull-Anfrage-Benchmarks durch und verfolgen Sie diese mit bencher run.

Diese Einrichtung funktioniert, weil pull_request_target im Kontext des Zielzweigs der Pull-Anfrage l├Ąuft, wo Geheimnisse wie Ihr BENCHER_API_TOKEN und das GITHUB_TOKEN verf├╝gbar sind. Daher wird dieser Workflow nur dann ausgef├╝hrt, wenn er auf dem Ziel Zweig existiert. Vermeiden Sie das Einstellen von Geheimnissen als Umgebungsvariablen, wie BENCHER_API_TOKEN. ├ťbergeben Sie stattdessen das API-Token explizit an bencher run. (z.B.: --token ${{ secrets.BENCHER_API_TOKEN }}) Siehe diese GitHub Security Lab Aufschreibung und diesen Blogbeitrag zur Vermeidung von pwn-Anfragen f├╝r einen vollst├Ąndigen ├ťberblick.

Benchmark Fork-PR vom Zielbranch mit erforderlichen Pr├╝fern

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"

Diese Einrichtung ist genau die gleiche wie Benchmark Fork-PR vom Zielbranch mit der zus├Ątzlichen Anforderung der Genehmigung eines erforderlichen Pr├╝fer vor jedem Lauf einer Fork-Pull-Anfrage. Pull-Anfragen aus demselben Repository ben├Âtigen keine Genehmigung. Um dies einzurichten, m├╝ssen Sie zwei GitHub Action-Umgebungen erstellen (z.B.: Repo -> Einstellungen -> Umgebungen -> Neue Umgebung). Die interne Umgebung sollte keine Schutzregeln f├╝r die Bereitstellung haben. Die externe Umgebung sollte jedoch Erforderliche Pr├╝fer haben, die denen vertraut sind, die Fork PRs vor dem Benchmarking ├╝berpr├╝fen.

Benchmark Fork PR und Hochladen vom Standard-Zweig

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. Erstellen Sie eine Run and Cache Benchmarks Workflow-Datei.
  2. F├╝hren Sie Ihre Benchmarks bei pull_request Events durch.
  3. Speichern Sie die Benchmark-Ergebnisse in einer Datei und laden Sie diese als Artefakt hoch.
  4. Laden Sie das pull_request Event als Artefakt hoch.
  5. Erstellen Sie eine zweite Workflow-Datei, Track Benchmarks.
  6. Verketten Sie Track Benchmarks mit Run and Cache Benchmarks mit dem Event workflow_run.
  7. Extrahieren Sie die notwendigen Daten aus dem gecachten pull_request Event.
  8. Verfolgen Sie die gecachten Benchmark-Ergebnisse mit bencher run.
  9. Erstellen Sie eine dritte Workflow-Datei und verwenden Sie das urspr├╝ngliche obige Beispiel, um push Events zur main Zweig auszuf├╝hren.

Diese Einrichtung funktioniert, weil workflow_run im Kontext des Standardzweigs des Repositorys l├Ąuft, wo Geheimnisse wie Ihr BENCHER_API_TOKEN und das GITHUB_TOKEN verf├╝gbar sind. Daher werden diese Workflows nur dann ausgef├╝hrt, wenn sie auf dem Standard Branch existieren. Siehe Verwendung von Daten aus dem ausl├Âsenden Workflow f├╝r einen vollst├Ąndigen ├ťberblick. Die Pull-Anfrage-Nummer, der Head-Zweig und der Base-Zweig, die im initialen Workflow verwendet wurden, m├╝ssen explizit ├╝bergeben werden, da sie innerhalb von workflow_run nicht verf├╝gbar sind.



­čÉ░ Herzlichen Gl├╝ckwunsch! Sie haben gelernt, wie man Bencher in GitHub-Aktionen verwendet! ­čÄë


Weitermachen: ├ťberblick ├╝ber Benchmarking Ô×í

­čĄľ Dieses Dokument wurde automatisch von OpenAI GPT-4 generiert. Es ist m├Âglicherweise nicht korrekt und kann Fehler enthalten. Wenn Sie Fehler finden, ├Âffnen Sie bitte ein Problem auf GitHub.