diff --git a/.github/workflows/build-bindings-ios.yml b/.github/workflows/build-bindings-ios.yml index 2811d8a82..ef8bd20ab 100644 --- a/.github/workflows/build-bindings-ios.yml +++ b/.github/workflows/build-bindings-ios.yml @@ -72,6 +72,49 @@ jobs: name: sdk-bindings-${{ matrix.target }} path: libs/target/${{ matrix.target }}/release/libbreez_sdk_bindings.a + merge: + runs-on: macOS-latest + needs: build + name: build ios-universal + steps: + - uses: actions/download-artifact@v4 + with: + name: sdk-bindings-aarch64-apple-ios + path: aarch64-apple-ios + + - uses: actions/download-artifact@v4 + with: + name: sdk-bindings-x86_64-apple-ios + path: x86_64-apple-ios + + - uses: actions/download-artifact@v4 + with: + name: sdk-bindings-aarch64-apple-ios-sim + path: aarch64-apple-ios-sim + + - name: Build iOS universal + run: | + mkdir -p ios-universal + mkdir -p ios-universal-sim + # build universal lib for arm device and x86 sim + lipo -create -output ios-universal/libbreez_sdk_bindings.a aarch64-apple-ios/libbreez_sdk_bindings.a x86_64-apple-ios/libbreez_sdk_bindings.a + # build universal lib for arm sim and x86 sim + lipo -create -output ios-universal-sim/libbreez_sdk_bindings.a aarch64-apple-ios-sim/libbreez_sdk_bindings.a x86_64-apple-ios/libbreez_sdk_bindings.a + + - name: Archive release + uses: actions/upload-artifact@v4 + with: + name: sdk-bindings-ios-universal + path: | + ios-universal/libbreez_sdk_bindings.a + + - name: Archive release + uses: actions/upload-artifact@v4 + with: + name: sdk-bindings-ios-universal-sim + path: | + ios-universal-sim/libbreez_sdk_bindings.a + build-dummies: if: ${{ inputs.use-dummy-binaries }} runs-on: ubuntu-latest @@ -82,6 +125,8 @@ jobs: aarch64-apple-ios, x86_64-apple-ios, aarch64-apple-ios-sim, + ios-universal, + ios-universal-sim, ] steps: - name: Build dummy ios ${{ matrix.target }} diff --git a/.github/workflows/publish-all-platforms.yml b/.github/workflows/publish-all-platforms.yml index df0cccc54..ca8cc3699 100644 --- a/.github/workflows/publish-all-platforms.yml +++ b/.github/workflows/publish-all-platforms.yml @@ -14,7 +14,7 @@ on: description: 'array of packages to publish (remove what you do not want)' required: true type: string - default: '["csharp", "golang", "maven", "kotlin-mpp", "flutter", "react-native", "python"]' + default: '["csharp", "golang", "maven", "kotlin-mpp", "flutter", "react-native", "python", "swift"]' csharp-ref: description: 'optional commit/tag/branch reference for the C# project. Defaults to ref.' required: false @@ -47,7 +47,7 @@ on: description: 'array of packages to publish (remove what you do not want)' required: true type: string - default: '["csharp", "golang", "maven", "kotlin-mpp", "flutter", "react-native", "python"]' + default: '["csharp", "golang", "maven", "kotlin-mpp", "flutter", "react-native", "python", "swift"]' csharp-ref: description: 'optional commit/tag/branch reference for the C# project. Defaults to ref.' required: false @@ -78,6 +78,7 @@ jobs: flutter-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'flutter') && inputs.package-version) || '' }} react-native-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'react-native') && inputs.package-version) || '' }} python-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'python') && inputs.package-version) || '' }} + swift-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'swift') && inputs.package-version) || '' }} use-dummy-binaries: ${{ inputs.use-dummy-binaries }} publish: ${{ inputs.publish }} steps: @@ -95,12 +96,12 @@ jobs: # (e.g. bindings-windows: true) if you want to test something. repository: ${{ needs.pre-setup.outputs.repository }} bindings-windows: ${{ !!needs.pre-setup.outputs.csharp-package-version || !!needs.pre-setup.outputs.golang-package-version || !!needs.pre-setup.outputs.python-package-version }} - bindings-darwin: ${{ !!needs.pre-setup.outputs.csharp-package-version || !!needs.pre-setup.outputs.golang-package-version || !!needs.pre-setup.outputs.python-package-version }} + bindings-darwin: ${{ !!needs.pre-setup.outputs.csharp-package-version || !!needs.pre-setup.outputs.golang-package-version || !!needs.pre-setup.outputs.python-package-version || !!needs.pre-setup.outputs.swift-package-version }} bindings-linux: ${{ !!needs.pre-setup.outputs.csharp-package-version || !!needs.pre-setup.outputs.golang-package-version || !!needs.pre-setup.outputs.python-package-version }} bindings-android: ${{ !!needs.pre-setup.outputs.kotlin-mpp-package-version || !!needs.pre-setup.outputs.maven-package-version || !!needs.pre-setup.outputs.golang-package-version }} - bindings-ios: ${{ !!needs.pre-setup.outputs.kotlin-mpp-package-version || !!needs.pre-setup.outputs.maven-package-version }} + bindings-ios: ${{ !!needs.pre-setup.outputs.kotlin-mpp-package-version || !!needs.pre-setup.outputs.maven-package-version || !!needs.pre-setup.outputs.swift-package-version }} kotlin: ${{ !!needs.pre-setup.outputs.kotlin-mpp-package-version || !!needs.pre-setup.outputs.maven-package-version || !!needs.pre-setup.outputs.flutter-package-version }} - swift: ${{ !!needs.pre-setup.outputs.flutter-package-version }} + swift: ${{ !!needs.pre-setup.outputs.flutter-package-version || !!needs.pre-setup.outputs.swift-package-version }} python: ${{ !!needs.pre-setup.outputs.python-package-version }} csharp: ${{ !!needs.pre-setup.outputs.csharp-package-version }} golang: ${{ !!needs.pre-setup.outputs.golang-package-version }} @@ -108,6 +109,7 @@ jobs: kotlin-mpp: ${{ !!needs.pre-setup.outputs.kotlin-mpp-package-version }} flutter: ${{ !!needs.pre-setup.outputs.flutter-package-version }} react-native: ${{ !!needs.pre-setup.outputs.react-native-package-version }} + spm-cocoapods: ${{ !!needs.pre-setup.outputs.swift-package-version }} ref: ${{ needs.pre-setup.outputs.ref }} csharp-package-version: ${{ needs.pre-setup.outputs.csharp-package-version || '0.0.2' }} csharp-ref: ${{ needs.pre-setup.outputs.csharp-ref }} @@ -117,6 +119,7 @@ jobs: flutter-package-version: ${{ needs.pre-setup.outputs.flutter-package-version || '0.0.2' }} react-native-package-version: ${{ needs.pre-setup.outputs.react-native-package-version || '0.0.2' }} python-package-version: ${{ needs.pre-setup.outputs.python-package-version || '0.0.2' }} + swift-package-version: ${{ needs.pre-setup.outputs.swift-package-version || '0.0.2' }} publish: ${{ needs.pre-setup.outputs.publish }} use-dummy-binaries: ${{ needs.pre-setup.outputs.use-dummy-binaries }} steps: @@ -247,7 +250,12 @@ jobs: needs: - setup - build-language-bindings - if: ${{ needs.setup.outputs.flutter == 'true' }} + - publish-swift + - publish-maven + # The flutter package depends on the swift and android packages to be available at runtime. + # Therefore, if swift and/or android publishing is turned on, we will run this job only if swift and/or android is successfully published. + # If however swift and/or android is skipped, we will run this job nonetheless. + if: ${{ needs.setup.outputs.flutter == 'true' && always() && !failure() && !cancelled() }} uses: ./.github/workflows/publish-flutter.yml with: repository: ${{ needs.setup.outputs.repository }} @@ -257,12 +265,15 @@ jobs: secrets: REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} - # react native version x.y.z will at runtime require - # ios and android packages x.y.z being published already. publish-react-native: needs: - setup - if: ${{ needs.setup.outputs.react-native == 'true' }} + - publish-swift + - publish-maven + # The react native package depends on the swift and android packages to be available at runtime. + # Therefore, if swift and/or android publishing is turned on, we will run this job only if swift and/or android is successfully published. + # If however swift and/or android is skipped, we will run this job nonetheless. + if: ${{ needs.setup.outputs.react-native == 'true' && always() && !failure() && !cancelled() }} uses: ./.github/workflows/publish-react-native.yml with: repository: ${{ needs.setup.outputs.repository }} @@ -288,3 +299,21 @@ jobs: publish: ${{ needs.setup.outputs.publish == 'true' }} secrets: PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} + + publish-swift: + needs: + - setup + - build-bindings-darwin + - build-bindings-ios + - build-language-bindings + if: ${{ needs.setup.outputs.spm-cocoapods == 'true' }} + uses: ./.github/workflows/publish-swift.yml + with: + repository: ${{ needs.setup.outputs.repository }} + ref: ${{ needs.setup.outputs.ref }} + package-version: ${{ needs.setup.outputs.swift-package-version }} + publish: ${{ needs.setup.outputs.publish == 'true' }} + secrets: + REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} + SWIFT_RELEASE_TOKEN: ${{ secrets. SWIFT_RELEASE_TOKEN }} + COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} diff --git a/.github/workflows/publish-swift.yml b/.github/workflows/publish-swift.yml new file mode 100644 index 000000000..20d748061 --- /dev/null +++ b/.github/workflows/publish-swift.yml @@ -0,0 +1,141 @@ +name: Publish Swift Package & CocoaPod +on: + workflow_call: + inputs: + repository: + description: 'sdk repository, defaults to current repository' + required: false + type: string + ref: + description: 'commit/tag/branch reference' + required: true + type: string + package-version: + description: 'version for the swift package / cocoapod (MAJOR.MINOR.BUILD) (no v prefix)' + required: true + type: string + publish: + description: 'value indicating whether to commit/tag a release.' + required: true + type: boolean + default: true + secrets: + REPO_SSH_KEY: + description: 'ssh key to commit to the breez-sdk-swift repository' + required: true + SWIFT_RELEASE_TOKEN: + description: 'token to create a release to the breez-sdk-swift repository' + required: true + COCOAPODS_TRUNK_TOKEN: + description: 'token to publish to cocoapods' + required: true + +jobs: + build-tag-release: + runs-on: macos-latest + steps: + - name: Checkout breez-sdk-swift repo + uses: actions/checkout@v3 + with: + repository: breez/breez-sdk-swift + ssh-key: ${{ secrets.REPO_SSH_KEY }} + path: breez-sdk-swift + + - name: Checkout breez-sdk repo + uses: actions/checkout@v3 + with: + repository: ${{ inputs.repository || github.repository }} + ref: ${{ inputs.ref || github.sha }} + path: breez-sdk + + - uses: actions/download-artifact@v4 + with: + name: bindings-swift + path: breez-sdk/libs/sdk-bindings/bindings-swift/Sources/BreezSDK/ + + - uses: actions/download-artifact@v4 + with: + name: sdk-bindings-aarch64-apple-ios + path: breez-sdk/libs/target/aarch64-apple-ios/release/ + + - uses: actions/download-artifact@v4 + with: + name: sdk-bindings-ios-universal-sim + path: breez-sdk/libs/target/ios-universal-sim/release/ + + - uses: actions/download-artifact@v4 + with: + name: sdk-bindings-darwin-universal + path: breez-sdk/libs/target/darwin-universal/release/ + + - name: Create XCFramework + working-directory: breez-sdk/libs/sdk-bindings + run: | + cp bindings-swift/Sources/BreezSDK/breez_sdkFFI.h bindings-swift/breez_sdkFFI.xcframework/ios-arm64/breez_sdkFFI.framework/Headers + cp bindings-swift/Sources/BreezSDK/breez_sdkFFI.h bindings-swift/breez_sdkFFI.xcframework/ios-arm64_x86_64-simulator/breez_sdkFFI.framework/Headers + cp bindings-swift/Sources/BreezSDK/breez_sdkFFI.h bindings-swift/breez_sdkFFI.xcframework/macos-arm64_x86_64/breez_sdkFFI.framework/Headers + cp ../target/aarch64-apple-ios/release/libbreez_sdk_bindings.a bindings-swift/breez_sdkFFI.xcframework/ios-arm64/breez_sdkFFI.framework/breez_sdkFFI + cp ../target/ios-universal-sim/release/libbreez_sdk_bindings.a bindings-swift/breez_sdkFFI.xcframework/ios-arm64_x86_64-simulator/breez_sdkFFI.framework/breez_sdkFFI + cp ../target/darwin-universal/release/libbreez_sdk_bindings.a bindings-swift/breez_sdkFFI.xcframework/macos-arm64_x86_64/breez_sdkFFI.framework/breez_sdkFFI + rm bindings-swift/Sources/BreezSDK/breez_sdkFFI.h + rm bindings-swift/Sources/BreezSDK/breez_sdkFFI.modulemap + + - name: Compress xcframework + working-directory: breez-sdk/libs/sdk-bindings/bindings-swift + run: | + zip -9 -r breez_sdkFFI.xcframework.zip breez_sdkFFI.xcframework + echo "XCF_CHECKSUM=`swift package compute-checksum breez_sdkFFI.xcframework.zip`" >> $GITHUB_ENV + + - name: Archive xcframework + uses: actions/upload-artifact@v4 + with: + name: breez_sdkFFI-${{ inputs.package-version || inputs.ref }}.xcframework + path: breez-sdk/libs/sdk-bindings/bindings-swift/breez_sdkFFI.xcframework + + - name: Update swift package + working-directory: breez-sdk/libs/sdk-bindings/bindings-swift + run: | + # Update package definition + sed 's#.binaryTarget(name: "breez_sdkFFI", path: "./breez_sdkFFI.xcframework"),#.binaryTarget(name: "breez_sdkFFI", url: "https://github.com/breez/breez-sdk-swift/releases/download/${{ inputs.package-version }}/breez_sdkFFI.xcframework.zip", checksum: "${{ env.XCF_CHECKSUM }}"),#;/.testTarget(name: "BreezSDKTests", dependencies: \["BreezSDK"\]),/d' Package.swift > ../../../../breez-sdk-swift/Package.swift + # Update language bindings + cp -r Sources ../../../../breez-sdk-swift + + - name: Update cocoapods definitions + working-directory: breez-sdk-swift + run: | + sed -i '' 's#^.\{2\}spec.version.*$# spec.version = "${{ inputs.package-version }}"#' breez_sdkFFI.podspec + sed -i '' 's#^.\{2\}spec.version.*$# spec.version = "${{ inputs.package-version }}"#' BreezSDK.podspec + + - name: Tag swift package + working-directory: breez-sdk-swift + if: ${{ inputs.publish }} + run: | + git add Package.swift + git add Sources + git add breez_sdkFFI.podspec + git add BreezSDK.podspec + git commit -m "Update Breez SDK Swift bindings to version ${{ inputs.package-version }}" + git push + git tag ${{ inputs.package-version }} -m "${{ inputs.package-version }}" + git push --tags + + - name: Release and attach XCFramework binary artifact + if: ${{ inputs.publish }} + uses: softprops/action-gh-release@v2 + with: + repository: breez/breez-sdk-swift + files: | + breez-sdk/libs/sdk-bindings/bindings-swift/breez_sdkFFI.xcframework.zip + tag_name: ${{ inputs.package-version }} + generate_release_notes: false + token: ${{ secrets.SWIFT_RELEASE_TOKEN }} + prerelease: true + + - name: Push update to Cocoapods trunk + working-directory: breez-sdk-swift + if: ${{ inputs.publish }} + env: + COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} + run: | + pod trunk push breez_sdkFFI.podspec --allow-warnings + pod trunk push BreezSDK.podspec --allow-warnings --synchronous