Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 92 additions & 36 deletions .github/workflows/release-swift-client.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ on:
- patch
- minor
- major

concurrency:
group: sdk-release
cancel-in-progress: false

jobs:
release:
runs-on: macos-latest
runs-on: macos-26
permissions:
contents: write
id-token: write
Expand All @@ -35,9 +34,21 @@ jobs:
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: '22.13.1'
registry-url: 'https://registry.npmjs.org'

- name: Upgrade npm for Trusted Publishers
run: npm install -g npm@11.5.1

- name: Install pnpm
run: |
npm install -g corepack@latest
corepack enable
corepack prepare pnpm@11.3.0 --activate

- name: Show Xcode version
run: xcodebuild -version
- name: Select Xcode version
run: |
sudo xcode-select -s /Applications/Xcode_26.6.app
xcodebuild -version

- name: Configure git
run: |
Expand All @@ -53,12 +64,8 @@ jobs:
id: current_version
working-directory: ./clients/swift
run: |
# Extract the latest released semver entry. Ignore [Unreleased].
CURRENT_VERSION=$(grep -m 1 -E '^## \[[0-9]+\.[0-9]+\.[0-9]+\]' CHANGELOG.md | sed 's/## \[\(.*\)\].*/\1/' || true)
if [ -z "$CURRENT_VERSION" ]; then
CURRENT_VERSION="0.0.0"
fi
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
CURRENT_VERSION=$(node -p "require('./package.json').version")
echo "version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT"

- name: Get previous release tag
id: previous_tag
Expand All @@ -69,33 +76,29 @@ jobs:
fi
echo "tag=$PREV_TAG" >> $GITHUB_OUTPUT

- name: Calculate new version
- name: Bump version
id: new_version
working-directory: ./clients/swift
run: |
CURRENT="${{ steps.current_version.outputs.version }}"

# Validate version format (X.Y.Z)
if ! [[ "$CURRENT" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Invalid version format '$CURRENT'. Expected X.Y.Z"
exit 1
fi

IFS='.' read -r -a parts <<< "$CURRENT"

case "${{ github.event.inputs.version_type }}" in
major)
NEW_VERSION="$((parts[0] + 1)).0.0"
;;
minor)
NEW_VERSION="${parts[0]}.$((parts[1] + 1)).0"
;;
patch)
NEW_VERSION="${parts[0]}.${parts[1]}.$((parts[2] + 1))"
;;
esac

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

- name: Verify release tags are available
run: |
for tag in \
"${{ steps.new_version.outputs.tag }}" \
"${{ steps.new_version.outputs.spm_tag }}"
do
if git rev-parse "refs/tags/$tag" >/dev/null 2>&1; then
echo "Release tag $tag already exists"
exit 1
fi
done

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Generate changelog
continue-on-error: true
Expand Down Expand Up @@ -173,18 +176,70 @@ jobs:
working-directory: ./clients/swift
run: swift test

- name: Check preview CLI package
working-directory: ./clients/swift
run: pnpm run check

- name: Run stock preview capture test
working-directory: ./clients/swift
run: |
xcrun simctl shutdown all
DEVICE_UDID="$(xcrun simctl list devices available --json | node --input-type=module -e '
let input = "";
process.stdin.setEncoding("utf8");
process.stdin.on("data", chunk => input += chunk);
process.stdin.on("end", () => {
let payload = JSON.parse(input);
let device = Object.entries(payload.devices)
.filter(([runtime]) => runtime.includes(".SimRuntime.iOS-"))
.flatMap(([, devices]) => devices)
.find(candidate => candidate.isAvailable !== false);
if (!device) process.exit(1);
process.stdout.write(device.udid);
});
')"
xcrun simctl boot "$DEVICE_UDID"
xcrun simctl bootstatus "$DEVICE_UDID" -b
VIZZLY_SIMULATOR_UDID="$DEVICE_UDID" pnpm run test:previews:e2e

- name: Verify npm package version is unpublished
working-directory: ./clients/swift
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"
exit 1
fi

