-
Notifications
You must be signed in to change notification settings - Fork 191
ci(swift): Swift CI/CD only – auto-tag, build-release, release, Packa… #323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
f84e929
e728114
30c23a6
00c1eba
cb07423
9dfb4ec
37ad693
cfe813b
fcbe222
1328ad3
7f21179
98336e9
9127453
459abcf
2139b85
6d83bcb
892c82a
0c5f063
b1fa241
3f4934d
93ddf5e
129a799
c884700
124fa8b
7055a3d
7c38b94
0d4c26b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| # ============================================================================= | ||
| # Swift SDK Auto-Tag (Phase 1 CI/CD) | ||
| # | ||
| # Merges to main automatically create a new git tag swift-vX.Y.Z to mark | ||
| # official Swift SDK release points. Full build/publish automation will be | ||
| # added later. No builds, no publishing, no macOS runners in this phase. | ||
| # | ||
| # PR description: Merges to main auto-create swift-vX.Y.Z tags to mark | ||
| # official Swift SDK release points. Full build/publish automation will be | ||
| # added later. | ||
| # ============================================================================= | ||
|
|
||
| name: Swift SDK Auto-Tag | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| jobs: | ||
| tag: | ||
| name: Create Swift SDK Tag | ||
| if: github.actor != 'github-actions[bot]' | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Configure Git | ||
| run: | | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||
|
|
||
| - name: Compute Next Tag | ||
| id: next_tag | ||
| run: | | ||
| set -e | ||
| SDK_VERSION=$(grep -E 'let sdkVersion = "' Package.swift | head -1 | sed -E 's/.*"([^"]+)".*/\1/') | ||
| if [ -z "$SDK_VERSION" ]; then | ||
| echo "Unable to determine sdkVersion from Package.swift" | ||
| exit 1 | ||
| fi | ||
| NEW_TAG="swift-v$SDK_VERSION" | ||
| echo "tag=$NEW_TAG" >> "$GITHUB_OUTPUT" | ||
| echo "Computed tag from Package.swift sdkVersion: $NEW_TAG" | ||
|
|
||
| - name: Skip If Tag Exists | ||
| id: skip | ||
| run: | | ||
| NEW_TAG="${{ steps.next_tag.outputs.tag }}" | ||
| if git rev-parse "$NEW_TAG" >/dev/null 2>&1; then | ||
| echo "Tag $NEW_TAG already exists, skipping (idempotent rerun)" | ||
| echo "skip=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "skip=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| - name: Create and Push Tag | ||
| if: steps.skip.outputs.skip != 'true' | ||
| run: | | ||
| NEW_TAG="${{ steps.next_tag.outputs.tag }}" | ||
| git tag -a "$NEW_TAG" -m "Swift SDK Release $NEW_TAG" | ||
| git push origin "$NEW_TAG" | ||
| echo "Pushed tag: $NEW_TAG" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,222 @@ | ||
| # ============================================================================= | ||
| # Swift SDK Build & Release (Phase 2 CI/CD) | ||
| # | ||
| # When a swift-v* tag is pushed (from Phase 1), build native XCFrameworks via | ||
| # build-ios.sh and the Swift SDK via build-swift.sh on macOS, compute SHA256 | ||
| # checksums of the ZIPs, update Package.swift with those checksums and | ||
| # sdkVersion, commit and push to main, move the tag to that commit, then | ||
| # create a GitHub Release and attach the built artifacts. SPM consumers then | ||
| # resolve the tag and get correct checksums for the release assets. | ||
| # | ||
| # Phase 1 decides when (tag on merge to main). Phase 2 performs what | ||
| # (build + package + release assets + checksum update). | ||
| # | ||
| # PR description: Swift SDK builds are automated on swift-v* tag push: | ||
| # build-ios.sh and build-swift.sh run on macOS, and the resulting XCFrameworks | ||
| # are attached to the GitHub Release. No CocoaPods/App Store; no cross-SDK | ||
| # orchestration. | ||
| # ============================================================================= | ||
|
|
||
| name: Swift SDK Build & Release | ||
|
|
||
| on: | ||
| push: | ||
| tags: | ||
| - 'swift-v*' | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| env: | ||
| COMMONS_DIR: sdk/runanywhere-commons | ||
| SWIFT_SDK_DIR: sdk/runanywhere-swift | ||
|
|
||
| jobs: | ||
| build-and-release: | ||
| name: Build & Release Swift SDK | ||
| runs-on: macos-14 | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| fetch-tags: true | ||
|
|
||
| - name: Determine Version | ||
| id: version | ||
| run: | | ||
| TAG="${GITHUB_REF#refs/tags/}" | ||
| VERSION="${TAG#swift-v}" | ||
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | ||
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | ||
| echo "Building Swift SDK $TAG (version $VERSION)" | ||
|
|
||
| - name: Build Native XCFrameworks | ||
| run: | | ||
| ./${COMMONS_DIR}/scripts/build-ios.sh --clean | ||
| echo "XCFrameworks:" | ||
| ls -la ${COMMONS_DIR}/dist/*.xcframework/ 2>/dev/null || true | ||
|
|
||
| - name: Verify Required XCFrameworks | ||
| run: | | ||
| set -e | ||
| COMMONS_DIST="${COMMONS_DIR}/dist" | ||
| REQUIRED="RACommons RABackendLLAMACPP RABackendONNX" | ||
| for name in $REQUIRED; do | ||
| if [ ! -d "${COMMONS_DIST}/${name}.xcframework" ]; then | ||
| echo "Missing required framework: ${name}.xcframework" | ||
| exit 1 | ||
| fi | ||
| done | ||
| echo "All required XCFrameworks are present." | ||
|
|
||
| - name: Build Swift SDK | ||
| run: | | ||
| ./${SWIFT_SDK_DIR}/scripts/build-swift.sh --local --build-commons --release | ||
| echo "Swift build complete" | ||
|
|
||
| - name: Prepare Release Assets | ||
| id: assets | ||
| run: | | ||
| VERSION="${{ steps.version.outputs.version }}" | ||
| COMMONS_DIST="${COMMONS_DIR}/dist" | ||
| mkdir -p release-assets | ||
| for name in RACommons RABackendLLAMACPP RABackendONNX; do | ||
| if [ -d "${COMMONS_DIST}/${name}.xcframework" ]; then | ||
| zip_name="${name}-ios-v${VERSION}.zip" | ||
| (cd "${COMMONS_DIST}" && zip -r "${GITHUB_WORKSPACE}/release-assets/${zip_name}" "${name}.xcframework") | ||
| echo "Created release-assets/${zip_name}" | ||
| fi | ||
| done | ||
| echo "assets_dir=release-assets" >> "$GITHUB_OUTPUT" | ||
| ls -la release-assets/ | ||
|
|
||
| - name: Compute Checksums | ||
| id: checksums | ||
| run: | | ||
| VERSION="${{ steps.version.outputs.version }}" | ||
| for name in RACommons RABackendLLAMACPP RABackendONNX; do | ||
| if [ ! -f "release-assets/${name}-ios-v${VERSION}.zip" ]; then | ||
| echo "Missing required asset: release-assets/${name}-ios-v${VERSION}.zip" | ||
| exit 1 | ||
| fi | ||
| done | ||
| COMMONS_CHECKSUM=$(shasum -a 256 "release-assets/RACommons-ios-v${VERSION}.zip" | cut -d ' ' -f 1) | ||
| LLAMACPP_CHECKSUM=$(shasum -a 256 "release-assets/RABackendLLAMACPP-ios-v${VERSION}.zip" | cut -d ' ' -f 1) | ||
| ONNX_CHECKSUM=$(shasum -a 256 "release-assets/RABackendONNX-ios-v${VERSION}.zip" | cut -d ' ' -f 1) | ||
| echo "commons=$COMMONS_CHECKSUM" >> "$GITHUB_OUTPUT" | ||
| echo "llamacpp=$LLAMACPP_CHECKSUM" >> "$GITHUB_OUTPUT" | ||
| echo "onnx=$ONNX_CHECKSUM" >> "$GITHUB_OUTPUT" | ||
| echo "RACommons: $COMMONS_CHECKSUM" | ||
| echo "RABackendLLAMACPP: $LLAMACPP_CHECKSUM" | ||
| echo "RABackendONNX: $ONNX_CHECKSUM" | ||
|
|
||
| - name: Ensure Main Matches Tag | ||
| run: | | ||
| TAG="${{ steps.version.outputs.tag }}" | ||
| git fetch origin main --prune | ||
| TAG_COMMIT=$(git rev-parse "${TAG}^{commit}") | ||
| MAIN_COMMIT=$(git rev-parse "origin/main") | ||
| if [ "$TAG_COMMIT" != "$MAIN_COMMIT" ]; then | ||
| echo "Tag ${TAG} points to ${TAG_COMMIT}, but origin/main is ${MAIN_COMMIT}" | ||
| echo "Refusing to update Package.swift on main to avoid mismatched assets." | ||
| exit 1 | ||
| fi | ||
| git checkout -B main origin/main | ||
|
|
||
| - name: Update Package.swift Checksums and Version | ||
| run: | | ||
| VERSION="${{ steps.version.outputs.version }}" | ||
| COMMONS_CHECKSUM="${{ steps.checksums.outputs.commons }}" | ||
| LLAMACPP_CHECKSUM="${{ steps.checksums.outputs.llamacpp }}" | ||
| ONNX_CHECKSUM="${{ steps.checksums.outputs.onnx }}" | ||
| # Ensure production mode for release (remote binaries) | ||
| sed -i '' 's/let useLocalBinaries = true/let useLocalBinaries = false/' Package.swift | ||
| # Update sdkVersion | ||
| sed -i '' 's/let sdkVersion = "[^"]*"/let sdkVersion = "'"$VERSION"'"/' Package.swift | ||
| # Update the three binary target checksums (range: url line through checksum line) | ||
| sed -i '' '/RACommons-ios-v.*zip/,/checksum:/ s/checksum: "[^"]*"/checksum: "'"$COMMONS_CHECKSUM"'"/' Package.swift | ||
| sed -i '' '/RABackendLLAMACPP-ios-v.*zip/,/checksum:/ s/checksum: "[^"]*"/checksum: "'"$LLAMACPP_CHECKSUM"'"/' Package.swift | ||
| sed -i '' '/RABackendONNX-ios-v.*zip/,/checksum:/ s/checksum: "[^"]*"/checksum: "'"$ONNX_CHECKSUM"'"/' Package.swift | ||
| echo "Updated Package.swift sdkVersion and checksums" | ||
| grep -A1 "RACommons-ios" Package.swift | head -4 | ||
|
|
||
| - name: Commit and Push Package.swift Update | ||
| run: | | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||
| git add Package.swift | ||
| if git diff --staged --quiet; then | ||
| echo "No Package.swift changes to commit" | ||
| else | ||
| git commit -m "chore(swift): update Package.swift checksums for swift-v${{ steps.version.outputs.version }}" | ||
| git push origin HEAD:main | ||
| fi | ||
|
||
|
|
||
| - name: Create Semver Tag for SPM | ||
| run: | | ||
| VERSION="${{ steps.version.outputs.version }}" | ||
| # SPM resolves versions from semver tags (e.g. 0.1.2 or v0.1.2) | ||
| # Create v${VERSION} on the checksum-updated commit so consumers can use from: "X.Y.Z" | ||
| SEMVER_TAG="v${VERSION}" | ||
| git tag -a "${SEMVER_TAG}" -m "Swift SDK ${SEMVER_TAG}" | ||
| git push origin "${SEMVER_TAG}" | ||
| echo "Semver tag ${SEMVER_TAG} created for SPM resolution" | ||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| - name: Create GitHub Release | ||
| uses: softprops/action-gh-release@v2 | ||
| with: | ||
| tag_name: v${{ steps.version.outputs.version }} | ||
| name: RunAnywhere Swift SDK v${{ steps.version.outputs.version }} | ||
| body: | | ||
| ## RunAnywhere Swift SDK v${{ steps.version.outputs.version }} | ||
|
|
||
| Privacy-first, on-device AI SDK for iOS and macOS. Built automatically on swift-v* tag push (Phase 2 CI). | ||
|
|
||
| ### Installation | ||
|
|
||
| **Swift Package Manager:** | ||
| ```swift | ||
| dependencies: [ | ||
| .package( | ||
| url: "https://github.com/RunanywhereAI/runanywhere-sdks", | ||
| from: "${{ steps.version.outputs.version }}" | ||
| ) | ||
| ] | ||
| ``` | ||
|
|
||
| Then add the products you need: | ||
| ```swift | ||
| .target( | ||
| name: "YourApp", | ||
| dependencies: [ | ||
| .product(name: "RunAnywhere", package: "runanywhere-sdks"), | ||
| .product(name: "LlamaCPPRuntime", package: "runanywhere-sdks"), | ||
| .product(name: "ONNXRuntime", package: "runanywhere-sdks"), | ||
| ] | ||
| ) | ||
| ``` | ||
|
|
||
| ### Features | ||
| - **LLM**: On-device text generation via llama.cpp | ||
| - **STT**: Speech-to-text via Sherpa-ONNX Whisper | ||
| - **TTS**: Text-to-speech via Sherpa-ONNX Piper | ||
| - **VAD**: Voice activity detection | ||
| - **Privacy**: All processing happens on-device | ||
|
|
||
| ### Requirements | ||
| - iOS 17.0+ / macOS 14.0+ | ||
| - Swift 5.9+ | ||
| - Xcode 15.0+ | ||
|
|
||
| ### Documentation | ||
| [Swift SDK README](https://github.com/RunanywhereAI/runanywhere-sdks/tree/main/sdk/runanywhere-swift) | ||
|
|
||
| --- | ||
| Built from runanywhere-sdks @ ${{ github.sha }} | ||
| files: release-assets/*.zip | ||
| draft: false | ||
| prerelease: false | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P1] Broad trigger: tags on every push to
mainThis workflow triggers on any push to
main(including merges, reverts, and automated commits from other workflows). If Phase 2 commits tomain, that commit will also trigger Phase 1 and create another tag unless you add a guard (e.g., skip when actor isgithub-actions[bot]or when commit message matches the checksum update). Otherwise you can end up in a tag churn/feedback loop.Prompt To Fix With AI