Wie man Bencher in GitHub-Aktionen verwendet


on:
push:
branches: main
jobs:
benchmark_with_bencher:
name: Continuous Benchmarking with Bencher
runs-on: ubuntu-latest
env:
BENCHER_PROJECT: save-walter-white
BENCHER_TESTBED: ubuntu-latest
BENCHER_ADAPTER: json
steps:
- uses: actions/checkout@v4
- uses: bencherdev/bencher@main
- name: Track Benchmarks with Bencher
run: |
bencher run \
--branch "$GITHUB_REF_NAME" \
--token "${{ secrets.BENCHER_API_TOKEN }}" \
--err \
"bencher mock"
  1. Erstellen Sie eine GitHub Actions workflow Datei. (z.B.: .github/workflows/benchmarks.yml)
  2. F├╝hren Sie bei push Ereignissen zum main branch aus. Siehe die GitHub Actions on Dokumentation f├╝r einen vollst├Ąndigen ├ťberblick. Siehe auch Pull-Anfragen unten.
  3. Erstellen Sie eine GitHub Actions job. (z.B.: benchmark_with_bencher)
  4. Das Projekt muss bereits existieren. Geben Sie die --project Option or die BENCHER_PROJECT Umgebungsvariable mit dem Slug oder der UUID des Projekts an (z.B.: BENCHER_PROJECT: save-walter-white).
  5. Optional: Setzen Sie die --testbed Option oder die BENCHER_TESTBED Umgebungsvariable auf den Slug oder die UUID des Testbetts. (z.B.: BENCHER_TESTBED: ubuntu-latest). Das Testbett muss bereits existieren. Wenn dies nicht gesetzt ist, wird das Testbett localhost verwendet.
  6. Optional: Setzen Sie die --adapter Option oder die BENCHER_ADAPTER Umgebungsvariable auf den gew├╝nschten Adapternamen. (z.B.: BENCHER_ADAPTER: json). Wenn dies nicht gesetzt ist, wird der magic Adapter verwendet. Siehe Benchmark Harness Adapter f├╝r einen vollst├Ąndigen ├ťberblick.
  7. Pr├╝fen Sie Ihren Quellcode aus. (z.B.: uses: actions/checkout@v4)
  8. Installieren Sie die Bencher CLI mit der GitHub Action. (z.B.: uses: bencherdev/bencher@main)
  9. Verfolgen Sie Ihre Benchmarks mit dem bencher run CLI-Unterbefehl:
    1. Optional: Setzen Sie die --branch Option oder die BENCHER_BRANCH Umgebungsvariable auf den Slug oder die UUID des Branches. (z.B.: --branch main). Der Branch muss bereits existieren. Wenn dies nicht gesetzt ist, wird der main Branch verwendet.
    2. Der API-Token muss bereits existieren. F├╝gen Sie BENCHER_API_TOKEN als Repository-Secret hinzu. (z.B.: Repo -> Einstellungen -> Geheimnisse und Variablen -> Aktionen -> Neues Repository-Geheimnis). Setzen Sie die --token Option oder die BENCHER_API_TOKEN Umgebungsvariable auf den API-Token. (z.B.: --token ${{ secrets.BENCHER_API_TOKEN }})
    3. Lassen Sie den Befehl fehlschlagen, wenn ein Alert generiert wird. (z.B.: --err). Damit ein Alert generiert werden kann, muss bereits ein Schwellenwert existieren.
    4. F├╝hren Sie Ihre Benchmarks aus und generieren Sie einen Bericht aus den Ergebnissen. (z.B.: "bencher mock")

Pull-Anfragen

Um Leistungseinbu├čen in Pull-Anfragen zu entdecken, m├╝ssen Sie Ihre Benchmarks bei PRs ausf├╝hren. Wenn Sie nur erwarten, Pull-Anfragen von Branches innerhalb des gleichen Repositorys zu haben, k├Ânnen Sie das obige Beispiel einfach modifizieren, um auch on pull_request Ereignisse zu laufen.

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

