feat: Android home-screen widgets (Jetpack Glance) #1089
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: "26" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Lint | |
| run: npm run lint | |
| fastlane-validate: | |
| name: Fastlane Metadata | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Validate | |
| uses: ashutoshgngwr/validate-fastlane-supply-metadata@c8857fdbbd3e00f9a5cbe8604bcecfa95ce8fef8 # v2.1.0 | |
| with: | |
| usePlayStoreLocales: true | |
| ios-build: | |
| name: iOS Detox (build) | |
| runs-on: depot-macos-26 | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup Xcode 26.5 | |
| run: | | |
| sudo xcode-select -s /Applications/Xcode_26.5.app/Contents/Developer | |
| xcodebuild -version | |
| sudo xcodebuild -runFirstLaunch | |
| xcrun simctl list runtimes | |
| if ! xcrun simctl list runtimes | grep -q "iOS"; then | |
| sudo xcodebuild -downloadPlatform iOS | |
| fi | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: "26" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Setup Expo | |
| run: npx expo install | |
| - name: Prebuild iOS | |
| run: npx expo prebuild --platform ios --clean | |
| - name: Build Detox framework cache | |
| run: npx detox build-framework-cache | |
| - name: Build | |
| run: npx detox build --configuration ios.sim.release | |
| - name: Upload app artifact | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: ios-evcc-app | |
| path: ios/build/Build/Products/Release-iphonesimulator/evcc.app | |
| if-no-files-found: error | |
| retention-days: 7 | |
| ios-test: | |
| name: iOS Detox (test) | |
| runs-on: depot-macos-26 | |
| timeout-minutes: 30 | |
| needs: ios-build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup Xcode 26.5 | |
| run: | | |
| sudo xcode-select -s /Applications/Xcode_26.5.app/Contents/Developer | |
| sudo xcodebuild -runFirstLaunch | |
| xcrun simctl list runtimes | |
| if ! xcrun simctl list runtimes | grep -q "iOS"; then | |
| sudo xcodebuild -downloadPlatform iOS | |
| fi | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: "26" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build Detox framework cache | |
| # the cache lives at ~/Library/Detox/... so it's per-runner; each shard | |
| # is a fresh depot-macos-26, the build job's cache is not visible here | |
| run: npx detox build-framework-cache | |
| - name: Install applesimutils | |
| run: | | |
| # remove unused preinstalled taps that trigger trust warnings on every brew call | |
| brew untap aws/tap azure/bicep hashicorp/tap wix-incubator/brew || true | |
| brew tap wix/brew && brew trust wix/brew && brew install applesimutils | |
| - name: Download app artifact | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: ios-evcc-app | |
| path: ios/build/Build/Products/Release-iphonesimulator/evcc.app | |
| - name: Setup evcc daemon | |
| run: | | |
| brew tap evcc-io/tap | |
| brew trust evcc-io/tap | |
| brew update | |
| brew install evcc | |
| sudo evcc --disable-auth & | |
| - name: Setup Caddy | |
| env: | |
| CADDY_VERSION: 2.11.2 | |
| CADDY_SHA256: 7ab765777e953574d5713a69cab3f5a2f643a5c1cc264d4239a60ff845b465d8 | |
| run: | | |
| curl -fsSL -o caddy.tar.gz "https://github.com/caddyserver/caddy/releases/download/v${CADDY_VERSION}/caddy_${CADDY_VERSION}_mac_arm64.tar.gz" | |
| echo "${CADDY_SHA256} caddy.tar.gz" | shasum -a 256 -c - | |
| tar -xzf caddy.tar.gz caddy | |
| chmod +x caddy | |
| ./caddy run & | |
| - name: Test (shard ${{ matrix.shard }}/2) | |
| run: npx detox test --configuration ios.sim.release --cleanup --headless --maxWorkers 2 -- --shard=${{ matrix.shard }}/2 | |
| - name: Upload artifacts on failure | |
| if: failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: ios-detox-artifacts-shard-${{ matrix.shard }} | |
| path: e2e/artifacts/ | |
| retention-days: 7 | |
| android-build: | |
| name: "Android Detox (build)" | |
| runs-on: depot-ubuntu-24.04-32 | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup Environment | |
| run: touch android-detox-build | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: "26" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Setup Expo | |
| run: npx expo install | |
| - name: Prebuild Android | |
| run: npx expo prebuild --platform android --clean | |
| - name: Setup Java | |
| uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 | |
| with: | |
| distribution: "temurin" | |
| java-version: "17" | |
| - name: Gradle cache | |
| uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 | |
| - name: Build | |
| run: npx detox build --configuration android.emu.release | |
| - name: Upload app apk | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: android-detox-app.apk | |
| path: android/app/build/outputs/apk/release/app-release.apk | |
| if-no-files-found: error | |
| retention-days: 7 | |
| - name: Upload detox apk | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: android-detox-runner.apk | |
| path: android/app/build/outputs/apk/androidTest/release/app-release-androidTest.apk | |
| if-no-files-found: error | |
| retention-days: 7 | |
| android-test: | |
| name: "Android Detox (test)" | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| needs: android-build | |
| strategy: | |
| matrix: | |
| api-level: [35] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: "26" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Setup Expo | |
| run: npx expo install | |
| - name: Prebuild Android | |
| run: npx expo prebuild --platform android --clean | |
| - name: Download app apk | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: android-detox-app.apk | |
| path: android/app/build/outputs/apk/release | |
| - name: Download detox apk | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: android-detox-runner.apk | |
| path: android/app/build/outputs/apk/androidTest/release | |
| - name: Install system dependencies for android emulator | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libpulse0 | |
| - name: Enable KVM | |
| run: | | |
| 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 | |
| - name: Setup evcc daemon | |
| run: | | |
| curl -1sLf 'https://dl.evcc.io/public/evcc/stable/setup.deb.sh' | sudo -E bash | |
| sudo apt update | |
| sudo apt install -y evcc | |
| sudo systemctl stop evcc | |
| sudo evcc --disable-auth --database /var/lib/evcc/evcc.db & | |
| - name: Setup Caddy | |
| env: | |
| CADDY_VERSION: 2.11.2 | |
| CADDY_SHA256: 94391dfefe1f278ac8f387ab86162f0e88d87ff97df367f360e51e3cda3df56f | |
| run: | | |
| curl -fsSL -o caddy.tar.gz "https://github.com/caddyserver/caddy/releases/download/v${CADDY_VERSION}/caddy_${CADDY_VERSION}_linux_amd64.tar.gz" | |
| echo "${CADDY_SHA256} caddy.tar.gz" | sha256sum -c - | |
| tar -xzf caddy.tar.gz caddy | |
| chmod +x caddy | |
| ./caddy run & | |
| - name: Test | |
| uses: reactivecircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2.38.0 | |
| with: | |
| api-level: ${{ matrix.api-level }} | |
| disk-size: 1G | |
| heap-size: 1G | |
| force-avd-creation: false | |
| target: google_apis | |
| arch: x86_64 | |
| disable-animations: true | |
| emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | |
| script: npx detox test --configuration android.emu.release --cleanup --headless | |
| - name: Upload artifacts on failure | |
| if: failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: android-detox-artifacts-api-level-${{ matrix.api-level }} | |
| path: e2e/artifacts/ | |
| retention-days: 7 | |
| detox-status: | |
| name: Detox Status | |
| runs-on: ubuntu-24.04 | |
| needs: [ios-test, android-test] | |
| if: always() | |
| steps: | |
| - name: Check results | |
| run: | | |
| if [ "${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}" = "true" ]; then | |
| echo "A Detox job failed or was cancelled." | |
| exit 1 | |
| fi | |
| fdroid-build: | |
| name: F-Droid | |
| runs-on: depot-ubuntu-24.04-32 | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Get version | |
| id: version | |
| run: echo "version=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT | |
| - name: Setup Environment | |
| run: | | |
| sed -i '/^\s*\[$/{ N; /\n\s*"expo-camera"/{ :loop; N; /\],$/!b loop; d } }' app.config.ts | |
| touch fdroid-build | |
| - name: Setup F-Droid | |
| run: | | |
| sudo add-apt-repository ppa:fdroid/fdroidserver | |
| sudo apt update | |
| sudo apt install fdroidserver | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: "26" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: | | |
| npm remove expo-camera | |
| npm ci | |
| - name: Setup Expo | |
| run: npx expo install | |
| - name: Prebuild Android | |
| run: npx expo prebuild --platform android --clean | |
| - name: Setup Java | |
| uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 | |
| with: | |
| distribution: "temurin" | |
| java-version: "17" | |
| - name: Gradle cache | |
| uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 | |
| - name: Build | |
| run: | | |
| cd android | |
| ./gradlew :app:assembleRelease --parallel --build-cache | |
| - name: Scan | |
| run: fdroid scanner --verbose --exit-code android/app/build/outputs/apk/release/app-release.apk | |
| - name: Upload apk | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: evcc-${{ steps.version.outputs.version }}-fdroid.apk | |
| path: android/app/build/outputs/apk/release/app-release.apk | |
| if-no-files-found: error | |
| retention-days: 90 |