Re-enable validation with Docker image pull retry logic

Added exponential backoff retry logic to handle Docker Hub CDN
propagation delays (2-5 minutes after push).

Validation workflow now:
- Retries Docker image pull up to 10 times
- Uses exponential backoff: 30s, 60s, 120s, 120s...
- Total timeout: ~10 minutes max
- Continues with asset-only validation if image unavailable

This keeps validation enabled (important for quality) while
fixing the race condition that caused consistent failures.

Related to #695
This commit is contained in:
rcourtman 2025-11-12 13:24:54 +00:00
parent 0ab0309be0
commit c89f5ae773
2 changed files with 44 additions and 27 deletions

View file

@ -436,20 +436,13 @@ jobs:
echo "Review the draft release and publish when ready."
echo ""
# Validation disabled - was causing race conditions with Docker image propagation
# The release workflow already has comprehensive checks:
# - Version guard
# - Preflight tests (backend + frontend + linting)
# - Docker image builds
# - Release asset creation with checksums
# Manual validation can be done after draft release creation if needed
# validate-release-assets:
# needs: create-release
# uses: ./.github/workflows/validate-release-assets.yml
# secrets: inherit
# with:
# tag: ${{ needs.create-release.outputs.tag }}
# version: ${{ inputs.version }}
# release_id: ${{ needs.create-release.outputs.release_id }}
# draft: true
# target_commitish: ${{ needs.create-release.outputs.target_commitish }}
validate-release-assets:
needs: create-release
uses: ./.github/workflows/validate-release-assets.yml
secrets: inherit
with:
tag: ${{ needs.create-release.outputs.tag }}
version: ${{ inputs.version }}
release_id: ${{ needs.create-release.outputs.release_id }}
draft: true
target_commitish: ${{ needs.create-release.outputs.target_commitish }}

View file

@ -157,23 +157,47 @@ jobs:
if: steps.context.outputs.should_run == 'true'
run: docker --version
- name: Pull Docker image (if available)
- name: Pull Docker image (with retry logic)
if: steps.context.outputs.should_run == 'true'
id: docker
continue-on-error: true
run: |
IMAGE="rcourtman/pulse:${{ steps.context.outputs.tag }}"
echo "Attempting to pull Docker image: $IMAGE"
echo "Docker Hub CDN propagation can take 2-5 minutes after push..."
echo ""
if docker pull "$IMAGE" 2>/dev/null; then
echo "✓ Docker image available: $IMAGE"
echo "image_available=true" >> $GITHUB_OUTPUT
echo "image=$IMAGE" >> $GITHUB_OUTPUT
else
echo "⚠️ Docker image not yet available: $IMAGE"
echo "⚠️ Will skip Docker image validation"
echo "image_available=false" >> $GITHUB_OUTPUT
fi
# Retry logic: 10 attempts with exponential backoff
# Total time: ~10 minutes max
MAX_ATTEMPTS=10
ATTEMPT=1
WAIT_TIME=30
while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
echo "Attempt $ATTEMPT/$MAX_ATTEMPTS: Pulling image..."
if docker pull "$IMAGE" 2>/dev/null; then
echo "✓ Docker image available: $IMAGE"
echo "image_available=true" >> $GITHUB_OUTPUT
echo "image=$IMAGE" >> $GITHUB_OUTPUT
exit 0
fi
if [ $ATTEMPT -lt $MAX_ATTEMPTS ]; then
echo "⚠️ Image not yet available, waiting ${WAIT_TIME}s before retry..."
sleep $WAIT_TIME
WAIT_TIME=$((WAIT_TIME * 2)) # Exponential backoff
if [ $WAIT_TIME -gt 120 ]; then
WAIT_TIME=120 # Cap at 2 minutes
fi
fi
ATTEMPT=$((ATTEMPT + 1))
done
echo "⚠️ Docker image not available after $MAX_ATTEMPTS attempts"
echo "⚠️ Will skip Docker image validation"
echo "image_available=false" >> $GITHUB_OUTPUT
- name: Run validation script
if: steps.context.outputs.should_run == 'true'