on:
pull_request:
types: [opened, reopened, synchronize]
jobs:
benchmark_pr_with_bencher:
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
permissions:
pull-requests: write
name: Continuous Benchmarking with Bencher
runs-on: ubuntu-latest
env:
BENCHER_PROJECT: save-walter-white
BENCHER_TESTBED: ubuntu-latest
BENCHER_ADAPTER: json
steps:
- uses: actions/checkout@v4
- 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 }}" \
--token "${{ secrets.BENCHER_API_TOKEN }}" \
--err \
"bencher mock"
  1. Erstellen Sie eine GitHub Actions workflow Datei. (z.B.: .github/workflows/pr_benchmarks.yml)
  2. F├╝hren Sie bei pull_request Ereignissen aus, wenn und nur wenn der Pull Request aus dem gleichen Repository stammt. F├╝r die Verarbeitung von Fork PRs siehe unten Pull Requests von Forks.
  3. Legen Sie die Berechtigungen f├╝r das GITHUB_TOKEN auf write f├╝r pull-requests. Abh├Ąngig von Ihren GitHub-Einstellungen ist dies m├Âglicherweise nicht erforderlich. Aber f├╝r alle Organisationen und pers├Ânlichen Repositories, die nach dem 02. Februar 2023 erstellt wurden, ist dies das Standardverhalten. Siehe die GitHub-Dokumentation f├╝r eine vollst├Ąndige ├ťbersicht.
  4. W├Ąhlen Sie den Branch aus, den Sie verwenden m├Âchten:
    1. Verwenden Sie die aktuellen Branch-Daten, wenn sie bereits existieren. (z.B.: --if-branch "$GITHUB_REF_NAME")
    2. Erstellen Sie eine Kopie der PR-Zielbranch-Daten und -Schwellenwerte, wenn sie bereits existieren. (z.B.: --else-if-branch "$GITHUB_BASE_REF")
    3. Andernfalls erstellen Sie eine Kopie der main Branch-Daten und Schwellenwerte. (z.B.: --else-if-branch main)
  5. Setzen Sie den GitHub API-Authentifizierungs-Token. (z.B.: --github-actions "${{ secrets.GITHUB_TOKEN }}") Wenn diese Option als Teil eines Pull Requests gesetzt ist, werden die Ergebnisse dem Pull Request als Kommentar hinzugef├╝gt. Hierf├╝r wird die GitHub Actions GITHUB_TOKEN Umgebungsvariable verwendet.
  6. Sehen Sie in der bencher run Dokumentation nach, um eine vollst├Ąndige ├ťbersicht ├╝ber alle M├Âglichkeiten zur Konfiguration des Pull Request-Kommentars mit den --ci-* Flags zu erhalten.
  7. (Nicht dargestellt) Erstellen Sie eine zweite GitHub Actions workflow Datei und verwenden Sie das initiale Beispiel oben, um bei push Ereignissen zum main Branch zu laufen. (z.B.: .github/workflows/benchmarks.yml)

Pull-Anfragen von Forks

Wenn Sie planen, Pull-Anfragen von Forks zu akzeptieren, wie es oft bei ├Âffentlichen Open-Source-Projekten der Fall ist, dann m├╝ssen Sie die Dinge ein wenig anders handhaben. Aus Sicherheitsgr├╝nden sind Geheimnisse wie Ihr BENCHER_API_TOKEN und das GITHUB_TOKEN in GitHub Actions f├╝r PRs von Forks nicht verf├╝gbar. Das hei├čt, wenn ein externer Mitwirkender eine PR von einem Fork ├Âffnet, wird das oben genannte Beispiel nicht funktionieren. Es gibt zwei M├Âglichkeiten f├╝r PRs von Forks:

Benchmark Fork PR von Zielbranch mit erforderlichen Reviewern

ÔÜá´ŞĆ Es ist sehr, sehr wichtig, jeden Fork PR gr├╝ndlich zu ├╝berpr├╝fen, bevor er genehmigt wird! Wenn Sie dies nicht tun, k├Ânnte das Ergebnis eine Pwn-Anfrage sein!

Wenn Sie es vorziehen, dass dies nicht ├╝ber Ihrem Kopf h├Ąngt, sehen Sie unten Benchmark Fork PR und Upload von Default Branch.

