blob: 85cabd223d7483b9663dcf3fe0f1988a6152d06c [file]
#!/usr/bin/env bash
# .github/scripts/gh_api_retry.sh
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to you under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Source this file, then call gh_api_retry with the arguments of "gh api".
# The GitHub API sometimes fails for a short time: a network error, a 5xx
# answer, a rate limit, or an error page instead of JSON. gh_api_retry
# tries again after 5, 10 and 20 seconds. It does not try again when the
# answer is HTTP 404 or 422, because the next try gives the same answer.
# It prints the output of the successful try and returns 0, or it prints
# the errors of the last try to stderr and returns 1.
gh_api_retry()
{
local delay=5
local err
local out
local try
err=$(mktemp)
for try in 1 2 3 4; do
if out=$(gh api "$@" 2> "$err"); then
rm -f "$err"
printf '%s\n' "$out"
return 0
fi
if grep -q 'HTTP 404\|HTTP 422' "$err" || [ "$try" -eq 4 ]; then
break
fi
echo "gh api $1 failed (try $try of 4), trying again in ${delay} s:" \
"$(head -c 200 "$err")" >&2
sleep "$delay"
delay=$((delay * 2))
done
cat "$err" >&2
rm -f "$err"
return 1
}