feat(mobile): move buttons in the bottom sheet to the kebabu menu #46473
Workflow file for this run
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: Build Mobile | |
| on: | |
| workflow_call: | |
| inputs: | |
| ref: | |
| required: false | |
| type: string | |
| environment: | |
| description: 'Target environment' | |
| required: true | |
| default: 'development' | |
| type: string | |
| secrets: | |
| KEY_JKS: | |
| required: true | |
| ALIAS: | |
| required: true | |
| ANDROID_KEY_PASSWORD: | |
| required: true | |
| ANDROID_STORE_PASSWORD: | |
| required: true | |
| APP_STORE_CONNECT_API_KEY_ID: | |
| required: true | |
| APP_STORE_CONNECT_API_KEY_ISSUER_ID: | |
| required: true | |
| APP_STORE_CONNECT_API_KEY: | |
| required: true | |
| IOS_CERTIFICATE_P12: | |
| required: true | |
| IOS_CERTIFICATE_PASSWORD: | |
| required: true | |
| IOS_PROVISIONING_PROFILE: | |
| required: true | |
| IOS_PROVISIONING_PROFILE_SHARE_EXTENSION: | |
| required: true | |
| IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION: | |
| required: true | |
| IOS_DEVELOPMENT_PROVISIONING_PROFILE: | |
| required: true | |
| IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION: | |
| required: true | |
| IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION: | |
| required: true | |
| FASTLANE_TEAM_ID: | |
| required: true | |
| pull_request: | |
| push: | |
| branches: [main] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: {} | |
| jobs: | |
| pre-job: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| should_run: ${{ steps.check.outputs.should_run }} | |
| steps: | |
| - id: token | |
| uses: immich-app/devtools/actions/create-workflow-token@da177fa133657503ddb7503f8ba53dccefec5da1 # create-workflow-token-action-v1.0.0 | |
| with: | |
| app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} | |
| private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} | |
| - name: Check what should run | |
| id: check | |
| uses: immich-app/devtools/actions/pre-job@08bac802a312fc89808e0dd589271ca0974087b5 # pre-job-action-v2.0.0 | |
| with: | |
| github-token: ${{ steps.token.outputs.token }} | |
| filters: | | |
| mobile: | |
| - 'mobile/**' | |
| force-filters: | | |
| - '.github/workflows/build-mobile.yml' | |
| force-events: 'workflow_call,workflow_dispatch' | |
| build-sign-android: | |
| name: Build and sign Android | |
| needs: pre-job | |
| permissions: | |
| contents: read | |
| # Skip when PR from a fork | |
| if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' && fromJSON(needs.pre-job.outputs.should_run).mobile == true }} | |
| runs-on: mich | |
| steps: | |
| - id: token | |
| uses: immich-app/devtools/actions/create-workflow-token@da177fa133657503ddb7503f8ba53dccefec5da1 # create-workflow-token-action-v1.0.0 | |
| with: | |
| app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} | |
| private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} | |
| - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 | |
| with: | |
| ref: ${{ inputs.ref || github.sha }} | |
| persist-credentials: false | |
| token: ${{ steps.token.outputs.token }} | |
| - name: Create the Keystore | |
| env: | |
| KEY_JKS: ${{ secrets.KEY_JKS }} | |
| working-directory: ./mobile | |
| run: printf "%s" $KEY_JKS | base64 -d > android/key.jks | |
| - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0 | |
| with: | |
| distribution: 'zulu' | |
| java-version: '17' | |
| - name: Restore Gradle Cache | |
| id: cache-gradle-restore | |
| uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| ~/.android/sdk | |
| mobile/android/.gradle | |
| mobile/.dart_tool | |
| key: build-mobile-gradle-${{ runner.os }}-main | |
| - name: Setup Flutter SDK | |
| uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0 | |
| with: | |
| channel: 'stable' | |
| flutter-version-file: ./mobile/pubspec.yaml | |
| cache: true | |
| - name: Setup Android SDK | |
| uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3.2.2 | |
| with: | |
| packages: '' | |
| - name: Get Packages | |
| working-directory: ./mobile | |
| run: flutter pub get | |
| - name: Generate translation file | |
| run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart | |
| working-directory: ./mobile | |
| - name: Generate platform APIs | |
| run: make pigeon | |
| working-directory: ./mobile | |
| - name: Build Android App Bundle | |
| working-directory: ./mobile | |
| env: | |
| ALIAS: ${{ secrets.ALIAS }} | |
| ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} | |
| ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }} | |
| IS_MAIN: ${{ github.ref == 'refs/heads/main' }} | |
| run: | | |
| if [[ $IS_MAIN == 'true' ]]; then | |
| flutter build apk --release | |
| flutter build apk --release --split-per-abi --target-platform android-arm,android-arm64,android-x64 | |
| else | |
| flutter build apk --debug --split-per-abi --target-platform android-arm64 | |
| fi | |
| - name: Publish Android Artifact | |
| uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 | |
| with: | |
| name: release-apk-signed | |
| path: mobile/build/app/outputs/flutter-apk/*.apk | |
| - name: Save Gradle Cache | |
| id: cache-gradle-save | |
| uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| if: github.ref == 'refs/heads/main' | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| ~/.android/sdk | |
| mobile/android/.gradle | |
| mobile/.dart_tool | |
| key: ${{ steps.cache-gradle-restore.outputs.cache-primary-key }} | |
| build-sign-ios: | |
| name: Build and sign iOS | |
| needs: pre-job | |
| permissions: | |
| contents: read | |
| # Run on main branch or workflow_dispatch, or on PRs/other branches (build only, no upload) | |
| if: ${{ !github.event.pull_request.head.repo.fork && fromJSON(needs.pre-job.outputs.should_run).mobile == true }} | |
| runs-on: macos-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| with: | |
| ref: ${{ inputs.ref || github.sha }} | |
| persist-credentials: false | |
| - name: Setup Flutter SDK | |
| uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2 | |
| with: | |
| channel: 'stable' | |
| flutter-version-file: ./mobile/pubspec.yaml | |
| cache: true | |
| - name: Install Flutter dependencies | |
| working-directory: ./mobile | |
| run: flutter pub get | |
| - name: Generate translation files | |
| run: dart run easy_localization:generate -S ../i18n && dart run bin/generate_keys.dart | |
| working-directory: ./mobile | |
| - name: Generate platform APIs | |
| run: make pigeon | |
| working-directory: ./mobile | |
| - name: Setup Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: '3.3' | |
| bundler-cache: true | |
| working-directory: ./mobile/ios | |
| - name: Install CocoaPods dependencies | |
| working-directory: ./mobile/ios | |
| run: | | |
| pod install | |
| - name: Create API Key | |
| env: | |
| API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} | |
| API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} | |
| API_KEY_CONTENT: ${{ secrets.APP_STORE_CONNECT_API_KEY }} | |
| working-directory: ./mobile/ios | |
| run: | | |
| mkdir -p ~/.appstoreconnect/private_keys | |
| echo "$API_KEY_CONTENT" | base64 --decode > ~/.appstoreconnect/private_keys/AuthKey_${API_KEY_ID}.p8 | |
| - name: Import Certificate and Provisioning Profiles | |
| env: | |
| IOS_CERTIFICATE_P12: ${{ secrets.IOS_CERTIFICATE_P12 }} | |
| IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }} | |
| IOS_PROVISIONING_PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }} | |
| IOS_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_SHARE_EXTENSION }} | |
| IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION }} | |
| IOS_DEVELOPMENT_PROVISIONING_PROFILE: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE }} | |
| IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION }} | |
| IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION }} | |
| ENVIRONMENT: ${{ inputs.environment || 'development' }} | |
| working-directory: ./mobile/ios | |
| run: | | |
| # Decode certificate | |
| echo "$IOS_CERTIFICATE_P12" | base64 --decode > certificate.p12 | |
| # Decode provisioning profiles based on environment | |
| if [[ "$ENVIRONMENT" == "development" ]]; then | |
| echo "$IOS_DEVELOPMENT_PROVISIONING_PROFILE" | base64 --decode > profile_dev.mobileprovision | |
| echo "$IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION" | base64 --decode > profile_dev_share.mobileprovision | |
| echo "$IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION" | base64 --decode > profile_dev_widget.mobileprovision | |
| ls -lh profile_dev*.mobileprovision | |
| else | |
| echo "$IOS_PROVISIONING_PROFILE" | base64 --decode > profile.mobileprovision | |
| echo "$IOS_PROVISIONING_PROFILE_SHARE_EXTENSION" | base64 --decode > profile_share.mobileprovision | |
| echo "$IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION" | base64 --decode > profile_widget.mobileprovision | |
| ls -lh profile*.mobileprovision | |
| fi | |
| - name: Create keychain and import certificate | |
| env: | |
| KEYCHAIN_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }} | |
| CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }} | |
| working-directory: ./mobile/ios | |
| run: | | |
| # Create keychain | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain | |
| security default-keychain -s build.keychain | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain | |
| security set-keychain-settings -t 3600 -u build.keychain | |
| # Import certificate | |
| security import certificate.p12 -k build.keychain -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security | |
| security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" build.keychain | |
| # Verify certificate was imported | |
| security find-identity -v -p codesigning build.keychain | |
| - name: Build and deploy to TestFlight | |
| env: | |
| FASTLANE_TEAM_ID: ${{ secrets.FASTLANE_TEAM_ID }} | |
| IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }} | |
| KEYCHAIN_NAME: build.keychain | |
| KEYCHAIN_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }} | |
| APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} | |
| APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} | |
| ENVIRONMENT: ${{ inputs.environment || 'development' }} | |
| BUNDLE_ID_SUFFIX: ${{ inputs.environment == 'production' && '' || 'development' }} | |
| GITHUB_REF: ${{ github.ref }} | |
| working-directory: ./mobile/ios | |
| run: | | |
| # Only upload to TestFlight on main branch | |
| if [[ "$GITHUB_REF" == "refs/heads/main" ]]; then | |
| if [[ "$ENVIRONMENT" == "development" ]]; then | |
| bundle exec fastlane gha_testflight_dev | |
| else | |
| bundle exec fastlane gha_release_prod | |
| fi | |
| else | |
| # Build only, no TestFlight upload for non-main branches | |
| bundle exec fastlane gha_build_only | |
| fi | |
| - name: Clean up keychain | |
| if: always() | |
| run: | | |
| security delete-keychain build.keychain || true | |
| - name: Upload IPA artifact | |
| uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 | |
| with: | |
| name: ios-release-ipa | |
| path: mobile/ios/Runner.ipa |