-
Notifications
You must be signed in to change notification settings - Fork 608
144 lines (132 loc) · 6.05 KB
/
benchmark_trigger.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# Copyright 2023 The IREE Authors
#
# Licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
name: Benchmark Trigger
# Trigger benchmark CI workflows when benchmark PR labels are added.
# When a benchmark label is added, this cancels and then re-runs the CI
# workflow. When the workflow is re-run, it will pick up the latest PR
# description and labels. See
# https://github.com/openxla/iree/issues/10042#issuecomment-1449250094 for
# more background.
#
# This workflow is running on the base branch the PR targets.
on:
pull_request_target:
types:
- labeled
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
# Target workflow that runs the benchmarks.
WORKFLOW_NAME: CI
BENCHMARK_LABEL_PREFIX: 'benchmarks:'
jobs:
# Precondition check is a separate step because we can't put the concurrency
# constraint on it; otherwise the irrelevant labeling events will cancel the
# events that meet the preconditions. Even with cancel-in-progress = false,
# the queued events will still be cancelled.
precondition:
runs-on: ubuntu-20.04
outputs:
found-label: ${{ steps.precondition.outputs.found-label }}
triggered-at: ${{ steps.precondition.outputs.triggered-at }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: "Checking labels"
id: precondition
run: |
echo "found-label=$(jq \
--arg label_prefix ${BENCHMARK_LABEL_PREFIX} \
'.label.name | startswith($label_prefix)' \
${GITHUB_EVENT_PATH})" >> "${GITHUB_OUTPUT}"
# pull_request_target event doesn't have the workflow start time. Get
# the approximate start time at the beginning.
echo "triggered-at=$(date +%s)" >> "${GITHUB_OUTPUT}"
trigger:
needs: precondition
if: fromJSON(needs.precondition.outputs.found-label)
runs-on: ubuntu-20.04
# Required for cancel and rerun APIs.
permissions:
actions: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
concurrency:
# Only allows a single trigger to run for a PR concurrently.
# Timestamp-based check below makes sure we don't rerun benchmark twice
# when multiple label events happen the same time. We don't use
# `cancel-in-progress` to avoid that because cancelled jobs are
# considered as failures and show red on Github UI.
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
steps:
- name: "Checking out repository"
# This checkouts from the base branch instead of the pull request. See
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
- name: "Finding the previous workflow run"
id: find-workflow
env:
RUN_JSON: workflow-run.json
run: |
gh api "/repos/${GITHUB_REPOSITORY}/actions/runs" --method GET -F head_sha="${HEAD_SHA}" \
| jq --arg name "${WORKFLOW_NAME}" '.workflow_runs | map(select(.name == $name))[0]' \
> "${RUN_JSON}"
echo "workflow-url=$(jq '.url' ${RUN_JSON})" >> "${GITHUB_OUTPUT}"
echo "run-status=$(jq --raw-output '.status' ${RUN_JSON})" >> "${GITHUB_OUTPUT}"
echo "run-started-at=$(jq --raw-output '.run_started_at' ${RUN_JSON})" >> "${GITHUB_OUTPUT}"
- name: "Checking if the workflow has been rerun"
id: check
if: fromJSON(steps.find-workflow.outputs.workflow-url) != null
env:
RUN_STARTED_AT: ${{ steps.find-workflow.outputs.run-started-at }}
TRIGGERED_AT: ${{ needs.precondition.outputs.triggered-at }}
run: |
# If the latest workflow run started after the trigger event, it means
# the workflow has been rerun and picked up the new labels. Skip rerun
# in this case.
RUN_STARTED_AT_EPOCH="$(date --date="${RUN_STARTED_AT}" +%s)"
if (( RUN_STARTED_AT_EPOCH < TRIGGERED_AT )); then
SHOULD_RERUN="true"
else
SHOULD_RERUN="false"
fi
echo "should-rerun=${SHOULD_RERUN}" >> "${GITHUB_OUTPUT}"
cat <<EOF
Workflow run started at $(date --utc --date="${RUN_STARTED_AT}")
Trigger event started at $(date --utc --date="@${TRIGGERED_AT}")
Should rerun: "${SHOULD_RERUN}"
EOF
- name: "Cancelling the previous workflow run"
# If the workflow isn't completed, we need to cancel it first; otherwise
# the API can't rerun it.
if: |
fromJSON(steps.check.outputs.should-rerun) &&
steps.find-workflow.outputs.run-status != 'completed'
env:
IREE_WORKFLOW_RUN_URL: ${{ fromJSON(steps.find-workflow.outputs.workflow-url) }}
run: build_tools/github_actions/cancel_workflow_and_wait.sh
- name: "Getting the latest commit SHA"
# A push might have happened to trigger a new workflow run. Check the
# PR's latest commit SHA and only rerun if there is no new push.
#
# It reduces the chance that we rerun a workflow on the previous commit
# and cancel (due to the concurrency constraint) the run on the newer
# commit. Even if that happens, users will see their CI run fails and
# can rerun it manually from the UI.
id: get-sha
if: fromJSON(steps.check.outputs.should-rerun)
run: |
echo "latest-sha=$(gh api /repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER} \
| jq --raw-output '.head.sha')" \
>> "${GITHUB_OUTPUT}"
- name: "Rerequesting the workflow"
if: |
fromJSON(steps.check.outputs.should-rerun) &&
steps.get-sha.outputs.latest-sha == env.HEAD_SHA
env:
WORKFLOW_RUN_URL: ${{ fromJSON(steps.find-workflow.outputs.workflow-url) }}
run: |
gh api "${WORKFLOW_RUN_URL}/rerun" --method POST