Skip to content

Commit cf79256

Browse files
Merge pull request #207 from prey/chore/mdm-serial-number
MDM Restrictions Support
2 parents bfad9a3 + b5a9114 commit cf79256

25 files changed

+1583
-330
lines changed

.DS_Store

6 KB
Binary file not shown.

.github/workflows/android-ci.yml

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Android CI Pipeline
2+
# Runs 3 jobs in parallel:
3+
# - Lint: static analysis (~2 min)
4+
# - Unit Tests: Robolectric tests on JVM, no emulator needed (~1 min)
5+
# - Instrumented Tests: runs on Android emulator (~8-10 min)
6+
# Total time is the slowest job (~10 min).
7+
# If the emulator job is unstable in CI, you can safely disable it
8+
# and rely on Robolectric tests only.
9+
10+
name: Android CI
11+
12+
on:
13+
push:
14+
branches: [ master ]
15+
pull_request:
16+
branches: [ master ]
17+
18+
jobs:
19+
lint:
20+
name: Lint
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- name: Set up JDK 17
26+
uses: actions/setup-java@v4
27+
with:
28+
java-version: '17'
29+
distribution: 'temurin'
30+
31+
- name: Setup Gradle
32+
uses: gradle/actions/setup-gradle@v4
33+
with:
34+
validate-wrappers: false
35+
36+
- name: Create CI dummy files
37+
run: |
38+
echo '{"project_info":{"project_number":"0","project_id":"prey-ci","storage_bucket":"prey-ci.appspot.com"},"client":[{"client_info":{"mobilesdk_app_id":"1:0:android:0","android_client_info":{"package_name":"com.prey"}},"api_key":[{"current_key":"fake"}]}],"configuration_version":"1"}' > app/google-services.json
39+
printf 'properties\napi-key-batch=\nemail-batch=\nask-for-name-batch=false\ntoken=\n' > app/src/main/res/raw/batch.properties
40+
echo "google_maps_key=fake-key-for-ci" > secrets.properties
41+
printf 'properties\nprey-campaign=ci\nprey-panel=https://localhost\ngcm-id-prefix=0\nprey-domain=localhost\nprey-subdomain=panel\nemail-feedback=ci@test.com\nsubject-feedback=CI\napi-v2=/api/v2/\nscheduled=false\nminute-scheduled=15\ntimeout-report=60\ngeofence-maximum-accuracy=100\nprey-jwt=fake\nprey-google-play=https://play.google.com\ngeofence-loitering-delay=300000\ndistance-location=50\ngeofence-notification-responsiveness=30000\ndistance-aware=100\nradius-aware=200\nprey-terms=https://localhost/terms\nprey-terms-es=https://localhost/es/terms\nprey-forgot=https://localhost/forgot\nopen-pin=false\n' > app/src/main/res/raw/config.properties
42+
43+
- name: Run lint
44+
run: ./gradlew lintDebug
45+
46+
- name: Upload lint results
47+
if: always()
48+
uses: actions/upload-artifact@v4
49+
with:
50+
name: lint-results
51+
path: app/build/reports/lint-results-debug.html
52+
53+
unit-test:
54+
name: Unit Tests (Robolectric)
55+
runs-on: ubuntu-latest
56+
steps:
57+
- uses: actions/checkout@v4
58+
59+
- name: Set up JDK 17
60+
uses: actions/setup-java@v4
61+
with:
62+
java-version: '17'
63+
distribution: 'temurin'
64+
65+
- name: Setup Gradle
66+
uses: gradle/actions/setup-gradle@v4
67+
with:
68+
validate-wrappers: false
69+
70+
- name: Create CI dummy files
71+
run: |
72+
echo '{"project_info":{"project_number":"0","project_id":"prey-ci","storage_bucket":"prey-ci.appspot.com"},"client":[{"client_info":{"mobilesdk_app_id":"1:0:android:0","android_client_info":{"package_name":"com.prey"}},"api_key":[{"current_key":"fake"}]}],"configuration_version":"1"}' > app/google-services.json
73+
printf 'properties\napi-key-batch=\nemail-batch=\nask-for-name-batch=false\ntoken=\n' > app/src/main/res/raw/batch.properties
74+
echo "google_maps_key=fake-key-for-ci" > secrets.properties
75+
printf 'properties\nprey-campaign=ci\nprey-panel=https://localhost\ngcm-id-prefix=0\nprey-domain=localhost\nprey-subdomain=panel\nemail-feedback=ci@test.com\nsubject-feedback=CI\napi-v2=/api/v2/\nscheduled=false\nminute-scheduled=15\ntimeout-report=60\ngeofence-maximum-accuracy=100\nprey-jwt=fake\nprey-google-play=https://play.google.com\ngeofence-loitering-delay=300000\ndistance-location=50\ngeofence-notification-responsiveness=30000\ndistance-aware=100\nradius-aware=200\nprey-terms=https://localhost/terms\nprey-terms-es=https://localhost/es/terms\nprey-forgot=https://localhost/forgot\nopen-pin=false\n' > app/src/main/res/raw/config.properties
76+
77+
- name: Run unit tests
78+
run: ./gradlew testDebugUnitTest
79+
80+
- name: Upload unit test results
81+
if: always()
82+
uses: actions/upload-artifact@v4
83+
with:
84+
name: unit-test-results
85+
path: app/build/reports/tests/testDebugUnitTest/
86+
87+
instrumented-test:
88+
name: Instrumented Tests (Emulator)
89+
runs-on: ubuntu-latest
90+
steps:
91+
- uses: actions/checkout@v4
92+
93+
- name: Set up JDK 17
94+
uses: actions/setup-java@v4
95+
with:
96+
java-version: '17'
97+
distribution: 'temurin'
98+
99+
- name: Setup Gradle
100+
uses: gradle/actions/setup-gradle@v4
101+
with:
102+
validate-wrappers: false
103+
104+
- name: Create CI dummy files
105+
run: |
106+
echo '{"project_info":{"project_number":"0","project_id":"prey-ci","storage_bucket":"prey-ci.appspot.com"},"client":[{"client_info":{"mobilesdk_app_id":"1:0:android:0","android_client_info":{"package_name":"com.prey"}},"api_key":[{"current_key":"fake"}]}],"configuration_version":"1"}' > app/google-services.json
107+
printf 'properties\napi-key-batch=\nemail-batch=\nask-for-name-batch=false\ntoken=\n' > app/src/main/res/raw/batch.properties
108+
echo "google_maps_key=fake-key-for-ci" > secrets.properties
109+
printf 'properties\nprey-campaign=ci\nprey-panel=https://localhost\ngcm-id-prefix=0\nprey-domain=localhost\nprey-subdomain=panel\nemail-feedback=ci@test.com\nsubject-feedback=CI\napi-v2=/api/v2/\nscheduled=false\nminute-scheduled=15\ntimeout-report=60\ngeofence-maximum-accuracy=100\nprey-jwt=fake\nprey-google-play=https://play.google.com\ngeofence-loitering-delay=300000\ndistance-location=50\ngeofence-notification-responsiveness=30000\ndistance-aware=100\nradius-aware=200\nprey-terms=https://localhost/terms\nprey-terms-es=https://localhost/es/terms\nprey-forgot=https://localhost/forgot\nopen-pin=false\n' > app/src/main/res/raw/config.properties
110+
111+
- name: Enable KVM
112+
run: |
113+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
114+
sudo udevadm control --reload-rules
115+
sudo udevadm trigger --name-match=kvm
116+
117+
- name: Run instrumented tests
118+
uses: reactivecircus/android-emulator-runner@v2
119+
with:
120+
api-level: 30
121+
arch: x86_64
122+
script: ./gradlew connectedDebugAndroidTest
123+
124+
- name: Upload instrumented test results
125+
if: always()
126+
uses: actions/upload-artifact@v4
127+
with:
128+
name: instrumented-test-results
129+
path: app/build/reports/androidTests/connected/

