diff --git a/.github/workflows/openclaw-live-and-e2e-checks-reusable.yml b/.github/workflows/openclaw-live-and-e2e-checks-reusable.yml index 123634bda32f..10c60cf9ac1b 100644 --- a/.github/workflows/openclaw-live-and-e2e-checks-reusable.yml +++ b/.github/workflows/openclaw-live-and-e2e-checks-reusable.yml @@ -774,11 +774,10 @@ jobs: - name: Log in to GHCR for shared Docker E2E image if: contains(matrix.profiles, inputs.release_test_profile) - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ github.token }} + run: bash .release-harness/scripts/ci-docker-login-ghcr.sh + env: + GHCR_USERNAME: ${{ github.actor }} + GITHUB_TOKEN: ${{ github.token }} - name: Setup Node environment if: contains(matrix.profiles, inputs.release_test_profile) @@ -1035,11 +1034,10 @@ jobs: path: .release-harness - name: Log in to GHCR for shared Docker E2E image - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ github.token }} + run: bash .release-harness/scripts/ci-docker-login-ghcr.sh + env: + GHCR_USERNAME: ${{ github.actor }} + GITHUB_TOKEN: ${{ github.token }} - name: Setup Node environment uses: ./.github/actions/setup-node-env @@ -1211,11 +1209,10 @@ jobs: path: .release-harness - name: Log in to GHCR for shared Docker E2E image - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ github.token }} + run: bash .release-harness/scripts/ci-docker-login-ghcr.sh + env: + GHCR_USERNAME: ${{ github.actor }} + GITHUB_TOKEN: ${{ github.token }} - name: Setup Node environment uses: ./.github/actions/setup-node-env @@ -1470,11 +1467,10 @@ jobs: - name: Log in to GHCR if: steps.plan.outputs.needs_e2e_image == '1' - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ github.token }} + run: bash .release-harness/scripts/ci-docker-login-ghcr.sh + env: + GHCR_USERNAME: ${{ github.actor }} + GITHUB_TOKEN: ${{ github.token }} - name: Check existing shared Docker E2E images id: image_exists @@ -1585,11 +1581,10 @@ jobs: echo "Shared live-test image: \`${live_image}\`" >> "$GITHUB_STEP_SUMMARY" - name: Log in to GHCR - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ github.token }} + run: bash scripts/ci-docker-login-ghcr.sh + env: + GHCR_USERNAME: ${{ github.actor }} + GITHUB_TOKEN: ${{ github.token }} - name: Check existing shared live-test image id: image_exists @@ -1731,11 +1726,10 @@ jobs: - name: Log in to GHCR if: contains(matrix.profiles, inputs.release_test_profile) - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ github.token }} + run: bash .release-harness/scripts/ci-docker-login-ghcr.sh + env: + GHCR_USERNAME: ${{ github.actor }} + GITHUB_TOKEN: ${{ github.token }} - name: Validate provider credential if: contains(matrix.profiles, inputs.release_test_profile) @@ -1906,11 +1900,10 @@ jobs: run: bash scripts/ci-hydrate-live-auth.sh - name: Log in to GHCR - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ github.token }} + run: bash .release-harness/scripts/ci-docker-login-ghcr.sh + env: + GHCR_USERNAME: ${{ github.actor }} + GITHUB_TOKEN: ${{ github.token }} - name: Validate provider credentials shell: bash @@ -2435,11 +2428,10 @@ jobs: - name: Log in to GHCR if: contains(matrix.profiles, inputs.release_test_profile) && (inputs.live_suite_filter == '' || inputs.live_suite_filter == matrix.suite_id || (inputs.live_suite_filter == 'live-gateway-advisory-docker' && startsWith(matrix.suite_id, 'live-gateway-advisory-docker-'))) - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ github.token }} + run: bash .release-harness/scripts/ci-docker-login-ghcr.sh + env: + GHCR_USERNAME: ${{ github.actor }} + GITHUB_TOKEN: ${{ github.token }} - name: Configure suite-specific env if: contains(matrix.profiles, inputs.release_test_profile) && (inputs.live_suite_filter == '' || inputs.live_suite_filter == matrix.suite_id || (inputs.live_suite_filter == 'live-gateway-advisory-docker' && startsWith(matrix.suite_id, 'live-gateway-advisory-docker-'))) diff --git a/scripts/ci-docker-login-ghcr.sh b/scripts/ci-docker-login-ghcr.sh new file mode 100755 index 000000000000..88a9ef869730 --- /dev/null +++ b/scripts/ci-docker-login-ghcr.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -euo pipefail + +registry="${GHCR_REGISTRY:-ghcr.io}" +username="${GHCR_USERNAME:-${GITHUB_ACTOR:-github-actions[bot]}}" + +if [[ -z "${GITHUB_TOKEN:-}" ]]; then + echo "GITHUB_TOKEN is required for GHCR login." >&2 + exit 1 +fi + +for attempt in 1 2 3 4; do + if printf '%s' "$GITHUB_TOKEN" | docker login "$registry" --username "$username" --password-stdin; then + exit 0 + fi + if [[ "$attempt" -eq 4 ]]; then + break + fi + sleep_seconds=$((attempt * 5)) + echo "GHCR login failed on attempt ${attempt}; retrying in ${sleep_seconds}s." >&2 + sleep "$sleep_seconds" +done + +echo "GHCR login failed after 4 attempts." >&2 +exit 1