- name: Pack npm package
id: pack
working-directory: ./clients/swift
run: |
PACK_FILE=$(npm pack --ignore-scripts)
echo "file=$PACK_FILE" >> $GITHUB_OUTPUT

- name: Configure git identity
run: |
git config --local user.email "${{ secrets.GIT_USER_EMAIL }}"
git config --local user.name "${{ secrets.GIT_USER_NAME }}"

- name: Commit and push changes
run: |
git add clients/swift/CHANGELOG.md
git add clients/swift/package.json clients/swift/CHANGELOG.md
git commit -m "🔖 Swift client v${{ steps.new_version.outputs.version }}"
git push origin main
git tag "${{ steps.new_version.outputs.tag }}"
git push origin "${{ steps.new_version.outputs.tag }}"
git tag "${{ steps.new_version.outputs.spm_tag }}"
git push --atomic origin \
main \
"${{ steps.new_version.outputs.tag }}" \
"${{ steps.new_version.outputs.spm_tag }}"

- name: Publish preview CLI package to npm
working-directory: ./clients/swift
run: |
npm config delete //registry.npmjs.org/:_authToken 2>/dev/null || true
rm -f ~/.npmrc 2>/dev/null || true
npm config set registry https://registry.npmjs.org/
npm publish "${{ steps.pack.outputs.file }}" --provenance --access public

- name: Read changelog for release
id: release_notes
Expand All @@ -204,6 +259,7 @@ jobs:
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 }}
draft: false
prerelease: false
env:
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/sdk-unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ jobs:
# Swift SDK - uses the Xcode version configured by the hosted runner
swift:
name: Swift SDK
runs-on: macos-latest
# Xcode 16.2 and 16.4 are both installed on this pinned image.
runs-on: macos-15
timeout-minutes: 8
needs: changes
if: needs.changes.outputs.swift == 'true'
Expand Down
13 changes: 13 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ let package = Package(
.library(
name: "VizzlyXCTest",
targets: ["VizzlyXCTest"]),
.library(
name: "VizzlyPreviewRuntime",
type: .dynamic,
targets: ["VizzlyPreviewRuntime"]),
],
targets: [
.target(
Expand All @@ -26,6 +30,15 @@ let package = Package(
name: "VizzlyXCTest",
dependencies: ["Vizzly"],
path: "clients/swift/Sources/VizzlyXCTest"),
.target(
name: "CVizzlyPreviewRuntime",
dependencies: [],
path: "clients/swift/Sources/CVizzlyPreviewRuntime",
publicHeadersPath: "include"),
.target(
name: "VizzlyPreviewRuntime",
dependencies: ["CVizzlyPreviewRuntime"],
path: "clients/swift/Sources/VizzlyPreviewRuntime"),
.testTarget(
name: "VizzlyTests",
dependencies: ["Vizzly", "VizzlyXCTest"],
Expand Down
2 changes: 2 additions & 0 deletions clients/swift/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Swift Package Manager
.build/
*.xcodeproj
!Fixtures/PreviewFixture/PreviewFixture.xcodeproj/
!Fixtures/PreviewFixture/PreviewFixture.xcodeproj/project.pbxproj
.swiftpm/

# Xcode
Expand Down
17 changes: 17 additions & 0 deletions clients/swift/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Added `vizzly previews` for rendering the SwiftUI `#Preview`
declarations already in an iOS app.
- Added the `VizzlyPreviewRuntime` Swift Package product required for preview
capture.
- Added fixed layouts, portrait and landscape traits, and `--include` filtering
for focused local runs.
- Added automatic selection when there is one project, shared scheme, and
booted Simulator. Ambiguous choices require an explicit option.
- Added preview failure reporting. Successful screenshots are kept when another
preview fails.
- Added local TDD review, cloud uploads, local-only output, configuration, and a
JSON manifest.
- Kept the existing `Vizzly` and `VizzlyXCTest` APIs and package dependencies
unchanged.

## [0.1.0] - 2026-06-01

### What's Changed
Expand Down
Loading