-
Notifications
You must be signed in to change notification settings - Fork 378
357 lines (332 loc) · 12.7 KB
/
git-bisect.yml
File metadata and controls
357 lines (332 loc) · 12.7 KB
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
name: "Workflow/Bisect"
defaults:
run:
shell: bash --noprofile --norc -euo pipefail {0}
on:
workflow_dispatch:
inputs:
runner:
description: "Runner label"
required: false
default: linux-amd64-cpu16
type: string
good_ref:
description: "Good ref/sha/tag/branch. Defaults to latest release tag. Accepts '-Nd' (e.g., '-14d') to mean 'origin/main as of N days ago'."
required: false
type: string
bad_ref:
description: "Bad ref/sha/tag/branch. Defaults to main. Accepts '-Nd' (e.g., '-14d') to mean 'origin/main as of N days ago'."
required: false
type: string
launch_args:
description: "Arguments for .devcontainer/launch.sh -d"
required: false
default: ""
type: string
preset:
description: "CMake preset"
required: false
default: ""
type: string
cmake_options:
description: "Additional options passed to CMake preset configure (e.g. -DVAR=ON)"
required: false
default: ""
type: string
configure_override:
description: "Command to run for configuration; overrides preset and cmake_options"
required: false
default: ""
type: string
build_targets:
description: "Space separated ninja build targets"
required: false
default: ""
type: string
ctest_targets:
description: "Space separated CTest targets"
required: false
default: ""
type: string
lit_precompile_tests:
description: "Space-separated libcudacxx lit test paths to precompile without execution"
required: false
default: ""
type: string
lit_tests:
description: "Space-separated libcudacxx lit test paths to execute"
required: false
default: ""
type: string
custom_test_cmd:
description: "Command run after build and tests"
required: false
default: ""
type: string
workflow_call:
inputs:
runner:
description: "Runner label"
required: false
default: linux-amd64-cpu16
type: string
good_ref:
description: "Good ref/sha/tag/branch. Defaults to latest release tag. Accepts '-Nd' (e.g., '-14d') to mean 'origin/main as of N days ago'."
required: false
type: string
bad_ref:
description: "Bad ref/sha/tag/branch. Defaults to HEAD. Accepts '-Nd' (e.g., '-14d') to mean 'origin/main as of N days ago'."
required: false
type: string
launch_args:
description: "Arguments for .devcontainer/launch.sh -d"
required: false
default: ""
type: string
preset:
description: "CMake preset"
required: false
default: ""
type: string
cmake_options:
description: "Additional options passed to CMake preset configure (e.g. -DVAR=ON)"
required: false
default: ""
type: string
configure_override:
description: "Command to run for configuration; overrides preset and cmake_options"
required: false
default: ""
type: string
build_targets:
description: "Space separated ninja build targets"
required: false
default: ""
type: string
ctest_targets:
description: "Space separated CTest targets"
required: false
default: ""
type: string
lit_precompile_tests:
description: "Space-separated libcudacxx lit test paths to precompile without execution"
required: false
default: ""
type: string
lit_tests:
description: "Space-separated libcudacxx lit test paths to execute"
required: false
default: ""
type: string
custom_test_cmd:
description: "Command run after build and tests"
required: false
default: ""
type: string
jobs:
# Hash all of the inputs and generate a descriptive, but unique, name for the bisect job.
# This is necessary because GitHub Actions does not provide an easy way to get the numeric
# job id from within a running job, unless the name is unique across the entire run.
generate-job-name:
name: Generate Unique Job Name
runs-on: ubuntu-latest
outputs:
job-name: ${{ steps.set-name.outputs.unique-name }}
steps:
- name: Set unique name
id: set-name
run: |
# Hash the inputs to create a unique identifier
input_string=$(cat <<HASH
${{ inputs.runner }}
${{ inputs.launch_args }}
${{ inputs.preset }}
${{ inputs.cmake_options }}
${{ inputs.configure_override }}
${{ inputs.build_targets }}
${{ inputs.ctest_targets }}
${{ inputs.lit_precompile_tests }}
${{ inputs.lit_tests }}
${{ inputs.custom_test_cmd }}
${{ inputs.good_ref }}
${{ inputs.bad_ref }}
HASH
)
hash=$(echo -n "$input_string" | sha256sum | awk '{print $1}')
short_hash=${hash:0:8}
function sanitize() {
echo "$1" | tr -cd '[:alnum:]-'
}
function compress() {
input=$1
input_length=${#input}
# "begin.and.end" -> "begin_d.end"
delim="_"
keep_chars=5
compressed_str=${input:0:keep_chars}$delim${input: -keep_chars}
compressed_length=${#compressed_str}
if [[ $input_length -gt $compressed_length ]]; then
echo "$compressed_str"
else
echo "$input"
fi
}
preset=$(sanitize "${{ inputs.preset }}")
good_ref=$(sanitize "${{ inputs.good_ref }}")
bad_ref=$(sanitize "${{ inputs.bad_ref }}")
build_targets=$(sanitize "${{ inputs.build_targets }}")
ctest_targets=$(sanitize "${{ inputs.ctest_targets }}")
lit_precompile_tests=$(sanitize "${{ inputs.lit_precompile_tests }}")
lit_tests=$(sanitize "${{ inputs.lit_tests }}")
build_targets_part=$(compress "$build_targets")
ctest_targets_part=$(compress "$ctest_targets")
# Parse "--cuda XX.Y" / "-c XX.Y" and "--host <str>" / "-H <str>"
launch_args="${{ inputs.launch_args }}"
cuda_version=$(grep -oP '(?:--cuda|-c)\s+\K\S+' <<< "$launch_args" || true)
host_name=$(grep -oP '(?:--host|-H)\s+\K\S+' <<< "$launch_args" || true)
# Parse `amd64/arm64` and -gpu-<gpu_name> from runner name.
# Ex: 'linux-amd64-gpu-rtxa6000-latest-1'
runner=${{ inputs.runner }}
cpu_arch=$(echo "${runner}" | grep -oP '(?:^|-)\K(?:amd64|arm64)(?=-)' || true)
gpu_name=$(echo "${runner}" | grep -oP '(?:-gpu-)\K\S+' || true)
unique_name="bisect"
declare -a vars=(
"runner"
"cuda_version"
"host_name"
"preset"
"build_targets_part"
"ctest_targets_part"
"lit_precompile_tests"
"lit_tests"
"gpu_name"
"cpu_arch"
"short_hash"
)
for var in "${vars[@]}"; do
val=${!var}
if [[ -n "$val" ]]; then
unique_name+="-$val""
fi
done
echo "Unique job name: $unique_name"
echo "unique-name=$unique_name" >> "$GITHUB_OUTPUT"
bisect:
needs: [generate-job-name]
name: ${{ needs.generate-job-name.outputs.job-name }}
runs-on: ${{ inputs.runner }}
permissions:
id-token: write
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0 # FULL history
fetch-tags: true # Ensure tags are present
- name: Get AWS credentials for sccache bucket
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::279114543810:role/gha-oidc-NVIDIA
aws-region: us-east-2
role-duration-seconds: 43200 # 12 hours
- name: Prepare AWS config for devcontainer
run: |
# The devcontainer will mount this path to the home directory
aws_dir="${{ github.workspace }}/.aws"
mkdir -p "${aws_dir}"
cat > "${aws_dir}/config" <<EOF
[default]
bucket=rapids-sccache-devs
region=us-east-2
EOF
cat > "${aws_dir}/credentials" <<EOF
[default]
aws_access_key_id=${AWS_ACCESS_KEY_ID}
aws_session_token=${AWS_SESSION_TOKEN}
aws_secret_access_key=${AWS_SECRET_ACCESS_KEY}
EOF
chmod 0600 "${aws_dir}/credentials"
chmod 0664 "${aws_dir}/config"
- name: Run git bisect
env:
GITHUB_TOKEN: ${{ github.token }}
LAUNCH_ARGS: ${{ inputs.launch_args }}
GITHUB_REPOSITORY: ${{ github.repository }}
# AWS credentials from the configure-aws-credentials action
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
AWS_SESSION_TOKEN: ${{ env.AWS_SESSION_TOKEN }}
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ env.AWS_REGION }}
run: |
echo -e "\e[1;34mLaunching devcontainer and running git bisect...\e[0m"
GPU_ARGS=""
if [[ "${{ inputs.runner }}" == *"-gpu-"* ]]; then
if [[ ! "${LAUNCH_ARGS}" =~ "--gpus" ]]; then
echo "GPU runner detected; enabling '--gpus all'"
GPU_ARGS="--gpus all"
else
echo "GPU runner detected, but '--gpus' already present in LAUNCH_ARGS"
fi
fi
# Grab the url for this step summary
run="$GITHUB_RUN_ID"
attempt="${GITHUB_RUN_ATTEMPT:-1}"
server="${GITHUB_SERVER_URL:-https://github.com}"
repo="$GITHUB_REPOSITORY"
job_name="${{ needs.generate-job-name.outputs.job-name }}"
job_id=$(
gh api --paginate --slurp \
repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/jobs \
--jq ".jobs[] | select(.name==\"${job_name}\") | .id"
) || :
echo "Job name: ${job_name}"
echo "Job names:"
gh api --paginate --slurp \
repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/jobs \
--jq ".jobs[] | .name" || :
echo "Jobs:"
gh api --paginate --slurp \
repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/jobs \
--jq ".jobs[] | .name" || :
GHA_LOG_URL="$server/$repo/actions/runs/$run/jobs/$job_id"
STEP_SUMMARY_URL="$server/$repo/actions/runs/$run/attempts/$attempt#summary-$job_id"
echo -e "\e[1;34mGHA Log URL: $GHA_LOG_URL\e[0m"
echo -e "\e[1;34mBisection Results: $STEP_SUMMARY_URL\e[0m"
mkdir -p /tmp/shared
rc=0
set -x
.devcontainer/launch.sh -d ${LAUNCH_ARGS} ${GPU_ARGS} \
--env "AWS_ROLE_ARN=" \
--env "AWS_REGION=${AWS_REGION}" \
--env "SCCACHE_REGION=${AWS_REGION}" \
--env "AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}" \
--env "AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}" \
--env "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" \
--env "GITHUB_REPOSITORY=${GITHUB_REPOSITORY}" \
--env "LAUNCH_ARGS=${LAUNCH_ARGS} ${GPU_ARGS}" \
--env "STEP_SUMMARY_URL=${STEP_SUMMARY_URL}" \
--env "GHA_LOG_URL=${GHA_LOG_URL}" \
--volume "/tmp/shared:/tmp/shared" \
-- ./ci/util/git_bisect.sh \
--summary-file "/tmp/shared/summary.md" \
--good-ref "${{ inputs.good_ref }}" \
--bad-ref "${{ inputs.bad_ref }}" \
--preset "${{ inputs.preset }}" \
--cmake-options "${{ inputs.cmake_options }}" \
--configure-override "${{ inputs.configure_override }}" \
--build-targets "${{ inputs.build_targets }}" \
--ctest-targets "${{ inputs.ctest_targets }}" \
--lit-precompile-tests "${{ inputs.lit_precompile_tests }}" \
--lit-tests "${{ inputs.lit_tests }}" \
--custom-test-cmd "${{ inputs.custom_test_cmd }}" \
|| rc=$?
set +x
# Append the summary (if any) to the GitHub step summary
if [[ -d /tmp/shared ]]; then
find /tmp/shared -type f -exec cat {} \; >> "$GITHUB_STEP_SUMMARY" || :
fi
echo -e "\e[1;34mGHA Log URL: $GHA_LOG_URL\e[0m"
echo -e "\e[1;34mBisection Results: $STEP_SUMMARY_URL\e[0m"
exit $rc