Skip to content

Commit e200402

Browse files
Merge branch 'andy_tandem_dev' into andy_tandem
2 parents 162234f + c8b073f commit e200402

334 files changed

Lines changed: 3079 additions & 1838 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.circleci/config.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ jobs:
3535
export ANDROID_SDK_ROOT=/usr/lib/android-sdk
3636
export ANDROID_HOME=/usr/lib/android-sdk
3737
env
38-
./gradlew -Dorg.gradle.jvmargs=-Xmx6g connectedFullDebugAndroidTest
38+
./gradlew \
39+
-Dorg.gradle.jvmargs="-Xmx8g -XX:+UseParallelGC -Xss1024m" \
40+
-Dkotlin.daemon.jvm.options="-Xmx2g" \
41+
-Dkotlin.compiler.execution.strategy="in-process" \
42+
-Dorg.gradle.daemon=true \
43+
connectedFullDebugAndroidTest
3944
4045
- run:
4146
name: Kill emulators
@@ -48,7 +53,12 @@ jobs:
4853
command: |
4954
export ANDROID_SDK_ROOT=/usr/lib/android-sdk
5055
export ANDROID_HOME=/usr/lib/android-sdk
51-
./gradlew -Dorg.gradle.jvmargs=-Xmx6g testFullDebugUnitTest
56+
./gradlew \
57+
-Dorg.gradle.jvmargs="-Xmx8g -XX:+UseParallelGC -Xss1024m" \
58+
-Dkotlin.daemon.jvm.options="-Xmx2g" \
59+
-Dkotlin.compiler.execution.strategy="in-process" \
60+
-Dorg.gradle.daemon=true \
61+
testFullDebugUnitTest
5262
5363
- run:
5464
run: Run jacocoAllDebugReport