on:
pull_request_target:
types: [opened, reopened, synchronize]
jobs:
fork_pr_requires_review:
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: fork_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@v4
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.number }}/merge' \
--else-if-branch '${{ github.base_ref }}' \
--else-if-branch main \
--github-actions "${{ secrets.GITHUB_TOKEN }}" \
--token "${{ secrets.BENCHER_API_TOKEN }}" \
--err \
"bencher mock"
  1. Erstellen Sie eine GitHub Actions workflow Datei. (z.B.: .github/workflows/pr_benchmarks.yml)
  2. F├╝hren Sie anhand von pull_request_target Ereignissen aus.
  3. Erstellen Sie einen job mit dem Namen fork_pr_requires_review, der vor jedem Lauf einer externen Pull-Anfrage (Fork PR) die Genehmigung eines erforderlichen Reviewers erfordert.
  4. Erstellen Sie einen dritten job, der von fork_pr_requires_review abh├Ąngt.
    1. Pr├╝fen Sie den Pull-Anfragen-Branch aus, speichern Sie jedoch nicht die Git-Anmeldedaten. (z.B.: persist-credentials: false)
    2. Verwenden Sie einfache Anf├╝hrungszeichen um alle nicht vertrauensw├╝rdigen Eingaben. (z.B.: --if-branch '${{ github.head_ref }}')
    3. Geben Sie alle Geheimnisse direkt ein. (z.B.: --token "${{ secrets.BENCHER_API_TOKEN }}")
    4. F├╝hren Sie Ihre Pull-Anfragen-Benchmarks mit bencher run aus und verfolgen Sie diese.
  5. (Nicht dargestellt) Erstellen Sie eine zweite GitHub Actions workflow Datei und verwenden Sie das obige erste Beispiel, um bei push Ereignissen zum main Branch zu laufen. (z.B.: .github/workflows/benchmarks.yml)

Dieses Setup funktioniert, weil pull_request_target im Kontext des Zielbranches der Pull-Anfrage ausgef├╝hrt wird, wo Geheimnisse wie Ihr BENCHER_API_TOKEN und das GITHUB_TOKEN verf├╝gbar sind. Daher wird dieser Workflow nur ausgef├╝hrt, wenn er auf dem Ziel Branch existiert.

Um dies zu konfigurieren, m├╝ssen Sie zwei GitHub Action-Umgebungen erstellen (z.B.: Repo -> Einstellungen -> Umgebungen -> Neue Umgebung). Die interne Umgebung sollte keine Deployment-Schutzregeln haben. Die externe Umgebung sollte jedoch mit Erforderlichen Reviewern besetzt sein, die vertrauensw├╝rdig genug sind, um PRs von Forks vor dem Benchmarking zu ├╝berpr├╝fen.

Es ist sehr wichtig, den Namen des PR-Branches (head ref) in einfachen Anf├╝hrungszeichen zu setzen. (z.B.: --if-branch '${{ github.head_ref }}'). Andernfalls k├Ânnte ein Angreifer einen b├Âsartig benannten Branch erstellen, der eine Befehlsinjektion ausf├╝hrt. Siehe diese GitHub Security Lab-Aufschreibung ├╝ber die Verhinderung von Pwn-Anfragen aus nicht vertrauensw├╝rdigen Eingaben f├╝r einen vollst├Ąndigen ├ťberblick.

Vermeiden Sie das Setzen von Geheimnissen als Umgebungsvariablen, wie GITHUB_TOKEN und BENCHER_API_TOKEN. Geben Sie stattdessen ausdr├╝cklich die Geheimnisse in bencher run ein. (z.B.: --token "${{ secrets.BENCHER_API_TOKEN }}") Sehen Sie diese GitHub Security Lab-Aufschreibung und diesen Blog-Post ├╝ber die Verhinderung von Pwn-Anfragen f├╝r einen vollst├Ąndigen ├ťberblick.

Benchmark Fork PR und Upload von Default Branch

