Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: add github workflow for performance regression check #95

Merged
merged 9 commits into from
Oct 21, 2021
146 changes: 146 additions & 0 deletions .github/workflows/pr-benchdiff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
name: Benchdiff

on:
issue_comment:
types: [created]
luchsh marked this conversation as resolved.
Show resolved Hide resolved
pull_request:
types: [opened]
paths-ignore:
- '**.md'

jobs:
# https://github.community/t/cancelling-rest-of-job-if-condition-is-met/18181
trigger:
name: Pull request comment trigger
outputs:
triggered: ${{ steps.output.outputs.triggered }}
pr_number: ${{ steps.output.outputs.pr_number }}
runs-on: ubuntu-latest
steps:
- name: Check pull request comment
if: ${{ github.event_name == 'issue_comment' }}
uses: khan/pull-request-comment-trigger@master
id: check-comment
with:
trigger: '/benchdiff'
env:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
- name: Set output
id: output
run: |
echo '::set-output name=triggered::${{ github.event_name == 'pull_request' || steps.check-comment.outputs.triggered }}'
echo '::set-output name=pr_number::${{ github.event.pull_request.number || github.event.issue.number }}'

benchdiff:
name: Performance regression check
needs: [trigger]
if: needs.trigger.outputs.triggered == 'true'
runs-on: ubuntu-latest
env:
# In markdown URL syntax
RUNS_URL: '[${{ github.workflow }} #${{ github.run_number }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})'
steps:
- name: Report job start
uses: peter-evans/create-or-update-comment@v1
with:
issue-number: '${{ needs.trigger.outputs.pr_number }}'
body: |
## Benchdiff

Runs: ${{ env.RUNS_URL }}

Job is started.
- name: Checkout
uses: actions/checkout@v2
- name: Checkout pull request HEAD
id: head
run: |
# Fetch github default branch as baseline
git fetch origin ${{ github.event.repository.default_branch }}:BENCHDIFF_BASE
git checkout BENCHDIFF_BASE
echo "::set-output name=base::$(git rev-parse HEAD)"

# Checkout HEAD of pull request and set its sha to step output
git fetch origin pull/${{ needs.trigger.outputs.pr_number }}/head:BENCHDIFF_HEAD
git checkout BENCHDIFF_HEAD
echo "::set-output name=head::$(git rev-parse HEAD)"

set -x
# Set modified packages to step output
# git diff: get difference between HEAD and baseline
# grep: filter non-go files
# xargs -r: --no-run-if-empty, ignore empty line
# xargs dirname: keep only the directory name (go packages)
# xargs ls: filter non-exist files
# sort | uniq: dedup
pkgs=$(git diff --name-only BENCHDIFF_BASE | grep '.go$' | xargs -r dirname | xargs -r ls -d 2>/dev/null | sort | uniq)
if [ ! -z "${pkgs}" ]; then
# awk: Add "./" prefix to let `go test` known they are relative paths
# tr: join paths to one line, otherwise benchdiff cannot recognize it
pkgs=$(echo "${pkgs}" | awk '{print "./" $0}' | tr '\n' ' ')
fi
echo "::set-output name=pkgs::${pkgs}"
- name: Setup go
uses: actions/setup-go@v2
with:
go-version: 1.16
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could setup the os by os: [ubuntu-latest] ? I wonder if we can also use something like go-latest instead of 1.16 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that action/setup-go supports semver, ^1.x should the the thing we need.

This PR use 1.16 because it is used in all of other workflows. If we use ^1.x, it would be better to update all of them.

$ grep -r go-version
codeql-analysis.yml:          go-version: 1.16
push-check.yml:          go-version: 1.16
pr-benchdiff.yml:          go-version: 1.16
pr-check.yml:          go-version: 1.16

- name: Benchdiff
uses: WillAbides/benchdiff-action@v0.3.3
id: diff
if: steps.head.outputs.pkgs != ''
with:
benchdiff_version: 0.7.1
status_sha: ${{ steps.head.outputs.head }}
status_name: Benchdiff result
status_on_degraded: neutral
benchdiff_args: |
--packages="${{ steps.head.outputs.pkgs }}"
--count=10
--warmup-count=1
--benchtime=1s
--benchmem
--tolerance=50
--base-ref=${{ steps.head.outputs.base }}
--debug
luchsh marked this conversation as resolved.
Show resolved Hide resolved
- name: Report benchdiff result via comment
uses: peter-evans/create-or-update-comment@v1
if: steps.head.outputs.pkgs != ''
with:
issue-number: '${{ needs.trigger.outputs.pr_number }}'
body: |
## Benchdiff

Command: `${{ steps.diff.outputs.bench_command }}`
HEAD: ${{ steps.diff.outputs.head_sha }}
Base: ${{ steps.diff.outputs.base_sha }}
Runs: ${{ env.RUNS_URL }}
Degraded: ${{ steps.diff.outputs.degraded_result }}

<details>
<summary>Results</summary>

${{ steps.diff.outputs.benchstat_output }}

</details>
- name: On skipped
uses: peter-evans/create-or-update-comment@v1
if: steps.head.outputs.pkgs == ''
with:
issue-number: '${{ needs.trigger.outputs.pr_number }}'
body: |
## Benchdiff

Runs: ${{ env.RUNS_URL }}

There is no package to bench.
- name: On failure
uses: peter-evans/create-or-update-comment@v1
if: ${{ failure() }}
with:
issue-number: '${{ needs.trigger.outputs.pr_number }}'
body: |
## Benchdiff

Runs: ${{ env.RUNS_URL }}

Job is failed.