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
105 changes: 105 additions & 0 deletions .github/workflows/swift-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Release Swift Package

on:
workflow_dispatch:
inputs:
tag:
description: Release tag (vX.Y.Z or X.Y.Z)
required: true

permissions:
contents: write

jobs:
release-swift:
runs-on: macos-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Normalize tag
id: tag
run: |
TAG="${{ inputs.tag }}"
if [[ "${TAG}" != v* ]]; then
TAG="v${TAG}"
fi
echo "tag=${TAG}" >> "${GITHUB_OUTPUT}"

- name: Ensure workflow runs on a branch
run: |
if [[ "${GITHUB_REF_TYPE}" != "branch" ]]; then
echo "This workflow must run on a branch ref."
exit 1
fi

- name: Check for existing tag or release
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="${{ steps.tag.outputs.tag }}"
if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q "${TAG}$"; then
echo "Tag already exists on origin: ${TAG}"
exit 1
fi
if gh release view "${TAG}" >/dev/null 2>&1; then
echo "Release already exists: ${TAG}"
exit 1
fi

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

- name: Build xcframework
run: bash cktap-swift/build-xcframework.sh

- name: Create archive and update checksum
run: bash scripts/swift_create_xcframework_archive.sh

- name: Update Package.swift tag
run: python3 scripts/swift_update_package_checksum.py --tag "${{ steps.tag.outputs.tag }}"

- name: Commit updated Swift files
run: |
git add Package.swift cktap-swift/Sources
if git diff --cached --quiet; then
echo "No Swift package changes to commit."
exit 0
fi
git commit -m "chore(swift): release ${{ steps.tag.outputs.tag }}"

- name: Create tag and push atomically
run: |
if git rev-parse "${{ steps.tag.outputs.tag }}" >/dev/null 2>&1; then
echo "Tag already exists: ${{ steps.tag.outputs.tag }}"
exit 1
fi
git tag "${{ steps.tag.outputs.tag }}"
git push --atomic origin HEAD "${{ steps.tag.outputs.tag }}"

- name: Create GitHub release and upload asset
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "${{ steps.tag.outputs.tag }}" \
cktap-swift/cktapFFI.xcframework.zip \
--title "${{ steps.tag.outputs.tag }}" \
--notes "Swift bindings release ${{ steps.tag.outputs.tag }}"

- name: Cleanup failed release
if: failure()
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="${{ steps.tag.outputs.tag }}"
if gh release view "${TAG}" >/dev/null 2>&1; then
gh release delete "${TAG}" --yes || true
fi
if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q "${TAG}$"; then
git push --delete origin "${TAG}" || true
fi
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ DerivedData/
*.xcframework.zip
Info.plist
Sources
!cktap-swift/Sources/
!cktap-swift/Sources/**
lib*.a

# Python ck-tap emulator
Expand Down
35 changes: 35 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

// Update tag and checksum when publishing a new Swift binary release.
let tag = "v0.1.0"
let checksum = "0000000000000000000000000000000000000000000000000000000000000000"
let url = "https://github.com/notmandatory/rust-cktap/releases/download/\(tag)/cktapFFI.xcframework.zip"

let package = Package(
name: "rust-cktap",
platforms: [
.macOS(.v12),
.iOS(.v18),
],
products: [
.library(
name: "CKTap",
targets: ["cktapFFI", "CKTap"]
),
],
targets: [
.target(
name: "CKTap",
dependencies: ["cktapFFI"],
path: "./cktap-swift/Sources"
),
.binaryTarget(
name: "cktapFFI",
url: url,
checksum: checksum
),
]
)
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ just run certs
just run read
```

## Swift Package

Swift bindings are distributed from this repo as a Swift Package. Once a
release includes `cktapFFI.xcframework.zip`, add the repository URL in Xcode
and use the `CKTap` product.

See `cktap-swift/README.md` for local development and release steps.

## Minimum Supported Rust Version (MSRV)

This library should always compile with any valid combination of features on Rust **1.85.0**.
Expand Down
2 changes: 1 addition & 1 deletion cktap-swift/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ let package = Package(
name: "cktap-swift",
platforms: [
.macOS(.v12),
.iOS(.v15)
.iOS(.v18)
],
products: [
.library(
Expand Down
40 changes: 40 additions & 0 deletions cktap-swift/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# CKTAP Swift bindings

This directory contains Swift bindings generated by UniFFI and a local SwiftPM
manifest used during development.

## Local development

- Run `just build` (or `./build-xcframework.sh`) to regenerate
`Sources/CKTap/cktap_ffi.swift` and `cktapFFI.xcframework`.
- Run `just test` to execute Swift tests.

## Publishing the Swift package

The repo root `Package.swift` is the public SwiftPM entry point. It expects a
GitHub release asset named `cktapFFI.xcframework.zip`.

### Manual

1. Build the xcframework:
```
just build
```
2. Create the zip from `cktap-swift`:
```
cd cktap-swift
zip -r cktapFFI.xcframework.zip cktapFFI.xcframework
```
3. Upload the zip to the GitHub release tag.
4. Compute the checksum:
```
swift package compute-checksum cktapFFI.xcframework.zip
```
5. Update the root `Package.swift` `tag` and `checksum`, then tag and release.

### Automated

Run the `Release Swift Package` workflow with a tag (e.g. `v0.1.1`). It builds
the xcframework, creates the zip, updates the root `Package.swift`, commits the
Swift sources, tags the release, and uploads the asset. If the workflow fails
after committing, it will not auto-revert the commit.
Loading
Loading