v0.0.19 #251
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: Storefront App CI | |
| on: | |
| pull_request: | |
| branches: [main] | |
| push: | |
| branches: [main] | |
| tags: ["v*"] | |
| env: | |
| FLEETBASE_KEY: ${{ secrets.FLEETBASE_KEY }} | |
| STOREFRONT_KEY: ${{ secrets.STOREFRONT_KEY }} | |
| GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }} | |
| ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} | |
| jobs: | |
| install_and_test: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| cache-key: ${{ steps.cache-key.outputs.key }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Activate Yarn 3.6.4 | |
| run: corepack prepare yarn@3.6.4 --activate | |
| - name: Get yarn cache directory path | |
| id: yarn-cache-dir-path | |
| run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT | |
| - name: Cache yarn dependencies | |
| uses: actions/cache@v4 | |
| id: yarn-cache | |
| with: | |
| path: ${{ steps.yarn-cache-dir-path.outputs.dir }} | |
| key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-yarn- | |
| - name: Install dependencies | |
| run: yarn install --immutable | |
| - name: Create .env file | |
| run: | | |
| echo "APP_LINK_PREFIX=${{ secrets.APP_LINK_PREFIX }}" > .env | |
| echo "FLEETBASE_KEY=${{ secrets.FLEETBASE_KEY }}" > .env | |
| echo "STOREFRONT_KEY=${{ secrets.STOREFRONT_KEY }}" > .env | |
| echo "GOOGLE_MAPS_API_KEY=${{ secrets.GOOGLE_MAPS_API_KEY }}" >> .env | |
| echo "FACEBOOK_APP_ID=${{ secrets.FACEBOOK_APP_ID }}" >> .env | |
| echo "FACEBOOK_CLIENT_TOKEN=${{ secrets.FACEBOOK_CLIENT_TOKEN }}" >> .env | |
| echo "GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}" >> .env | |
| echo "GOOGLE_IOS_CLIENT_ID=${{ secrets.GOOGLE_IOS_CLIENT_ID }}" >> .env | |
| - name: Generate cache key | |
| id: cache-key | |
| run: echo "key=${{ runner.os }}-deps-${{ hashFiles('**/yarn.lock', '**/package.json') }}" >> $GITHUB_OUTPUT | |
| # Optional: Run tests if you have them | |
| # - name: Run tests | |
| # run: yarn test | |
| android_build: | |
| runs-on: ubuntu-latest | |
| needs: install_and_test | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Activate Yarn 3.6.4 | |
| run: corepack prepare yarn@3.6.4 --activate | |
| - name: Cache yarn dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.yarn/cache | |
| **/node_modules | |
| key: ${{ needs.install_and_test.outputs.cache-key }} | |
| restore-keys: | | |
| ${{ runner.os }}-deps- | |
| - name: Install dependencies | |
| run: yarn install --immutable | |
| - name: Create .env file | |
| run: | | |
| echo "APP_LINK_PREFIX=${{ secrets.APP_LINK_PREFIX }}" > .env | |
| echo "FLEETBASE_KEY=${{ secrets.FLEETBASE_KEY }}" > .env | |
| echo "STOREFRONT_KEY=${{ secrets.STOREFRONT_KEY }}" > .env | |
| echo "GOOGLE_MAPS_API_KEY=${{ secrets.GOOGLE_MAPS_API_KEY }}" >> .env | |
| echo "FACEBOOK_APP_ID=${{ secrets.FACEBOOK_APP_ID }}" >> .env | |
| echo "FACEBOOK_CLIENT_TOKEN=${{ secrets.FACEBOOK_CLIENT_TOKEN }}" >> .env | |
| echo "GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}" >> .env | |
| echo "GOOGLE_IOS_CLIENT_ID=${{ secrets.GOOGLE_IOS_CLIENT_ID }}" >> .env | |
| - name: Generate google-services.json | |
| env: | |
| GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }} | |
| run: | | |
| echo "$GOOGLE_SERVICES_JSON" > android/app/google-services.json | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: "temurin" | |
| java-version: "21" | |
| - name: Install Ninja (Ubuntu) | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y ninja-build | |
| - name: Ensure Android SDK/NDK/CMake toolchain | |
| shell: bash | |
| env: | |
| ANDROID_SDK_ROOT: /usr/local/lib/android/sdk | |
| run: | | |
| set -e | |
| # Find a working sdkmanager (latest if present, else first found) | |
| if [ -x "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" ]; then | |
| SDKMGR="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" | |
| else | |
| SDKMGR=$(ls -1d "$ANDROID_SDK_ROOT/cmdline-tools"/*/bin/sdkmanager 2>/dev/null | head -n1 || true) | |
| if [ -z "$SDKMGR" ]; then | |
| echo "No cmdline-tools found; installing 'cmdline-tools;latest' with the preinstalled sdkmanager..." | |
| # Use the prebundled sdkmanager path on GH runners | |
| SDKMGR="$ANDROID_SDK_ROOT/cmdline-tools/bin/sdkmanager" | |
| "$SDKMGR" "cmdline-tools;latest" | |
| SDKMGR="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" | |
| fi | |
| fi | |
| echo "Using sdkmanager at: $SDKMGR" | |
| # Accept licenses; don't fail on SIGPIPE from 'yes' | |
| yes | "$SDKMGR" --licenses >/dev/null 2>&1 || true | |
| # Helper: install component if missing | |
| need() { | |
| local p="$1" | |
| if ! "$SDKMGR" --list_installed | grep -q "^ $p$"; then | |
| echo "Installing $p" | |
| "$SDKMGR" "$p" | |
| else | |
| echo "✓ $p already installed" | |
| fi | |
| } | |
| # Match root gradle pins | |
| need "platforms;android-35" | |
| need "build-tools;35.0.0" | |
| need "ndk;27.1.12297006" | |
| # CMake version | |
| need "cmake;3.22.1" | |
| # Sanity output | |
| "$ANDROID_SDK_ROOT/cmake/3.22.1/bin/cmake" --version || true | |
| test -f "$ANDROID_SDK_ROOT/ndk/27.1.12297006/source.properties" && echo "✅ NDK 27.1.12297006 installed" | |
| - name: Cache Gradle Wrapper | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.gradle/wrapper | |
| key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradle-wrapper.properties') }} | |
| - name: Cache Gradle Dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.gradle/caches | |
| key: ${{ runner.os }}-gradle-caches-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: | | |
| ${{ runner.os }}-gradle-caches- | |
| - name: Make Gradlew Executable | |
| run: cd android && chmod +x ./gradlew | |
| - name: Build Android Debug APK | |
| run: | | |
| cd android | |
| ./gradlew clean assembleDebug --no-daemon --stacktrace --info | |
| - name: Upload Android APK | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: android-debug-apk | |
| path: android/app/build/outputs/apk/debug/app-debug.apk | |
| retention-days: 30 | |
| ios_build: | |
| runs-on: macos-latest | |
| needs: install_and_test | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Xcode | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: latest-stable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Activate Yarn 3.6.4 | |
| run: corepack prepare yarn@3.6.4 --activate | |
| - name: Cache yarn dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.yarn/cache | |
| **/node_modules | |
| key: ${{ needs.install_and_test.outputs.cache-key }} | |
| restore-keys: | | |
| ${{ runner.os }}-deps- | |
| - name: Install dependencies | |
| run: yarn install --immutable | |
| - name: Create .env file | |
| run: | | |
| echo "APP_LINK_PREFIX=${{ secrets.APP_LINK_PREFIX }}" > .env | |
| echo "FLEETBASE_KEY=${{ secrets.FLEETBASE_KEY }}" > .env | |
| echo "STOREFRONT_KEY=${{ secrets.STOREFRONT_KEY }}" > .env | |
| echo "GOOGLE_MAPS_API_KEY=${{ secrets.GOOGLE_MAPS_API_KEY }}" >> .env | |
| echo "FACEBOOK_APP_ID=${{ secrets.FACEBOOK_APP_ID }}" >> .env | |
| echo "FACEBOOK_CLIENT_TOKEN=${{ secrets.FACEBOOK_CLIENT_TOKEN }}" >> .env | |
| echo "GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}" >> .env | |
| echo "GOOGLE_IOS_CLIENT_ID=${{ secrets.GOOGLE_IOS_CLIENT_ID }}" >> .env | |
| - name: Cache CocoaPods | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ios/Pods | |
| ~/Library/Caches/CocoaPods | |
| ~/.cocoapods | |
| key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pods- | |
| - name: Install CocoaPods | |
| run: | | |
| sudo gem install cocoapods | |
| cd ios && pod install --repo-update | |
| - name: List available simulators | |
| run: xcrun simctl list devices available | grep iPhone | |
| - name: Build iOS app for simulator | |
| run: | | |
| cd ios | |
| # Try to find an available iPhone simulator | |
| AVAILABLE_SIMULATORS=$(xcrun simctl list devices available | grep "iPhone" | head -5) | |
| echo "Available iPhone simulators:" | |
| echo "$AVAILABLE_SIMULATORS" | |
| # Extract the first iPhone simulator ID | |
| SIMULATOR_ID=$(echo "$AVAILABLE_SIMULATORS" | head -1 | grep -o '[A-F0-9-]\{36\}' | head -1) | |
| if [ -n "$SIMULATOR_ID" ]; then | |
| echo "Using iPhone simulator ID: $SIMULATOR_ID" | |
| DESTINATION="id=$SIMULATOR_ID" | |
| else | |
| echo "No iPhone simulator found, trying generic iOS Simulator destination" | |
| DESTINATION="generic/platform=iOS Simulator" | |
| fi | |
| echo "Building with destination: $DESTINATION" | |
| xcodebuild -workspace StorefrontApp.xcworkspace \ | |
| -scheme StorefrontApp \ | |
| -configuration Debug \ | |
| -sdk iphonesimulator \ | |
| -destination "$DESTINATION" \ | |
| -derivedDataPath build \ | |
| -allowProvisioningUpdates \ | |
| build | |
| - name: Upload iOS build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ios-debug-build | |
| path: ios/build/Build/Products/Debug-iphonesimulator/ | |
| retention-days: 30 | |
| # Release builds for tagged versions | |
| android_release: | |
| runs-on: ubuntu-latest | |
| needs: install_and_test | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Activate Yarn 3.6.4 | |
| run: corepack prepare yarn@3.6.4 --activate | |
| - name: Install dependencies | |
| run: yarn install --immutable | |
| - name: Create .env file | |
| run: | | |
| echo "APP_LINK_PREFIX=${{ secrets.APP_LINK_PREFIX }}" > .env | |
| echo "FLEETBASE_KEY=${{ secrets.FLEETBASE_KEY }}" > .env | |
| echo "STOREFRONT_KEY=${{ secrets.STOREFRONT_KEY }}" > .env | |
| echo "GOOGLE_MAPS_API_KEY=${{ secrets.GOOGLE_MAPS_API_KEY }}" >> .env | |
| echo "FACEBOOK_APP_ID=${{ secrets.FACEBOOK_APP_ID }}" >> .env | |
| echo "FACEBOOK_CLIENT_TOKEN=${{ secrets.FACEBOOK_CLIENT_TOKEN }}" >> .env | |
| echo "GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}" >> .env | |
| echo "GOOGLE_IOS_CLIENT_ID=${{ secrets.GOOGLE_IOS_CLIENT_ID }}" >> .env | |
| - name: Generate google-services.json | |
| env: | |
| GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }} | |
| run: | | |
| echo "$GOOGLE_SERVICES_JSON" > android/app/google-services.json | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: "temurin" | |
| java-version: "21" | |
| - name: Cache Gradle Dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.gradle/caches | |
| key: ${{ runner.os }}-gradle-caches-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| - name: Build Android Release APK | |
| run: | | |
| cd android | |
| ./gradlew clean assembleRelease --no-daemon --stacktrace | |
| - name: Upload Android Release APK | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: android-release-apk | |
| path: android/app/build/outputs/apk/release/app-release.apk | |
| retention-days: 90 | |
| ios_release: | |
| runs-on: macos-latest | |
| needs: install_and_test | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Xcode | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: latest-stable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "yarn" | |
| - name: Enable Corepack | |
| run: corepack enable | |
| - name: Activate Yarn 3.6.4 | |
| run: corepack prepare yarn@3.6.4 --activate | |
| - name: Install dependencies | |
| run: yarn install --immutable | |
| - name: Create .env file | |
| run: | | |
| echo "APP_LINK_PREFIX=${{ secrets.APP_LINK_PREFIX }}" > .env | |
| echo "FLEETBASE_KEY=${{ secrets.FLEETBASE_KEY }}" > .env | |
| echo "STOREFRONT_KEY=${{ secrets.STOREFRONT_KEY }}" > .env | |
| echo "GOOGLE_MAPS_API_KEY=${{ secrets.GOOGLE_MAPS_API_KEY }}" >> .env | |
| echo "FACEBOOK_APP_ID=${{ secrets.FACEBOOK_APP_ID }}" >> .env | |
| echo "FACEBOOK_CLIENT_TOKEN=${{ secrets.FACEBOOK_CLIENT_TOKEN }}" >> .env | |
| echo "GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}" >> .env | |
| echo "GOOGLE_IOS_CLIENT_ID=${{ secrets.GOOGLE_IOS_CLIENT_ID }}" >> .env | |
| - name: Cache CocoaPods | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ios/Pods | |
| ~/Library/Caches/CocoaPods | |
| ~/.cocoapods | |
| key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} | |
| - name: Install CocoaPods | |
| run: | | |
| sudo gem install cocoapods | |
| cd ios && pod install --repo-update | |
| - name: Build iOS Release Archive | |
| run: | | |
| cd ios | |
| xcodebuild -workspace StorefrontApp.xcworkspace \ | |
| -scheme StorefrontApp \ | |
| -configuration Release \ | |
| -archivePath build/StorefrontApp.xcarchive \ | |
| -allowProvisioningUpdates \ | |
| archive | |
| - name: Upload iOS Release Archive | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ios-release-archive | |
| path: ios/build/StorefrontApp.xcarchive | |
| retention-days: 90 |