Merge pull request #1802 from selfxyz/release/staging-2026-03-03

Release to Staging v2.9.16 - 2026-03-03
This commit is contained in:
Justin Hernandez
2026-03-02 18:37:19 -08:00
committed by GitHub
159 changed files with 4329 additions and 1406 deletions

View File

@@ -1304,6 +1304,16 @@ jobs:
with:
node-version-file: .nvmrc
- name: Copy version-manager from build branch
run: |
BUILD_REF="${{ github.ref_name }}"
echo "📋 Using version-manager.cjs from build branch: $BUILD_REF"
SCRIPT_CONTENT=$(git show "origin/${BUILD_REF}:app/scripts/version-manager.cjs") || {
echo "❌ Failed to read version-manager.cjs from origin/${BUILD_REF}"
exit 1
}
echo "$SCRIPT_CONTENT" > "${{ env.APP_PATH }}/scripts/version-manager.cjs"
- name: Apply version bump from outputs
run: |
cd ${{ env.APP_PATH }}
@@ -1314,56 +1324,39 @@ jobs:
IOS_SUCCESS="${{ needs.build-ios.result }}"
ANDROID_SUCCESS="${{ needs.build-android.result }}"
echo "📝 Applying version bump: $VERSION (iOS: $IOS_BUILD, Android: $ANDROID_BUILD)"
echo "📝 Applying version bump: $VERSION (iOS: $IOS_BUILD [$IOS_SUCCESS], Android: $ANDROID_BUILD [$ANDROID_SUCCESS])"
# Update package.json version
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
pkg.version = '$VERSION';
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
console.log('✅ Updated package.json');
"
# Update package.json, version.json, and platform build files
# Pass build results so the script only updates platforms that succeeded
node scripts/version-manager.cjs apply "$VERSION" "$IOS_BUILD" "$ANDROID_BUILD" "$IOS_SUCCESS" "$ANDROID_SUCCESS"
# Update version.json build numbers and deployment timestamps
node -e "
const fs = require('fs');
const version = JSON.parse(fs.readFileSync('version.json', 'utf8'));
const timestamp = new Date().toISOString();
- name: Load version-managed files
run: |
cd ${{ env.APP_PATH }}
// Only bump build numbers for successful builds
if ('$IOS_SUCCESS' === 'success') {
version.ios.build = $IOS_BUILD;
version.ios.lastDeployed = timestamp;
console.log('✅ Updated iOS build number to $IOS_BUILD and lastDeployed timestamp');
} else {
console.log('⏭️ Skipped iOS build number bump (build did not succeed)');
}
VERSION_MANAGED_FILES="$(node scripts/version-manager.cjs files --shell)"
if [ -z "$VERSION_MANAGED_FILES" ]; then
echo "❌ Failed to load version-managed files"
exit 1
fi
if ('$ANDROID_SUCCESS' === 'success') {
version.android.build = $ANDROID_BUILD;
version.android.lastDeployed = timestamp;
console.log('✅ Updated Android build number to $ANDROID_BUILD and lastDeployed timestamp');
} else {
console.log('⏭️ Skipped Android build number bump (build did not succeed)');
}
fs.writeFileSync('version.json', JSON.stringify(version, null, 2) + '\n');
console.log('✅ Updated version.json');
"
echo "✅ Versions applied successfully"
{
echo "VERSION_MANAGED_FILES<<EOF"
echo "$VERSION_MANAGED_FILES"
echo "EOF"
} >> $GITHUB_ENV
echo "🗂️ Version-managed files: $VERSION_MANAGED_FILES"
- name: Verify version changes
run: |
cd ${{ env.APP_PATH }}
# Check that version files actually changed
if ! git diff --quiet package.json version.json; then
# Check that version-managed files actually changed
if ! git diff --quiet -- $VERSION_MANAGED_FILES; then
echo "✅ Version changes detected"
git diff package.json version.json
git diff -- $VERSION_MANAGED_FILES
else
echo "⚠️ No version changes detected in package.json or version.json"
echo "⚠️ No version changes detected in version-managed files"
echo "This may indicate a problem with version application"
exit 1
fi
@@ -1430,14 +1423,14 @@ jobs:
# Commit the version changes
cd ${{ env.APP_PATH }}
git add package.json version.json
git add $VERSION_MANAGED_FILES
if git diff --cached --quiet; then
echo "⚠️ No version changes to commit"
exit 0
fi
git commit -m "chore: bump mobile app version to $VERSION" -m "Update build numbers and deployment timestamps after successful deployment."
git commit -m "chore: bump mobile app version to $VERSION" -m "Update build numbers, platform build files, and deployment timestamps after successful deployment."
# Create new branch from current HEAD (bump target branch with version bump)
git checkout -b ${BRANCH_NAME}
@@ -1462,6 +1455,7 @@ jobs:
This PR updates:
- Build numbers for deployed platforms
- Platform build files (Android `versionCode`, iOS `CURRENT_PROJECT_VERSION` and `MARKETING_VERSION`)
- Deployment timestamps (\`lastDeployed\`) for successful builds
This PR was automatically created by the mobile deployment workflow." \

View File

@@ -3,7 +3,7 @@ name: Mobile E2E
env:
# Build environment versions
JAVA_VERSION: 17
ANDROID_API_LEVEL: 33
ANDROID_API_LEVEL: 34
ANDROID_NDK_VERSION: 27.0.12077973
XCODE_VERSION: 26
# Cache versions
@@ -41,14 +41,15 @@ on:
workflow_dispatch:
jobs:
android-build-test:
# Currently build-only for Android with private repos. E2E steps are preserved but skipped (if: false).
# To re-enable full E2E: change `if: false` to `if: true` on Maestro and emulator steps.
e2e-android:
concurrency:
group: ${{ github.workflow }}-android-${{ github.ref }}
cancel-in-progress: true
timeout-minutes: 120
runs-on: ubuntu-latest
runs-on:
- "self-hosted"
- "selfxyz-org"
- "ubuntu-24-04"
steps:
- uses: actions/checkout@v6
- name: Read and sanitize Node.js version
@@ -109,36 +110,45 @@ jobs:
max_attempts: 3
retry_wait_seconds: 5
command: yarn install --immutable --silent
- name: Validate Maestro test file
if: false # Skip for build-only test - keep logic for future E2E
run: |
[ -f app/tests/e2e/launch.android.flow.yaml ] || { echo "❌ Android E2E test file missing"; exit 1; }
- name: Cache Maestro
if: false # Skip for build-only test - keep logic for future E2E
id: cache-maestro
uses: actions/cache@v4
with:
path: ~/.maestro
key: ${{ runner.os }}-maestro-${{ env.MAESTRO_VERSION }}
- name: Install Maestro
if: false # Skip for build-only test - keep logic for future E2E
run: curl -Ls "https://get.maestro.mobile.dev" | bash
- name: Add Maestro to path
if: false # Skip for build-only test - keep logic for future E2E
run: echo "$HOME/.maestro/bin" >> "$GITHUB_PATH"
- name: Free up disk space
uses: ./.github/actions/free-disk-space
- name: Check Java installation
run: |
echo "INSTALL_JAVA=false" >> "$GITHUB_ENV"
if command -v java &> /dev/null && java -version &> /dev/null; then
echo "Java already installed: $(java -version 2>&1 | head -n 1)"
else
echo "Java not found or not working, will install..."
echo "INSTALL_JAVA=true" >> "$GITHUB_ENV"
fi
- name: Setup Java environment
if: env.INSTALL_JAVA == 'true'
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
- name: Install Maestro
run: curl -Ls "https://get.maestro.mobile.dev" | bash
- name: Add Maestro to path
run: echo "$HOME/.maestro/bin" >> "$GITHUB_PATH"
- name: Free up disk space
if: false # We should be fine for self-hosted
uses: ./.github/actions/free-disk-space
- name: Cache Gradle packages
uses: ./.github/actions/cache-gradle
- name: Setup Android SDK
uses: android-actions/setup-android@v3
with:
accept-android-sdk-licenses: true
- name: Install NDK
uses: nick-fields/retry@v3
with:
@@ -146,6 +156,7 @@ jobs:
max_attempts: 3
retry_wait_seconds: 10
command: sdkmanager "ndk;${{ env.ANDROID_NDK_VERSION }}"
- name: Build dependencies (outside emulator)
run: |
echo "Building dependencies..."
@@ -165,8 +176,12 @@ jobs:
run: |
echo "Building Android APK..."
chmod +x app/android/gradlew
(cd app/android && ./gradlew assembleDebug --quiet --parallel --build-cache --no-configuration-cache) || { echo "❌ Android build failed"; exit 1; }
(
cd app/android &&
E2E_BUILD=true ./gradlew assembleDebug -PbundleInDebug=true --quiet --parallel --build-cache --no-configuration-cache
) || { echo "❌ Android build failed"; exit 1; }
echo "✅ Android build succeeded"
- name: Clean up Gradle build artifacts
uses: ./.github/actions/cleanup-gradle-artifacts
- name: Verify APK and android-passport-nfc-reader integration
@@ -208,32 +223,80 @@ jobs:
fi
echo "🎉 Build verification completed successfully!"
echo " Emulator testing is temporarily disabled - build testing only"
- name: Check KVM access
id: kvm
run: |
if [ ! -e /dev/kvm ]; then
echo "::warning::/dev/kvm not found — emulator will run in software mode (slow). Enable nested virtualization for better performance."
echo "available=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if [ -w /dev/kvm ]; then
echo "✅ /dev/kvm is already writable"
elif [ -d /etc/udev/rules.d ]; then
echo "Setting KVM permissions via udev..."
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
else
echo "No udev available, setting /dev/kvm permissions directly..."
sudo chmod 666 /dev/kvm
fi
ls -la /dev/kvm
echo "available=true" >> "$GITHUB_OUTPUT"
- name: Install emulator runtime dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq \
libx11-6 libgl1 libpulse0 libnss3 \
libxcomposite1 libxcursor1 libxi6 libxtst6 \
libxrandr2 libxss1 libxdamage1 libxfixes3 \
libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
libgbm1 libgtk-3-0 libpango-1.0-0 libcairo2 \
> /dev/null 2>&1
- name: Create E2E test script
run: |
cat > /tmp/run-e2e.sh << 'EOF'
#!/bin/bash
set -euo pipefail
APP_ID="com.proofofpassportapp"
echo "Installing app on emulator..."
APK_PATH="app/android/app/build/outputs/apk/debug/app-debug.apk"
[ -f "$APK_PATH" ] || { echo "❌ APK not found at $APK_PATH"; exit 1; }
adb uninstall "$APP_ID" >/dev/null 2>&1 || true
adb install -r "$APK_PATH" || { echo "❌ App installation failed"; exit 1; }
adb shell pm clear "$APP_ID" >/dev/null 2>&1 || true
echo "✅ App installed successfully"
echo "⏰ Giving the emulator a moment to settle..."
sleep 5
echo "🎭 Running Maestro tests..."
export MAESTRO_DRIVER_STARTUP_TIMEOUT=180000
export LAUNCH_WAIT_MS=180000
if ! maestro test app/tests/e2e/launch.android.flow.yaml --format junit --output app/maestro-results.xml; then
echo "❌ Maestro failed - dumping Android diagnostics"
adb shell dumpsys activity activities | sed -n '1,240p' || true
adb logcat -d | tail -n 400 || true
exit 1
fi
EOF
chmod +x /tmp/run-e2e.sh
- name: Install and Test on Android
if: false # Skip emulator/E2E for build-only test - keep logic for future E2E
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ env.ANDROID_API_LEVEL }}
arch: x86_64
target: google_apis
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -camera-front none -memory 8192 -cores 4 -accel on
target: default
channel: stable
force-avd-creation: true
emulator-options: >-
-no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim
-camera-back none -camera-front none -memory 8192 -cores 4
${{ steps.kvm.outputs.available == 'true' && '-accel on' || '-accel off' }}
disable-animations: true
script: |
echo "Installing app on emulator..."
APK_PATH="app/android/app/build/outputs/apk/debug/app-debug.apk"
[ -f "$APK_PATH" ] || { echo "❌ APK not found at $APK_PATH"; exit 1; }
adb install -r "$APK_PATH" || { echo "❌ App installation failed"; exit 1; }
echo "✅ App installed successfully"
script: /tmp/run-e2e.sh
echo "⏰ Giving the emulator a moment to settle..."
sleep 5
echo "🎭 Running Maestro tests..."
export MAESTRO_DRIVER_STARTUP_TIMEOUT=180000
maestro test app/tests/e2e/launch.android.flow.yaml --format junit --output app/maestro-results.xml
- name: Upload test results
if: false # Skip for build-only test - keep logic for future E2E
if: always()
uses: actions/upload-artifact@v4
with:
name: maestro-results-android