diff --git a/.github/workflows/build-binaries.yml b/.github/workflows/build-binaries.yml
index e2f04a9489..6965128a33 100644
--- a/.github/workflows/build-binaries.yml
+++ b/.github/workflows/build-binaries.yml
@@ -17,14 +17,13 @@ jobs:
strategy:
matrix:
target: [macosx, iphoneos, iphonesimulator, appletvos, appletvsimulator, watchos, watchsimulator, maccatalyst, xros, xrsimulator]
- xcode: ["15.3"]
+ env:
+ DEVELOPER_DIR: /Applications/Xcode_15.3.app/Contents/Developer
steps:
- uses: actions/checkout@v4
-
- - name: Switch to Xcode ${{ matrix.xcode }}
- uses: maxim-lobanov/setup-xcode@v1.6.0
- with:
- xcode-version: ${{ matrix.xcode }}
+ - name: Download visionOS
+ if: matrix.target == 'xros' || matrix.target == 'xrsimulator'
+ run: xcodebuild -downloadPlatform visionOS
- name: Get Core Version
id: get-core-version
@@ -44,6 +43,11 @@ jobs:
fetch-depth: 0
fetch-tags: true
+ # CMake 3.30 introduced a check which tries to validate that the compiler
+ # supports the requested architextures but it doesn't work.
+ - name: Patch CMake
+ run: sed -i '' 's/CMAKE_HOST_APPLE AND CMAKE_SYSTEM_NAME STREQUAL "Darwin"/CMAKE_HOST_APPLE AND CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_GENERATOR STREQUAL "Xcode"/' /opt/homebrew/Cellar/cmake/*/share/cmake/Modules/CMakeDetermineCompilerABI.cmake
+
- name: Checkout Core@${{ steps.get-core-version.outputs.version }}
run: git checkout ${{ steps.get-core-version.outputs.version }} --recurse-submodules -f
working-directory: core
diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml
new file mode 100644
index 0000000000..7d24c1b379
--- /dev/null
+++ b/.github/workflows/build-pr.yml
@@ -0,0 +1,469 @@
+
+# This is a generated file produced by scripts/pr-ci-matrix.rb.
+name: Pull request build and test
+on:
+ pull_request:
+ paths-ignore:
+ - '**.md'
+ workflow_dispatch:
+
+jobs:
+ docs:
+ runs-on: macos-14
+ name: Test docs
+ steps:
+ - uses: actions/checkout@v4
+ - uses: ruby/setup-ruby@v1
+ with:
+ bundler-cache: true
+ - run: sudo xcode-select -switch /Applications/Xcode_16.app
+ - run: bundle exec sh build.sh verify-docs
+ swiftlint:
+ runs-on: macos-14
+ name: Check swiftlint
+ steps:
+ - uses: actions/checkout@v4
+ - run: sudo xcode-select -switch /Applications/Xcode_16.app
+ - run: brew install swiftlint
+ - run: sh build.sh verify-swiftlint
+
+ osx-15_3:
+ runs-on: macos-14
+ name: Test osx on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr osx
+
+ osx-15_4:
+ runs-on: macos-14
+ name: Test osx on Xcode 15.4
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.4.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr osx
+
+ osx-16:
+ runs-on: macos-15
+ name: Test osx on Xcode 16
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr osx
+
+ osx-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test osx on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr osx
+
+ osx-encryption-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test osx-encryption on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr osx-encryption
+
+ swiftpm-15_3:
+ runs-on: macos-14
+ name: Test swiftpm on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr swiftpm
+
+ swiftpm-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test swiftpm on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr swiftpm
+
+ swiftpm-debug-15_3:
+ runs-on: macos-14
+ name: Test swiftpm-debug on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr swiftpm-debug
+
+ swiftpm-debug-15_4:
+ runs-on: macos-14
+ name: Test swiftpm-debug on Xcode 15.4
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.4.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr swiftpm-debug
+
+ swiftpm-debug-16:
+ runs-on: macos-15
+ name: Test swiftpm-debug on Xcode 16
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr swiftpm-debug
+
+ swiftpm-debug-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test swiftpm-debug on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr swiftpm-debug
+
+ swiftpm-address-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test swiftpm-address on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr swiftpm-address
+
+ swiftpm-thread-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test swiftpm-thread on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr swiftpm-thread
+
+ ios-static-15_3:
+ runs-on: macos-14
+ name: Test ios-static on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr ios-static
+
+ ios-static-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test ios-static on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr ios-static
+
+ ios-15_3:
+ runs-on: macos-14
+ name: Test ios on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr ios
+
+ ios-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test ios on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr ios
+
+ watchos-15_3:
+ runs-on: macos-14
+ name: Test watchos on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr watchos
+
+ watchos-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test watchos on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr watchos
+
+ tvos-15_3:
+ runs-on: macos-14
+ name: Test tvos on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr tvos
+
+ tvos-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test tvos on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr tvos
+
+ visionos-15_3:
+ runs-on: macos-14
+ name: Test visionos on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr visionos
+
+ visionos-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test visionos on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr visionos
+
+ osx-swift-15_3:
+ runs-on: macos-14
+ name: Test osx-swift on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr osx-swift
+
+ osx-swift-15_4:
+ runs-on: macos-14
+ name: Test osx-swift on Xcode 15.4
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.4.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr osx-swift
+
+ osx-swift-16:
+ runs-on: macos-15
+ name: Test osx-swift on Xcode 16
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr osx-swift
+
+ osx-swift-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test osx-swift on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr osx-swift
+
+ ios-swift-15_3:
+ runs-on: macos-14
+ name: Test ios-swift on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr ios-swift
+
+ ios-swift-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test ios-swift on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr ios-swift
+
+ tvos-swift-15_3:
+ runs-on: macos-14
+ name: Test tvos-swift on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr tvos-swift
+
+ tvos-swift-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test tvos-swift on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr tvos-swift
+
+ osx-swift-evolution-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test osx-swift-evolution on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr osx-swift-evolution
+
+ ios-swift-evolution-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test ios-swift-evolution on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr ios-swift-evolution
+
+ tvos-swift-evolution-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test tvos-swift-evolution on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr tvos-swift-evolution
+
+ catalyst-15_3:
+ runs-on: macos-14
+ name: Test catalyst on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr catalyst
+
+ catalyst-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test catalyst on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr catalyst
+
+ catalyst-swift-15_3:
+ runs-on: macos-14
+ name: Test catalyst-swift on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr catalyst-swift
+
+ catalyst-swift-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test catalyst-swift on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr catalyst-swift
+
+ xcframework-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test xcframework on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr xcframework
+
+ cocoapods-osx-15_3:
+ runs-on: macos-14
+ name: Test cocoapods-osx on Xcode 15.3
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.3.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr cocoapods-osx
+
+ cocoapods-osx-15_4:
+ runs-on: macos-14
+ name: Test cocoapods-osx on Xcode 15.4
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_15.4.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr cocoapods-osx
+
+ cocoapods-osx-16:
+ runs-on: macos-15
+ name: Test cocoapods-osx on Xcode 16
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr cocoapods-osx
+
+ cocoapods-osx-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test cocoapods-osx on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr cocoapods-osx
+
+ cocoapods-ios-static-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test cocoapods-ios-static on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr cocoapods-ios-static
+
+ cocoapods-ios-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test cocoapods-ios on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr cocoapods-ios
+
+ cocoapods-watchos-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test cocoapods-watchos on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr cocoapods-watchos
+
+ cocoapods-tvos-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test cocoapods-tvos on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr cocoapods-tvos
+
+ cocoapods-catalyst-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test cocoapods-catalyst on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr cocoapods-catalyst
+
+ ios-swiftui-16_1_Release_Candidate:
+ runs-on: macos-15
+ name: Test ios-swiftui on Xcode 16.1_Release_Candidate
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_16.1_Release_Candidate.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr ios-swiftui
diff --git a/.github/workflows/master-push.yml b/.github/workflows/master-push.yml
index 9372e9bc7a..25e6bae29d 100644
--- a/.github/workflows/master-push.yml
+++ b/.github/workflows/master-push.yml
@@ -6,10 +6,10 @@ on:
- "master"
- "release/**"
env:
- XCODE_VERSION: "['15.3', '15.4', '16_beta_6', '16.1_beta']"
+ XCODE_VERSION: "['15.3', '15.4', '16', '16.1_Release_Candidate']"
PLATFORM: "['ios', 'osx', 'watchos', 'tvos', 'catalyst', 'visionos']"
- DOC_VERSION: '15.4'
- RELEASE_VERSION: '15.4'
+ RELEASE_VERSION: '16'
+ DEVELOPER_DIR: /Applications/Xcode_16.app/Contents/Developer
jobs:
prepare:
runs-on: ubuntu-latest
@@ -30,7 +30,7 @@ jobs:
version="$(sed -n 's/^VERSION=\(.*\)$/\1/p' "${GITHUB_WORKSPACE}/dependencies.list")"
echo "VERSION=$version" >> $GITHUB_OUTPUT
build-docs:
- runs-on: macos-14
+ runs-on: macos-15
name: Package docs
needs: prepare
steps:
@@ -38,8 +38,6 @@ jobs:
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- - name: Select Xcode Version
- run: sudo xcode-select -switch /Applications/Xcode_${{ env.DOC_VERSION }}.app
- name: Prepare docs for packaging
run: bundle exec sh -x build.sh release-package-docs
- name: Upload docs to artifacts library
@@ -48,7 +46,7 @@ jobs:
name: realm-docs
path: docs/realm-docs.zip
build-examples:
- runs-on: macos-14
+ runs-on: macos-15
name: Package examples
needs: prepare
steps:
@@ -61,15 +59,27 @@ jobs:
name: realm-examples
path: realm-examples.zip
build-product: # Creates framework for each platform, xcode version, target and configuration
- runs-on: macos-14
name: Package framework
needs: prepare
strategy:
- max-parallel: 20 # Blocks of 20, therefore if any of the build fails, we don't get a lot of XCode Clouds builds hanging, which are expensive.
+ max-parallel: 20
matrix:
platform: ${{ fromJSON(needs.prepare.outputs.PLATFORM_MATRIX) }}
xcode-version: ${{ fromJSON(needs.prepare.outputs.XCODE_VERSIONS_MATRIX) }}
configuration: [swift, static]
+ include:
+ - xcode-version: 15.3
+ xcode-version-tag: 15.3
+ os: macos-14
+ - xcode-version: 15.4
+ xcode-version-tag: 15.4
+ os: macos-14
+ - xcode-version: 16
+ xcode-version-tag: '16.0'
+ os: macos-15
+ - xcode-version: 16.1_Release_Candidate
+ xcode-version-tag: 16.1
+ os: macos-15
exclude:
- platform: osx
configuration: static
@@ -81,79 +91,39 @@ jobs:
configuration: static
- platform: catalyst
configuration: static
- - platform: visionos
- xcode-version: 15.1
+ runs-on: ${{ matrix.os }}
+ env:
+ DEVELOPER_DIR: /Applications/Xcode_${{matrix.xcode-version}}.app/Contents/Developer
steps:
- uses: actions/checkout@v4
- - name: Build ${{ matrix.platform }} with Xcode ${{ matrix.xcode-version }}
- run: DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode-version }}.app/Contents/Developer sh build.sh ${{ matrix.platform }}-${{matrix.configuration}}
- - run: rm -r build/DerivedData
+ - name: Download visionOS
+ if: matrix.platform == 'visionos' && matrix.os == 'macos-14'
+ run: xcodebuild -downloadPlatform visionOS
+ - run: sh build.sh ${{matrix.platform}}-${{matrix.configuration}}
+ - run: tar cf build.tar build/*/${{matrix.platform}}
- name: Upload framework
uses: actions/upload-artifact@v4
with:
- name: build-${{ matrix.platform }}-${{ matrix.xcode-version }}-${{ matrix.configuration }}
- path: build
+ name: build-${{matrix.platform}}-${{matrix.xcode-version-tag}}-${{matrix.configuration}}
+ path: build.tar
compression-level: 1
- package-xcframework-platform: # Creates xcframework for each platform and xcode version
- runs-on: macos-14
- name: Package xcframework for platform
- needs: [build-product, prepare]
- strategy:
- matrix:
- platform: ${{ fromJSON(needs.prepare.outputs.PLATFORM_MATRIX) }}
- xcode-version: ${{ fromJSON(needs.prepare.outputs.XCODE_VERSIONS_MATRIX) }}
- exclude:
- - platform: visionos
- xcode-version: 15.1
- steps:
- - uses: actions/checkout@v4
- - name: Select Xcode Version
- run: sudo xcode-select -switch /Applications/Xcode_${{ env.RELEASE_VERSION }}.app
- - name: Install the Apple certificate and provisioning profile
- env:
- DEVELOPMENT_CERTIFICATE_BASE64: ${{ secrets.DEVELOPMENT_CERTIFICATE_BASE64 }}
- P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
- KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
- run: |
- sh -x build.sh install-apple-certificates
- - name: Restore frameworks
- uses: actions/download-artifact@v4
- with:
- pattern: build-${{ matrix.platform }}*-${{ matrix.xcode-version }}-*
- - name: Create xcframework
- env:
- SIGNING_IDENTITY: ${{ secrets.SIGNING_IDENTITY }}
- run: |
- sh -x build.sh release-create-xcframework-${{ matrix.xcode-version }} ${{ matrix.platform }}
- - name: Upload xcframework
- uses: actions/upload-artifact@v4
- with:
- name: realm-${{ matrix.platform }}-${{ matrix.xcode-version }}
- path: realm-${{ matrix.platform }}-${{ matrix.xcode-version }}.zip
- package-release: # Creates xcframework for each platform and xcode version
- runs-on: macos-14
+ package-release:
+ runs-on: macos-15
name: Package release file
- needs: [package-xcframework-platform, prepare]
+ needs: [build-product, prepare]
steps:
- uses: actions/checkout@v4
- - name: Select Xcode Version
- run: sudo xcode-select -switch /Applications/Xcode_${{ env.RELEASE_VERSION }}.app
+ - uses: actions/download-artifact@v4
- name: Install the Apple certificate and provisioning profile
env:
DEVELOPMENT_CERTIFICATE_BASE64: ${{ secrets.DEVELOPMENT_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
- run: |
- sh -x build.sh install-apple-certificates
- - name: Restore packages xcframeworks
- uses: actions/download-artifact@v4
- with:
- pattern: realm-*
+ run: sh build.sh install-apple-certificates
- name: Create release
env:
SIGNING_IDENTITY: ${{ secrets.SIGNING_IDENTITY }}
- run: |
- sh -x build.sh release-package
+ run: sh -x build.sh release-package
- name: Upload release artifactss
uses: actions/upload-artifact@v4
with:
@@ -162,52 +132,48 @@ jobs:
- name: Upload release for testing
uses: actions/upload-artifact@v4
with:
- name: realm-swift-${{ needs.prepare.outputs.VERSION }}
+ name: test-release-package
path: pkg/realm-swift-${{ needs.prepare.outputs.VERSION }}.zip
test-package-examples:
- runs-on: macos-14
+ runs-on: macos-15
name: Test examples
needs: [package-release, prepare]
steps:
- uses: actions/checkout@v4
- - name: Select Xcode Version
- run: sudo xcode-select -switch /Applications/Xcode_${{ env.RELEASE_VERSION }}.app
- name: Restore release
uses: actions/download-artifact@v4
with:
- name: realm-swift-${{ needs.prepare.outputs.VERSION }}
+ name: test-release-package
- name: Test examples
run: sh -x build.sh release-test-examples
test-ios-static:
- runs-on: macos-14
+ runs-on: macos-15
name: Run tests on iOS with configuration Static
needs: package-release
steps:
- uses: actions/checkout@v4
- - name: Select Xcode Version
- run: sudo xcode-select -switch /Applications/Xcode_${{ env.RELEASE_VERSION }}.app
- name: Test ios static
run: sh -x build.sh test-ios-static
test-osx-static:
- runs-on: macos-14
+ runs-on: macos-15
name: Run tests on macOS
needs: package-release
steps:
- uses: actions/checkout@v4
- - name: Select Xcode Version
- run: sudo xcode-select -switch /Applications/Xcode_${{ env.RELEASE_VERSION }}.app
- name: Test osx static
run: |
export REALM_DISABLE_METADATA_ENCRYPTION=1
sh -x build.sh test-osx
test-installation:
- runs-on: macos-14
+ runs-on: macos-15
name: Run installation test
needs: [package-release, prepare]
+ env:
+ REALM_TEST_BRANCH: "${{github.ref_name}}"
strategy:
matrix:
platform: ${{ fromJSON(needs.prepare.outputs.PLATFORM_MATRIX) }}
- installation: [cocoapods, spm, carthage, xcframework]
+ installation: [cocoapods, spm, carthage]
linkage: [dynamic, static]
exclude:
- platform: visionos
@@ -215,8 +181,6 @@ jobs:
installation: carthage
- installation: carthage
linkage: static
- - installation: xcframework
- linkage: static
include:
- platform: ios
installation: xcframework
@@ -226,50 +190,51 @@ jobs:
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- - name: Select Xcode Version
- run: sudo xcode-select -switch /Applications/Xcode_${{ env.RELEASE_VERSION }}.app
+ - name: Download visionOS
+ if: matrix.platform == 'visionos' && matrix.os == 'macos-14'
+ run: xcodebuild -downloadPlatform visionOS
- name: Restore release
uses: actions/download-artifact@v4
if: ${{ matrix.installation == 'xcframework' }}
with:
- name: realm-${{ matrix.platform }}-${{ env.RELEASE_VERSION }}
- - name: Unzip package release
- if: ${{ matrix.installation == 'xcframework' }}
- run: |
- mkdir -p build
- unzip realm-${{ matrix.platform }}-${{ env.RELEASE_VERSION }}.zip -d build
+ name: test-release-package
- name: Run installation test
run: |
- echo "REALM_TEST_BRANCH=${{ github.ref_name }}" >> $GITHUB_OUTPUT
+ find . -name '*.zip' -depth 1 -exec mv {} examples/installation \;
cd examples/installation
bundle exec ./build.rb ${{ matrix.platform }} ${{ matrix.installation }} ${{ matrix.linkage }}
test-installation-xcframework:
- runs-on: macos-14
name: Run installation test for xcframework
needs: [package-release, prepare]
- env:
- PLATFORM: 'osx'
strategy:
matrix:
xcode-version: ${{ fromJSON(needs.prepare.outputs.XCODE_VERSIONS_MATRIX) }}
+ include:
+ - xcode-version: 15.3
+ os: macos-14
+ - xcode-version: 15.4
+ os: macos-14
+ - xcode-version: 16
+ os: macos-15
+ - xcode-version: 16.1_Release_Candidate
+ os: macos-15
+ env:
+ PLATFORM: 'osx'
+ DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode-version }}.app/Contents/Developer
+ REALM_TEST_BRANCH: "${{github.ref_name}}"
+ runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- - name: Select Xcode Version
- run: sudo xcode-select -switch /Applications/Xcode_${{ matrix.xcode-version }}.app
- name: Restore release
uses: actions/download-artifact@v4
with:
- name: realm-${{ env.PLATFORM }}-${{ matrix.xcode-version }}
- - name: Unzip package release
- run: |
- mkdir -p build
- unzip realm-${{ env.PLATFORM }}-${{ matrix.xcode-version }}.zip -d build
+ name: test-release-package
- name: Run installation test
run: |
- echo "REALM_TEST_BRANCH=${{ github.ref_name }}" >> $GITHUB_OUTPUT
+ find . -name '*.zip' -depth 1 -exec mv {} examples/installation \;
cd examples/installation
bundle exec ./build.rb osx xcframework dynamic
diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml
index 9ab1a8bb95..a8b6902f63 100644
--- a/.github/workflows/publish-release.yml
+++ b/.github/workflows/publish-release.yml
@@ -1,8 +1,8 @@
name: Publish release
on: workflow_dispatch
env:
- XCODE_VERSION: "['15.3', '15.4', '16_beta_6', '16.1_beta']"
- TEST_XCODE_VERSION: '15.4'
+ XCODE_VERSION: "['15.3', '15.4', '16', '16.1_beta_3']"
+ TEST_XCODE_VERSION: '16'
jobs:
prepare:
runs-on: ubuntu-latest
@@ -33,7 +33,7 @@ jobs:
tag_exists_error: false
message: ""
publish-docs:
- runs-on: macos-latest
+ runs-on: macos-15
name: Publish docs to S3 Bucket
needs: tag-release
env:
@@ -49,7 +49,7 @@ jobs:
- name: Publish docs
run: bundle exec sh -x build.sh publish-docs ${{ github.sha }}
create-release:
- runs-on: macos-latest
+ runs-on: macos-15
name: Create github release
needs: [tag-release, prepare]
env:
@@ -62,7 +62,7 @@ jobs:
- name: Create Github release
run: bundle exec ./build.sh publish-github ${{ github.sha }}
publish-cocoapods:
- runs-on: macos-latest
+ runs-on: macos-15
name: Publish Cocoapods specs
needs: [tag-release, prepare]
env:
@@ -74,8 +74,22 @@ jobs:
bundler-cache: true
- name: Publish
run: bundle exec ./build.sh publish-cocoapods v${{ needs.prepare.outputs.VERSION }}
+ update-checker:
+ runs-on: macos-15
+ name: Update to latest version update checker file
+ needs: tag-release
+ env:
+ AWS_ACCESS_KEY_ID: ${{ secrets.UPDATE_CHECKER_ACCESS_KEY }}
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.UPDATE_CHECKER_SECRET_KEY }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: ruby/setup-ruby@v1
+ with:
+ bundler-cache: true
+ - run: brew install s3cmd
+ - run: bundle exec ./build.sh publish-update-checker
test-installation:
- runs-on: macos-14
+ runs-on: macos-15
name: Run installation test for ${{ matrix.platform }}, ${{ matrix.installation }} and ${{ matrix.linkage }}
needs: [create-release, prepare, publish-cocoapods]
strategy:
@@ -119,10 +133,10 @@ jobs:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ env.TEST_XCODE_VERSION }}
- - name: Set REALM_TEST_RELEASE
- run: echo "REALM_TEST_RELEASE=${{ needs.prepare.outputs.VERSION }}" >> $GITHUB_ENV
- name: Run installation test
uses: nick-fields/retry@v3
+ env:
+ REALM_TEST_RELEASE: ${{ needs.prepare.outputs.VERSION }}
with:
command: |
cd examples/installation
@@ -132,9 +146,9 @@ jobs:
retry_wait_seconds: 60
retry_on: error
post-slack-release:
- runs-on: macos-latest
+ runs-on: macos-15
name: Publish to release Slack channel
- needs: [create-release, prepare, publish-cocoapods, publish-docs]
+ needs: [create-release, prepare, publish-cocoapods, update-checker, publish-docs]
env:
WEBHOOK_URL: ${{ secrets.SLACK_RELEASES_WEBHOOK }}
steps:
@@ -152,7 +166,7 @@ jobs:
webhook-url: ${{ env.WEBHOOK_URL }}
version: ${{ needs.prepare.outputs.VERSION }}
add-empty-changelog:
- runs-on: macos-latest
+ runs-on: macos-15
permissions:
contents: write
name: Add empty changelog and commits/push it
diff --git a/.github/workflows/update-xcode-cloud-workflows.yml b/.github/workflows/update-xcode-cloud-workflows.yml
deleted file mode 100644
index c4d5dd66d6..0000000000
--- a/.github/workflows/update-xcode-cloud-workflows.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Update XCode Cloud Workflows
-on: workflow_dispatch
-jobs:
- main:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - name: Get Token
- id: token
- run: |
- token=$(ruby ./scripts/xcode_cloud_helper.rb --issuer-id ${{ secrets.APPLE_STORE_CONNECT_ISSUER_ID }} --key-id ${{ secrets.APPLE_STORE_CONNECT_KEY_ID }} --pk "${{ secrets.APPLE_STORE_CONNECT_API_KEY }}" get-token)
- echo "TOKEN=$token" >> $GITHUB_OUTPUT
- - name: Run ruby script
- run: echo "both" | ./scripts/xcode_cloud_helper.rb -t ${{ steps.token.outputs.TOKEN }} synchronize-workflows
-
-
diff --git a/CHANGELOG.md b/CHANGELOG.md
index babb10b6b4..13572f0cae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,26 @@ x.y.z Release notes (yyyy-MM-dd)
### Internal
* Upgraded realm-core from ? to ?
+20.0.1 Release notes (2024-09-21)
+=============================================================
+
+### Fixed
+
+* Having a query with a number of predicates ORed together may result in a
+ crash on some platforms (strict weak ordering check failing on iphone)
+ ([#8028](https://github.com/realm/realm-core/issues/8028), since v10.50.0)
+
+### Compatibility
+
+* Realm Studio: 15.0.0 or later.
+* Carthage release for Swift is built with Xcode 15.4.0.
+* CocoaPods: 1.10 or later.
+* Xcode: 15.3.0-16.1 beta.
+
+### Internal
+
+* Upgraded realm-core from v20.0.0 to 20.1.0
+
20.0.0 Release notes (2024-09-09)
=============================================================
diff --git a/Package.swift b/Package.swift
index d54319d7c8..e26ff5be42 100644
--- a/Package.swift
+++ b/Package.swift
@@ -3,8 +3,8 @@
import PackageDescription
import Foundation
-let coreVersion = Version("20.0.0")
-let cocoaVersion = Version("20.0.0")
+let coreVersion = Version("20.1.0")
+let cocoaVersion = Version("20.0.1")
#if compiler(>=6)
let swiftVersion = [SwiftVersion.version("6")]
diff --git a/Realm/Realm-Info.plist b/Realm/Realm-Info.plist
index c21b79da64..24aa1812db 100644
--- a/Realm/Realm-Info.plist
+++ b/Realm/Realm-Info.plist
@@ -17,11 +17,11 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 20.0.0
+ 20.0.1
CFBundleSignature
????
CFBundleVersion
- 20.0.0
+ 20.0.1
NSHumanReadableCopyright
Copyright © 2014-2021 Realm. All rights reserved.
NSPrincipalClass
diff --git a/build.sh b/build.sh
index f6227f8c4e..83104a650e 100755
--- a/build.sh
+++ b/build.sh
@@ -21,17 +21,13 @@ if [ -n "${CI}" ]; then
CODESIGN_PARAMS=(CODE_SIGN_IDENTITY='' CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO)
fi
-if [ -n "${CI_XCODE_CLOUD}" ]; then
- DERIVED_DATA="$CI_DERIVED_DATA_PATH"
- ROOT_WORKSPACE="$CI_WORKSPACE"
- BRANCH="$CI_BRANCH"
-elif [ -n "${GITHUB_WORKSPACE}" ]; then
- DERIVED_DATA="$GITHUB_WORKSPACE/build/DerivedData/Realm"
+if [ -n "${GITHUB_WORKSPACE}" ]; then
+ DERIVED_DATA="$GITHUB_WORKSPACE/build/DerivedData"
ROOT_WORKSPACE="$GITHUB_WORKSPACE"
- BRANCH="$GITHUB_REF"
+ BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF}}"
else
ROOT_WORKSPACE="$(pwd)"
- DERIVED_DATA="$ROOT_WORKSPACE/build/DerivedData/Realm"
+ DERIVED_DATA="$ROOT_WORKSPACE/build/DerivedData"
BRANCH="$(git branch --show-current)"
fi
@@ -74,6 +70,7 @@ command:
examples-tvos-swift: builds all Swift tvOS examples
get-version: get the current version
+ get-ioplatformuuid: get io platform uuid
set-version version: set the version
set-core-version version: set the version of core to use
@@ -88,6 +85,7 @@ command:
publish-github: create a Github release for the currently checked-out tag
publish-docs: publish a built docs release to the website
+ publish-update-checker: publish cocoa file with a version to check for update logic
publish-cocoapods [tag]: publish the requested tag to CocoaPods
prepare-publish-changelog: creates a changelog file to be used in Slack
@@ -175,7 +173,7 @@ build_combined() {
build_args=(-scheme "$product" -configuration "$config" build REALM_HIDE_SYMBOLS=YES)
# Derive build paths
- local build_products_path="$DERIVED_DATA/Build/Products"
+ local build_products_path="$DERIVED_DATA/Realm/Build/Products"
local product_name="$product.framework"
local os_path="$build_products_path/$config${config_suffix}/$product_name"
local simulator_path="$build_products_path/$config-$simulator_suffix/$product_name"
@@ -196,89 +194,12 @@ build_combined() {
-framework "$os_path" "${simulator_framework[@]}"
}
-# To be used with Github actions runner
-build_platform() {
- local product="$1"
- local platform="$2"
- local config="$CONFIGURATION"
-
- local destination build_args config_suffix
- case "$platform" in
- osx)
- config_suffix=
- destination='generic/platform=macOS'
- ;;
- ios)
- config_suffix=-iphoneos
- destination='generic/platform=iOS'
- ;;
- watchos)
- config_suffix=-watchos
- destination='generic/platform=watchOS'
- ;;
- tvos)
- config_suffix=-appletvos
- destination='generic/platform=tvOS'
- ;;
- visionos)
- config_suffix=-xros
- destination='generic/platform=visionOS'
- ;;
- catalyst)
- config_suffix=-maccatalyst
- destination='generic/platform=macOS,variant=Mac Catalyst'
- ;;
- osx)
- destination='generic/platform=macOS'
- ;;
- iossimulator)
- config_suffix=-iphonesimulator
- destination='generic/platform=iOS'
- ;;
- watchossimulator)
- config_suffix=-watchsimulator
- destination='generic/platform=watchOS'
- ;;
- tvossimulator)
- config_suffix=-appletvsimulator
- destination='generic/platform=tvOS'
- ;;
- visionossimulator)
- config_suffix=-xrsimulator
- destination='generic/platform=visionOS'
- ;;
- esac
-
- build_products_path="$DERIVED_DATA/Build/Products"
- build_path="$build_products_path/$config${config_suffix}"
-
- build_args=(-scheme "$product" -configuration "$config" build REALM_HIDE_SYMBOLS=YES)
-
- if [[ "$platform" = *"simulator" ]]; then
- xc -destination "$destination Simulator" "${build_args[@]}"
- else
- xc -destination "$destination" "${build_args[@]}"
- fi
-
- # This is only for test, and simulates how it is packaged by XCode Cloud
- number="$((10000 + $RANDOM % 99999))"
- folder_name="RealmSwift Build $number Build Products for $product on iOS"
- dir="$folder_name/$config${config_suffix}"
- mkdir -p "$dir"
- cp -a "$build_path/." "$dir"
-
- config_name="$(tr [A-Z] [a-z] <<< "$config")"
- zip -r product.zip "$dir"
- rm -rf "$folder_name"
-}
-
create_xcframework() {
local product="$1"
local config="$2"
- local platform="$3"
- local out_path="$ROOT_WORKSPACE/$config/$platform/$product.xcframework"
- find "$ROOT_WORKSPACE" -path "*/$config*/$product.framework" \
+ local out_path="$ROOT_WORKSPACE/$config/$product.xcframework"
+ find "$ROOT_WORKSPACE"/build-*/"$config" -name "$product.framework" \
| sed 's/.*/-framework &/' \
| xargs xcodebuild -create-xcframework -allow-internal-distribution -output "$out_path"
codesign --timestamp -s "$SIGNING_IDENTITY" "$out_path"
@@ -306,6 +227,14 @@ plist_get() {
/usr/libexec/PlistBuddy -c "Print :$2" "$1" 2> /dev/null
}
+iphone_name() {
+ if (( $(xcode_version_major) < 16 )); then
+ echo 'iPhone 14'
+ else
+ echo 'iPhone 16'
+ fi
+}
+
######################################
# Device Test Helper
######################################
@@ -510,21 +439,17 @@ case "$COMMAND" in
"xcframework")
# Build all of the requested frameworks
shift
- if (( $(xcode_version_major) < 15 )); then
- PLATFORMS="${*:-osx ios watchos tvos catalyst}"
- else
- PLATFORMS="${*:-osx ios watchos tvos catalyst visionos}"
- fi
+ PLATFORMS="${*:-osx ios watchos tvos catalyst visionos}"
for platform in $PLATFORMS; do
sh build.sh "$platform-swift"
done
# Assemble them into xcframeworks
- rm -rf "$DERIVED_DATA/Build/Products"*.xcframework
- find "$DERIVED_DATA/Build/Products" -name 'Realm.framework' \
+ rm -rf "$DERIVED_DATA/Realm/Build/Products"*.xcframework
+ find "$DERIVED_DATA/Realm/Build/Products" -name 'Realm.framework' \
| sed 's/.*/-framework &/' \
| xargs xcodebuild -create-xcframework -allow-internal-distribution -output "build/$CONFIGURATION/Realm.xcframework"
- find "$DERIVED_DATA/Build/Products" -name 'RealmSwift.framework' \
+ find "$DERIVED_DATA/Realm/Build/Products" -name 'RealmSwift.framework' \
| sed 's/.*/-framework &/' \
| xargs xcodebuild -create-xcframework -allow-internal-distribution -output "build/$CONFIGURATION/RealmSwift.xcframework"
@@ -581,12 +506,12 @@ case "$COMMAND" in
;;
"test-ios")
- xctest Realm -configuration "$CONFIGURATION" -sdk iphonesimulator -destination 'name=iPhone 14'
+ xctest Realm -configuration "$CONFIGURATION" -sdk iphonesimulator -destination "name=$(iphone_name)"
exit 0
;;
"test-ios-swift")
- xctest RealmSwift -configuration "$CONFIGURATION" -sdk iphonesimulator -destination 'name=iPhone 14'
+ xctest RealmSwift -configuration "$CONFIGURATION" -sdk iphonesimulator -destination "name=$(iphone_name)"
exit 0
;;
@@ -650,7 +575,7 @@ case "$COMMAND" in
;;
"test-ios-swiftui")
- xctest 'SwiftUITestHost' -configuration "$CONFIGURATION" -sdk iphonesimulator -destination 'name=iPhone 11'
+ xctest 'SwiftUITestHost' -configuration "$CONFIGURATION" -sdk iphonesimulator -destination "name=$(iphone_name)"
exit 0
;;
@@ -664,6 +589,16 @@ case "$COMMAND" in
exit 0
;;
+ "test-visionos")
+ xctest Realm -configuration "$CONFIGURATION" -sdk xrsimulator -destination 'platform=visionOS Simulator,name=Apple Vision Pro' CODE_SIGN_IDENTITY=''
+ exit 0
+ ;;
+
+ "test-visionos-swift")
+ xctest RealmSwift -configuration "$CONFIGURATION" -sdk xrsimulator -destination 'platform=visionOS Simulator,name=Apple Vision Pro' CODE_SIGN_IDENTITY=''
+ exit 0
+ ;;
+
######################################
# Full verification
######################################
@@ -697,15 +632,15 @@ case "$COMMAND" in
;;
"verify-cocoapods")
- export REALM_TEST_BRANCH="$sha"
+ export REALM_TEST_BRANCH="$BRANCH"
if [[ -d .git ]]; then
# Verify the current branch, unless one was already specified in the sha environment variable.
- if [[ -z $sha ]]; then
+ if [[ -z $BRANCH ]]; then
export REALM_TEST_BRANCH=$(git rev-parse --abbrev-ref HEAD)
fi
if [[ $(git log -1 '@{push}..') != "" ]] || ! git diff-index --quiet HEAD; then
- echo "WARNING: verify-cocoapods will test the latest revision of $sha found on GitHub."
+ echo "WARNING: verify-cocoapods will test the latest revision of $BRANCH found on GitHub."
echo " Any unpushed local changes will not be tested."
echo ""
sleep 1
@@ -725,7 +660,7 @@ case "$COMMAND" in
PLATFORM=$(echo "$COMMAND" | cut -d - -f 3)
cd examples/installation
- REALM_TEST_BRANCH="$sha" ./build.rb "$PLATFORM" cocoapods "$LINKAGE"
+ REALM_TEST_BRANCH="$BRANCH" ./build.rb "$PLATFORM" cocoapods "$LINKAGE"
;;
"verify-docs")
@@ -742,15 +677,15 @@ case "$COMMAND" in
;;
"verify-spm")
- export REALM_TEST_BRANCH="$sha"
+ export REALM_TEST_BRANCH="$BRANCH"
if [[ -d .git ]]; then
# Verify the current branch, unless one was already specified in the sha environment variable.
- if [[ -z $sha ]]; then
+ if [[ -z $BRANCH ]]; then
export REALM_TEST_BRANCH=$(git rev-parse --abbrev-ref HEAD)
fi
if [[ $(git log -1 '@{push}..') != "" ]] || ! git diff-index --quiet HEAD; then
- echo "WARNING: verify-spm will test the latest revision of $sha found on GitHub."
+ echo "WARNING: verify-spm will test the latest revision of $BRANCH found on GitHub."
echo " Any unpushed local changes will not be tested."
echo ""
sleep 1
@@ -771,7 +706,7 @@ case "$COMMAND" in
PLATFORM=$(echo "$COMMAND" | cut -d - -f 3)
cd examples/installation
- REALM_TEST_BRANCH="$sha" ./build.rb "$PLATFORM" spm "$LINKAGE"
+ REALM_TEST_BRANCH="$BRANCH" ./build.rb "$PLATFORM" spm "$LINKAGE"
exit 0
;;
@@ -806,9 +741,7 @@ case "$COMMAND" in
sh build.sh examples-osx
(
- DERIVED_EXAMPLE_DATA=${DERIVED_DATA:-examples/osx/objc/build/DerivedData/RealmExamples}
-
- cd $DERIVED_EXAMPLE_DATA/Build/Products/$CONFIGURATION
+ cd examples/osx/objc/build/DerivedData/RealmExamples/Build/Products/Release
DYLD_FRAMEWORK_PATH=. ./JSONImport >/dev/null
)
exit 0
@@ -1024,9 +957,12 @@ case "$COMMAND" in
"ci-pr")
echo "Building with Xcode Version $(xcodebuild -version)"
- export sha="$BRANCH"
export REALM_EXTRA_BUILD_ARGUMENTS='GCC_GENERATE_DEBUGGING_SYMBOLS=NO -allowProvisioningUpdates'
- target=$(echo "$CI_WORKFLOW" | cut -f1 -d_)
+ target="$2"
+ if [[ "$target" == visionos ]] && (( $(xcode_version_major) < 16 )); then
+ echo 'Installing visionOS'
+ xcodebuild -downloadPlatform visionOS
+ fi
sh build.sh "verify-$target"
;;
@@ -1044,29 +980,10 @@ case "$COMMAND" in
zip -r docs/realm-docs.zip docs/objc_output docs/swift_output
;;
- release-create-xcframework-*)
- platform="$2"
- xcode_version=$(echo "$COMMAND" | cut -d- -f4)
-
- find . -name 'build-*.zip' -exec unzip {} \;
-
- create_xcframework Realm Release "$platform"
- create_xcframework RealmSwift Release "$platform"
-
- if [ "$platform" = "ios" ]; then
- create_xcframework Realm Static "$platform"
- else
- mkdir -p "Static/$platform"
- fi
-
- zip --symlinks -r "realm-$platform-$xcode_version.zip" "Release/$platform" "Static/$platform"
- exit 0
- ;;
-
"release-package")
version="$(sed -n 's/^VERSION=\(.*\)$/\1/p' "${source_root}/dependencies.list")"
- find . -name 'realm-*-1*' -maxdepth 1 \
- | sed 's@./realm-[a-z]*-\(.*\)@\1@' \
+ find . -name 'build-*-1*' -maxdepth 1 \
+ | sed 's@./build-[a-z]*-\(.*\)-.*@\1@' \
| sort -u --version-sort \
| xargs ./scripts/create-release-package.rb "${ROOT_WORKSPACE}/pkg" "${version}"
;;
@@ -1117,90 +1034,6 @@ case "$COMMAND" in
# Release tests
######################################
- # Should select xcode version `xcode-select` first.
- # Pass xcode version as argument
- # This simulates what is done in XCode Cloud
- "test-create-frameworks")
- xcode_version="$2"
- targets="Realm RealmSwift"
-
- platforms=("ios" "iossimulator" "osx" "tvos" "tvossimulator" "watchos" "watchossimulator" "catalyst")
- if [ "$xcode_version" == "15.2" ]; then
- platforms+=("visionos" "visionossimulator")
- fi
-
- for platform in "${platforms[@]}"; do
- for target in $targets; do
- echo "Building $platform and $target release"
- ./build.sh "release-package-$platform-$xcode_version-$target-release"
- ./build.sh "release-build_$platform-$xcode_version-$target-release"
-
- # Only generates Realm framework for Static configuration and ios platform
- if [[ "$platform" == "ios" || "$platform" == "iossimulator" ]] && [[ "$target" == "Realm" ]]; then
- echo "Building $platform and $target static"
- ./build.sh "release-package-$platform-$xcode_version-$target-static"
- ./build.sh "release-package-build_$platform-$xcode_version-$target-static"
- fi
- done
- done
- ;;
-
- "test-build-product-workflow-xcode-cloud")
- issuer_id=""
- key_id=""
- pk_path=""
-
- token=$(ruby ./scripts/xcode_cloud_helper.rb --issuer-id $issuer_id --key-id $key_id --pk-path $pk_path get-token)
- echo "Authentication token -> $token"
-
- # Test parameters
- platform="ios"
- target="RealmSwift"
- xcode_version="15.2"
- configuration="release"
-
- workflow_id=$(ruby ./scripts/xcode_cloud_helper.rb create-workflow release-package-build $platform $xcode_version $target $configuration -t $token)
- echo "Created workflow -> $workflow_id"
- build_run_id=$(ruby ./scripts/xcode_cloud_helper.rb build-workflow $workflow_id dp/new_migration_branch -t $token)
- echo "Build Run -> $build_run_id"
- while [ "$status" != 'COMPLETE' ]
- do
- token=$(ruby ./scripts/xcode_cloud_helper.rb --issuer-id $issuer_id --key-id $key_id --pk-path $pk_path get-token)
- status=$(ruby ./scripts/xcode_cloud_helper.rb get-build-status $build_run_id -t $token)
- echo "Status $status" | ts
- sleep 20
- done
- completion_status=$(ruby ./scripts/xcode_cloud_helper.rb get-build-result $build_run_id -t $token)
- echo "Completion Status $completion_status" | ts
- if [ "$completion_status" != 'SUCCEEDED' ]; then
- echo "XCode build failed"
- ruby ./scripts/xcode_cloud_helper.rb print-build-logs $build_run_id -t $token
- exit 1
- fi
-
- ruby ./scripts/xcode_cloud_helper.rb print-build-logs $build_run_id -t $token
- ruby ./scripts/xcode_cloud_helper.rb download-artifact $build_run_id -t $token
- ruby ./scripts/xcode_cloud_helper.rb delete-workflow $workflow_id -t $token
- ;;
-
- # Pass xcode version as argument
- # For this to work, product builds should be located in the root of the project
- "test-create-platform-xcframeworks")
- xcode_version="$2"
-
- platforms=("ios" "osx" "tvos" "watchos" "catalyst")
- if [ "$xcode_version" == "15.1" ]; then
- platforms+=("visionos")
- fi
-
- for platform in "${platforms[@]}"; do
- ./build.sh release-create-xcframework_$xcode_version $platform
-
- rm -rf "$ROOT_WORKSPACE/Release"
- rm -rf "$ROOT_WORKSPACE/Static"
- done
- ;;
-
"test-package-examples")
VERSION="$(sed -n 's/^VERSION=\(.*\)$/\1/p' "${source_root}/dependencies.list")"
dir="realm-swift-${VERSION}"
@@ -1226,22 +1059,6 @@ case "$COMMAND" in
sh build.sh examples-tvos-swift
;;
- # This is used for test or if we want to use Github Actions to build each framework
- release-package-build_*)
- filename="Configuration/Release.xcconfig"
- sed -i '' "s/REALM_HIDE_SYMBOLS = NO;/REALM_HIDE_SYMBOLS = YES;/" "$filename"
-
- # Remove the identifier of the command, so we can obtain the parameters from the command
- build_command=${COMMAND#"release-package-build_"}
- parameters=(${build_command//-/ })
-
- platform=${parameters[0]}
- target=${parameters[1]}
-
- build_platform "$target" "$platform"
- exit 0
- ;;
-
######################################
# Publish
######################################
diff --git a/ci_scripts/ci_post_clone.sh b/ci_scripts/ci_post_clone.sh
deleted file mode 100755
index c8da17df76..0000000000
--- a/ci_scripts/ci_post_clone.sh
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/bash
-
-set -eo pipefail
-
-######################################
-# Dependency Installer
-######################################
-
-USE_BUNDLE_EXEC=''
-install_dependencies() {
- if [[ "$CI_WORKFLOW" == "docs"* ]]; then
- install_ruby
- elif [[ "$CI_WORKFLOW" == "swiftlint"* ]]; then
- brew install swiftlint
- elif [[ "$CI_WORKFLOW" == "cocoapods"* ]]; then
- install_ruby
- elif [[ "$CI_WORKFLOW" = *"spm"* ]] || [[ "$CI_WORKFLOW" = "xcframework"* ]]; then
- install_ruby
- elif [[ "$CI_WORKFLOW" == *"carthage"* ]]; then
- brew install carthage
- else
- sh build.sh download-core
- fi
-}
-
-install_ruby() {
- brew install rbenv ruby-build
- rbenv install
- eval "$(rbenv init -)"
- bundle install
- USE_BUNDLE_EXEC=true
-}
-
-env
-
-cd "$(dirname "$0")"/..
-install_dependencies
-
-# Xcode Cloud doesn't let us set the configuration to build, so set it by
-# modifying the scheme files
-target=$(echo "$CI_WORKFLOW" | cut -f1 -d_)
-configuration="Release"
-case "$target" in
- *-debug) configuration="Debug" ;;
- *-static) configuration="Static" ;;
-esac
-
-find Realm.xcodeproj -name '*.xcscheme' \
- -exec sed -i '' "s/buildConfiguration = \"Debug\"/buildConfiguration = \"$configuration\"/" {} \;
-
-# If testing library evolution mode, patch the config to enable it
-if [[ "$target" == *-evolution ]]; then
- filename='Configuration/RealmSwift/RealmSwift.xcconfig'
- sed -i '' "s/REALM_BUILD_LIBRARY_FOR_DISTRIBUTION = NO;/REALM_BUILD_LIBRARY_FOR_DISTRIBUTION = YES;/" "$filename"
-fi
-
-# If testing encryption, patch the scheme to enable it
-if [[ "$target" == *-encryption ]]; then
- filename='Realm.xcodeproj/xcshareddata/xcschemes/Realm.xcscheme'
- xmllint --shell "$filename" << EOF
- cd /Scheme/LaunchAction/EnvironmentVariables/EnvironmentVariable[@key='REALM_ENCRYPT_ALL']/@isEnabled
- set YES
- save
-EOF
-fi
-
-# In release we are creating some workflows which build the framework for each platform, target and configuration,
-# and we need to set the linker flags in the Configuration file.
-if [[ "$target" == "release-package-build-"* ]]; then
- filename="Configuration/Release.xcconfig"
- sed -i '' "s/REALM_HIDE_SYMBOLS = NO;/REALM_HIDE_SYMBOLS = YES;/" "$filename"
-fi
-
-# Xcode cloud currently doesn't have visionOS installed for Xcode 15.3
-if [[ "$CI_WORKFLOW" == release-package-build-vision*_15.3 ]]; then
- xcodebuild -downloadAllPlatforms
-fi
-
-# If we're building the dummy CI target then run the test. Other schemes are
-# built via Xcode cloud's xcodebuild invocation. We can't do this via a build
-# step on the CI target as that results in nested invocations of xcodebuild,
-# which doesn't work.
-if [[ "$CI_XCODE_SCHEME" == CI ]]; then
- if [[ -n "$USE_BUNDLE_EXEC" ]]; then
- bundle exec sh build.sh ci-pr
- else
- sh build.sh ci-pr
- fi
-fi
diff --git a/dependencies.list b/dependencies.list
index ca8211e69a..bd708bd499 100755
--- a/dependencies.list
+++ b/dependencies.list
@@ -1,2 +1,2 @@
-VERSION=20.0.0
-REALM_CORE_VERSION=v20.0.0
+VERSION=20.0.1
+REALM_CORE_VERSION=v20.1.0
diff --git a/examples/installation/SubRealm/SubRealm.podspec b/examples/installation/SubRealm/SubRealm.podspec
index 8af535de9a..015ba2ef72 100644
--- a/examples/installation/SubRealm/SubRealm.podspec
+++ b/examples/installation/SubRealm/SubRealm.podspec
@@ -11,6 +11,7 @@ Pod::Spec.new do |s|
s.osx.deployment_target = '10.15'
s.watchos.deployment_target = '5.0'
s.tvos.deployment_target = '12.0'
+ s.visionos.deployment_target = '1.0'
s.source_files = "*.swift"
s.dependency 'RealmSwift'
end
diff --git a/scripts/pr-ci-matrix.rb b/scripts/pr-ci-matrix.rb
index f91e99ec5b..3ea97e04ea 100755
--- a/scripts/pr-ci-matrix.rb
+++ b/scripts/pr-ci-matrix.rb
@@ -1,137 +1,101 @@
#!/usr/bin/env ruby
-# Matrix of current targets and XCode versions, and is used to add/update/delete XCode cloud workflows.
+XCODE_VERSIONS = %w(15.3 15.4 16 16.1_Release_Candidate)
+DOC_VERSION = '16'
-Destination = Struct.new(:build_platform, :test_destination) do |cls|
- def cls.macOS
- Destination.new('MACOS', {
- 'deviceTypeName' => 'Mac',
- 'deviceTypeIdentifier' => 'mac',
- 'runtimeName' => 'Same As Selected macOS Version',
- 'runtimeIdentifier' => 'builder',
- 'kind' => 'MAC'
- })
- end
+all = ->(v) { true }
+latest_only = ->(v) { v == XCODE_VERSIONS.last }
+oldest_and_latest = ->(v) { v == XCODE_VERSIONS.first or v == XCODE_VERSIONS.last }
- def cls.catalyst
- Destination.new('MACOS', {
- 'deviceTypeName' => 'Mac (Mac Catalyst)',
- 'deviceTypeIdentifier' => 'mac_catalyst',
- 'runtimeName' => 'Same As Selected macOS Version',
- 'runtimeIdentifier' => 'builder',
- 'kind' => 'MAC'
- })
- end
-
- def cls.iOS
- Destination.new('IOS', {
- 'deviceTypeName' => 'iPhone 11',
- 'deviceTypeIdentifier' => 'com.apple.CoreSimulator.SimDeviceType.iPhone-11',
- 'runtimeName' => 'Latest from Selected Xcode (iOS 16.1)',
- 'runtimeIdentifier' => 'default',
- 'kind' => 'SIMULATOR'
- })
- end
-
- def cls.tvOS
- Destination.new('TVOS', {
- 'deviceTypeName' => 'Recommended Apple TVs',
- 'deviceTypeIdentifier' => 'recommended_apple_tvs',
- 'runtimeName' => 'Latest from Selected Xcode (tvOS 16.4)',
- 'runtimeIdentifier' => 'default',
- 'kind' => 'SIMULATOR'
- })
- end
-
- def cls.generic
- Destination.new('MACOS', nil)
- end
+def minimum_version(major)
+ ->(v) { v.split('.').first.to_i >= major }
end
-Target = Struct.new(:name, :scheme, :filter, :destination) do
- def action
- action = {
- name: self.name,
- actionType: 'BUILD',
- destination: nil,
- buildDistributionAudience: nil,
- scheme: self.scheme,
- platform: self.destination.build_platform,
- isRequiredToPass: true
- }
-
- test_destination = self.destination.test_destination
- if test_destination
- action[:actionType] = 'TEST'
- action[:destination] = 'ANY_MAC'
- action[:testConfiguration] = {
- kind: 'USE_SCHEME_SETTINGS',
- testPlanName: '',
- testDestinations: [test_destination]
- }
+targets = {
+ 'osx' => all,
+ 'osx-encryption' => latest_only,
+
+ 'swiftpm' => oldest_and_latest,
+ 'swiftpm-debug' => all,
+ 'swiftpm-address' => latest_only,
+ 'swiftpm-thread' => latest_only,
+
+ 'ios-static' => oldest_and_latest,
+ 'ios' => oldest_and_latest,
+ 'watchos' => oldest_and_latest,
+ 'tvos' => oldest_and_latest,
+ 'visionos' => oldest_and_latest,
+
+ 'osx-swift' => all,
+ 'ios-swift' => oldest_and_latest,
+ 'tvos-swift' => oldest_and_latest,
+
+ 'osx-swift-evolution' => latest_only,
+ 'ios-swift-evolution' => latest_only,
+ 'tvos-swift-evolution' => latest_only,
+
+ 'catalyst' => oldest_and_latest,
+ 'catalyst-swift' => oldest_and_latest,
+
+ 'xcframework' => latest_only,
+
+ 'cocoapods-osx' => all,
+ 'cocoapods-ios-static' => latest_only,
+ 'cocoapods-ios' => latest_only,
+ 'cocoapods-watchos' => latest_only,
+ 'cocoapods-tvos' => latest_only,
+ 'cocoapods-catalyst' => latest_only,
+ 'ios-swiftui' => latest_only,
+}
+
+output_file = """
+# This is a generated file produced by scripts/pr-ci-matrix.rb.
+name: Pull request build and test
+on:
+ pull_request:
+ paths-ignore:
+ - '**.md'
+ workflow_dispatch:
+
+jobs:
+ docs:
+ runs-on: macos-14
+ name: Test docs
+ steps:
+ - uses: actions/checkout@v4
+ - uses: ruby/setup-ruby@v1
+ with:
+ bundler-cache: true
+ - run: sudo xcode-select -switch /Applications/Xcode_#{DOC_VERSION}.app
+ - run: bundle exec sh build.sh verify-docs
+ swiftlint:
+ runs-on: macos-14
+ name: Check swiftlint
+ steps:
+ - uses: actions/checkout@v4
+ - run: sudo xcode-select -switch /Applications/Xcode_#{DOC_VERSION}.app
+ - run: brew install swiftlint
+ - run: sh build.sh verify-swiftlint
+"""
+
+targets.each { |name, filter|
+ XCODE_VERSIONS.each { |version|
+ if not filter.call(version)
+ next
end
-
- return action
- end
-end
-
-# Each test target has a name, a scheme, an xcode version filter, and a
-# destination to run tests on. Targets which aren't testing a framework
-# use the 'CI' target and always the a 'generic' destination.
-#
-# To avoid using excess CI resources we don't build the full matrix of
-# combinations of targets and Xcode version. We generally test each build
-# method (Xcode project, Swift package, and podspec) on every Xcode version for
-# a single platform, and everything else is tested with the oldest and newest
-# supported Xcode versions. Some things (e.g. swiftlint) only test the latest
-# because they don't care about Xcode versions, while some others are latest-only
-# because they're particularly slow to run.
-module Workflows
- XCODE_VERSIONS = %w(15.3 15.4 16\ beta\ 6 16.1\ beta)
-
- all = ->(v) { true }
- latest_only = ->(v) { v == XCODE_VERSIONS.last }
- oldest_and_latest = ->(v) { v == XCODE_VERSIONS.first or v == XCODE_VERSIONS.last }
-
- TARGETS = [
- Target.new('osx', 'Realm', all, Destination.macOS),
- Target.new('osx-encryption', 'Realm', latest_only, Destination.macOS),
- Target.new('osx-swift', 'RealmSwift', all, Destination.macOS),
- Target.new('osx-swift-evolution', 'RealmSwift', latest_only, Destination.macOS),
-
- Target.new('ios', 'Realm', oldest_and_latest, Destination.iOS),
- Target.new('ios-static', 'Realm', oldest_and_latest, Destination.iOS),
- Target.new('ios-swift', 'RealmSwift', oldest_and_latest, Destination.iOS),
- Target.new('ios-swift-evolution', 'RealmSwift', latest_only, Destination.iOS),
-
- Target.new('tvos', 'Realm', oldest_and_latest, Destination.tvOS),
- Target.new('tvos-static', 'Realm', oldest_and_latest, Destination.tvOS),
- Target.new('tvos-swift', 'RealmSwift', oldest_and_latest, Destination.tvOS),
- Target.new('tvos-swift-evolution', 'RealmSwift', latest_only, Destination.tvOS),
-
- Target.new('catalyst', 'Realm', oldest_and_latest, Destination.catalyst),
- Target.new('catalyst-swift', 'RealmSwift', oldest_and_latest, Destination.catalyst),
-
- Target.new('watchos', 'Realm', oldest_and_latest, Destination.generic),
- Target.new('watchos-swift', 'RealmSwift', oldest_and_latest, Destination.generic),
-
- Target.new('swiftui', 'SwiftUITests', latest_only, Destination.iOS),
-
- Target.new('docs', 'CI', latest_only, Destination.generic),
- Target.new('swiftlint', 'CI', latest_only, Destination.generic),
-
- Target.new('swiftpm', 'CI', oldest_and_latest, Destination.generic),
- Target.new('swiftpm-debug', 'CI', all, Destination.generic),
- Target.new('swiftpm-address', 'CI', latest_only, Destination.generic),
- Target.new('swiftpm-thread', 'CI', latest_only, Destination.generic),
- Target.new('spm-ios', 'CI', all, Destination.generic),
-
- Target.new('xcframework', 'CI', latest_only, Destination.generic),
-
- Target.new('cocoapods-osx', 'CI', all, Destination.generic),
- Target.new('cocoapods-ios', 'CI', latest_only, Destination.generic),
- Target.new('cocoapods-ios-static', 'CI', latest_only, Destination.generic),
- Target.new('cocoapods-watchos', 'CI', latest_only, Destination.generic),
- Target.new('cocoapods-tvos', 'CI', latest_only, Destination.generic),
- Target.new('cocoapods-catalyst', 'CI', latest_only, Destination.generic),
- ]
+ image = version.start_with?('16') ? 'macos-15' : 'macos-14'
+ output_file << """
+ #{name}-#{version.gsub(' ', '_').gsub('.', '_')}:
+ runs-on: #{image}
+ name: Test #{name} on Xcode #{version}
+ env:
+ DEVELOPER_DIR: '/Applications/Xcode_#{version}.app/Contents/Developer'
+ steps:
+ - uses: actions/checkout@v4
+ - run: sh -x build.sh ci-pr #{name}
+"""
+ }
+}
+
+File.open('.github/workflows/build-pr.yml', "w") do |file|
+ file.puts output_file
end
diff --git a/scripts/xcode_cloud_helper.rb b/scripts/xcode_cloud_helper.rb
deleted file mode 100755
index 52726474f9..0000000000
--- a/scripts/xcode_cloud_helper.rb
+++ /dev/null
@@ -1,603 +0,0 @@
-#!/usr/bin/env ruby
-require 'base64'
-require 'json'
-require 'jwt'
-require 'net/http'
-require 'net/https'
-require 'optparse'
-require 'pp'
-require 'uri'
-require_relative "pr-ci-matrix"
-require_relative "release-matrix"
-
-include Workflows
-
-APP_STORE_URL = 'https://api.appstoreconnect.apple.com/v1'
-HTTP = Net::HTTP.new('api.appstoreconnect.apple.com', 443)
-HTTP.use_ssl = true
-HTTP.max_retries = 2
-
-def sh(*args)
- puts "executing: #{args.join(' ')}" if false
- system(*args, false ? {} : {:out => '/dev/null'}) || exit(1)
-end
-
-def request(req)
- req['Authorization'] = "Bearer #{JWT_TOKEN}"
- # puts req.path
- counter = 0
- while true do
- sleep 5
- counter +=1
- response = HTTP.request(req)
- break if (response.code =~ /20./ ) == 0
- break if counter == 2
- end
-
- raise "Error: #{response.code} #{response.body}" unless response.code =~ /20./
- response
-end
-
-def get(path)
- req = Net::HTTP::Get.new("/v1/#{path}")
- req['Accept'] = 'application/json'
- response = request req
- # puts response.body
- JSON.parse(response.body)
-end
-
-def post(path, body)
- req = Net::HTTP::Post.new("/v1/#{path}")
- req['Content-Type'] = 'application/json'
- req.body = body.to_json
- response = request req
- JSON.parse(response.body)
-end
-
-def get_jwt_bearer_from_file(issuer_id, key_id, pk_path)
- private_key = File.read(pk_path)
- get_jwt_bearer(issuer_id, key_id, private_key)
-end
-
-def get_jwt_bearer(issuer_id, key_id, pk)
- private_key = OpenSSL::PKey.read(pk)
- info = {
- iss: issuer_id,
- exp: Time.now.to_i + 20 * 60,
- aud: 'appstoreconnect-v1'
- }
- header_fields = { kid: key_id }
- JWT.encode(info, private_key, 'ES256', header_fields)
-end
-
-def get_workflows
- product_id = get_realm_product_id
- get("/ciProducts/#{product_id}/workflows?limit=200")['data']
-end
-
-def get_products
- get('ciProducts')['data'].map do |product|
- {
- id: product['id'],
- product: product['attributes']['name'],
- type: product['attributes']['productType']
- }
- end
-end
-
-def get_repositories
- response = get('scmRepositories')['data'].map do |repo|
- {
- id: repo['id'],
- name: repo['attributes']['repositoryName'],
- url: repo['attributes']['httpCloneUrl']
- }
- end
-end
-
-def get_macos_versions
- get('ciMacOsVersions')['data'].map do |macos|
- {
- id: macos['id'],
- name: macos['attributes']['name'],
- version: macos['attributes']['version']
- }
- end
-end
-
-def get_xcode_versions
- data = get('ciXcodeVersions')['data']
- Hash[data.collect { |xcode|
- [xcode['attributes']['name'], xcode['id']]
- }]
-end
-
-def get_build_actions(build_run)
- get("/ciBuildRuns/#{build_run}/actions")['data'].map do |build_run|
- {
- id: build_run['id'],
- }
- end
-end
-
-def get_artifacts(build_action)
- get("/ciBuildActions/#{build_action}/artifacts")['data'].map do |artifact|
- {
- id: artifact['id'],
- }
- end
-end
-
-def get_git_references
- repository_id = get_realm_repository_id
- get("/scmRepositories/#{repository_id}/gitReferences?limit=200")
-end
-
-def get_workflow_info(id)
- get("ciWorkflows/#{id}")
-end
-
-def get_build_info(id)
- get("/ciBuildRuns/#{id}")
-end
-
-def get_artifact_info(id)
- get("/ciArtifacts/#{id}")
-end
-
-def create_workflow(target, xcode_version, pull_request)
- result = post('ciWorkflows', create_workflow_request(target, xcode_version, pull_request))
- id = result["data"]["id"]
- return id
-end
-
-def create_workflow_request(target, xcode_version, pull_request)
- xcode_version_id = get_xcode_id(xcode_version)
- data = {
- data: {
- type: 'ciWorkflows',
- attributes: {
- name: "#{target.name}_#{xcode_version}",
- description: 'Create by Github Action Update XCode Cloud Workflows',
- isLockedForEditing: false,
- containerFilePath: 'Realm.xcodeproj',
- isEnabled: true,
- clean: false,
- actions: [target.action]
- },
- relationships: {
- xcodeVersion: {
- data: {
- type: 'ciXcodeVersions',
- id: xcode_version_id
- }
- },
- macOsVersion: {
- data: {
- type: 'ciMacOsVersions',
- id: get_macos_latest_release(xcode_version_id)
- }
- },
- product: {
- data: {
- type: 'ciProducts',
- id: get_realm_product_id
- }
- },
- repository: {
- data: {
- type: 'scmRepositories',
- id: get_realm_repository_id
- }
- }
- }
- }
- }
-
- if pull_request
- data[:data][:attributes][:pullRequestStartCondition] = {
- source: {
- isAllMatch: true,
- },
- destination: {
- isAllMatch: true,
- },
- autoCancel: true
- }
- else
- data[:data][:attributes][:manualBranchStartCondition] = {
- source: {
- isAllMatch: true,
- },
- destination: {
- isAllMatch: true,
- },
- autoCancel: true
- }
- end
-
- data
-end
-
-def enable_workflow(id)
- req = Net::HTTP::Patch.new("/v1/ciWorkflows/#{id}")
- req['Content-type'] = 'application/json'
- req.body = {
- data: {
- type: 'ciWorkflows',
- attributes: {
- isEnabled: true
- },
- id: id
- }
- }.to_json
- response = request req
- puts response.body
- result = JSON.parse(response.body)
- id = result['data']['id']
- puts "Workflow updated #{id}"
- return id
-end
-
-def delete_workflow(id)
- req = Net::HTTP::Delete.new("/v1/ciWorkflows/#{id}")
- req['Content-type'] = 'application/json'
- response = request req
-end
-
-def start_build(id, branch)
- branch_id = find_git_reference_for_branch(branch)
- result = post('ciBuildRuns', {
- data: {
- type: 'ciBuildRuns',
- attributes: {},
- relationships: {
- workflow: {
- data: {
- type: 'ciWorkflows',
- id: id
- }
- },
- sourceBranchOrTag: {
- data: {
- type: 'scmGitReferences',
- id: branch_id
- }
- }
- }
- }
- })
- id = result['data']['id']
- return id
-end
-
-def get_macos_version_for_xcode_version(version)
- result = get("ciXcodeVersions/#{version}/macOsVersions")
- latest = result['data'].find { |version| version['attributes']['name'] == 'Latest Release' }
- latest['id']
-end
-
-def synchronize_workflows()
- desired_workflows = Workflows::TARGETS.flat_map { |target|
- Workflows::XCODE_VERSIONS.filter_map { |version|
- if target.filter.call(version)
- {target: target, version: version}
- end
- }
- }
- current_workflows = get_workflows.filter_map { |workflow|
- name = workflow['attributes']['name']
- # don't touch release pipeline jobs
- next if name.start_with? 'release-'
- pieces = name.partition('_')
- {name: pieces.first, version: pieces.last, id: workflow['id']}
- }
-
- workflows_to_remove = current_workflows.reject { |current|
- desired_workflows.find { |desired|
- desired[:target].name == current[:name] && desired[:version] == current[:version]
- }
- }
- workflows_to_create = desired_workflows.reject { |desired|
- current_workflows.find { |current|
- desired[:target].name == current[:name] && desired[:version] == current[:version]
- }
- }
-
- puts 'Workflows to remove:'
- workflows_to_remove.each { |w|
- puts "- #{w[:name]}: #{w[:version]}"
- }
- puts ''
- puts 'Workflows to create:'
- workflows_to_create.each { |w|
- puts "- #{w[:target].name}: #{w[:version]}"
- }
- puts ''
- print 'Do you wish to continue [create/delete/both/quit]? '
-
- case STDIN.gets.chomp.downcase
- when 'create'
- workflows_to_remove = []
- when 'delete'
- workflows_to_create = []
- when 'both'
- when 'quit'
- puts 'Exiting without making any changes'
- exit 0
- else
- puts 'Unrecoginized command'
- exit 1
- end
-
- workflows_to_create.each { |w|
- id = create_workflow(w[:target], w[:version], true)
- puts "#{w[:target]}: https://appstoreconnect.apple.com/teams/69a6de86-7f37-47e3-e053-5b8c7c11a4d1/frameworks/#{get_realm_product_id}/workflows/#{id}"
- }
- workflows_to_remove.each { |w|
- delete_workflow(w[:id])
- puts "Workflow deleted #{w[:name]}"
- }
-end
-
-def get_build_status(build_run)
- build_state = get_build_info(build_run)
- status = build_state["data"]["attributes"]["executionProgress"]
- return status
-end
-
-def get_build_result(build_run)
- build_state = get_build_info(build_run)
- completion_status = build_state["data"]["attributes"]["completionStatus"]
- return completion_status
-end
-
-def get_logs_for_build(build_run)
- actions = get_build_actions(build_run)
- artifacts = get_artifacts(actions[0][:id]) # we are only running one action, so we use the first one in the list
- artifact_url = ''
- artifacts.each { |artifact|
- artifact_info = get_artifact_info(artifact[:id])
- if artifact_info["data"]["attributes"]["fileName"].include? 'Logs'
- artifact_url = artifact_info["data"]["attributes"]["downloadUrl"]
- end
- }
- print_logs(artifact_url)
-end
-
-def print_logs(url)
- sh 'curl', '--output', 'logs.zip', "#{url}"
- sh 'unzip', '-o', 'logs.zip'
- log_files = Dir["RealmSwift*/*.log"]
- log_files.each { |log_file|
- text = File.readlines("#{log_file}").map do |line|
- puts line
- end
- }
-end
-
-def find_git_reference_for_branch(branch)
- next_page = ''
- references = get_git_references
- branch_reference = references["data"].find { |reference|
- reference["attributes"]["kind"] == "BRANCH" && reference["attributes"]["name"] == branch
- }
- while branch_reference == nil || next_page == nil
- next_page = references["links"]["next"]
- next_page.slice!(APP_STORE_URL)
- references = get(next_page)
- branch_reference = references["data"].find { |reference| reference["attributes"]["kind"] == "BRANCH" && reference["attributes"]["name"] == branch }
- end
- return branch_reference["id"]
-end
-
-def download_artifact_for_build(build_id_run)
- actions = get_build_actions(build_id_run)
- artifacts = get_artifacts(actions[0][:id]) # One actions per workflow
- artifact_url = ''
- artifacts.each { |artifact|
- artifact_info = get_artifact_info(artifact[:id])
- if artifact_info["data"]["attributes"]["fileName"].include? 'Products'
- artifact_url = artifact_info["data"]["attributes"]["downloadUrl"]
- end
- }
-
- sh 'curl', '--output', "xcode-cloud-build-#{build_id_run}.zip", "#{artifact_url}"
-end
-
-def clean_up_release_workflows()
- workflows_to_remove = get_workflows.filter_map { |workflow|
- if workflow['attributes']['name'].start_with?('release-package-build')
- {name: workflow['attributes']['name'], id: workflow['id']}
- end
- }
- workflows_to_remove.each { |w|
- delete_workflow(w[:id])
- puts "Workflow deleted #{w[:name]}"
- }
-end
-
-$xcode_ids = nil
-def get_xcode_id(version)
- $xcode_ids ||= get_xcode_versions
- id = $xcode_ids["Xcode #{version}"]
- if not id
- puts "Nonexistent Xcode version #{version}"
- puts "Valid versions are:"
- $xcode_ids.keys.each { |v| puts "- #{v}"}
- exit 1
- end
- id
-end
-
-$mac_dict = Hash.new { |h, k| h[k] = get_macos_version_for_xcode_version(k) }
-def get_macos_latest_release(xcodeVersionId)
- return $mac_dict[xcodeVersionId]
-end
-
-$product_id = nil
-def get_realm_product_id
- $product_id ||= get_products.find { |p| p[:product] == 'RealmSwift' }[:id]
-end
-
-$repository_id = nil
-def get_realm_repository_id
- $repository_id ||= get_repositories.find { |repo| repo[:name] == 'realm-swift' }[:id]
-end
-
-$workflows_list = nil
-def get_workflow_id_for_name(name)
- $workflows_list ||= get_workflows
- $workflows_list.find { |w| w['attributes']['name'].split('_')[0] == name }['id']
-end
-
-Options = Struct.new(:token, :team_id, :issuer_id, :key_id, :pk_path, :pk)
-options = Options.new()
-$parser = OptionParser.new do |opts|
- opts.banner = "Usage: ruby #{__FILE__} [options] command"
- opts.separator <<~END
-
- All commands require either --token or all three of --issuer-id, --key-id,
- and --pk-path or --pk to automatically create a token.
-
- Commands:
- list-workflows
- Returns a list of current workflows for the RealmSwift product.
- list-products
- Returns a list of products associated to the Apple Connect Store account.
- list-repositories
- Returns a list of repositories integrated with XCode Cloud.
- list-mac-versions
- Returns a list of available mac versions.
- list-xcode-versions
- Returns a list of available xcode version.
- info-workflow workflow_id
- Returns the info for the corresponding workflow.
- synchronize-workflows
- Delete old workflows and/or create new ones.
- build-workflow workflow-id
- Run a build for the corresponding workflow.
- create-workflow platform xcode_version target configuration
- Creates a workflow to create platform framework for an specific configuration, target and xcode version.
- delete-workflow workflow-id
- Deletes the workflow.
- wait-build build_id
- Check status of a current build and waits, returns when completed or fails.
- download-artifact build_id
- Download a build artifact for any given build run with a build action.
- clean-up-release-workflows
- Cleans all workflows created for a release (starts with release-package-build).
- get-build-status
- Get build current status.
- get-build-result
- Get build run completion status (Complete, Error).
- print-build-logs
- Print build logs.
- get-token
- Get Apple Connect Store API Token for local use.
-
- Options:
- END
-
- opts.on("-h", "--help", "Display this help") do
- puts opts
- exit 0
- end
- opts.on('-t TOKEN', '--token TOKEN', 'Apple Connect API token') do |token|
- options[:token] = token
- end
- opts.on('--issuer-id ID', 'Apple Connect API Issuer ID.') do |id|
- options[:issuer_id] = id
- end
- opts.on('--key-id ID', 'Apple Connect API Key ID.') do |id|
- options[:key_id] = id
- end
- opts.on('--pk-path PATH', 'Apple Connect API path to private key file.') do |path|
- options[:pk_path] = path
- end
- opts.on('--pk PK', 'Apple Connect API private key.') do |pk|
- options[:pk] = pk
- end
-end
-$parser.parse!
-
-def usage()
- puts $parser
- exit 1
-end
-
-if options[:issuer_id] and options[:key_id] and options[:pk_path]
- JWT_TOKEN = get_jwt_bearer_from_file(options[:issuer_id], options[:key_id], options[:pk_path])
-elsif options[:issuer_id] and options[:key_id] and options[:pk]
- JWT_TOKEN = get_jwt_bearer(options[:issuer_id], options[:key_id], options[:pk])
-elsif options[:token]
- JWT_TOKEN = options[:token]
-else
- usage
-end
-
-COMMAND = ARGV.shift
-usage unless COMMAND
-
-case COMMAND
-when 'list-workflows'
- pp get_workflows
-when 'list-products'
- pp get_products
-when 'list-repositories'
- pp get_repositories
-when 'list-mac-versions'
- pp get_macos_versions
-when 'list-xcode-versions'
- pp get_xcode_versions
-when 'info-workflow'
- workflow_id = ARGV.shift
- usage unless workflow_id
- pp get_workflow_info(workflow_id)
-when 'enable-workflow'
- workflow_id = ARGV.shift
- usage unless workflow_id
- enable_workflow(workflow_id)
-when 'synchronize-workflows'
- synchronize_workflows()
-when 'build-workflow'
- workflow_id = ARGV.shift
- branch = ARGV.shift
- usage unless workflow_id
- id = start_build(workflow_id, branch)
- puts id
-when 'create-workflow'
- prefix = ARGV.shift
- platform = ARGV.shift
- xcode_version = ARGV.shift
- target = ARGV.shift
- configuration = ARGV.shift
- usage unless platform and xcode_version and target and configuration
- release_target = ReleaseTarget.new("#{prefix}-#{platform}-#{target}-#{configuration}", target, platform)
- id = create_workflow(release_target, xcode_version, false)
- puts id
-when 'delete-workflow'
- workflow_id = ARGV.shift
- delete_workflow(workflow_id)
-when 'download-artifact'
- build_id = ARGV.shift
- usage unless build_id
- download_artifact_for_build(build_id)
-when 'clean-up-release-workflows'
- clean_up_release_workflows()
-when 'get-build-status'
- build_id = ARGV.shift
- status = get_build_status(build_id)
- puts status
-when 'get-build-result'
- build_id = ARGV.shift
- usage unless build_id
- completion_status = get_build_result(build_id)
- puts completion_status
-when 'print-build-logs'
- build_id = ARGV.shift
- usage unless build_id
- get_logs_for_build(build_id)
-when 'get-token'
- puts JWT_TOKEN
-end