diff --git a/.github/actions/publish-vsix/action.yml b/.github/actions/publish-vsix/action.yml index be6c5d13..3eb483fe 100644 --- a/.github/actions/publish-vsix/action.yml +++ b/.github/actions/publish-vsix/action.yml @@ -120,11 +120,26 @@ runs: exit 1 fi + publish_with_retry() { + local attempt + for attempt in 1 2 3; do + echo "Publish attempt ${attempt}/3" + if "$@"; then + return 0 + fi + if [ "$attempt" -lt 3 ]; then + echo "Publish failed; retrying in 15s..." + sleep 15 + fi + done + return 1 + } + if [ "${{ inputs.publish-tool }}" = "vsce" ]; then export VSCE_PAT="${!TOKEN_ENV}" # ensure the expected env var is set - npx @vscode/vsce publish --packagePath "${{ inputs.vsix-path }}" --skip-duplicate $PRE_RELEASE_FLAG + publish_with_retry npx @vscode/vsce publish --packagePath "${{ inputs.vsix-path }}" --skip-duplicate $PRE_RELEASE_FLAG else - npx ovsx publish "${{ inputs.vsix-path }}" -p "${!TOKEN_ENV}" --skip-duplicate $PRE_RELEASE_FLAG + publish_with_retry npx ovsx publish "${{ inputs.vsix-path }}" -p "${!TOKEN_ENV}" --skip-duplicate $PRE_RELEASE_FLAG fi PUBLISH_EXIT_CODE=$? diff --git a/.github/actions/vscode/publish-vsix/action.yml b/.github/actions/vscode/publish-vsix/action.yml index b9696014..ee6a5149 100644 --- a/.github/actions/vscode/publish-vsix/action.yml +++ b/.github/actions/vscode/publish-vsix/action.yml @@ -117,11 +117,26 @@ runs: exit 1 fi + publish_with_retry() { + local attempt + for attempt in 1 2 3; do + echo "Publish attempt ${attempt}/3" + if "$@"; then + return 0 + fi + if [ "$attempt" -lt 3 ]; then + echo "Publish failed; retrying in 15s..." + sleep 15 + fi + done + return 1 + } + if [ "${{ inputs.publish-tool }}" = "vsce" ]; then export VSCE_PAT="${!TOKEN_ENV}" # ensure the expected env var is set - npx @vscode/vsce publish --packagePath "${{ inputs.vsix-path }}" --skip-duplicate $PRE_RELEASE_FLAG + publish_with_retry npx @vscode/vsce publish --packagePath "${{ inputs.vsix-path }}" --skip-duplicate $PRE_RELEASE_FLAG else - npx ovsx publish "${{ inputs.vsix-path }}" -p "${!TOKEN_ENV}" --skip-duplicate $PRE_RELEASE_FLAG + publish_with_retry npx ovsx publish "${{ inputs.vsix-path }}" -p "${!TOKEN_ENV}" --skip-duplicate $PRE_RELEASE_FLAG fi echo "✅ Successfully published to $MARKETPLACE_NAME" diff --git a/.github/workflows/openvsx-publish-release-vsix.yml b/.github/workflows/openvsx-publish-release-vsix.yml index 6bb5c5fa..f366ff7d 100644 --- a/.github/workflows/openvsx-publish-release-vsix.yml +++ b/.github/workflows/openvsx-publish-release-vsix.yml @@ -36,6 +36,23 @@ jobs: IDEE_OVSX_PAT: ${{ secrets.IDEE_OVSX_PAT }} PRE_RELEASE: ${{ steps.release.outputs.pre-release }} run: | + # Open VSX can hang the same way as vsce; retry per VSIX. + # --skip-duplicate makes a retry a no-op if the first attempt committed. + publish_with_retry() { + local attempt + for attempt in 1 2 3; do + echo "Publish attempt ${attempt}/3" + if "$@"; then + return 0 + fi + if [ "$attempt" -lt 3 ]; then + echo "Publish failed; retrying in 15s..." + sleep 15 + fi + done + return 1 + } + while IFS= read -r -d '' vsix; do args=("$vsix" -p "$IDEE_OVSX_PAT" --skip-duplicate) pre_release_suffix='' @@ -49,5 +66,8 @@ jobs: continue fi - npx ovsx publish "${args[@]}" + if ! publish_with_retry npx ovsx publish "${args[@]}"; then + echo "::error::Failed to publish $vsix after 3 attempts" + exit 1 + fi done < <(find extensions -type f -name '*.vsix' -print0) diff --git a/.github/workflows/vscode-promote-prerelease.yml b/.github/workflows/vscode-promote-prerelease.yml index 9fcdd26f..3a353770 100644 --- a/.github/workflows/vscode-promote-prerelease.yml +++ b/.github/workflows/vscode-promote-prerelease.yml @@ -198,6 +198,24 @@ jobs: REPO="${{ github.repository }}" FAILED=0 + # Marketplace gallery requests can sit until typed-rest-client's 180s + # socket timeout. vsce/ovsx have no timeout flag; retry per VSIX. + # --skip-duplicate makes a retry a no-op if the first attempt committed. + publish_with_retry() { + local attempt + for attempt in 1 2 3; do + echo "Publish attempt ${attempt}/3" + if "$@"; then + return 0 + fi + if [ "$attempt" -lt 3 ]; then + echo "Publish failed; retrying in 15s..." + sleep 15 + fi + done + return 1 + } + for VSIX in "${VSIX_FILES[@]}"; do NAME=$(basename "$VSIX") echo "::group::$NAME → $MARKETPLACE_NAME" @@ -213,14 +231,14 @@ jobs: fi if [ "$PUBLISH_TOOL" = "vsce" ]; then - if VSCE_PAT="$TOKEN" npx @vscode/vsce publish --packagePath "$VSIX" --skip-duplicate --pre-release; then + if VSCE_PAT="$TOKEN" publish_with_retry npx @vscode/vsce publish --packagePath "$VSIX" --skip-duplicate --pre-release; then echo "✅ Published $NAME to $MARKETPLACE_NAME" else echo "::error::Failed to publish $NAME to $MARKETPLACE_NAME" FAILED=1 fi else - if npx ovsx publish "$VSIX" -p "$TOKEN" --skip-duplicate --pre-release; then + if publish_with_retry npx ovsx publish "$VSIX" -p "$TOKEN" --skip-duplicate --pre-release; then echo "✅ Published $NAME to $MARKETPLACE_NAME" else echo "::error::Failed to publish $NAME to $MARKETPLACE_NAME" diff --git a/.github/workflows/vscode-publish-release-vsix.yml b/.github/workflows/vscode-publish-release-vsix.yml index e04c3cd2..979afbf6 100644 --- a/.github/workflows/vscode-publish-release-vsix.yml +++ b/.github/workflows/vscode-publish-release-vsix.yml @@ -36,6 +36,24 @@ jobs: PRE_RELEASE: ${{ steps.release.outputs.pre-release }} VSCE_PERSONAL_ACCESS_TOKEN: ${{ secrets.VSCE_PERSONAL_ACCESS_TOKEN }} run: | + # Marketplace gallery requests can sit until typed-rest-client's 180s + # socket timeout. vsce has no timeout flag; retry per VSIX. + # --skip-duplicate makes a retry a no-op if the first attempt committed. + publish_with_retry() { + local attempt + for attempt in 1 2 3; do + echo "Publish attempt ${attempt}/3" + if "$@"; then + return 0 + fi + if [ "$attempt" -lt 3 ]; then + echo "Publish failed; retrying in 15s..." + sleep 15 + fi + done + return 1 + } + while IFS= read -r -d '' vsix; do args=(--packagePath "$vsix" --skip-duplicate) if [ "$PRE_RELEASE" = true ]; then @@ -47,5 +65,8 @@ jobs: continue fi - VSCE_PAT="$VSCE_PERSONAL_ACCESS_TOKEN" npx @vscode/vsce publish "${args[@]}" + if ! VSCE_PAT="$VSCE_PERSONAL_ACCESS_TOKEN" publish_with_retry npx @vscode/vsce publish "${args[@]}"; then + echo "::error::Failed to publish $vsix after 3 attempts" + exit 1 + fi done < <(find extensions -type f -name '*.vsix' -print0) diff --git a/.github/workflows/vscode-release-explicit.yml b/.github/workflows/vscode-release-explicit.yml index 944538f6..970ce43e 100644 --- a/.github/workflows/vscode-release-explicit.yml +++ b/.github/workflows/vscode-release-explicit.yml @@ -136,7 +136,13 @@ jobs: PRE_RELEASE_FLAG: ${{ inputs.pre-release && '--pre-release' || '' }} run: | cd "$EXTENSION" - npx vsce publish $PRE_RELEASE_FLAG + ok=0 + for attempt in 1 2 3; do + echo "Publish attempt ${attempt}/3" + npx vsce publish --skip-duplicate $PRE_RELEASE_FLAG && { ok=1; break; } + [ "$attempt" -lt 3 ] && sleep 15 + done + [ "$ok" -eq 1 ] - name: Publish to Open VSX if: | @@ -148,7 +154,13 @@ jobs: PRE_RELEASE_FLAG: ${{ inputs.pre-release && '--pre-release' || '' }} run: | cd "$EXTENSION" - npx ovsx publish $PRE_RELEASE_FLAG -p "$OVSX_PAT" + ok=0 + for attempt in 1 2 3; do + echo "Publish attempt ${attempt}/3" + npx ovsx publish --skip-duplicate $PRE_RELEASE_FLAG -p "$OVSX_PAT" && { ok=1; break; } + [ "$attempt" -lt 3 ] && sleep 15 + done + [ "$ok" -eq 1 ] - name: Prepare artifact name id: artifact