name: Publish Docker Images on: release: types: [published] workflow_dispatch: inputs: tag: description: 'Release tag (e.g., v4.34.0)' required: true type: string concurrency: group: docker-publish-${{ github.event.release.tag_name || inputs.tag }} cancel-in-progress: false jobs: publish: runs-on: ubuntu-latest timeout-minutes: 15 permissions: contents: read packages: write steps: - name: Extract version from release tag id: version run: | TAG="${{ github.event.release.tag_name || inputs.tag }}" VERSION="${TAG#v}" echo "tag=${TAG}" >> $GITHUB_OUTPUT echo "version=${VERSION}" >> $GITHUB_OUTPUT echo "Publishing Docker images for ${TAG}" - name: Log in to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Copy staging images to final tags run: | TAG="${{ steps.version.outputs.tag }}" VERSION="${{ steps.version.outputs.version }}" STAGING_TAG="staging-${TAG}" # Retry function for transient Docker Hub failures retry_push() { local cmd="$1" local max_attempts=3 local attempt=1 local delay=10 while [ $attempt -le $max_attempts ]; do echo "Attempt $attempt of $max_attempts..." if eval "$cmd"; then return 0 fi echo "Attempt $attempt failed" if [ $attempt -lt $max_attempts ]; then echo "Waiting ${delay}s before retry..." sleep $delay delay=$((delay * 2)) fi attempt=$((attempt + 1)) done echo "All $max_attempts attempts failed" return 1 } echo "Copying pulse staging image to final tags..." retry_push "docker buildx imagetools create \ --tag rcourtman/pulse:${TAG} \ --tag rcourtman/pulse:${VERSION} \ --tag rcourtman/pulse:latest \ --tag ghcr.io/${{ github.repository_owner }}/pulse:${TAG} \ --tag ghcr.io/${{ github.repository_owner }}/pulse:${VERSION} \ --tag ghcr.io/${{ github.repository_owner }}/pulse:latest \ ghcr.io/${{ github.repository_owner }}/pulse:${STAGING_TAG}" echo "Copying pulse-docker-agent staging image to final tags..." retry_push "docker buildx imagetools create \ --tag rcourtman/pulse-docker-agent:${TAG} \ --tag rcourtman/pulse-docker-agent:${VERSION} \ --tag rcourtman/pulse-docker-agent:latest \ --tag ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:${TAG} \ --tag ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:${VERSION} \ --tag ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:latest \ ghcr.io/${{ github.repository_owner }}/pulse-docker-agent:${STAGING_TAG}" - name: Output image information run: | echo "✅ Docker images published successfully!" echo "" echo "Server images:" echo " - rcourtman/pulse:${{ steps.version.outputs.tag }}" echo " - rcourtman/pulse:${{ steps.version.outputs.version }}" echo " - rcourtman/pulse:latest" echo "" echo "Agent images:" echo " - rcourtman/pulse-docker-agent:${{ steps.version.outputs.tag }}" echo " - rcourtman/pulse-docker-agent:${{ steps.version.outputs.version }}" echo " - rcourtman/pulse-docker-agent:latest"