Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/49.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
ci: Retry flaky Docker registry push and manifest operations during release publish
```
31 changes: 28 additions & 3 deletions .github/scripts/publish_docker_registries.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,50 @@ set -euo pipefail
# PUBLISH_GHCR=false Skip GHCR (default: publish)
# PUBLISH_ECR=false Skip ECR Public (default: publish)
# PUBLISH_DOCKERHUB=false Skip Docker Hub (default: publish)
# RETRY_ATTEMPTS=5 Retries for docker push / manifest push (default: 5)
# RETRY_INITIAL_DELAY_SECS=4 Initial backoff seconds between retries (default: 4)

function usage {
echo "Usage: $0 <version> <github_sha> <image_name> <docker_target>"
}

# Retry flaky registry operations (Docker Hub auth timeouts are common on manifest push).
function retry() {
local max_attempts="${RETRY_ATTEMPTS:-5}"
local delay="${RETRY_INITIAL_DELAY_SECS:-4}"
local attempt=1

while true; do
if "$@"; then
return 0
fi

if (( attempt >= max_attempts )); then
echo "ERROR: command failed after ${max_attempts} attempts: $*" >&2
return 1
fi

echo "Attempt ${attempt}/${max_attempts} failed; retrying in ${delay}s: $*" >&2
sleep "${delay}"
delay=$(( delay * 2 ))
attempt=$(( attempt + 1 ))
done
}

function publish_manifest() {
local registry_prefix="$1"
shift
local tags=( "$@" )

docker manifest rm "${registry_prefix}:${version}" >/dev/null 2>&1 || true
docker manifest create "${registry_prefix}:${version}" "${tags[@]}"
docker manifest push "${registry_prefix}:${version}"
retry docker manifest push "${registry_prefix}:${version}"
echo "Published ${registry_prefix}:${version}"

if [[ "${PUBLISH_LATEST:-false}" == "true" ]]; then
docker manifest rm "${registry_prefix}:latest" >/dev/null 2>&1 || true
docker manifest create "${registry_prefix}:latest" "${tags[@]}"
docker manifest push "${registry_prefix}:latest"
retry docker manifest push "${registry_prefix}:latest"
echo "Published ${registry_prefix}:latest"
fi
}
Expand All @@ -47,7 +72,7 @@ function publish_registry() {
for arch in amd64 arm64; do
local arch_tag="${registry_prefix}:${version}-${arch}"
docker tag "${src_image}" "${arch_tag}"
docker push "${arch_tag}"
retry docker push "${arch_tag}"
arch_tags+=( "${arch_tag}" )
done

Expand Down
Loading