From 3e269f59294f2d280b273f07cb3f7923b0b7a2f2 Mon Sep 17 00:00:00 2001 From: heznpc Date: Fri, 24 Apr 2026 08:22:19 +0900 Subject: [PATCH] fix(cd): skip CWS upload when version already deployed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recent CD runs failed with HTTP 400 from Chrome Web Store because the same manifest version was uploaded twice — a patch-level PR didn't bump manifest.json but still touched src/, so the changes-guard passed and the workflow tried to re-upload v3.5.5 on top of v3.5.5. Fix: gate the upload on `cws-v${VERSION}` tag absence, and tag origin on a successful upload. Subsequent runs at the same version see the tag and skip with a GitHub ::notice:: explaining how to override (bump version or re-dispatch with force=true). The existing `force=true` workflow_dispatch input still bypasses the guard for manual re-uploads. --- .github/workflows/cd.yml | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 32c4039..ea52ce6 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -77,8 +77,23 @@ jobs: echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "Deploying v$VERSION" + - name: Skip if version was already deployed + if: steps.secrets.outputs.configured == 'true' && github.event.inputs.force != 'true' + id: tag_guard + env: + VERSION: ${{ steps.version.outputs.version }} + run: | + TAG="cws-v${VERSION}" + git fetch --tags --depth=1 origin "refs/tags/${TAG}:refs/tags/${TAG}" 2>/dev/null || true + if git rev-parse --verify --quiet "refs/tags/${TAG}" >/dev/null; then + echo "::notice::${TAG} already exists on origin — v${VERSION} was already deployed. Skipping upload. Bump manifest.json version or re-run with force=true to override." + echo "should_upload=false" >> "$GITHUB_OUTPUT" + else + echo "should_upload=true" >> "$GITHUB_OUTPUT" + fi + - name: Build zip - if: steps.secrets.outputs.configured == 'true' + if: steps.secrets.outputs.configured == 'true' && steps.tag_guard.outputs.should_upload != 'false' run: | mkdir -p store-assets zip -r store-assets/skillbridge.zip manifest.json _locales/ src/ assets/icons/ -x '*.DS_Store' @@ -86,7 +101,7 @@ jobs: echo "Built store-assets/skillbridge.zip ($SIZE)" - name: Upload to Chrome Web Store - if: steps.secrets.outputs.configured == 'true' + if: steps.secrets.outputs.configured == 'true' && steps.tag_guard.outputs.should_upload != 'false' uses: mnao305/chrome-extension-upload@v5.0.0 with: file-path: store-assets/skillbridge.zip @@ -96,8 +111,16 @@ jobs: refresh-token: ${{ secrets.CWS_REFRESH_TOKEN }} publish: ${{ github.event.inputs.publish || 'true' }} + - name: Tag version on successful upload + if: steps.secrets.outputs.configured == 'true' && steps.tag_guard.outputs.should_upload != 'false' + env: + VERSION: ${{ steps.version.outputs.version }} + run: | + git tag "cws-v${VERSION}" + git push origin "cws-v${VERSION}" + - name: Upload zip as artifact - if: steps.secrets.outputs.configured == 'true' + if: steps.secrets.outputs.configured == 'true' && steps.tag_guard.outputs.should_upload != 'false' uses: actions/upload-artifact@v4 with: name: skillbridge-v${{ steps.version.outputs.version }}