Fewer race-conditions in Vercel redeploy (#46826)

Conrad Irwin created

Should avoid releases rolling back to older vercel versions

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Change summary

.github/workflows/after_release.yml                |  6 ++
script/redeploy-vercel                             | 39 ++++++++++++++++
tooling/xtask/src/tasks/workflows/after_release.rs |  4 
3 files changed, 46 insertions(+), 3 deletions(-)

Detailed changes

.github/workflows/after_release.yml 🔗

@@ -27,8 +27,12 @@ jobs:
     - name: after_release::rebuild_releases_page::refresh_cloud_releases
       run: curl -fX POST https://cloud.zed.dev/releases/refresh?expect_tag=${{ github.event.release.tag_name || inputs.tag_name }}
       shell: bash -euxo pipefail {0}
+    - name: steps::checkout_repo
+      uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+      with:
+        clean: false
     - name: after_release::rebuild_releases_page::redeploy_zed_dev
-      run: npm exec --yes -- vercel@37 --token="$VERCEL_TOKEN" --scope zed-industries redeploy https://zed.dev
+      run: ./script/redeploy-vercel
       shell: bash -euxo pipefail {0}
       env:
         VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}

script/redeploy-vercel 🔗

@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+if [[ -z "${VERCEL_TOKEN:-}" ]]; then
+    echo "Error: VERCEL_TOKEN environment variable is not set."
+    echo "Get a token from https://vercel.com/account/tokens"
+    exit 1
+fi
+
+MAX_ATTEMPTS="60"
+SLEEP_SECONDS="10"
+VERCEL_SCOPE="zed-industries"
+VERCEL_URL="https://zed.dev"
+
+echo "Checking for in-progress deployments..."
+
+for ((i=1; i<=MAX_ATTEMPTS; i++)); do
+    RESPONSE=$(curl -s -H "Authorization: Bearer $VERCEL_TOKEN" \
+        "https://api.vercel.com/v6/deployments?slug=${VERCEL_SCOPE}&state=BUILDING,INITIALIZING,QUEUED&target=production&limit=1")
+
+    COUNT=$(echo "$RESPONSE" | jq '.deployments | length')
+
+    if [ "$COUNT" = "0" ]; then
+        echo "No in-progress deployments found. Proceeding with redeploy."
+        break
+    fi
+
+    if [ "$i" = "$MAX_ATTEMPTS" ]; then
+        echo "Timed out waiting for deployments to complete after $((MAX_ATTEMPTS * SLEEP_SECONDS)) seconds."
+        exit 1
+    fi
+
+    echo "Attempt $i/$MAX_ATTEMPTS: Found $COUNT in-progress deployment(s). Waiting ${SLEEP_SECONDS}s..."
+    sleep "$SLEEP_SECONDS"
+done
+
+echo "Triggering redeploy of ${VERCEL_URL}..."
+npm exec --yes -- vercel@37 --token="$VERCEL_TOKEN" --scope "$VERCEL_SCOPE" redeploy "$VERCEL_URL"

tooling/xtask/src/tasks/workflows/after_release.rs 🔗

@@ -51,8 +51,7 @@ fn rebuild_releases_page() -> NamedJob {
     }
 
     fn redeploy_zed_dev() -> Step<Run> {
-        named::bash("npm exec --yes -- vercel@37 --token=\"$VERCEL_TOKEN\" --scope zed-industries redeploy https://zed.dev")
-            .add_env(("VERCEL_TOKEN", vars::VERCEL_TOKEN))
+        named::bash("./script/redeploy-vercel").add_env(("VERCEL_TOKEN", vars::VERCEL_TOKEN))
     }
 
     named::job(
@@ -60,6 +59,7 @@ fn rebuild_releases_page() -> NamedJob {
             .runs_on(runners::LINUX_SMALL)
             .with_repository_owner_guard()
             .add_step(refresh_cloud_releases())
+            .add_step(checkout_repo())
             .add_step(redeploy_zed_dev()),
     )
 }