From feef012d276995f7f2aba3677da533d81d5af174 Mon Sep 17 00:00:00 2001 From: Robert DeLuca Date: Mon, 28 Sep 2026 23:24:00 -0500 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=94=A7=20Make=20Swift=20SDK=20release?= =?UTF-8?q?s=20resumable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a Node runtime supported by npm trusted publishing and update the release action. Allow a tagged Swift release to resume after a publish or GitHub release failure without creating a second version. --- .github/workflows/release-ember-client.yml | 6 +- .github/workflows/release-ruby-client.yml | 2 +- .../workflows/release-static-site-client.yml | 6 +- .../workflows/release-storybook-client.yml | 6 +- .github/workflows/release-swift-client.yml | 101 +++++++++++++----- .github/workflows/release-vitest-client.yml | 6 +- .github/workflows/release.yml | 6 +- 7 files changed, 89 insertions(+), 44 deletions(-) diff --git a/.github/workflows/release-ember-client.yml b/.github/workflows/release-ember-client.yml index b0d92eb2..5a980411 100644 --- a/.github/workflows/release-ember-client.yml +++ b/.github/workflows/release-ember-client.yml @@ -39,7 +39,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Upgrade npm for Trusted Publishers @@ -124,7 +124,7 @@ jobs: - name: Set Node.js back to release version uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Install dependencies @@ -219,7 +219,7 @@ jobs: } >> $GITHUB_OUTPUT - name: Create GitHub Release - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: tag_name: ${{ steps.version.outputs.tag }} name: ๐Ÿน Ember SDK v${{ steps.version.outputs.version }} diff --git a/.github/workflows/release-ruby-client.yml b/.github/workflows/release-ruby-client.yml index 6e0bfb1d..55e6632c 100644 --- a/.github/workflows/release-ruby-client.yml +++ b/.github/workflows/release-ruby-client.yml @@ -204,7 +204,7 @@ jobs: } >> $GITHUB_OUTPUT - name: Create GitHub Release - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: tag_name: ${{ steps.new_version.outputs.tag }} name: ๐Ÿ’Ž Ruby Client v${{ steps.new_version.outputs.version }} diff --git a/.github/workflows/release-static-site-client.yml b/.github/workflows/release-static-site-client.yml index 8b62cca7..d4febdf5 100644 --- a/.github/workflows/release-static-site-client.yml +++ b/.github/workflows/release-static-site-client.yml @@ -34,7 +34,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Upgrade npm for Trusted Publishers @@ -115,7 +115,7 @@ jobs: - name: Set Node.js back to release version uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Install dependencies @@ -225,7 +225,7 @@ jobs: } >> $GITHUB_OUTPUT - name: Create GitHub Release - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: tag_name: ${{ steps.version.outputs.tag }} name: ๐Ÿ—๏ธ Static Site Plugin v${{ steps.version.outputs.version }} diff --git a/.github/workflows/release-storybook-client.yml b/.github/workflows/release-storybook-client.yml index e6024d4a..9cf55f7f 100644 --- a/.github/workflows/release-storybook-client.yml +++ b/.github/workflows/release-storybook-client.yml @@ -34,7 +34,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Upgrade npm for Trusted Publishers @@ -115,7 +115,7 @@ jobs: - name: Set Node.js back to release version uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Install dependencies @@ -215,7 +215,7 @@ jobs: } >> $GITHUB_OUTPUT - name: Create GitHub Release - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: tag_name: ${{ steps.version.outputs.tag }} name: ๐Ÿ“š Storybook Plugin v${{ steps.version.outputs.version }} diff --git a/.github/workflows/release-swift-client.yml b/.github/workflows/release-swift-client.yml index c39952c6..903b7bf3 100644 --- a/.github/workflows/release-swift-client.yml +++ b/.github/workflows/release-swift-client.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: version_type: - description: 'Version bump type' + description: 'Version bump type (ignored when resuming)' required: true default: 'patch' type: choice @@ -12,6 +12,10 @@ on: - patch - minor - major + resume_version: + description: 'Resume a tagged release after a publish or release failure' + required: false + type: string concurrency: group: sdk-release cancel-in-progress: false @@ -33,7 +37,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Upgrade npm for Trusted Publishers @@ -57,35 +61,58 @@ jobs: - name: Ensure we have latest main run: | - git fetch origin main + git fetch origin main --tags git reset --hard origin/main - - name: Get current version - id: current_version + - name: Prepare release version + id: new_version working-directory: ./clients/swift + env: + RESUME_VERSION: ${{ github.event.inputs.resume_version }} + VERSION_TYPE: ${{ github.event.inputs.version_type }} run: | - CURRENT_VERSION=$(node -p "require('./package.json').version") - echo "version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT" + if [ -n "$RESUME_VERSION" ]; then + if [[ ! "$RESUME_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Resume version must be a stable semver version, got: $RESUME_VERSION" + exit 1 + fi - - name: Get previous release tag - id: previous_tag - run: | - PREV_TAG="" - if git rev-parse "swift/v${{ steps.current_version.outputs.version }}" >/dev/null 2>&1; then - PREV_TAG="swift/v${{ steps.current_version.outputs.version }}" + RELEASE_TAG="swift/v$RESUME_VERSION" + SPM_TAG="v$RESUME_VERSION" + for tag in "$RELEASE_TAG" "$SPM_TAG"; do + if ! git rev-parse --verify "refs/tags/$tag" >/dev/null 2>&1; then + echo "Cannot resume release: tag $tag does not exist" + exit 1 + fi + done + + git checkout --detach "$SPM_TAG" + PACKAGE_VERSION=$(node -p "require('./package.json').version") + if [ "$PACKAGE_VERSION" != "$RESUME_VERSION" ]; then + echo "Tag $SPM_TAG contains package version $PACKAGE_VERSION, not $RESUME_VERSION" + exit 1 + fi + + NEW_VERSION="$RESUME_VERSION" + PREVIOUS_TAG="" + echo "resume=true" >> "$GITHUB_OUTPUT" + else + CURRENT_VERSION=$(node -p "require('./package.json').version") + PREVIOUS_TAG="" + if git rev-parse "swift/v$CURRENT_VERSION" >/dev/null 2>&1; then + PREVIOUS_TAG="swift/v$CURRENT_VERSION" + fi + NEW_VERSION=$(npm version "$VERSION_TYPE" --no-git-tag-version | sed 's/^v//') + echo "resume=false" >> "$GITHUB_OUTPUT" fi - echo "tag=$PREV_TAG" >> $GITHUB_OUTPUT - - name: Bump version - id: new_version - working-directory: ./clients/swift - run: | - NEW_VERSION=$(npm version ${{ github.event.inputs.version_type }} --no-git-tag-version | sed 's/v//') - echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "tag=swift/v$NEW_VERSION" >> $GITHUB_OUTPUT - echo "spm_tag=v$NEW_VERSION" >> $GITHUB_OUTPUT + echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT" + echo "tag=swift/v$NEW_VERSION" >> "$GITHUB_OUTPUT" + echo "spm_tag=v$NEW_VERSION" >> "$GITHUB_OUTPUT" + echo "previous_tag=$PREVIOUS_TAG" >> "$GITHUB_OUTPUT" - name: Verify release tags are available + if: steps.new_version.outputs.resume != 'true' run: | for tag in \ "${{ steps.new_version.outputs.tag }}" \ @@ -101,6 +128,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Generate changelog + if: steps.new_version.outputs.resume != 'true' continue-on-error: true uses: openai/codex-action@a26d2d4d8b78a694338b8e3715c3630254340b2c # v1 with: @@ -113,10 +141,10 @@ jobs: Context: - Client location: `clients/swift/` - - Previous tag: `${{ steps.previous_tag.outputs.tag }}` + - Previous tag: `${{ steps.new_version.outputs.previous_tag }}` - New version: `${{ steps.new_version.outputs.version }}` - This is a monorepo with multiple clients and a CLI. - - Compare URL when a previous tag exists: `https://github.com/vizzly-testing/cli/compare/${{ steps.previous_tag.outputs.tag }}...swift/v${{ steps.new_version.outputs.version }}` + - Compare URL when a previous tag exists: `https://github.com/vizzly-testing/cli/compare/${{ steps.new_version.outputs.previous_tag }}...swift/v${{ steps.new_version.outputs.version }}` - Release URL when this is the first Swift tag: `https://github.com/vizzly-testing/cli/releases/tag/swift/v${{ steps.new_version.outputs.version }}` Instructions: @@ -144,6 +172,7 @@ jobs: **Full Changelog**: - name: Update CHANGELOG.md + if: steps.new_version.outputs.resume != 'true' working-directory: ./clients/swift run: | # Check if changelog was generated successfully @@ -202,11 +231,23 @@ jobs: xcrun simctl bootstatus "$DEVICE_UDID" -b VIZZLY_SIMULATOR_UDID="$DEVICE_UDID" pnpm run test:previews:e2e - - name: Verify npm package version is unpublished + - name: Check npm package version + id: npm_version working-directory: ./clients/swift + env: + RELEASE_VERSION: ${{ steps.new_version.outputs.version }} + RESUME_RELEASE: ${{ steps.new_version.outputs.resume }} run: | - if npm view @vizzly-testing/swift@${{ steps.new_version.outputs.version }} version >/dev/null 2>&1; then - echo "@vizzly-testing/swift@${{ steps.new_version.outputs.version }} is already published" + if NPM_OUTPUT=$(npm view "@vizzly-testing/swift@$RELEASE_VERSION" version 2>&1); then + if [ "$RESUME_RELEASE" != "true" ]; then + echo "@vizzly-testing/swift@$RELEASE_VERSION is already published" + exit 1 + fi + echo "published=true" >> "$GITHUB_OUTPUT" + elif printf '%s\n' "$NPM_OUTPUT" | grep -q 'E404'; then + echo "published=false" >> "$GITHUB_OUTPUT" + else + printf '%s\n' "$NPM_OUTPUT" exit 1 fi @@ -218,11 +259,13 @@ jobs: echo "file=$PACK_FILE" >> $GITHUB_OUTPUT - name: Configure git identity + if: steps.new_version.outputs.resume != 'true' run: | git config --local user.email "${{ secrets.GIT_USER_EMAIL }}" git config --local user.name "${{ secrets.GIT_USER_NAME }}" - name: Commit and push changes + if: steps.new_version.outputs.resume != 'true' run: | git add clients/swift/package.json clients/swift/CHANGELOG.md git commit -m "๐Ÿ”– Swift client v${{ steps.new_version.outputs.version }}" @@ -234,6 +277,7 @@ jobs: "${{ steps.new_version.outputs.spm_tag }}" - name: Publish preview CLI package to npm + if: steps.npm_version.outputs.published != 'true' working-directory: ./clients/swift run: | npm config delete //registry.npmjs.org/:_authToken 2>/dev/null || true @@ -254,12 +298,13 @@ jobs: } >> $GITHUB_OUTPUT - name: Create GitHub Release - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: tag_name: ${{ steps.new_version.outputs.tag }} name: ๐Ÿ“ฑ Swift SDK v${{ steps.new_version.outputs.version }} body: ${{ steps.release_notes.outputs.notes }} files: ./clients/swift/${{ steps.pack.outputs.file }} + overwrite_files: true draft: false prerelease: false env: diff --git a/.github/workflows/release-vitest-client.yml b/.github/workflows/release-vitest-client.yml index c76aa7be..78f890a4 100644 --- a/.github/workflows/release-vitest-client.yml +++ b/.github/workflows/release-vitest-client.yml @@ -34,7 +34,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Upgrade npm for Trusted Publishers @@ -115,7 +115,7 @@ jobs: - name: Set Node.js back to release version uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Install dependencies @@ -205,7 +205,7 @@ jobs: } >> $GITHUB_OUTPUT - name: Create GitHub Release - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: tag_name: ${{ steps.version.outputs.tag }} name: ๐Ÿงช Vitest Integration v${{ steps.version.outputs.version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f3696845..c7a96128 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Upgrade npm for Trusted Publishers @@ -159,7 +159,7 @@ jobs: - name: Restore Node.js for publishing uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: - node-version: '22.13.1' + node-version: '22.14.0' registry-url: 'https://registry.npmjs.org' - name: Restore npm and pnpm for publishing @@ -194,7 +194,7 @@ jobs: git push origin "${{ steps.version.outputs.new_version }}" - name: Create GitHub Release - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: tag_name: ${{ steps.version.outputs.new_version }} name: ${{ github.event.inputs.version_type == 'beta' && '๐Ÿงช' || 'โœจ' }} ${{ steps.version.outputs.new_version }} From 1299b6fd4a5b619cd95103a1dc723b166d0e0227 Mon Sep 17 00:00:00 2001 From: Robert DeLuca Date: Mon, 28 Sep 2026 23:56:56 -0500 Subject: [PATCH 2/2] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Keep=20Swift=20release?= =?UTF-8?q?s=20on=20the=20standard=20flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current version mismatch is fixed by publishing a new Swift release. Remove the one-off resume path and keep the same version-bump flow used by other clients. --- .github/workflows/release-swift-client.yml | 65 ++++------------------ 1 file changed, 10 insertions(+), 55 deletions(-) diff --git a/.github/workflows/release-swift-client.yml b/.github/workflows/release-swift-client.yml index 903b7bf3..df6d7c62 100644 --- a/.github/workflows/release-swift-client.yml +++ b/.github/workflows/release-swift-client.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: version_type: - description: 'Version bump type (ignored when resuming)' + description: 'Version bump type' required: true default: 'patch' type: choice @@ -12,10 +12,6 @@ on: - patch - minor - major - resume_version: - description: 'Resume a tagged release after a publish or release failure' - required: false - type: string concurrency: group: sdk-release cancel-in-progress: false @@ -68,43 +64,14 @@ jobs: id: new_version working-directory: ./clients/swift env: - RESUME_VERSION: ${{ github.event.inputs.resume_version }} VERSION_TYPE: ${{ github.event.inputs.version_type }} run: | - if [ -n "$RESUME_VERSION" ]; then - if [[ ! "$RESUME_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Resume version must be a stable semver version, got: $RESUME_VERSION" - exit 1 - fi - - RELEASE_TAG="swift/v$RESUME_VERSION" - SPM_TAG="v$RESUME_VERSION" - for tag in "$RELEASE_TAG" "$SPM_TAG"; do - if ! git rev-parse --verify "refs/tags/$tag" >/dev/null 2>&1; then - echo "Cannot resume release: tag $tag does not exist" - exit 1 - fi - done - - git checkout --detach "$SPM_TAG" - PACKAGE_VERSION=$(node -p "require('./package.json').version") - if [ "$PACKAGE_VERSION" != "$RESUME_VERSION" ]; then - echo "Tag $SPM_TAG contains package version $PACKAGE_VERSION, not $RESUME_VERSION" - exit 1 - fi - - NEW_VERSION="$RESUME_VERSION" - PREVIOUS_TAG="" - echo "resume=true" >> "$GITHUB_OUTPUT" - else - CURRENT_VERSION=$(node -p "require('./package.json').version") - PREVIOUS_TAG="" - if git rev-parse "swift/v$CURRENT_VERSION" >/dev/null 2>&1; then - PREVIOUS_TAG="swift/v$CURRENT_VERSION" - fi - NEW_VERSION=$(npm version "$VERSION_TYPE" --no-git-tag-version | sed 's/^v//') - echo "resume=false" >> "$GITHUB_OUTPUT" + CURRENT_VERSION=$(node -p "require('./package.json').version") + PREVIOUS_TAG="" + if git rev-parse "swift/v$CURRENT_VERSION" >/dev/null 2>&1; then + PREVIOUS_TAG="swift/v$CURRENT_VERSION" fi + NEW_VERSION=$(npm version "$VERSION_TYPE" --no-git-tag-version | sed 's/^v//') echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT" echo "tag=swift/v$NEW_VERSION" >> "$GITHUB_OUTPUT" @@ -112,7 +79,6 @@ jobs: echo "previous_tag=$PREVIOUS_TAG" >> "$GITHUB_OUTPUT" - name: Verify release tags are available - if: steps.new_version.outputs.resume != 'true' run: | for tag in \ "${{ steps.new_version.outputs.tag }}" \ @@ -128,7 +94,6 @@ jobs: run: pnpm install --frozen-lockfile - name: Generate changelog - if: steps.new_version.outputs.resume != 'true' continue-on-error: true uses: openai/codex-action@a26d2d4d8b78a694338b8e3715c3630254340b2c # v1 with: @@ -172,7 +137,6 @@ jobs: **Full Changelog**: - name: Update CHANGELOG.md - if: steps.new_version.outputs.resume != 'true' working-directory: ./clients/swift run: | # Check if changelog was generated successfully @@ -231,21 +195,16 @@ jobs: xcrun simctl bootstatus "$DEVICE_UDID" -b VIZZLY_SIMULATOR_UDID="$DEVICE_UDID" pnpm run test:previews:e2e - - name: Check npm package version - id: npm_version + - name: Verify npm package version is unpublished working-directory: ./clients/swift env: RELEASE_VERSION: ${{ steps.new_version.outputs.version }} - RESUME_RELEASE: ${{ steps.new_version.outputs.resume }} run: | if NPM_OUTPUT=$(npm view "@vizzly-testing/swift@$RELEASE_VERSION" version 2>&1); then - if [ "$RESUME_RELEASE" != "true" ]; then - echo "@vizzly-testing/swift@$RELEASE_VERSION is already published" - exit 1 - fi - echo "published=true" >> "$GITHUB_OUTPUT" + echo "@vizzly-testing/swift@$RELEASE_VERSION is already published" + exit 1 elif printf '%s\n' "$NPM_OUTPUT" | grep -q 'E404'; then - echo "published=false" >> "$GITHUB_OUTPUT" + : else printf '%s\n' "$NPM_OUTPUT" exit 1 @@ -259,13 +218,11 @@ jobs: echo "file=$PACK_FILE" >> $GITHUB_OUTPUT - name: Configure git identity - if: steps.new_version.outputs.resume != 'true' run: | git config --local user.email "${{ secrets.GIT_USER_EMAIL }}" git config --local user.name "${{ secrets.GIT_USER_NAME }}" - name: Commit and push changes - if: steps.new_version.outputs.resume != 'true' run: | git add clients/swift/package.json clients/swift/CHANGELOG.md git commit -m "๐Ÿ”– Swift client v${{ steps.new_version.outputs.version }}" @@ -277,7 +234,6 @@ jobs: "${{ steps.new_version.outputs.spm_tag }}" - name: Publish preview CLI package to npm - if: steps.npm_version.outputs.published != 'true' working-directory: ./clients/swift run: | npm config delete //registry.npmjs.org/:_authToken 2>/dev/null || true @@ -304,7 +260,6 @@ jobs: name: ๐Ÿ“ฑ Swift SDK v${{ steps.new_version.outputs.version }} body: ${{ steps.release_notes.outputs.notes }} files: ./clients/swift/${{ steps.pack.outputs.file }} - overwrite_files: true draft: false prerelease: false env: