Skip to content

Commit e3be2b5

Browse files
authored
Merge pull request #71 from tetherto/staging
2 parents bb736d9 + 83c7cc3 commit e3be2b5

92 files changed

Lines changed: 16372 additions & 10844 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.

.github/workflows/build-and-publish.yml

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ on:
55
branches:
66
- main
77
- dev
8+
- staging
89

910

1011
jobs:
@@ -37,10 +38,10 @@ jobs:
3738
docker builder prune -af || true
3839
df -h
3940
40-
- uses: actions/checkout@v4
41+
- uses: actions/checkout@v6
4142
with:
4243
submodules: true
43-
token: ${{ secrets.PAT_TOKEN }}
44+
token: ${{ secrets.PAT_TOKEN }}
4445

4546
- uses: actions/setup-node@v4
4647
with:
@@ -62,8 +63,8 @@ jobs:
6263

6364
- name: Install worker dependencies
6465
run: |
65-
git config --global url."https://github.com/".insteadOf git@github.com:
66-
git config --global url."https://".insteadOf ssh://
66+
git config --global url."https://${{ secrets.PAT_TOKEN }}:x-oauth-basic@github.com/".insteadOf "ssh://git@github.com/"
67+
git config --global url."https://${{ secrets.PAT_TOKEN }}:x-oauth-basic@github.com/".insteadOf "git@github.com:"
6768
git config --global url."https://${{ secrets.PAT_TOKEN }}:x-oauth-basic@github.com/".insteadOf "https://github.com/"
6869
npm install --install-links --legacy-peer-deps
6970
env:
@@ -145,45 +146,71 @@ jobs:
145146
# CHANGED: add branch-aware profile
146147
eas build --platform android --profile ${{ steps.branch_profile.outputs.PROFILE }} --local --non-interactive
147148
148-
- name: Build APK for GitHub release (only when production profile)
149-
if: steps.branch_profile.outputs.PROFILE == 'production'
149+
- name: Resolve APK profile by branch
150+
id: apk_profile
151+
run: |
152+
if [ "${GITHUB_REF##*/}" = "main" ]; then
153+
APK_PROFILE=production-apk
154+
else
155+
APK_PROFILE=preview-apk
156+
fi
157+
echo "APK_PROFILE=$APK_PROFILE" >> "$GITHUB_OUTPUT"
158+
159+
- name: Build APK for GitHub release
150160
env:
151161
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
152162
run: |
153-
eas build --platform android --profile preview --local --non-interactive
163+
eas build --platform android --profile ${{ steps.apk_profile.outputs.APK_PROFILE }} --local --non-interactive
154164
155-
- name: Find and rename Android artifact
165+
- name: Find and rename Android artifacts
156166
id: find_android
157167
run: |
158168
set -euo pipefail
169+
VERSION="${{ steps.meta.outputs.VERSION }}"
170+
159171
AAB_PATH=$(find "$GITHUB_WORKSPACE" -name "*.aab" -type f | head -n 1 || true)
160172
echo "Original AAB: $AAB_PATH"
161-
162173
if [ -n "$AAB_PATH" ]; then
163-
VERSION="${{ steps.meta.outputs.VERSION }}"
164-
NEW_NAME="PearPass-Mobile-Android-v${VERSION}.aab"
165-
NEW_PATH="$GITHUB_WORKSPACE/$NEW_NAME"
166-
167-
mv "$AAB_PATH" "$NEW_PATH"
168-
echo "Renamed AAB to: $NEW_PATH"
169-
170-
echo "AAB_PATH=$NEW_PATH" >> "$GITHUB_OUTPUT"
174+
NEW_AAB="PearPass-Mobile-Android-v${VERSION}.aab"
175+
NEW_AAB_PATH="$GITHUB_WORKSPACE/$NEW_AAB"
176+
mv "$AAB_PATH" "$NEW_AAB_PATH"
177+
echo "AAB_PATH=$NEW_AAB_PATH" >> "$GITHUB_OUTPUT"
171178
else
172179
echo "No .aab file found."
173180
echo "AAB_PATH=" >> "$GITHUB_OUTPUT"
174181
fi
175182
183+
APK_PATH=$(find "$GITHUB_WORKSPACE" -name "*.apk" -type f | head -n 1 || true)
184+
echo "Original APK: $APK_PATH"
185+
if [ -n "$APK_PATH" ]; then
186+
NEW_APK="PearPass-Mobile-Android-v${VERSION}.apk"
187+
NEW_APK_PATH="$GITHUB_WORKSPACE/$NEW_APK"
188+
mv "$APK_PATH" "$NEW_APK_PATH"
189+
echo "APK_PATH=$NEW_APK_PATH" >> "$GITHUB_OUTPUT"
190+
else
191+
echo "No .apk file found."
192+
echo "APK_PATH=" >> "$GITHUB_OUTPUT"
193+
fi
194+
176195
VERSION_CODE=$(jq -r '.expo.android.versionCode' app.json)
177196
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
178197
echo "VERSION_CODE=$VERSION_CODE" >> "$GITHUB_OUTPUT"
179198
echo "TIMESTAMP=$TIMESTAMP" >> "$GITHUB_OUTPUT"
180199
181-
- name: Upload Android artifacts
200+
- name: Upload Android AAB artifact
182201
uses: actions/upload-artifact@v4
183202
with:
184203
name: PearPass-Mobile-Android-v${{ steps.meta.outputs.VERSION }}.aab
185204
path: ${{ steps.find_android.outputs.AAB_PATH }}
186205
if-no-files-found: ignore
206+
207+
- name: Upload Android APK artifact
208+
if: steps.find_android.outputs.APK_PATH != ''
209+
uses: actions/upload-artifact@v4
210+
with:
211+
name: PearPass-Mobile-Android-v${{ steps.meta.outputs.VERSION }}.apk
212+
path: ${{ steps.find_android.outputs.APK_PATH }}
213+
if-no-files-found: error
187214

188215
- name: Submit to Google play via EAS
189216
env:
@@ -220,7 +247,7 @@ jobs:
220247
ios:
221248
runs-on: macos-latest
222249
steps:
223-
- uses: actions/checkout@v4
250+
- uses: actions/checkout@v6
224251
with:
225252
submodules: true
226253
token: ${{ secrets.PAT_TOKEN }}
@@ -238,8 +265,8 @@ jobs:
238265
239266
- name: Install worker dependencies
240267
run: |
241-
git config --global url."https://github.com/".insteadOf git@github.com:
242-
git config --global url."https://".insteadOf ssh://
268+
git config --global url."https://${{ secrets.PAT_TOKEN }}:x-oauth-basic@github.com/".insteadOf "ssh://git@github.com/"
269+
git config --global url."https://${{ secrets.PAT_TOKEN }}:x-oauth-basic@github.com/".insteadOf "git@github.com:"
243270
git config --global url."https://${{ secrets.PAT_TOKEN }}:x-oauth-basic@github.com/".insteadOf "https://github.com/"
244271
npm install --install-links --legacy-peer-deps
245272
env:
@@ -386,13 +413,20 @@ jobs:
386413
needs: [android, ios]
387414
if: github.ref == 'refs/heads/main'
388415
steps:
389-
- name: Download Android artifacts
416+
- name: Download Android AAB artifact
390417
uses: actions/download-artifact@v4
391418
with:
392419
name: PearPass-Mobile-Android-v${{ needs.android.outputs.version }}.aab
393420
path: ./dist
394421
continue-on-error: false
395422

423+
- name: Download Android APK artifact
424+
uses: actions/download-artifact@v4
425+
with:
426+
name: PearPass-Mobile-Android-v${{ needs.android.outputs.version }}.apk
427+
path: ./dist
428+
continue-on-error: false
429+
396430
- name: Download iOS artifacts
397431
uses: actions/download-artifact@v4
398432
with:
@@ -415,6 +449,7 @@ jobs:
415449
files: |
416450
dist/**/*.ipa
417451
dist/**/*.aab
452+
dist/**/*.apk
418453
env:
419454
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
420455

