@craft-native/android 0.0.72

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.
@@ -0,0 +1,329 @@
1
+ # Android Test Workflow
2
+ # Runs unit tests, instrumented tests, and lint checks
3
+ # Supports multiple API levels and device configurations
4
+
5
+ name: Android Tests
6
+
7
+ on:
8
+ push:
9
+ branches: [main, develop]
10
+ paths:
11
+ - 'android/**'
12
+ - '.github/workflows/android-test.yml'
13
+ pull_request:
14
+ branches: [main, develop]
15
+ paths:
16
+ - 'android/**'
17
+ workflow_dispatch:
18
+ inputs:
19
+ api_level:
20
+ description: 'Android API level'
21
+ required: false
22
+ default: '34'
23
+ run_instrumented:
24
+ description: 'Run instrumented tests'
25
+ required: false
26
+ default: 'true'
27
+ type: boolean
28
+
29
+ env:
30
+ JAVA_VERSION: '17'
31
+ GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4g -Dorg.gradle.daemon=false"
32
+
33
+ jobs:
34
+ lint:
35
+ name: Lint & Static Analysis
36
+ runs-on: ubuntu-latest
37
+ timeout-minutes: 15
38
+
39
+ steps:
40
+ - name: Checkout
41
+ uses: actions/checkout@v4
42
+
43
+ - name: Set up JDK
44
+ uses: actions/setup-java@v4
45
+ with:
46
+ java-version: ${{ env.JAVA_VERSION }}
47
+ distribution: 'temurin'
48
+
49
+ - name: Setup Gradle
50
+ uses: gradle/actions/setup-gradle@v3
51
+ with:
52
+ cache-read-only: ${{ github.ref != 'refs/heads/main' }}
53
+
54
+ - name: Run Lint
55
+ run: |
56
+ cd android
57
+ ./gradlew lint
58
+
59
+ - name: Upload Lint Results
60
+ uses: actions/upload-artifact@v4
61
+ if: always()
62
+ with:
63
+ name: lint-results
64
+ path: |
65
+ android/app/build/reports/lint-results*.html
66
+ android/app/build/reports/lint-results*.xml
67
+ retention-days: 14
68
+
69
+ - name: Run Detekt (if configured)
70
+ continue-on-error: true
71
+ run: |
72
+ cd android
73
+ if ./gradlew tasks --all | grep -q "detekt"; then
74
+ ./gradlew detekt
75
+ fi
76
+
77
+ - name: Comment on PR with Lint Results
78
+ uses: actions/github-script@v7
79
+ if: github.event_name == 'pull_request' && failure()
80
+ with:
81
+ script: |
82
+ const fs = require('fs');
83
+ const lintReport = 'android/app/build/reports/lint-results-debug.xml';
84
+ if (fs.existsSync(lintReport)) {
85
+ github.rest.issues.createComment({
86
+ issue_number: context.issue.number,
87
+ owner: context.repo.owner,
88
+ repo: context.repo.repo,
89
+ body: '⚠️ Lint checks found issues. Please review the artifacts for details.'
90
+ });
91
+ }
92
+
93
+ unit-tests:
94
+ name: Unit Tests
95
+ runs-on: ubuntu-latest
96
+ timeout-minutes: 20
97
+
98
+ steps:
99
+ - name: Checkout
100
+ uses: actions/checkout@v4
101
+
102
+ - name: Set up JDK
103
+ uses: actions/setup-java@v4
104
+ with:
105
+ java-version: ${{ env.JAVA_VERSION }}
106
+ distribution: 'temurin'
107
+
108
+ - name: Setup Gradle
109
+ uses: gradle/actions/setup-gradle@v3
110
+ with:
111
+ cache-read-only: ${{ github.ref != 'refs/heads/main' }}
112
+
113
+ - name: Run Unit Tests
114
+ run: |
115
+ cd android
116
+ ./gradlew testDebugUnitTest
117
+
118
+ - name: Upload Test Results
119
+ uses: actions/upload-artifact@v4
120
+ if: always()
121
+ with:
122
+ name: unit-test-results
123
+ path: |
124
+ android/app/build/reports/tests/
125
+ android/app/build/test-results/
126
+ retention-days: 14
127
+
128
+ - name: Publish Test Report
129
+ uses: mikepenz/action-junit-report@v4
130
+ if: always()
131
+ with:
132
+ report_paths: 'android/app/build/test-results/**/TEST-*.xml'
133
+ check_name: 'Unit Test Results'
134
+ fail_on_failure: true
135
+
136
+ - name: Generate Coverage Report
137
+ run: |
138
+ cd android
139
+ ./gradlew jacocoTestReport || true
140
+
141
+ - name: Upload Coverage
142
+ uses: actions/upload-artifact@v4
143
+ if: success()
144
+ with:
145
+ name: coverage-report
146
+ path: android/app/build/reports/jacoco/
147
+ retention-days: 14
148
+
149
+ instrumented-tests:
150
+ name: Instrumented Tests (API ${{ matrix.api-level }})
151
+ runs-on: ubuntu-latest
152
+ timeout-minutes: 45
153
+ needs: unit-tests
154
+
155
+ strategy:
156
+ fail-fast: false
157
+ matrix:
158
+ include:
159
+ - api-level: 34
160
+ target: google_apis
161
+ arch: x86_64
162
+ - api-level: 31
163
+ target: google_apis
164
+ arch: x86_64
165
+ - api-level: 28
166
+ target: google_apis
167
+ arch: x86_64
168
+
169
+ steps:
170
+ - name: Checkout
171
+ uses: actions/checkout@v4
172
+
173
+ - name: Set up JDK
174
+ uses: actions/setup-java@v4
175
+ with:
176
+ java-version: ${{ env.JAVA_VERSION }}
177
+ distribution: 'temurin'
178
+
179
+ - name: Setup Gradle
180
+ uses: gradle/actions/setup-gradle@v3
181
+ with:
182
+ cache-read-only: ${{ github.ref != 'refs/heads/main' }}
183
+
184
+ - name: Enable KVM group perms
185
+ run: |
186
+ echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
187
+ sudo udevadm control --reload-rules
188
+ sudo udevadm trigger --name-match=kvm
189
+
190
+ - name: AVD cache
191
+ uses: actions/cache@v4
192
+ id: avd-cache
193
+ with:
194
+ path: |
195
+ ~/.android/avd/*
196
+ ~/.android/adb*
197
+ key: avd-${{ matrix.api-level }}-${{ matrix.target }}-${{ matrix.arch }}
198
+
199
+ - name: Create AVD and generate snapshot for caching
200
+ if: steps.avd-cache.outputs.cache-hit != 'true'
201
+ uses: reactivecircus/android-emulator-runner@v2
202
+ with:
203
+ api-level: ${{ matrix.api-level }}
204
+ target: ${{ matrix.target }}
205
+ arch: ${{ matrix.arch }}
206
+ force-avd-creation: false
207
+ emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
208
+ disable-animations: true
209
+ script: echo "Generated AVD snapshot for caching"
210
+
211
+ - name: Run Instrumented Tests
212
+ uses: reactivecircus/android-emulator-runner@v2
213
+ with:
214
+ api-level: ${{ matrix.api-level }}
215
+ target: ${{ matrix.target }}
216
+ arch: ${{ matrix.arch }}
217
+ force-avd-creation: false
218
+ emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
219
+ disable-animations: true
220
+ script: |
221
+ cd android
222
+ ./gradlew connectedDebugAndroidTest
223
+
224
+ - name: Upload Instrumented Test Results
225
+ uses: actions/upload-artifact@v4
226
+ if: always()
227
+ with:
228
+ name: instrumented-test-results-api${{ matrix.api-level }}
229
+ path: |
230
+ android/app/build/reports/androidTests/
231
+ android/app/build/outputs/androidTest-results/
232
+ retention-days: 14
233
+
234
+ - name: Publish Instrumented Test Report
235
+ uses: mikepenz/action-junit-report@v4
236
+ if: always()
237
+ with:
238
+ report_paths: 'android/app/build/outputs/androidTest-results/**/*.xml'
239
+ check_name: 'Instrumented Test Results (API ${{ matrix.api-level }})'
240
+ fail_on_failure: true
241
+
242
+ screenshot-tests:
243
+ name: Screenshot Tests
244
+ runs-on: ubuntu-latest
245
+ timeout-minutes: 30
246
+ if: github.event_name == 'pull_request'
247
+
248
+ steps:
249
+ - name: Checkout
250
+ uses: actions/checkout@v4
251
+ with:
252
+ fetch-depth: 0
253
+
254
+ - name: Set up JDK
255
+ uses: actions/setup-java@v4
256
+ with:
257
+ java-version: ${{ env.JAVA_VERSION }}
258
+ distribution: 'temurin'
259
+
260
+ - name: Setup Gradle
261
+ uses: gradle/actions/setup-gradle@v3
262
+
263
+ - name: Enable KVM
264
+ run: |
265
+ echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
266
+ sudo udevadm control --reload-rules
267
+ sudo udevadm trigger --name-match=kvm
268
+
269
+ - name: Run Screenshot Tests
270
+ uses: reactivecircus/android-emulator-runner@v2
271
+ with:
272
+ api-level: 34
273
+ target: google_apis
274
+ arch: x86_64
275
+ force-avd-creation: false
276
+ emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim
277
+ disable-animations: true
278
+ script: |
279
+ cd android
280
+ ./gradlew verifyPaparazziDebug || ./gradlew recordPaparazziDebug
281
+
282
+ - name: Upload Screenshot Differences
283
+ uses: actions/upload-artifact@v4
284
+ if: failure()
285
+ with:
286
+ name: screenshot-differences
287
+ path: |
288
+ android/app/build/paparazzi/
289
+ android/app/out/failures/
290
+ retention-days: 14
291
+
292
+ test-summary:
293
+ name: Test Summary
294
+ runs-on: ubuntu-latest
295
+ needs: [lint, unit-tests, instrumented-tests]
296
+ if: always()
297
+
298
+ steps:
299
+ - name: Download all artifacts
300
+ uses: actions/download-artifact@v4
301
+ with:
302
+ path: artifacts
303
+
304
+ - name: Generate Summary
305
+ run: |
306
+ echo "## Android Test Results" >> $GITHUB_STEP_SUMMARY
307
+ echo "" >> $GITHUB_STEP_SUMMARY
308
+
309
+ echo "### Jobs Status" >> $GITHUB_STEP_SUMMARY
310
+ echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
311
+ echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
312
+ echo "| Lint | ${{ needs.lint.result }} |" >> $GITHUB_STEP_SUMMARY
313
+ echo "| Unit Tests | ${{ needs.unit-tests.result }} |" >> $GITHUB_STEP_SUMMARY
314
+ echo "| Instrumented Tests | ${{ needs.instrumented-tests.result }} |" >> $GITHUB_STEP_SUMMARY
315
+
316
+ echo "" >> $GITHUB_STEP_SUMMARY
317
+ echo "### Test Artifacts" >> $GITHUB_STEP_SUMMARY
318
+
319
+ if [ -d "artifacts" ]; then
320
+ find artifacts -type f -name "*.xml" -o -name "*.html" | head -20 | while read f; do
321
+ echo "- $f" >> $GITHUB_STEP_SUMMARY
322
+ done
323
+ fi
324
+
325
+ - name: Check for failures
326
+ if: needs.lint.result == 'failure' || needs.unit-tests.result == 'failure' || needs.instrumented-tests.result == 'failure'
327
+ run: |
328
+ echo "❌ Some tests failed. Please review the artifacts for details."
329
+ exit 1
@@ -0,0 +1,9 @@
1
+ # Preserve the JavaScript bridge contract and its annotated methods when R8
2
+ # optimizes release builds. These classes are reached from WebView by name.
3
+ -keepattributes RuntimeVisibleAnnotations,RuntimeInvisibleAnnotations
4
+ -keepclassmembers class * {
5
+ @android.webkit.JavascriptInterface <methods>;
6
+ }
7
+ -keep class {{PACKAGE_NAME}}.CraftBridge { *; }
8
+ -keep class {{PACKAGE_NAME}}.CraftHealthConnect { *; }
9
+ -keep class {{PACKAGE_NAME}}.LocationRecordingService { *; }
@@ -0,0 +1,18 @@
1
+ pluginManagement {
2
+ repositories {
3
+ google()
4
+ mavenCentral()
5
+ gradlePluginPortal()
6
+ }
7
+ }
8
+
9
+ dependencyResolutionManagement {
10
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
11
+ repositories {
12
+ google()
13
+ mavenCentral()
14
+ }
15
+ }
16
+
17
+ rootProject.name = "{{APP_NAME}}"
18
+ include(":app")