.github/workflows/aaps-ci.yml

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
name: AAPS CI
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
buildVariant:
7+
description: 'Select Build Variant'
8+
required: true
9+
default: 'fullRelease'
10+
type: choice
11+
options:
12+
- fullRelease
13+
- fullDebug
14+
- aapsclientRelease
15+
- aapsclientDebug
16+
- aapsclient2Release
17+
- aapsclient2Debug
18+
- pumpcontrolRelease
19+
- pumpcontrolDebug
20+
21+
jobs:
22+
build:
23+
name: Build AAPS
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Decode Secrets Keystore Set and Oauth2 to Env
27+
run: |
28+
if [ -n "${{ secrets.KEYSTORE_SET }}" ]; then
29+
echo "🔐 Decoding KEYSTORE_SET..."
30+
DECODED=$(echo "${{ secrets.KEYSTORE_SET }}" | base64 -d)
31+
32+
KEYSTORE_BASE64=$(echo "$DECODED" | cut -d'|' -f1)
33+
KEYSTORE_PASSWORD=$(echo "$DECODED" | cut -d'|' -f2)
34+
KEY_ALIAS=$(echo "$DECODED" | cut -d'|' -f3)
35+
KEY_PASSWORD=$(echo "$DECODED" | cut -d'|' -f4)
36+
37+
echo "KEYSTORE_BASE64=$KEYSTORE_BASE64" >> $GITHUB_ENV
38+
echo "KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD" >> $GITHUB_ENV
39+
echo "KEY_ALIAS=$KEY_ALIAS" >> $GITHUB_ENV
40+
echo "KEY_PASSWORD=$KEY_PASSWORD" >> $GITHUB_ENV
41+
42+
echo "::add-mask::$KEYSTORE_BASE64"
43+
echo "::add-mask::$KEYSTORE_PASSWORD"
44+
echo "::add-mask::$KEY_ALIAS"
45+
echo "::add-mask::$KEY_PASSWORD"
46+
47+
echo "✅ Keystore parameters extracted from KEYSTORE_SET"
48+
else
49+
echo "ℹ️ KEYSTORE_SET not provided, using separate secrets."
50+
echo "KEYSTORE_BASE64=${{ secrets.KEYSTORE_BASE64 }}" >> $GITHUB_ENV
51+
echo "KEYSTORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> $GITHUB_ENV
52+
echo "KEY_ALIAS=${{ secrets.KEY_ALIAS }}" >> $GITHUB_ENV
53+
echo "KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> $GITHUB_ENV
54+
fi
55+
echo "GDRIVE_OAUTH2=${{ secrets.GDRIVE_OAUTH2 }}" >> $GITHUB_ENV
56+
57+
- name: Check Secrets
58+
run: |
59+
echo "🔍 Checking required secrets..."
60+
MISSING=0
61+
62+
check_secret() {
63+
if [ -z "$1" ]; then
64+
echo "❌ Missing secret: $2"
65+
MISSING=1
66+
fi
67+
}
68+
69+
# Check secrets
70+
check_secret "$GDRIVE_OAUTH2" "GDRIVE_OAUTH2"
71+
72+
check_secret "$KEYSTORE_BASE64" "KEYSTORE_BASE64"
73+
check_secret "$KEYSTORE_PASSWORD" "KEYSTORE_PASSWORD"
74+
check_secret "$KEY_ALIAS" "KEY_ALIAS"
75+
check_secret "$KEY_PASSWORD" "KEY_PASSWORD"
76+
77+
if [ "$MISSING" -eq 1 ]; then
78+
echo "🛑 Missing required secrets. Stopping build."
79+
exit 1
80+
fi
81+
82+
echo "✅ All required secrets are present."
83+
84+
- name: Decode keystore file
85+
run: |
86+
mkdir -p "$RUNNER_TEMP/keystore"
87+
echo "$KEYSTORE_BASE64" | base64 -d > "$RUNNER_TEMP/keystore/keystore.jks"
88+
89+
- name: Validating keystore, alias and password
90+
run: |
91+
set -x
92+
echo "🔐 Validating keystore, alias and password"
93+
94+
# Create a dummy JAR file (quick method using zip)
95+
echo "test" > dummy.txt
96+
zip -q dummy.jar dummy.txt
97+
rm dummy.txt
98+
99+
# Attempt to validate using jarsigner
100+
JARSIGNER_LOG=$(mktemp)
101+
if ! jarsigner \
102+
-keystore "$RUNNER_TEMP/keystore/keystore.jks" \
103+
-storepass "$KEYSTORE_PASSWORD" \
104+
-keypass "$KEY_PASSWORD" \
105+
dummy.jar "$KEY_ALIAS" > "$JARSIGNER_LOG" 2>&1; then
106+
echo "❌ Either KEYSTORE_BASE64, KEYSTORE_PASSWORD, KEY_PASSWORD, or KEY_ALIAS is incorrect"
107+
echo "🔍 jarsigner error output:"
108+
cat "$JARSIGNER_LOG"
109+
rm -f "$JARSIGNER_LOG" dummy.jar
110+
exit 1
111+
fi
112+
rm -f "$JARSIGNER_LOG" dummy.jar
113+
echo "✅ Keystore, alias, and key password are valid."
114+
115+
rm -f "$KEYTOOL_LOG"
116+
echo "✅ Keystore and credentials validated."
117+
118+
- name: Decode GDrive OAuth2 secrets
119+
run: |
120+
echo "🔐 Decoding GDRIVE_OAUTH2..."
121+
DECODED=$(echo "${{ secrets.GDRIVE_OAUTH2 }}" | base64 -d)
122+
123+
GDRIVE_CLIENT_ID=$(echo "$DECODED" | cut -d'|' -f1)
124+
GDRIVE_REFRESH_TOKEN=$(echo "$DECODED" | cut -d'|' -f2)
125+
126+
echo "::add-mask::$GDRIVE_CLIENT_ID"
127+
echo "::add-mask::$GDRIVE_REFRESH_TOKEN"
128+
129+
echo "GDRIVE_CLIENT_ID=$GDRIVE_CLIENT_ID" >> $GITHUB_ENV
130+
echo "GDRIVE_REFRESH_TOKEN=$GDRIVE_REFRESH_TOKEN" >> $GITHUB_ENV
131+
132+
echo "✅ GDRIVE_CLIENT_ID and GDRIVE_REFRESH_TOKEN extracted from GDRIVE_OAUTH2"
133+
134+
- name: Retrieving Google Drive access token
135+
run: |
136+
echo "🔐 Getting Google OAuth2 access token..."
137+
TOKEN_RESPONSE=$(curl -s -X POST https://oauth2.googleapis.com/token \
138+
-d client_id="$GDRIVE_CLIENT_ID" \
139+
-d refresh_token="$GDRIVE_REFRESH_TOKEN" \
140+
-d grant_type=refresh_token)
141+
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r .access_token)
142+
echo "::add-mask::$ACCESS_TOKEN"
143+
if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
144+
echo "❌ Failed to get access token."
145+
echo "$TOKEN_RESPONSE"
146+
exit 1
147+
fi
148+
echo "ACCESS_TOKEN=$ACCESS_TOKEN" >> $GITHUB_ENV
149+
echo "✅ Access token obtained."
150+
151+
- name: Checkout source code
152+
uses: actions/checkout@v4
153+
154+
- name: Set BUILD_VARIANT
155+
run: |
156+
BUILD_VARIANT="${{ github.event.inputs.buildVariant }}"
157+
echo "BUILD_VARIANT=$BUILD_VARIANT" >> $GITHUB_ENV
158+
VARIANT_FLAVOR=$(echo "$BUILD_VARIANT" | sed -E 's/(Release|Debug)$//' | tr '[:upper:]' '[:lower:]')
159+
VARIANT_TYPE=$(echo "$BUILD_VARIANT" | grep -oE '(Release|Debug)$' | tr '[:upper:]' '[:lower:]')
160+
echo "VARIANT_FLAVOR=$VARIANT_FLAVOR" >> $GITHUB_ENV
161+
echo "VARIANT_TYPE=$VARIANT_TYPE" >> $GITHUB_ENV
162+
VERSION_SUFFIX=""
163+
if [[ "$VARIANT_FLAVOR" != "full" ]]; then VERSION_SUFFIX="$VARIANT_FLAVOR"; fi
164+
if [[ "$VARIANT_TYPE" == "debug" ]]; then VERSION_SUFFIX="$VERSION_SUFFIX-debug"; fi
165+
if [[ -n "$VERSION_SUFFIX" && "$VERSION_SUFFIX" != -* ]]; then VERSION_SUFFIX="-$VERSION_SUFFIX"; fi
166+
echo "VERSION_SUFFIX=$VERSION_SUFFIX" >> $GITHUB_ENV
167+
168+
- name: Extract VERSION
169+
run: |
170+
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
171+
if echo "$BRANCH_NAME" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?$'; then
172+
VERSION="$BRANCH_NAME"
173+
else
174+
VERSION=$(grep 'val appVersion' buildSrc/src/main/kotlin/Versions.kt | awk -F '"' '{print $2}')
175+
fi
176+
echo "VERSION=$VERSION" >> $GITHUB_ENV
177+
178+
- name: Set up JDK
179+
uses: actions/setup-java@v4
180+
with:
181+
# When upgrading the JDK, please update this section accordingly as well.
182+
java-version: 21
183+
distribution: 'temurin'
184+
cache: gradle
185+
186+
- name: Grant execute permission for gradlew
187+
run: chmod +x gradlew
188+
189+
- name: Build APKs
190+
run: |
191+
./gradlew assemble${{ env.BUILD_VARIANT }} \
192+
-Dorg.gradle.jvmargs="-Xmx8g -XX:+UseParallelGC -Xss1024m" \
193+
-Dkotlin.daemon.jvm.options="-Xmx2g" \
194+
-Dkotlin.compiler.execution.strategy="in-process" \
195+
-Dorg.gradle.daemon=true \
196+
-Dorg.gradle.workers.max=8 \
197+
-Dorg.gradle.caching=true \
198+
-Pandroid.injected.signing.store.file="$RUNNER_TEMP/keystore/keystore.jks" \
199+
-Pandroid.injected.signing.store.password="$KEYSTORE_PASSWORD" \
200+
-Pandroid.injected.signing.key.alias="$KEY_ALIAS" \
201+
-Pandroid.injected.signing.key.password="$KEY_PASSWORD"
202+
203+
- name: Rename APKs with version
204+
run: |
205+
mv app/build/outputs/apk/${{ env.VARIANT_FLAVOR }}/${{ env.VARIANT_TYPE }}/*.apk aaps-${{ env.VERSION }}${{ env.VERSION_SUFFIX }}.apk
206+
mv wear/build/outputs/apk/${{ env.VARIANT_FLAVOR }}/${{ env.VARIANT_TYPE }}/*.apk aaps-wear-${{ env.VERSION }}${{ env.VERSION_SUFFIX }}.apk
207+
208+
- name: Upload APKs to Google Drive
209+
run: |
210+
set -e
211+
echo "🔐 Start uploading APKs to Google Drive..."
212+
213+
echo "📁 Checking or creating AAPS folder"
214+
AAPS_FOLDER_ID=$(curl -s -X GET \
215+
-H "Authorization: Bearer $ACCESS_TOKEN" \
216+
"https://www.googleapis.com/drive/v3/files?q=name='AAPS'+and+mimeType='application/vnd.google-apps.folder'+and+trashed=false" \
217+
| jq -r '.files[0].id')
218+
219+
if [ "$AAPS_FOLDER_ID" == "null" ] || [ -z "$AAPS_FOLDER_ID" ]; then
220+
AAPS_FOLDER_ID=$(curl -s -X POST \
221+
-H "Authorization: Bearer $ACCESS_TOKEN" \
222+
-H "Content-Type: application/json" \
223+
-d '{"name": "AAPS", "mimeType": "application/vnd.google-apps.folder"}' \
224+
"https://www.googleapis.com/drive/v3/files" | jq -r '.id')
225+
echo "📂 Created AAPS folder: $AAPS_FOLDER_ID"
226+
else
227+
echo "📂 Found AAPS folder: $AAPS_FOLDER_ID"
228+
fi
229+
230+
echo "📁 Checking or creating version folder: $VERSION"
231+
VERSION_FOLDER_ID=$(curl -s -X GET \
232+
-H "Authorization: Bearer $ACCESS_TOKEN" \
233+
"https://www.googleapis.com/drive/v3/files?q=name='${VERSION}'+and+mimeType='application/vnd.google-apps.folder'+and+'$AAPS_FOLDER_ID'+in+parents+and+trashed=false" \
234+
| jq -r '.files[0].id')
235+
236+
if [ "$VERSION_FOLDER_ID" == "null" ] || [ -z "$VERSION_FOLDER_ID" ]; then
237+
VERSION_FOLDER_ID=$(curl -s -X POST \
238+
-H "Authorization: Bearer $ACCESS_TOKEN" \
239+
-H "Content-Type: application/json" \
240+
-d "{\"name\": \"${VERSION}\", \"mimeType\": \"application/vnd.google-apps.folder\", \"parents\": [\"$AAPS_FOLDER_ID\"]}" \
241+
"https://www.googleapis.com/drive/v3/files" | jq -r '.id')
242+
echo "📂 Created version folder: $VERSION_FOLDER_ID"
243+
else
244+
echo "📂 Found version folder: $VERSION_FOLDER_ID"
245+
fi
246+
247+
upload_to_gdrive() {
248+
FILE=$1
249+
NAME=$2
250+
if [ ! -f "$FILE" ]; then
251+
echo "❌ File not found: $FILE"
252+
exit 26
253+
fi
254+
255+
echo "📄 Checking if file $NAME already exists in Google Drive..."
256+
QUERY="name='${NAME}' and '${VERSION_FOLDER_ID}' in parents and trashed=false"
257+
ENCODED_QUERY=$(python3 -c "import urllib.parse; print(urllib.parse.quote('''$QUERY'''))")
258+
FILE_ID=$(curl -s \
259+
-H "Authorization: Bearer $ACCESS_TOKEN" \
260+
"https://www.googleapis.com/drive/v3/files?q=${ENCODED_QUERY}&fields=files(id)" \
261+
| jq -r '.files[0].id')
262+
263+
if [[ -n "$FILE_ID" && "$FILE_ID" != "null" ]]; then
264+
echo "🗑️ Deleting existing file with ID: $FILE_ID"
265+
curl -s -X DELETE \
266+
-H "Authorization: Bearer $ACCESS_TOKEN" \
267+
"https://www.googleapis.com/drive/v3/files/${FILE_ID}"
268+
fi
269+
270+
echo "⬆️ Uploading $FILE as $NAME to Google Drive..."
271+
RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/gdrive_response.json \
272+
-X POST \
273+
-H "Authorization: Bearer $ACCESS_TOKEN" \
274+
-F "metadata={\"name\":\"$NAME\", \"parents\":[\"$VERSION_FOLDER_ID\"]};type=application/json;charset=UTF-8" \
275+
-F "file=@$FILE;type=application/vnd.android.package-archive" \
276+
"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart")
277+
278+
HTTP_CODE="${RESPONSE: -3}"
279+
if [[ "$HTTP_CODE" != "200" && "$HTTP_CODE" != "201" ]]; then
280+
echo "❌ Upload failed with HTTP status: $HTTP_CODE"
281+
cat /tmp/gdrive_response.json
282+
exit 1
283+
fi
284+
285+
echo "✅ Uploaded: $NAME"
286+
}
287+
288+
upload_to_gdrive "aaps-${VERSION}${VERSION_SUFFIX}.apk" "aaps-${VERSION}${VERSION_SUFFIX}.apk"
289+
upload_to_gdrive "aaps-wear-${VERSION}${VERSION_SUFFIX}.apk" "aaps-wear-${VERSION}${VERSION_SUFFIX}.apk"
290+
291+
echo "🎉 APKs successfully uploaded to Google Drive!"

0 commit comments

Comments
 (0)