name: Run and Cache Benchmarks
on:
pull_request:
types: [opened, reopened, synchronize]
jobs:
benchmark:
name: Run Benchmarks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Mock Benchmarking
run: |
/bin/echo '{ "bencher::mock_0": { "latency": { "value": 1.0 } } }' > benchmark_results.json
- name: Upload Benchmark Results
uses: actions/upload-artifact@v4
with:
name: benchmark_results.json
path: ./benchmark_results.json
- name: Upload GitHub Pull Request Event
uses: actions/upload-artifact@v4
with:
name: event.json
path: ${{ github.event_path }}
  1. Erstellen Sie eine Run and Cache Benchmarks Workflow-Datei. (z.B.: .github/workflows/pr_benchmarks.yml)
  2. F├╝hren Sie alle Jobs in der Workflow auf pull_request Ereignissen aus.
  3. F├╝hren Sie die Benchmarks aus und speichern Sie die Ergebnisse in einer Datei. (z.B.: benchmark_results.json)
  4. Laden Sie die Benchmark-Ergebnisdatei als Artefakt hoch.
  5. Laden Sie das pull_request Ereignisobjekt als Artefakt hoch.
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_ADAPTER: json
BENCHER_TESTBED: ubuntu-latest
BENCHMARK_RESULTS: benchmark_results.json
PR_EVENT: event.json
steps:
- name: Download Benchmark Results
uses: actions/github-script@v6
with:
script: |
async 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));
}
await downloadArtifact(process.env.BENCHMARK_RESULTS);
await downloadArtifact(process.env.PR_EVENT);
- name: Unzip Benchmark Results
run: |
unzip $BENCHMARK_RESULTS.zip
unzip $PR_EVENT.zip
- name: Export PR Event Data
uses: actions/github-script@v6
with:
script: |
let fs = require('fs');
let prEvent = JSON.parse(fs.readFileSync(process.env.PR_EVENT, {encoding: 'utf8'}));
core.exportVariable("PR_HEAD", `${prEvent.number}/merge`);
core.exportVariable("PR_BASE", prEvent.pull_request.base.ref);
core.exportVariable("PR_DEFAULT", prEvent.pull_request.base.repo.default_branch);
core.exportVariable("PR_NUMBER", prEvent.number);
- 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 '${{ env.PR_DEFAULT }}' \
--ci-number '${{ env.PR_NUMBER }}' \
--github-actions "${{ secrets.GITHUB_TOKEN }}" \
--token "${{ secrets.BENCHER_API_TOKEN }}" \
--err \
--file "$BENCHMARK_RESULTS"
  1. Erstellen Sie eine zweite Workflow-Datei, Track Benchmarks. (z.B.: .github/workflows/track_benchmarks.yml)
  2. Verketten Sie Track Benchmarks mit Run and Cache Benchmarks mit dem workflow_run Ereignis.
  3. Laden Sie die zwischengespeicherten Benchmark-Ergebnisse und das pull_request Ereignis herunter.
  4. Extrahieren Sie die zwischengespeicherten Benchmark-Ergebnisse und das pull_request Ereignis.
  5. Exportieren Sie die notwendigen Daten aus dem pull_request Ereignis als Umgebungsvariablen.
  6. Verfolgen Sie die zwischengespeicherten Benchmark-Ergebnisse mit bencher run:
    1. Verwenden Sie einfache Anf├╝hrungszeichen um alle nicht vertrauensw├╝rdigen Eingaben. (z.B.: --if-branch '${{ env.PR_HEAD }}')
    2. Geben Sie explizit die Pull-Anfragen-Nummer ein. (z.B.: --ci-number '${{ env.PR_NUMBER }}')
    3. Geben Sie den Dateipfad zur Benchmark-Ergebnisdatei ein. (z.B. --file "$BENCHMARK_RESULTS")
  7. (Nicht dargestellt) Erstellen Sie eine dritte GitHub Actions workflow Datei und verwenden Sie das obige erste Beispiel, um bei push Ereignissen zum main Branch zu laufen. (z.B.: .github/workflows/benchmarks.yml)

Dieses Setup funktioniert, weil workflow_run im Kontext des Standardbranches des Repositorys ausgef├╝hrt wird, wo Geheimnisse wie Ihr BENCHER_API_TOKEN und das GITHUB_TOKEN verf├╝gbar sind. Daher werden diese Workflows nur ausgef├╝hrt, wenn sie auf dem Standard Branch existieren. Siehe Nutzung von Daten aus dem ausl├Âsenden Workflow f├╝r einen vollst├Ąndigen ├ťberblick. Die Pull-Anfragen-Nummer, der Kopfbranch und der Basisbranch, die im initialen Workflow verwendet wurden, m├╝ssen explizit weitergegeben werden, da sie in workflow_run nicht verf├╝gbar sind.

Es ist sehr wichtig, den Namen des PR-Branches (head ref) in einfachen Anf├╝hrungszeichen zu setzen. (z.B.: --if-branch '${{ env.PR_HEAD }}'). Andernfalls k├Ânnte ein Angreifer einen b├Âsartig benannten Branch erstellen, der eine Befehlsinjektion ausf├╝hrt. Siehe diese GitHub Security Lab-Aufschreibung ├╝ber die Verhinderung von Pwn-Anfragen aus nicht vertrauensw├╝rdigen Eingaben f├╝r einen vollst├Ąndigen ├ťberblick.

Vermeiden Sie das Setzen von Geheimnissen als Umgebungsvariablen in der Run and Cache Benchmarks Workflow-Datei. Sehen Sie diese GitHub Security Lab-Aufschreibung und diesen Blog-Post ├╝ber die Verhinderung von Pwn-Anfragen f├╝r einen vollst├Ąndigen ├ťberblick.



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


Weitermachen: ├ťbersicht ├╝ber das 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.