.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/app/build
2+
/.idea
3+
/.gradle
4+
/app/debug
5+
/app/release
6+
app/google-services.json
7+
/build/reports
8+
secrets.properties
9+
app/src/main/res/raw/batch.properties
10+
app/src/main/res/raw/config.properties
11+
app/build.gradle.dev
12+
local.properties
13+
*.iml

app/build.gradle

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ apply plugin: 'com.android.application'
22
apply plugin: 'com.google.gms.google-services'
33
apply plugin: 'com.google.firebase.crashlytics'
44

5+
// Load secrets for release builds (google_maps_key, signing, etc.)
6+
def secretsFile = rootProject.file("secrets.properties")
7+
def secrets = new Properties()
8+
if (secretsFile.exists()) {
9+
secrets.load(new FileInputStream(secretsFile))
10+
}
11+
512
android {
613
namespace 'com.prey'
714
compileSdk 35
@@ -12,14 +19,17 @@ android {
1219

1320
targetSdk 35
1421

15-
versionCode 396
16-
versionName '2.6.14'
22+
versionCode 397
23+
versionName '2.6.15'
1724

1825
multiDexEnabled true
1926

2027
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
2128
buildConfigField("int", "COMPILE_SDK_VERSION", "35")
29+
// google_maps_key: reads from secrets.properties if available, empty string otherwise
30+
resValue "string", "google_maps_key", secrets.getProperty("google_maps_key", "")
2231
}
32+
2333
buildTypes {
2434
release {
2535
minifyEnabled false
@@ -68,9 +78,10 @@ dependencies {
6878
implementation "androidx.work:work-runtime:2.8.1"
6979

7080
testImplementation 'junit:junit:4.13.2'
81+
testImplementation 'org.robolectric:robolectric:4.14.1'
82+
testImplementation 'androidx.test:core:1.6.1'
83+
testImplementation 'androidx.test.ext:junit:1.2.1'
7184
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
7285
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
7386

7487
}
75-
76-

0 commit comments

Comments
 (0)