.github/workflows/lint.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Lint check
2+
3+
on:
4+
push:
5+
branches: [ main, dev ]
6+
pull_request:
7+
branches: [ main, dev ]
8+
9+
permissions:
10+
contents: read
11+
packages: read
12+
13+
jobs:
14+
lint:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
with:
21+
submodules: recursive
22+
23+
- name: Setup Node.js
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: "22.x"
27+
28+
- name: Install dependencies
29+
run: npm ci
30+
31+
- name: Run ESLint
32+
run: npm run lint

.github/workflows/test.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Test check
2+
3+
on:
4+
push:
5+
branches: [ main, dev ]
6+
pull_request:
7+
branches: [ main, dev ]
8+
9+
permissions:
10+
contents: read
11+
packages: read
12+
13+
jobs:
14+
test:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
with:
21+
submodules: recursive
22+
23+
- name: Setup Node.js
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: "22.x"
27+
28+
- name: Install dependencies
29+
run: npm ci
30+
31+
- name: Compile locale files
32+
run: npm run lingui:compile
33+
34+
- name: Run tests
35+
run: npm test

.npmrc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
11
legacy-peer-deps=true
2-
install-links=true
3-

android/app/build.gradle

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ android {
9393
minSdkVersion rootProject.ext.minSdkVersion
9494
targetSdkVersion rootProject.ext.targetSdkVersion
9595
versionCode 1
96-
versionName "1.1.1"
96+
versionName "1.2.1"
9797
}
9898
signingConfigs {
9999
debug {
@@ -188,12 +188,15 @@ dependencies {
188188
// RecyclerView dependency for autofill extension
189189
implementation("androidx.recyclerview:recyclerview:1.3.2")
190190

191-
// AndroidX Autofill for Samsung keyboard compatibility (same as Bitwarden uses)
191+
// AndroidX Autofill for Samsung keyboard compatibility
192192
implementation("androidx.autofill:autofill:1.3.0")
193193

194194
// AndroidX Biometric for fingerprint/face authentication
195195
implementation("androidx.biometric:biometric:1.1.0")
196196

197+
// WorkManager for reliable background task scheduling (clipboard clearing)
198+
implementation("androidx.work:work-runtime-ktx:2.9.0")
199+
197200
def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true";
198201
def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true";
199202
def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true";

android/app/src/main/AndroidManifest.xml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
55
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
66
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
7-
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
87
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
98
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
109
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
@@ -51,13 +50,5 @@
5150
android:windowSoftInputMode="adjustResize"
5251
android:launchMode="singleTop" />
5352

54-
<!-- Clipboard Clear Receiver -->
55-
<receiver
56-
android:name=".ClipboardClearReceiver"
57-
android:exported="false">
58-
<intent-filter>
59-
<action android:name="com.pears.pass.CLEAR_CLIPBOARD" />
60-
</intent-filter>
61-
</receiver>
6253
</application>
6354
</manifest>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.pears.pass
2+
3+
import android.content.ClipboardManager
4+
import android.content.Context
5+
import android.os.Build
6+
import android.content.ClipData
7+
import android.util.Log
8+
import androidx.work.Worker
9+
import androidx.work.WorkerParameters
10+
11+
/**
12+
* A WorkManager worker to clear the clipboard after a delay.
13+
* Uses WorkManager instead of AlarmManager+BroadcastReceiver because
14+
* WorkManager provides proper execution context that can access the clipboard
15+
* even on Android 10+ where background clipboard access is restricted.
16+
*/
17+
class ClearClipboardWorker(
18+
appContext: Context,
19+
workerParams: WorkerParameters,
20+
) : Worker(appContext, workerParams) {
21+
22+
companion object {
23+
const val TAG = "ClearClipboardWorker"
24+
}
25+
26+
private val clipboardManager =
27+
appContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
28+
29+
override fun doWork(): Result {
30+
return try {
31+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
32+
clipboardManager.clearPrimaryClip()
33+
} else {
34+
val clip = ClipData.newPlainText("", "")
35+
clipboardManager.setPrimaryClip(clip)
36+
}
37+
Log.d(TAG, "Clipboard cleared successfully")
38+
Result.success()
39+
} catch (e: Exception) {
40+
Log.e(TAG, "Failed to clear clipboard", e)
41+
Result.failure()
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)