@craft-native/ios 0.0.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +619 -0
- package/dist/cli.js +664 -0
- package/dist/index.js +584 -0
- package/package.json +33 -0
- package/templates/CraftActivityAttributes.swift +14 -0
- package/templates/CraftApp.swift +5169 -0
- package/templates/CraftAppExtensions.swift +361 -0
- package/templates/CraftLiveActivityWidget.swift.template +62 -0
- package/templates/CraftWatchApp.swift.template +155 -0
- package/templates/CraftWidget.swift +247 -0
- package/templates/Info.plist.template +66 -0
- package/templates/WatchApp.Info.plist.template +26 -0
- package/templates/WidgetExtension.Info.plist +31 -0
- package/templates/fastlane/Appfile +45 -0
- package/templates/fastlane/Fastfile +189 -0
- package/templates/fastlane/Gemfile +7 -0
- package/templates/fastlane/Matchfile +58 -0
- package/templates/github-workflow-ios.yml +192 -0
- package/templates/github-workflow-release.yml +175 -0
- package/templates/github-workflow-test.yml +272 -0
- package/templates/project.yml.template +36 -0
- package/templates/test-bridges.html +1463 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# iOS Build and Test Workflow
|
|
2
|
+
# Copy this file to your project's .github/workflows/ios.yml
|
|
3
|
+
|
|
4
|
+
name: iOS Build
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main, develop]
|
|
9
|
+
paths:
|
|
10
|
+
- 'ios/**'
|
|
11
|
+
- '*.swift'
|
|
12
|
+
- '*.xcodeproj/**'
|
|
13
|
+
- '*.xcworkspace/**'
|
|
14
|
+
pull_request:
|
|
15
|
+
branches: [main]
|
|
16
|
+
paths:
|
|
17
|
+
- 'ios/**'
|
|
18
|
+
- '*.swift'
|
|
19
|
+
- '*.xcodeproj/**'
|
|
20
|
+
- '*.xcworkspace/**'
|
|
21
|
+
workflow_dispatch:
|
|
22
|
+
|
|
23
|
+
env:
|
|
24
|
+
XCODE_VERSION: '15.0'
|
|
25
|
+
SCHEME: 'CraftApp'
|
|
26
|
+
PROJECT_PATH: 'ios/CraftApp.xcodeproj'
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
build:
|
|
30
|
+
name: Build iOS App
|
|
31
|
+
runs-on: macos-14
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- name: Checkout
|
|
35
|
+
uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- name: Select Xcode
|
|
38
|
+
run: sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app
|
|
39
|
+
|
|
40
|
+
- name: Show Xcode version
|
|
41
|
+
run: xcodebuild -version
|
|
42
|
+
|
|
43
|
+
- name: Install dependencies
|
|
44
|
+
run: |
|
|
45
|
+
if [ -f "ios/Podfile" ]; then
|
|
46
|
+
cd ios && pod install
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
- name: Build Debug
|
|
50
|
+
run: |
|
|
51
|
+
xcodebuild build \
|
|
52
|
+
-project "${{ env.PROJECT_PATH }}" \
|
|
53
|
+
-scheme "${{ env.SCHEME }}" \
|
|
54
|
+
-configuration Debug \
|
|
55
|
+
-destination 'platform=iOS Simulator,name=iPhone 15,OS=17.0' \
|
|
56
|
+
CODE_SIGN_IDENTITY="" \
|
|
57
|
+
CODE_SIGNING_REQUIRED=NO \
|
|
58
|
+
CODE_SIGNING_ALLOWED=NO \
|
|
59
|
+
| xcpretty
|
|
60
|
+
|
|
61
|
+
- name: Run Tests
|
|
62
|
+
run: |
|
|
63
|
+
xcodebuild test \
|
|
64
|
+
-project "${{ env.PROJECT_PATH }}" \
|
|
65
|
+
-scheme "${{ env.SCHEME }}" \
|
|
66
|
+
-destination 'platform=iOS Simulator,name=iPhone 15,OS=17.0' \
|
|
67
|
+
CODE_SIGN_IDENTITY="" \
|
|
68
|
+
CODE_SIGNING_REQUIRED=NO \
|
|
69
|
+
| xcpretty
|
|
70
|
+
|
|
71
|
+
build-release:
|
|
72
|
+
name: Build Release
|
|
73
|
+
runs-on: macos-14
|
|
74
|
+
needs: build
|
|
75
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
76
|
+
|
|
77
|
+
steps:
|
|
78
|
+
- name: Checkout
|
|
79
|
+
uses: actions/checkout@v4
|
|
80
|
+
|
|
81
|
+
- name: Select Xcode
|
|
82
|
+
run: sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app
|
|
83
|
+
|
|
84
|
+
- name: Install dependencies
|
|
85
|
+
run: |
|
|
86
|
+
if [ -f "ios/Podfile" ]; then
|
|
87
|
+
cd ios && pod install
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
- name: Build Release (unsigned)
|
|
91
|
+
run: |
|
|
92
|
+
xcodebuild build \
|
|
93
|
+
-project "${{ env.PROJECT_PATH }}" \
|
|
94
|
+
-scheme "${{ env.SCHEME }}" \
|
|
95
|
+
-configuration Release \
|
|
96
|
+
-destination 'generic/platform=iOS' \
|
|
97
|
+
CODE_SIGN_IDENTITY="" \
|
|
98
|
+
CODE_SIGNING_REQUIRED=NO \
|
|
99
|
+
CODE_SIGNING_ALLOWED=NO \
|
|
100
|
+
ONLY_ACTIVE_ARCH=NO \
|
|
101
|
+
| xcpretty
|
|
102
|
+
|
|
103
|
+
- name: Archive (unsigned)
|
|
104
|
+
run: |
|
|
105
|
+
xcodebuild archive \
|
|
106
|
+
-project "${{ env.PROJECT_PATH }}" \
|
|
107
|
+
-scheme "${{ env.SCHEME }}" \
|
|
108
|
+
-configuration Release \
|
|
109
|
+
-archivePath build/CraftApp.xcarchive \
|
|
110
|
+
CODE_SIGN_IDENTITY="" \
|
|
111
|
+
CODE_SIGNING_REQUIRED=NO \
|
|
112
|
+
CODE_SIGNING_ALLOWED=NO \
|
|
113
|
+
| xcpretty
|
|
114
|
+
|
|
115
|
+
- name: Upload Archive
|
|
116
|
+
uses: actions/upload-artifact@v4
|
|
117
|
+
with:
|
|
118
|
+
name: ios-archive
|
|
119
|
+
path: build/CraftApp.xcarchive
|
|
120
|
+
retention-days: 7
|
|
121
|
+
|
|
122
|
+
# Optional: Signed build for App Store
|
|
123
|
+
# Requires: APPLE_CERTIFICATE_P12, APPLE_CERTIFICATE_PASSWORD,
|
|
124
|
+
# APPLE_PROVISIONING_PROFILE, KEYCHAIN_PASSWORD secrets
|
|
125
|
+
build-signed:
|
|
126
|
+
name: Build Signed Release
|
|
127
|
+
runs-on: macos-14
|
|
128
|
+
needs: build
|
|
129
|
+
if: false # Set to true when you have signing configured
|
|
130
|
+
|
|
131
|
+
steps:
|
|
132
|
+
- name: Checkout
|
|
133
|
+
uses: actions/checkout@v4
|
|
134
|
+
|
|
135
|
+
- name: Select Xcode
|
|
136
|
+
run: sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app
|
|
137
|
+
|
|
138
|
+
- name: Install Apple Certificate
|
|
139
|
+
env:
|
|
140
|
+
CERTIFICATE_P12: ${{ secrets.APPLE_CERTIFICATE_P12 }}
|
|
141
|
+
CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
142
|
+
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
|
143
|
+
run: |
|
|
144
|
+
# Create temporary keychain
|
|
145
|
+
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
|
146
|
+
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
|
147
|
+
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
|
|
148
|
+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
|
149
|
+
|
|
150
|
+
# Import certificate
|
|
151
|
+
echo "$CERTIFICATE_P12" | base64 --decode > certificate.p12
|
|
152
|
+
security import certificate.p12 -P "$CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
|
|
153
|
+
security list-keychain -d user -s $KEYCHAIN_PATH
|
|
154
|
+
|
|
155
|
+
# Allow codesign to access keychain
|
|
156
|
+
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
|
157
|
+
|
|
158
|
+
- name: Install Provisioning Profile
|
|
159
|
+
env:
|
|
160
|
+
PROVISIONING_PROFILE: ${{ secrets.APPLE_PROVISIONING_PROFILE }}
|
|
161
|
+
run: |
|
|
162
|
+
echo "$PROVISIONING_PROFILE" | base64 --decode > profile.mobileprovision
|
|
163
|
+
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
|
|
164
|
+
cp profile.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/
|
|
165
|
+
|
|
166
|
+
- name: Build and Archive
|
|
167
|
+
run: |
|
|
168
|
+
xcodebuild archive \
|
|
169
|
+
-project "${{ env.PROJECT_PATH }}" \
|
|
170
|
+
-scheme "${{ env.SCHEME }}" \
|
|
171
|
+
-configuration Release \
|
|
172
|
+
-archivePath build/CraftApp.xcarchive \
|
|
173
|
+
| xcpretty
|
|
174
|
+
|
|
175
|
+
- name: Export IPA
|
|
176
|
+
run: |
|
|
177
|
+
xcodebuild -exportArchive \
|
|
178
|
+
-archivePath build/CraftApp.xcarchive \
|
|
179
|
+
-exportPath build/export \
|
|
180
|
+
-exportOptionsPlist ios/ExportOptions.plist \
|
|
181
|
+
| xcpretty
|
|
182
|
+
|
|
183
|
+
- name: Upload IPA
|
|
184
|
+
uses: actions/upload-artifact@v4
|
|
185
|
+
with:
|
|
186
|
+
name: ios-ipa
|
|
187
|
+
path: build/export/*.ipa
|
|
188
|
+
retention-days: 7
|
|
189
|
+
|
|
190
|
+
- name: Cleanup Keychain
|
|
191
|
+
if: always()
|
|
192
|
+
run: security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Mobile Release Workflow
|
|
2
|
+
# Copy this file to your project's .github/workflows/release.yml
|
|
3
|
+
# Builds both iOS and Android apps on tag push
|
|
4
|
+
|
|
5
|
+
name: Mobile Release
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
tags:
|
|
10
|
+
- 'v*'
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
inputs:
|
|
13
|
+
version:
|
|
14
|
+
description: 'Version number (e.g., 1.2.3)'
|
|
15
|
+
required: true
|
|
16
|
+
|
|
17
|
+
env:
|
|
18
|
+
XCODE_VERSION: '15.0'
|
|
19
|
+
JAVA_VERSION: '17'
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
# ==================== iOS Release ====================
|
|
23
|
+
ios-release:
|
|
24
|
+
name: Build iOS Release
|
|
25
|
+
runs-on: macos-14
|
|
26
|
+
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout
|
|
29
|
+
uses: actions/checkout@v4
|
|
30
|
+
|
|
31
|
+
- name: Select Xcode
|
|
32
|
+
run: sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app
|
|
33
|
+
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: |
|
|
36
|
+
if [ -f "ios/Podfile" ]; then
|
|
37
|
+
cd ios && pod install
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
- name: Set version
|
|
41
|
+
run: |
|
|
42
|
+
VERSION="${{ github.event.inputs.version || github.ref_name }}"
|
|
43
|
+
VERSION="${VERSION#v}" # Remove 'v' prefix if present
|
|
44
|
+
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
|
45
|
+
|
|
46
|
+
# Update Info.plist version
|
|
47
|
+
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $VERSION" ios/CraftApp/Info.plist
|
|
48
|
+
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${{ github.run_number }}" ios/CraftApp/Info.plist
|
|
49
|
+
|
|
50
|
+
- name: Build Archive (unsigned)
|
|
51
|
+
run: |
|
|
52
|
+
xcodebuild archive \
|
|
53
|
+
-project ios/CraftApp.xcodeproj \
|
|
54
|
+
-scheme CraftApp \
|
|
55
|
+
-configuration Release \
|
|
56
|
+
-archivePath build/CraftApp.xcarchive \
|
|
57
|
+
CODE_SIGN_IDENTITY="" \
|
|
58
|
+
CODE_SIGNING_REQUIRED=NO \
|
|
59
|
+
CODE_SIGNING_ALLOWED=NO \
|
|
60
|
+
| xcpretty
|
|
61
|
+
|
|
62
|
+
- name: Upload iOS Archive
|
|
63
|
+
uses: actions/upload-artifact@v4
|
|
64
|
+
with:
|
|
65
|
+
name: ios-release-${{ env.VERSION }}
|
|
66
|
+
path: build/CraftApp.xcarchive
|
|
67
|
+
retention-days: 30
|
|
68
|
+
|
|
69
|
+
# ==================== Android Release ====================
|
|
70
|
+
android-release:
|
|
71
|
+
name: Build Android Release
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
|
|
74
|
+
steps:
|
|
75
|
+
- name: Checkout
|
|
76
|
+
uses: actions/checkout@v4
|
|
77
|
+
|
|
78
|
+
- name: Set up JDK
|
|
79
|
+
uses: actions/setup-java@v4
|
|
80
|
+
with:
|
|
81
|
+
java-version: ${{ env.JAVA_VERSION }}
|
|
82
|
+
distribution: 'temurin'
|
|
83
|
+
cache: 'gradle'
|
|
84
|
+
|
|
85
|
+
- name: Set version
|
|
86
|
+
run: |
|
|
87
|
+
VERSION="${{ github.event.inputs.version || github.ref_name }}"
|
|
88
|
+
VERSION="${VERSION#v}" # Remove 'v' prefix if present
|
|
89
|
+
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
|
90
|
+
|
|
91
|
+
# Update build.gradle version
|
|
92
|
+
sed -i "s/versionName \".*\"/versionName \"$VERSION\"/" android/app/build.gradle
|
|
93
|
+
sed -i "s/versionCode [0-9]*/versionCode ${{ github.run_number }}/" android/app/build.gradle
|
|
94
|
+
|
|
95
|
+
- name: Grant execute permission
|
|
96
|
+
run: chmod +x android/gradlew
|
|
97
|
+
|
|
98
|
+
- name: Build Release APK
|
|
99
|
+
working-directory: android
|
|
100
|
+
run: ./gradlew assembleRelease
|
|
101
|
+
|
|
102
|
+
- name: Build Release Bundle
|
|
103
|
+
working-directory: android
|
|
104
|
+
run: ./gradlew bundleRelease
|
|
105
|
+
|
|
106
|
+
- name: Upload Android APK
|
|
107
|
+
uses: actions/upload-artifact@v4
|
|
108
|
+
with:
|
|
109
|
+
name: android-apk-${{ env.VERSION }}
|
|
110
|
+
path: android/app/build/outputs/apk/release/*.apk
|
|
111
|
+
retention-days: 30
|
|
112
|
+
|
|
113
|
+
- name: Upload Android Bundle
|
|
114
|
+
uses: actions/upload-artifact@v4
|
|
115
|
+
with:
|
|
116
|
+
name: android-bundle-${{ env.VERSION }}
|
|
117
|
+
path: android/app/build/outputs/bundle/release/*.aab
|
|
118
|
+
retention-days: 30
|
|
119
|
+
|
|
120
|
+
# ==================== Create GitHub Release ====================
|
|
121
|
+
create-release:
|
|
122
|
+
name: Create GitHub Release
|
|
123
|
+
runs-on: ubuntu-latest
|
|
124
|
+
needs: [ios-release, android-release]
|
|
125
|
+
permissions:
|
|
126
|
+
contents: write
|
|
127
|
+
|
|
128
|
+
steps:
|
|
129
|
+
- name: Checkout
|
|
130
|
+
uses: actions/checkout@v4
|
|
131
|
+
|
|
132
|
+
- name: Set version
|
|
133
|
+
run: |
|
|
134
|
+
VERSION="${{ github.event.inputs.version || github.ref_name }}"
|
|
135
|
+
VERSION="${VERSION#v}"
|
|
136
|
+
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
|
137
|
+
|
|
138
|
+
- name: Download iOS Artifact
|
|
139
|
+
uses: actions/download-artifact@v4
|
|
140
|
+
with:
|
|
141
|
+
name: ios-release-${{ env.VERSION }}
|
|
142
|
+
path: release/ios
|
|
143
|
+
|
|
144
|
+
- name: Download Android APK
|
|
145
|
+
uses: actions/download-artifact@v4
|
|
146
|
+
with:
|
|
147
|
+
name: android-apk-${{ env.VERSION }}
|
|
148
|
+
path: release/android
|
|
149
|
+
|
|
150
|
+
- name: Download Android Bundle
|
|
151
|
+
uses: actions/download-artifact@v4
|
|
152
|
+
with:
|
|
153
|
+
name: android-bundle-${{ env.VERSION }}
|
|
154
|
+
path: release/android
|
|
155
|
+
|
|
156
|
+
- name: Create Zip Archives
|
|
157
|
+
run: |
|
|
158
|
+
cd release
|
|
159
|
+
zip -r ios-archive-${{ env.VERSION }}.zip ios/
|
|
160
|
+
mv android/*.apk . 2>/dev/null || true
|
|
161
|
+
mv android/*.aab . 2>/dev/null || true
|
|
162
|
+
|
|
163
|
+
- name: Create Release
|
|
164
|
+
uses: softprops/action-gh-release@v1
|
|
165
|
+
with:
|
|
166
|
+
name: v${{ env.VERSION }}
|
|
167
|
+
tag_name: ${{ github.ref_name }}
|
|
168
|
+
draft: true
|
|
169
|
+
generate_release_notes: true
|
|
170
|
+
files: |
|
|
171
|
+
release/ios-archive-*.zip
|
|
172
|
+
release/*.apk
|
|
173
|
+
release/*.aab
|
|
174
|
+
env:
|
|
175
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# iOS Test Workflow
|
|
2
|
+
# Runs unit and UI tests on iOS simulators
|
|
3
|
+
# Supports multiple iOS versions and device types
|
|
4
|
+
|
|
5
|
+
name: iOS Tests
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
branches: [main, develop]
|
|
10
|
+
paths:
|
|
11
|
+
- 'ios/**'
|
|
12
|
+
- '.github/workflows/ios-test.yml'
|
|
13
|
+
pull_request:
|
|
14
|
+
branches: [main, develop]
|
|
15
|
+
paths:
|
|
16
|
+
- 'ios/**'
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
inputs:
|
|
19
|
+
ios_version:
|
|
20
|
+
description: 'iOS version to test'
|
|
21
|
+
required: false
|
|
22
|
+
default: '17.2'
|
|
23
|
+
device:
|
|
24
|
+
description: 'Simulator device'
|
|
25
|
+
required: false
|
|
26
|
+
default: 'iPhone 15'
|
|
27
|
+
|
|
28
|
+
env:
|
|
29
|
+
DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer
|
|
30
|
+
# Update these for your project
|
|
31
|
+
SCHEME: CraftApp
|
|
32
|
+
PROJECT_PATH: ios/CraftApp.xcodeproj
|
|
33
|
+
# Or use workspace:
|
|
34
|
+
# WORKSPACE_PATH: ios/CraftApp.xcworkspace
|
|
35
|
+
|
|
36
|
+
jobs:
|
|
37
|
+
unit-tests:
|
|
38
|
+
name: Unit Tests
|
|
39
|
+
runs-on: macos-14
|
|
40
|
+
timeout-minutes: 30
|
|
41
|
+
|
|
42
|
+
strategy:
|
|
43
|
+
fail-fast: false
|
|
44
|
+
matrix:
|
|
45
|
+
include:
|
|
46
|
+
- ios: '17.2'
|
|
47
|
+
device: 'iPhone 15'
|
|
48
|
+
- ios: '16.4'
|
|
49
|
+
device: 'iPhone 14'
|
|
50
|
+
# Add more combinations as needed
|
|
51
|
+
|
|
52
|
+
steps:
|
|
53
|
+
- name: Checkout
|
|
54
|
+
uses: actions/checkout@v4
|
|
55
|
+
|
|
56
|
+
- name: Select Xcode
|
|
57
|
+
run: sudo xcode-select -s /Applications/Xcode_15.2.app
|
|
58
|
+
|
|
59
|
+
- name: Show Xcode version
|
|
60
|
+
run: xcodebuild -version
|
|
61
|
+
|
|
62
|
+
- name: List available simulators
|
|
63
|
+
run: xcrun simctl list devices available
|
|
64
|
+
|
|
65
|
+
- name: Cache CocoaPods
|
|
66
|
+
uses: actions/cache@v4
|
|
67
|
+
with:
|
|
68
|
+
path: ios/Pods
|
|
69
|
+
key: ${{ runner.os }}-pods-${{ hashFiles('ios/Podfile.lock') }}
|
|
70
|
+
restore-keys: |
|
|
71
|
+
${{ runner.os }}-pods-
|
|
72
|
+
|
|
73
|
+
- name: Install CocoaPods
|
|
74
|
+
if: hashFiles('ios/Podfile') != ''
|
|
75
|
+
run: |
|
|
76
|
+
cd ios
|
|
77
|
+
pod install --repo-update
|
|
78
|
+
|
|
79
|
+
- name: Cache Swift Package Manager
|
|
80
|
+
uses: actions/cache@v4
|
|
81
|
+
with:
|
|
82
|
+
path: |
|
|
83
|
+
~/Library/Caches/org.swift.swiftpm
|
|
84
|
+
~/Library/Developer/Xcode/DerivedData/**/SourcePackages
|
|
85
|
+
key: ${{ runner.os }}-spm-${{ hashFiles('ios/**/Package.resolved') }}
|
|
86
|
+
restore-keys: |
|
|
87
|
+
${{ runner.os }}-spm-
|
|
88
|
+
|
|
89
|
+
- name: Run Unit Tests
|
|
90
|
+
run: |
|
|
91
|
+
set -o pipefail
|
|
92
|
+
xcodebuild test \
|
|
93
|
+
-project "$PROJECT_PATH" \
|
|
94
|
+
-scheme "$SCHEME" \
|
|
95
|
+
-destination "platform=iOS Simulator,OS=${{ matrix.ios }},name=${{ matrix.device }}" \
|
|
96
|
+
-resultBundlePath TestResults-${{ matrix.ios }}.xcresult \
|
|
97
|
+
-enableCodeCoverage YES \
|
|
98
|
+
CODE_SIGNING_ALLOWED=NO \
|
|
99
|
+
| xcpretty --color --report junit --output TestResults-${{ matrix.ios }}.xml
|
|
100
|
+
|
|
101
|
+
- name: Upload Test Results
|
|
102
|
+
uses: actions/upload-artifact@v4
|
|
103
|
+
if: always()
|
|
104
|
+
with:
|
|
105
|
+
name: test-results-ios-${{ matrix.ios }}
|
|
106
|
+
path: |
|
|
107
|
+
TestResults-${{ matrix.ios }}.xcresult
|
|
108
|
+
TestResults-${{ matrix.ios }}.xml
|
|
109
|
+
retention-days: 14
|
|
110
|
+
|
|
111
|
+
- name: Generate Coverage Report
|
|
112
|
+
if: success()
|
|
113
|
+
run: |
|
|
114
|
+
xcrun xccov view --report --json TestResults-${{ matrix.ios }}.xcresult > coverage-${{ matrix.ios }}.json
|
|
115
|
+
echo "## Coverage Summary" >> $GITHUB_STEP_SUMMARY
|
|
116
|
+
cat coverage-${{ matrix.ios }}.json | jq -r '.targets[] | "- \(.name): \(.lineCoverage * 100 | floor)%"' >> $GITHUB_STEP_SUMMARY
|
|
117
|
+
|
|
118
|
+
- name: Upload Coverage
|
|
119
|
+
uses: actions/upload-artifact@v4
|
|
120
|
+
if: success()
|
|
121
|
+
with:
|
|
122
|
+
name: coverage-ios-${{ matrix.ios }}
|
|
123
|
+
path: coverage-${{ matrix.ios }}.json
|
|
124
|
+
retention-days: 14
|
|
125
|
+
|
|
126
|
+
ui-tests:
|
|
127
|
+
name: UI Tests
|
|
128
|
+
runs-on: macos-14
|
|
129
|
+
timeout-minutes: 45
|
|
130
|
+
needs: unit-tests
|
|
131
|
+
|
|
132
|
+
steps:
|
|
133
|
+
- name: Checkout
|
|
134
|
+
uses: actions/checkout@v4
|
|
135
|
+
|
|
136
|
+
- name: Select Xcode
|
|
137
|
+
run: sudo xcode-select -s /Applications/Xcode_15.2.app
|
|
138
|
+
|
|
139
|
+
- name: Cache CocoaPods
|
|
140
|
+
uses: actions/cache@v4
|
|
141
|
+
with:
|
|
142
|
+
path: ios/Pods
|
|
143
|
+
key: ${{ runner.os }}-pods-${{ hashFiles('ios/Podfile.lock') }}
|
|
144
|
+
restore-keys: |
|
|
145
|
+
${{ runner.os }}-pods-
|
|
146
|
+
|
|
147
|
+
- name: Install CocoaPods
|
|
148
|
+
if: hashFiles('ios/Podfile') != ''
|
|
149
|
+
run: |
|
|
150
|
+
cd ios
|
|
151
|
+
pod install --repo-update
|
|
152
|
+
|
|
153
|
+
- name: Boot Simulator
|
|
154
|
+
run: |
|
|
155
|
+
DEVICE_ID=$(xcrun simctl list devices available --json | jq -r '.devices["com.apple.CoreSimulator.SimRuntime.iOS-17-2"][] | select(.name == "iPhone 15") | .udid' | head -1)
|
|
156
|
+
xcrun simctl boot "$DEVICE_ID" || true
|
|
157
|
+
# Wait for simulator to be ready
|
|
158
|
+
sleep 10
|
|
159
|
+
|
|
160
|
+
- name: Run UI Tests
|
|
161
|
+
run: |
|
|
162
|
+
set -o pipefail
|
|
163
|
+
xcodebuild test \
|
|
164
|
+
-project "$PROJECT_PATH" \
|
|
165
|
+
-scheme "${SCHEME}UITests" \
|
|
166
|
+
-destination "platform=iOS Simulator,OS=17.2,name=iPhone 15" \
|
|
167
|
+
-resultBundlePath UITestResults.xcresult \
|
|
168
|
+
CODE_SIGNING_ALLOWED=NO \
|
|
169
|
+
| xcpretty --color --report junit --output UITestResults.xml
|
|
170
|
+
|
|
171
|
+
- name: Upload UI Test Results
|
|
172
|
+
uses: actions/upload-artifact@v4
|
|
173
|
+
if: always()
|
|
174
|
+
with:
|
|
175
|
+
name: ui-test-results
|
|
176
|
+
path: |
|
|
177
|
+
UITestResults.xcresult
|
|
178
|
+
UITestResults.xml
|
|
179
|
+
retention-days: 14
|
|
180
|
+
|
|
181
|
+
- name: Capture Screenshots on Failure
|
|
182
|
+
if: failure()
|
|
183
|
+
run: |
|
|
184
|
+
mkdir -p screenshots
|
|
185
|
+
xcrun simctl io booted screenshot screenshots/failure-$(date +%s).png
|
|
186
|
+
|
|
187
|
+
- name: Upload Failure Screenshots
|
|
188
|
+
uses: actions/upload-artifact@v4
|
|
189
|
+
if: failure()
|
|
190
|
+
with:
|
|
191
|
+
name: failure-screenshots
|
|
192
|
+
path: screenshots/
|
|
193
|
+
retention-days: 7
|
|
194
|
+
|
|
195
|
+
snapshot-tests:
|
|
196
|
+
name: Snapshot Tests
|
|
197
|
+
runs-on: macos-14
|
|
198
|
+
timeout-minutes: 30
|
|
199
|
+
if: github.event_name == 'pull_request'
|
|
200
|
+
|
|
201
|
+
steps:
|
|
202
|
+
- name: Checkout
|
|
203
|
+
uses: actions/checkout@v4
|
|
204
|
+
with:
|
|
205
|
+
fetch-depth: 0
|
|
206
|
+
|
|
207
|
+
- name: Select Xcode
|
|
208
|
+
run: sudo xcode-select -s /Applications/Xcode_15.2.app
|
|
209
|
+
|
|
210
|
+
- name: Cache CocoaPods
|
|
211
|
+
uses: actions/cache@v4
|
|
212
|
+
with:
|
|
213
|
+
path: ios/Pods
|
|
214
|
+
key: ${{ runner.os }}-pods-${{ hashFiles('ios/Podfile.lock') }}
|
|
215
|
+
restore-keys: |
|
|
216
|
+
${{ runner.os }}-pods-
|
|
217
|
+
|
|
218
|
+
- name: Install CocoaPods
|
|
219
|
+
if: hashFiles('ios/Podfile') != ''
|
|
220
|
+
run: |
|
|
221
|
+
cd ios
|
|
222
|
+
pod install --repo-update
|
|
223
|
+
|
|
224
|
+
- name: Run Snapshot Tests
|
|
225
|
+
run: |
|
|
226
|
+
set -o pipefail
|
|
227
|
+
xcodebuild test \
|
|
228
|
+
-project "$PROJECT_PATH" \
|
|
229
|
+
-scheme "${SCHEME}SnapshotTests" \
|
|
230
|
+
-destination "platform=iOS Simulator,OS=17.2,name=iPhone 15" \
|
|
231
|
+
-resultBundlePath SnapshotTestResults.xcresult \
|
|
232
|
+
CODE_SIGNING_ALLOWED=NO \
|
|
233
|
+
| xcpretty --color
|
|
234
|
+
|
|
235
|
+
- name: Upload Snapshot Differences
|
|
236
|
+
uses: actions/upload-artifact@v4
|
|
237
|
+
if: failure()
|
|
238
|
+
with:
|
|
239
|
+
name: snapshot-differences
|
|
240
|
+
path: |
|
|
241
|
+
ios/**/FailureDiffs/
|
|
242
|
+
SnapshotTestResults.xcresult
|
|
243
|
+
retention-days: 14
|
|
244
|
+
|
|
245
|
+
test-summary:
|
|
246
|
+
name: Test Summary
|
|
247
|
+
runs-on: ubuntu-latest
|
|
248
|
+
needs: [unit-tests, ui-tests]
|
|
249
|
+
if: always()
|
|
250
|
+
|
|
251
|
+
steps:
|
|
252
|
+
- name: Download all artifacts
|
|
253
|
+
uses: actions/download-artifact@v4
|
|
254
|
+
with:
|
|
255
|
+
path: artifacts
|
|
256
|
+
|
|
257
|
+
- name: Generate Summary
|
|
258
|
+
run: |
|
|
259
|
+
echo "## iOS Test Results" >> $GITHUB_STEP_SUMMARY
|
|
260
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
261
|
+
|
|
262
|
+
if [ -d "artifacts" ]; then
|
|
263
|
+
echo "### Test Artifacts" >> $GITHUB_STEP_SUMMARY
|
|
264
|
+
find artifacts -name "*.xml" -exec echo "- {}" \; >> $GITHUB_STEP_SUMMARY
|
|
265
|
+
fi
|
|
266
|
+
|
|
267
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
268
|
+
echo "### Jobs Status" >> $GITHUB_STEP_SUMMARY
|
|
269
|
+
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
|
|
270
|
+
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
|
|
271
|
+
echo "| Unit Tests | ${{ needs.unit-tests.result }} |" >> $GITHUB_STEP_SUMMARY
|
|
272
|
+
echo "| UI Tests | ${{ needs.ui-tests.result }} |" >> $GITHUB_STEP_SUMMARY
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: {{APP_NAME}}
|
|
2
|
+
options:
|
|
3
|
+
bundleIdPrefix: {{BUNDLE_ID_PREFIX}}
|
|
4
|
+
deploymentTarget:
|
|
5
|
+
iOS: "{{IOS_VERSION}}"
|
|
6
|
+
settings:
|
|
7
|
+
MARKETING_VERSION: "{{VERSION}}"
|
|
8
|
+
CURRENT_PROJECT_VERSION: "{{BUILD_NUMBER}}"
|
|
9
|
+
CODE_SIGN_STYLE: Automatic
|
|
10
|
+
DEVELOPMENT_TEAM: "{{TEAM_ID}}"
|
|
11
|
+
targets:
|
|
12
|
+
{{APP_NAME}}:
|
|
13
|
+
type: application
|
|
14
|
+
platform: iOS
|
|
15
|
+
sources:
|
|
16
|
+
- Sources
|
|
17
|
+
- Shared
|
|
18
|
+
- path: dist
|
|
19
|
+
type: folder
|
|
20
|
+
buildPhase: resources
|
|
21
|
+
- path: craft.config.json
|
|
22
|
+
optional: true
|
|
23
|
+
buildPhase: resources
|
|
24
|
+
- path: Assets.xcassets
|
|
25
|
+
buildPhase: resources
|
|
26
|
+
- path: PrivacyInfo.xcprivacy
|
|
27
|
+
buildPhase: resources
|
|
28
|
+
settings:
|
|
29
|
+
INFOPLIST_FILE: Info.plist
|
|
30
|
+
CODE_SIGN_ENTITLEMENTS: Craft.entitlements
|
|
31
|
+
PRODUCT_BUNDLE_IDENTIFIER: {{BUNDLE_ID}}
|
|
32
|
+
TARGETED_DEVICE_FAMILY: "{{DEVICE_FAMILIES}}"
|
|
33
|
+
SWIFT_VERSION: "5.0"
|
|
34
|
+
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
|
|
35
|
+
{{NATIVE_DEPENDENCIES}}
|
|
36
|
+
{{NATIVE_TARGETS}}
|