├── .firebaserc ├── .github ├── dependabot.yml └── workflows │ ├── 00-main.yml │ ├── 01-test-analyze.yml │ ├── 02-conventional-release.yml │ ├── 03a-build-ios.yml │ ├── 03b-build-android.yml │ ├── 11-parse-screenshot.yml │ ├── 12a-integration-screenshot-ios.yml │ ├── 12b-integration-screenshot-android.yml │ ├── 13a-integration-screenshot-commit-ios.yml │ ├── 13b-integration-screenshot-commit-android.yml │ ├── 21a-upload-release-ios.yml │ ├── 21b-upload-release-android.yml │ ├── 90-main-pr.yml │ └── 91-lint-pr.yml ├── .gitignore ├── .metadata ├── .releaserc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── adr ├── 001-CI-CD-tool.md ├── 002-deploy-tool.md ├── 003-change-package-name-tool.md └── 004-versioning.md ├── analysis_options.yaml ├── android ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── app │ ├── build.gradle │ ├── google-services.json │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── org │ │ │ │ └── microservicer │ │ │ │ └── bootstrap │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── fastlane │ ├── Appfile │ ├── Fastfile │ ├── README.md │ └── metadata │ │ └── android │ │ ├── en-GB │ │ └── changelogs │ │ │ ├── 0.31.0.txt │ │ │ └── 0.31.1.txt │ │ └── en-US │ │ ├── full_description.txt │ │ ├── images │ │ ├── icon.png │ │ └── phoneScreenshots │ │ │ ├── pixel_6-0-home.png │ │ │ └── pixel_6-1-second.png │ │ ├── short_description.txt │ │ └── title.txt ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── docs └── images │ └── main_full.png ├── firebase.json ├── firestore.indexes.json ├── firestore.rules ├── flutter_pipelines.iml ├── git_hooks ├── commit-msg └── pre-commit ├── integration_test └── screenshot_test.dart ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Gemfile ├── Gemfile.lock ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings ├── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── GoogleService-Info.plist │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── RunnerTests │ └── RunnerTests.swift ├── fastlane │ ├── Appfile │ ├── Fastfile │ ├── Matchfile │ ├── README.md │ ├── devices.txt │ ├── metadata │ │ ├── copyright.txt │ │ ├── en-US │ │ │ ├── description.txt │ │ │ ├── keywords.txt │ │ │ ├── marketing_url.txt │ │ │ ├── name.txt │ │ │ ├── privacy_url.txt │ │ │ ├── promotional_text.txt │ │ │ ├── subtitle.txt │ │ │ └── support_url.txt │ │ ├── primary_category.txt │ │ ├── primary_first_sub_category.txt │ │ ├── primary_second_sub_category.txt │ │ ├── review_information │ │ │ ├── demo_password.txt │ │ │ ├── demo_user.txt │ │ │ ├── email_address.txt │ │ │ ├── first_name.txt │ │ │ ├── last_name.txt │ │ │ ├── notes.txt │ │ │ └── phone_number.txt │ │ ├── secondary_category.txt │ │ ├── secondary_first_sub_category.txt │ │ └── secondary_second_sub_category.txt │ └── screenshots │ │ └── en-US │ │ ├── iPhone SE (3rd generation)-0-home.png │ │ └── iPhone SE (3rd generation)-1-second.png └── firebase_app_id_file.json ├── lib ├── main.dart └── screens │ ├── home_page.dart │ └── second_screen.dart ├── pubspec.lock ├── pubspec.yaml ├── screenshots └── 0-home.png ├── scripts ├── clean_up.sh └── install_hooks.sh ├── shorebird.yaml ├── storage.rules ├── test └── widget_test.dart └── test_driver └── screenshot_test.dart /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "flutter-pipelines" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | # - package-ecosystem: "npm" # See documentation for possible values 9 | # directory: "/functions" # Location of package manifests 10 | # schedule: 11 | # interval: "weekly" 12 | - package-ecosystem: "pub" # See documentation for possible values 13 | directory: "/" # Location of package manifests 14 | schedule: 15 | interval: "weekly" 16 | commit-message: 17 | prefix: "chore(deps)" 18 | - package-ecosystem: "github-actions" 19 | directory: "/" 20 | schedule: 21 | interval: "weekly" 22 | commit-message: 23 | prefix: "chore(deps)" 24 | -------------------------------------------------------------------------------- /.github/workflows/00-main.yml: -------------------------------------------------------------------------------- 1 | name: main-workflow 2 | on: 3 | push: 4 | branches: 5 | - main 6 | - master 7 | workflow_dispatch: 8 | 9 | concurrency: 10 | group: ${{ github.workflow }} 11 | 12 | env: 13 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 14 | 15 | jobs: 16 | token: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: GH_TOKEN 20 | if: env.GH_TOKEN == '' 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | run: echo "GH_TOKEN=${GITHUB_TOKEN}" >> $GITHUB_ENV 24 | 25 | test-analyze: 26 | uses: ./.github/workflows/01-test-analyze.yml 27 | 28 | conventional-release: 29 | needs: 30 | - test-analyze 31 | uses: ./.github/workflows/02-conventional-release.yml 32 | secrets: inherit 33 | 34 | parse-screenshot: 35 | uses: ./.github/workflows/11-parse-screenshot.yml 36 | with: 37 | # Set to empty string to always take screenshots 38 | screenshot-text: "SCREENSHOT" 39 | 40 | build-ios: 41 | # set if false to disable iOS branch of build 42 | if: ${{ needs.conventional-release.outputs.new_release_published == 'true' }} 43 | needs: 44 | - conventional-release 45 | - parse-screenshot 46 | uses: ./.github/workflows/03a-build-ios.yml 47 | with: 48 | screenshot: ${{ needs.parse-screenshot.outputs.contains_screenshot }} 49 | ipa: "true" 50 | secrets: inherit 51 | 52 | upload-ios: 53 | if: ${{ needs.parse-screenshot.outputs.contains_screenshot == 'false' }} 54 | needs: 55 | - parse-screenshot 56 | - build-ios 57 | - conventional-release 58 | uses: ./.github/workflows/21a-upload-release-ios.yml 59 | with: 60 | new_release: ${{ needs.conventional-release.outputs.new_release }} 61 | new_release_notes: ${{ needs.conventional-release.outputs.new_release_notes }} 62 | secrets: inherit 63 | 64 | build-android: 65 | # set if false to disable android branch of build 66 | if: ${{ needs.conventional-release.outputs.new_release_published == 'true' }} 67 | needs: 68 | - conventional-release 69 | - parse-screenshot 70 | uses: ./.github/workflows/03b-build-android.yml 71 | with: 72 | screenshot: ${{ needs.parse-screenshot.outputs.contains_screenshot }} 73 | apk: "true" 74 | secrets: inherit 75 | 76 | upload-android: 77 | if: ${{ needs.parse-screenshot.outputs.contains_screenshot == 'false' }} 78 | needs: 79 | - parse-screenshot 80 | - build-android 81 | - conventional-release 82 | uses: ./.github/workflows/21b-upload-release-android.yml 83 | with: 84 | new_release: ${{ needs.conventional-release.outputs.new_release }} 85 | new_release_notes: ${{ needs.conventional-release.outputs.new_release_notes }} 86 | secrets: inherit 87 | 88 | integration-screenshot-ios: 89 | if: ${{ needs.parse-screenshot.outputs.contains_screenshot == 'true' }} 90 | needs: 91 | - parse-screenshot 92 | - build-ios 93 | uses: ./.github/workflows/12a-integration-screenshot-ios.yml 94 | with: 95 | model: "['iPhone 13 Pro Max', 'iPhone 8', 'iPad Pro (12.9-inch) (5th generation)', 'iPad Pro (11-inch) (3rd generation)']" 96 | #model: "['iPhone SE (3rd generation)']" 97 | 98 | integration-screenshot-android: 99 | if: ${{ needs.parse-screenshot.outputs.contains_screenshot == 'true' }} 100 | needs: 101 | - parse-screenshot 102 | - build-android 103 | uses: ./.github/workflows/12b-integration-screenshot-android.yml 104 | with: 105 | api_level: 30 106 | model: "['pixel_6']" 107 | 108 | integration-screenshot-commit-ios: 109 | if: ${{ needs.parse-screenshot.outputs.contains_screenshot == 'true' }} 110 | needs: 111 | - integration-screenshot-ios 112 | uses: ./.github/workflows/13a-integration-screenshot-commit-ios.yml 113 | with: 114 | locale: "['en-US']" 115 | secrets: inherit 116 | 117 | integration-screenshot-commit-android: 118 | if: ${{ needs.parse-screenshot.outputs.contains_screenshot == 'true' }} 119 | needs: 120 | - integration-screenshot-android 121 | uses: ./.github/workflows/13b-integration-screenshot-commit-android.yml 122 | with: 123 | locale: "['en-US']" 124 | secrets: inherit 125 | 126 | upload-ios-screenhot: 127 | needs: 128 | - integration-screenshot-commit-ios 129 | - conventional-release 130 | uses: ./.github/workflows/21a-upload-release-ios.yml 131 | with: 132 | new_release: ${{ needs.conventional-release.outputs.new_release }} 133 | new_release_notes: ${{ needs.conventional-release.outputs.new_release_notes }} 134 | secrets: inherit 135 | 136 | upload-android-screenhot: 137 | needs: 138 | - integration-screenshot-commit-android 139 | - conventional-release 140 | uses: ./.github/workflows/21b-upload-release-android.yml 141 | with: 142 | new_release: ${{ needs.conventional-release.outputs.new_release }} 143 | new_release_notes: ${{ needs.conventional-release.outputs.new_release_notes }} 144 | secrets: inherit 145 | -------------------------------------------------------------------------------- /.github/workflows/01-test-analyze.yml: -------------------------------------------------------------------------------- 1 | name: test-analyze 2 | on: 3 | workflow_call: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | timeout-minutes: 10 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | fetch-depth: 0 13 | - name: Flutter 14 | uses: subosito/flutter-action@v2 15 | with: 16 | cache: true 17 | cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' 18 | cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" 19 | - run: flutter pub get 20 | - run: flutter analyze --no-pub #--no-fatal-infos 21 | - run: flutter test -------------------------------------------------------------------------------- /.github/workflows/02-conventional-release.yml: -------------------------------------------------------------------------------- 1 | name: conventional-release 2 | on: 3 | workflow_call: 4 | secrets: 5 | GH_TOKEN: 6 | required: true 7 | 8 | outputs: 9 | new_release_published: 10 | description: 'If a new release was published' 11 | value: ${{ jobs.conventional-release.outputs.new_release_published }} 12 | new_release_version: 13 | description: 'The new release version' 14 | value: ${{ jobs.conventional-release.outputs.new_release_version }} 15 | new_release_notes: 16 | description: 'The release notes for the new release' 17 | value: ${{ jobs.conventional-release.outputs.new_release_notes }} 18 | 19 | jobs: 20 | conventional-release: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | with: 25 | fetch-depth: 1 26 | token: ${{ secrets.GH_TOKEN }} 27 | fetch-tags: true 28 | 29 | - name: Semantic Release 30 | uses: cycjimmy/semantic-release-action@v4 31 | id: semantic 32 | with: 33 | extra_plugins: | 34 | @semantic-release/changelog 35 | @semantic-release/exec 36 | @semantic-release/git 37 | env: 38 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 39 | 40 | outputs: 41 | new_release_published: ${{ steps.semantic.outputs.new_release_published }} 42 | new_release_version: ${{ steps.semantic.outputs.new_release_version }} 43 | new_release_notes: ${{ steps.semantic.outputs.new_release_notes }} 44 | -------------------------------------------------------------------------------- /.github/workflows/03a-build-ios.yml: -------------------------------------------------------------------------------- 1 | name: build-ios 2 | on: 3 | workflow_call: 4 | inputs: 5 | screenshot: 6 | type: string 7 | required: true 8 | ipa: 9 | description: 'Run IPA build' 10 | type: string 11 | required: true 12 | workflow_dispatch: 13 | inputs: 14 | screenshot: 15 | description: 'Run screenshot build' 16 | type: choice 17 | options: ['true', 'false'] 18 | required: true 19 | ipa: 20 | description: 'Run IPA build' 21 | type: choice 22 | options: ['true', 'false'] 23 | required: true 24 | 25 | 26 | jobs: 27 | build-ios: 28 | runs-on: macos-latest 29 | timeout-minutes: 20 30 | defaults: 31 | run: 32 | working-directory: ios 33 | steps: 34 | - uses: actions/checkout@v4 35 | with: 36 | fetch-depth: 0 37 | 38 | # Change the following key to match your secret repository choice 39 | - run: 'echo "$GC_KEYS" > gc_keys.json' 40 | shell: bash 41 | env: 42 | GC_KEYS: ${{ secrets.GC_KEYS }} 43 | 44 | - run: 'echo "$API_KEY" > AuthKey.p8' 45 | shell: bash 46 | env: 47 | API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }} 48 | 49 | - run: bundle install 50 | 51 | - run: bundle exec fastlane versioning 52 | 53 | - name: Flutter 54 | uses: subosito/flutter-action@v2 55 | with: 56 | cache: true 57 | cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' 58 | cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" 59 | - run: flutter build ios --simulator --target=integration_test/screenshot_test.dart 60 | if: ${{ inputs.screenshot == 'true' }} 61 | 62 | - name: Archive integration ipa 63 | if: ${{ inputs.screenshot == 'true' }} 64 | uses: actions/upload-artifact@v4 65 | with: 66 | name: app-simulator-build 67 | path: build/ios/iphonesimulator/Runner.app 68 | if-no-files-found: error 69 | retention-days: 3 70 | 71 | # Build ios Release 72 | - run: flutter build ios --release --config-only --no-codesign --target=lib/main.dart 73 | if: ${{ inputs.ipa == 'true' }} 74 | 75 | - run: bundle exec fastlane build 76 | if: ${{ inputs.ipa == 'true' }} 77 | 78 | - name: Archive ipa 79 | if: ${{ inputs.ipa == 'true' }} 80 | uses: actions/upload-artifact@v4 81 | with: 82 | name: Runner.ipa 83 | path: ios/Runner.ipa 84 | if-no-files-found: error 85 | retention-days: 3 86 | -------------------------------------------------------------------------------- /.github/workflows/03b-build-android.yml: -------------------------------------------------------------------------------- 1 | name: build-android 2 | on: 3 | workflow_call: 4 | inputs: 5 | screenshot: 6 | type: string 7 | required: true 8 | apk: 9 | description: 'Run APK build' 10 | type: string 11 | required: true 12 | workflow_dispatch: 13 | inputs: 14 | screenshot: 15 | description: 'Run screenshot build' 16 | type: choice 17 | options: ['true', 'false'] 18 | required: true 19 | apk: 20 | description: 'Run APK build' 21 | type: choice 22 | options: ['true', 'false'] 23 | required: true 24 | 25 | jobs: 26 | build-android: 27 | runs-on: ubuntu-latest 28 | timeout-minutes: 20 29 | defaults: 30 | run: 31 | working-directory: android 32 | steps: 33 | - uses: actions/checkout@v4 34 | with: 35 | fetch-depth: 0 36 | 37 | - name: Configure Keystore 38 | run: | 39 | echo "$PLAY_STORE_UPLOAD_KEY" | base64 --decode > app/upload-keystore.jks 40 | echo "storeFile=upload-keystore.jks" >> key.properties 41 | echo "keyAlias=$KEYSTORE_KEY_ALIAS" >> key.properties 42 | echo "storePassword=$KEYSTORE_STORE_PASSWORD" >> key.properties 43 | echo "keyPassword=$KEYSTORE_KEY_PASSWORD" >> key.properties 44 | env: 45 | PLAY_STORE_UPLOAD_KEY: ${{ secrets.PLAY_STORE_UPLOAD_KEY }} 46 | KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }} 47 | KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }} 48 | KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }} 49 | 50 | - uses: actions/setup-java@v4 51 | with: 52 | distribution: 'zulu' 53 | java-version: '17' 54 | 55 | - name: Setup Fastlane 56 | uses: ruby/setup-ruby@v1 57 | with: 58 | ruby-version: "3.2" 59 | bundler-cache: true 60 | working-directory: android 61 | 62 | - run: bundle install 63 | 64 | - run: bundle exec fastlane versioning 65 | env: 66 | PLAY_STORE_CONFIG_JSON: ${{ secrets.PLAY_STORE_CONFIG_JSON }} 67 | 68 | - name: Flutter 69 | uses: subosito/flutter-action@v2 70 | with: 71 | cache: true 72 | cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' 73 | cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" 74 | - run: flutter build apk --debug --target=integration_test/screenshot_test.dart 75 | if: ${{ inputs.screenshot == 'true' }} 76 | 77 | - name: Archive integration test apk 78 | if: ${{ inputs.screenshot == 'true' }} 79 | uses: actions/upload-artifact@v4 80 | with: 81 | name: app-debug.apk 82 | path: build/app/outputs/flutter-apk/app-debug.apk 83 | if-no-files-found: error 84 | retention-days: 3 85 | 86 | # Build android Release 87 | 88 | - run: flutter build appbundle --build-number ${{ env.ANDROID_VERSION_CODE }} --build-name ${{ env.ANDROID_VERSION_NAME }} --target lib/main.dart 89 | if: ${{ inputs.apk == 'true' }} 90 | 91 | - name: Archive appbundle 92 | if: ${{ inputs.apk == 'true' }} 93 | uses: actions/upload-artifact@v4 94 | with: 95 | name: app-release.aab 96 | path: build/app/outputs/bundle/release/app-release.aab 97 | if-no-files-found: error 98 | retention-days: 3 99 | -------------------------------------------------------------------------------- /.github/workflows/11-parse-screenshot.yml: -------------------------------------------------------------------------------- 1 | name: parse-screenshot 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | screenshot-text: 7 | description: 'Text to search for in commit message' 8 | required: true 9 | type: string 10 | outputs: 11 | contains_screenshot: 12 | description: 'If commit message contains screenshot keyword' 13 | value: ${{ jobs.check_commit_message.outputs.contains_screenshot }} 14 | 15 | jobs: 16 | check_commit_message: 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - name: Checkout repository 21 | uses: actions/checkout@v4 22 | with: 23 | fetch-depth: 0 24 | 25 | - name: Check Commit Message for '${{ inputs.screenshot-text }}' 26 | id: check_commit 27 | run: | 28 | COMMIT_MESSAGE=$(git log --format=%B -n 1 ${{ github.sha }}) 29 | if [[ $COMMIT_MESSAGE == *"${{ inputs.screenshot-text }}"* ]]; then 30 | echo "Contains Screenshot: true" 31 | echo "contains_screenshot=true" >> $GITHUB_OUTPUT 32 | else 33 | echo "Contains Screenshot: false" 34 | echo "contains_screenshot=false" >> $GITHUB_OUTPUT 35 | fi 36 | shell: bash 37 | 38 | outputs: 39 | contains_screenshot: ${{ steps.check_commit.outputs.contains_screenshot }} 40 | -------------------------------------------------------------------------------- /.github/workflows/12a-integration-screenshot-ios.yml: -------------------------------------------------------------------------------- 1 | name: integration-screenshot-ios 2 | on: 3 | workflow_call: 4 | inputs: 5 | model: 6 | required: true 7 | type: string 8 | 9 | jobs: 10 | take-screenshot-ios: 11 | runs-on: macos-latest 12 | timeout-minutes: 15 13 | strategy: 14 | matrix: 15 | model: ${{ fromJson(inputs.model) }} 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | 21 | - name: Download app 22 | uses: actions/download-artifact@v4 23 | with: 24 | name: app-simulator-build 25 | path: build/ios/iphonesimulator/Runner.app 26 | 27 | - name: Flutter 28 | uses: subosito/flutter-action@v2 29 | with: 30 | cache: true 31 | cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' 32 | cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" 33 | - uses: futureware-tech/simulator-action@v3 34 | with: 35 | model: ${{ matrix.model }} 36 | - run: >- 37 | flutter drive 38 | --driver=test_driver/screenshot_test.dart 39 | --use-application-binary=build/ios/iphonesimulator/Runner.app 40 | 41 | - name: Append model name to all files in screenshots folder 42 | run: | 43 | for file in screenshots/*; do 44 | filename=$(basename "$file") 45 | mv "$file" "screenshots/${{ matrix.model }}-$filename" 46 | done 47 | 48 | - name: Archive screenshots 49 | uses: actions/upload-artifact@v4 50 | with: 51 | name: ios-screenshot-${{ matrix.model }} 52 | path: screenshots 53 | if-no-files-found: error 54 | retention-days: 7 -------------------------------------------------------------------------------- /.github/workflows/12b-integration-screenshot-android.yml: -------------------------------------------------------------------------------- 1 | name: integration-screenshot-android 2 | on: 3 | workflow_call: 4 | inputs: 5 | api_level: 6 | description: 'Android API level' 7 | required: true 8 | type: number 9 | model: 10 | description: 'Android device model id' 11 | required: true 12 | type: string 13 | 14 | jobs: 15 | take-screenshot-android: 16 | runs-on: macos-latest 17 | timeout-minutes: 15 18 | env: 19 | API_LEVEL: ${{ inputs.api_level }} 20 | CORES: 3 21 | strategy: 22 | matrix: 23 | model: ${{ fromJson(inputs.model) }} 24 | steps: 25 | - name: checkout 26 | uses: actions/checkout@v4 27 | 28 | - name: Gradle cache 29 | uses: gradle/gradle-build-action@v3 30 | 31 | - name: Download app 32 | uses: actions/download-artifact@v4 33 | with: 34 | name: app-debug.apk 35 | 36 | - name: Flutter 37 | uses: subosito/flutter-action@v2 38 | with: 39 | cache: true 40 | cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' 41 | cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" 42 | 43 | - name: AVD cache 44 | uses: actions/cache@v4 45 | id: avd-cache 46 | with: 47 | path: | 48 | ~/.android/avd/* 49 | ~/.android/adb* 50 | key: avd-${{ env.API_LEVEL }} 51 | 52 | - name: create AVD and generate snapshot for caching 53 | if: steps.avd-cache.outputs.cache-hit != 'true' 54 | uses: reactivecircus/android-emulator-runner@v2 55 | with: 56 | api-level: ${{ env.API_LEVEL }} 57 | profile: ${{ matrix.model }} 58 | target: google_apis 59 | cores: ${{ env.CORES }} 60 | force-avd-creation: false 61 | emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none 62 | disable-animations: false 63 | script: avdmanager list device 64 | 65 | - name: run tests 66 | uses: reactivecircus/android-emulator-runner@v2 67 | with: 68 | api-level: ${{ env.API_LEVEL }} 69 | profile: ${{ matrix.model }} 70 | target: google_apis 71 | cores: ${{ env.CORES }} 72 | force-avd-creation: false 73 | emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none 74 | disable-animations: true 75 | script: "flutter drive --driver=test_driver/screenshot_test.dart --use-application-binary=app-debug.apk" 76 | 77 | - name: Append model name to all files in screenshots folder 78 | run: | 79 | for file in screenshots/*; do 80 | filename=$(basename "$file") 81 | mv "$file" "screenshots/${{ matrix.model }}-$filename" 82 | done 83 | 84 | - name: Archive screenshots 85 | uses: actions/upload-artifact@v4 86 | with: 87 | name: android-screenshot-${{ matrix.model }} 88 | path: screenshots 89 | if-no-files-found: error 90 | retention-days: 7 91 | -------------------------------------------------------------------------------- /.github/workflows/13a-integration-screenshot-commit-ios.yml: -------------------------------------------------------------------------------- 1 | name: integration-screenshot-commit-ios 2 | on: 3 | workflow_call: 4 | inputs: 5 | locale: 6 | required: true 7 | type: string 8 | secrets: 9 | token: 10 | required: true 11 | 12 | jobs: 13 | commit-screenshots: 14 | runs-on: ubuntu-latest 15 | timeout-minutes: 5 16 | strategy: 17 | matrix: 18 | locale: ${{ fromJson(inputs.locale) }} 19 | steps: 20 | - uses: actions/checkout@v4 21 | with: 22 | fetch-depth: 0 23 | token: ${{ secrets.GH_TOKEN }} 24 | 25 | - uses: actions/download-artifact@v4 26 | with: 27 | path: screenshots 28 | 29 | - name: Move ios screenshots 30 | run: | 31 | mkdir -p ios/fastlane/screenshots/${{ matrix.locale }} 32 | find ./screenshots -type f -path '*/ios-*/*' -exec cp {} ios/fastlane/screenshots/${{ matrix.locale }} \; 33 | 34 | - name: Check for changes in ios/fastlane/screenshots/${{ matrix.locale }} 35 | id: git-diff 36 | run: | 37 | git diff --quiet -- 'ios/fastlane/screenshots/${{ matrix.locale }}' || (echo "Changes exist in ios screenshots" && echo changes=true >> $GITHUB_OUTPUT) 38 | continue-on-error: true 39 | 40 | - name: Commit screenshots 41 | if: steps.git-diff.outputs.changes == 'true' 42 | run: | 43 | git config --global user.name "GitHub Actions" 44 | git config --global user.email "action@github.com" 45 | git config pull.rebase true 46 | git add ios/fastlane/screenshots/${{ matrix.locale }} 47 | git commit -m "chore: Update screenshots iOS" -m "[skip ci]" 48 | git pull && git push -------------------------------------------------------------------------------- /.github/workflows/13b-integration-screenshot-commit-android.yml: -------------------------------------------------------------------------------- 1 | name: integration-screenshot-commit-android 2 | on: 3 | workflow_call: 4 | inputs: 5 | locale: 6 | required: true 7 | type: string 8 | secrets: 9 | token: 10 | required: true 11 | 12 | jobs: 13 | commit-screenshots: 14 | runs-on: ubuntu-latest 15 | timeout-minutes: 5 16 | strategy: 17 | matrix: 18 | locale: ${{ fromJson(inputs.locale) }} 19 | steps: 20 | - uses: actions/checkout@v4 21 | with: 22 | fetch-depth: 0 23 | token: ${{ secrets.GH_TOKEN }} 24 | 25 | - uses: actions/download-artifact@v4 26 | with: 27 | path: screenshots 28 | 29 | - name: Move android screenshots 30 | run: | 31 | mkdir -p android/fastlane/metadata/android/${{ matrix.locale }}/images/phoneScreenshots 32 | find ./screenshots -type f -path '*/android-*/*' -exec cp {} android/fastlane/metadata/android/${{ matrix.locale }}/images/phoneScreenshots \; 33 | 34 | - name: Check for changes in android/fastlane/metadata/android/${{ matrix.locale }}/images/phoneScreenshots 35 | id: git-diff 36 | run: | 37 | git diff --quiet -- 'android/fastlane/metadata/android/${{ matrix.locale }}/images/phoneScreenshots' || (echo "Changes exist in android screenshots" && echo changes=true >> $GITHUB_OUTPUT) 38 | continue-on-error: true 39 | 40 | - name: Commit screenshots 41 | if: steps.git-diff.outputs.changes == 'true' 42 | run: | 43 | git config --global user.name "GitHub Actions" 44 | git config --global user.email "action@github.com" 45 | git config pull.rebase true 46 | git add android/fastlane/metadata/android/${{ matrix.locale }}/images/phoneScreenshots 47 | git commit -m "chore: Update screenshots android" -m "[skip ci]" 48 | git pull && git push -------------------------------------------------------------------------------- /.github/workflows/21a-upload-release-ios.yml: -------------------------------------------------------------------------------- 1 | name: upload-release-ios 2 | on: 3 | workflow_call: 4 | inputs: 5 | new_release: 6 | required: true 7 | type: string 8 | description: "The new release version number" 9 | new_release_notes: 10 | required: true 11 | type: string 12 | description: "The release notes for the new release" 13 | 14 | jobs: 15 | build: 16 | runs-on: macos-latest 17 | timeout-minutes: 10 18 | defaults: 19 | run: 20 | working-directory: ios 21 | steps: 22 | - uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 25 | 26 | - name: Download app 27 | uses: actions/download-artifact@v4 28 | with: 29 | name: Runner.ipa 30 | path: ios/ 31 | 32 | - run: 'echo "$API_KEY" > AuthKey.p8' 33 | shell: bash 34 | env: 35 | API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }} 36 | 37 | - run: bundle install 38 | 39 | - run: bundle exec fastlane upload_testflight 40 | env: 41 | RELEASE_NOTES: ${{ inputs.new_release_notes }} 42 | - run: bundle exec fastlane upload_metadata_app_store 43 | -------------------------------------------------------------------------------- /.github/workflows/21b-upload-release-android.yml: -------------------------------------------------------------------------------- 1 | name: upload-release-android 2 | on: 3 | workflow_call: 4 | inputs: 5 | new_release: 6 | required: true 7 | type: string 8 | description: "The new release version number" 9 | new_release_notes: 10 | required: true 11 | type: string 12 | description: "The release notes for the new release" 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | timeout-minutes: 5 18 | defaults: 19 | run: 20 | working-directory: android 21 | steps: 22 | - uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 25 | 26 | - name: Download app 27 | uses: actions/download-artifact@v4 28 | with: 29 | name: app-release.aab 30 | path: build/app/outputs/bundle/release/ 31 | 32 | # Setup Ruby, Bundler, and Gemfile dependencies 33 | - name: Setup Fastlane 34 | uses: ruby/setup-ruby@v1 35 | with: 36 | ruby-version: "3.2" 37 | bundler-cache: true 38 | working-directory: android 39 | - run: bundle install 40 | 41 | - run: bundle exec fastlane versioning 42 | env: 43 | PLAY_STORE_CONFIG_JSON: ${{ secrets.PLAY_STORE_CONFIG_JSON }} 44 | 45 | - run: echo "${{ inputs.new_release_notes }}" > ./fastlane/metadata/android/en-GB/changelogs/${{ env.ANDROID_VERSION_CODE }}.txt 46 | 47 | - run: bundle exec fastlane internal 48 | env: 49 | PLAY_STORE_CONFIG_JSON: ${{ secrets.PLAY_STORE_CONFIG_JSON }} 50 | -------------------------------------------------------------------------------- /.github/workflows/90-main-pr.yml: -------------------------------------------------------------------------------- 1 | name: main-pull-request 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | - master 7 | jobs: 8 | test-analyze: 9 | uses: ./.github/workflows/01-test-analyze.yml -------------------------------------------------------------------------------- /.github/workflows/91-lint-pr.yml: -------------------------------------------------------------------------------- 1 | name: "lint-pr" 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | 10 | permissions: 11 | pull-requests: read 12 | 13 | jobs: 14 | main: 15 | name: Validate PR title 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: amannn/action-semantic-pull-request@v5 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | 41 | # Android Studio will place build artifacts here 42 | /android/app/debug 43 | /android/app/profile 44 | /android/app/release 45 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 17 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 18 | - platform: android 19 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 20 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 21 | - platform: ios 22 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 23 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 24 | - platform: linux 25 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 26 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 27 | - platform: macos 28 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 29 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 30 | - platform: web 31 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 32 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 33 | - platform: windows 34 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 35 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | { 2 | "branches": [ 3 | "main", 4 | "master" 5 | ], 6 | "plugins": [ 7 | "@semantic-release/commit-analyzer", 8 | "@semantic-release/release-notes-generator", 9 | ["@semantic-release/changelog", { 10 | "linkReferences": "false", 11 | "linkCompare": "false" 12 | }], 13 | "@semantic-release/changelog", 14 | ["@semantic-release/exec", { 15 | "prepareCmd": "FOLDER_PATH=android/fastlane/metadata/android/en-GB/changelogs && mkdir -p $FOLDER_PATH && echo \"${nextRelease.notes}\" > $FOLDER_PATH/${nextRelease.version}.txt && git add $FOLDER_PATH/${nextRelease.version}.txt && sed -i \"s/^version: .*/version: ${nextRelease.version}/g\" pubspec.yaml" 16 | }], 17 | ["@semantic-release/git", { 18 | "assets": ["CHANGELOG.md", "pubspec.yaml", "android/fastlane/metadata/android/en-US/changelogs/${nextRelease.version}/default.txt"], 19 | "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" 20 | }], 21 | "@semantic-release/github" 22 | ] 23 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.31.1](https://github.com/microservicer/flutter-pipelines/compare/v0.31.0...v0.31.1) (2024-09-12) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * Missing release notes generator ([e6ab135](https://github.com/microservicer/flutter-pipelines/commit/e6ab135a83bef4261e231200d622bc8831945c5e)) 7 | 8 | ## [0.31.1](https://github.com/microservicer/flutter-pipelines/compare/v0.31.0...v0.31.1) (2024-09-12) 9 | 10 | 11 | ### Bug Fixes 12 | 13 | * Missing release notes generator ([e6ab135](https://github.com/microservicer/flutter-pipelines/commit/e6ab135a83bef4261e231200d622bc8831945c5e)) 14 | 15 | ## [0.30.3](https://github.com/microservicer/flutter-pipelines/compare/v0.30.2...v0.30.3) (2024-05-16) 16 | 17 | 18 | ### Bug Fixes 19 | 20 | * Update gem and Matchfiles ([da25625](https://github.com/microservicer/flutter-pipelines/commit/da25625ac75be6e88b9d70ded340108e5d6e5e1b)) 21 | 22 | ## [0.30.2](https://github.com/microservicer/flutter-pipelines/compare/v0.30.1...v0.30.2) (2024-05-16) 23 | 24 | 25 | ### Bug Fixes 26 | 27 | * Not running appstore config in register ([7d958e1](https://github.com/microservicer/flutter-pipelines/commit/7d958e16dde13420e80ee5517c863bdfcf1b3289)) 28 | 29 | ## [0.30.1](https://github.com/microservicer/flutter-pipelines/compare/v0.30.0...v0.30.1) (2024-05-14) 30 | 31 | 32 | ### Bug Fixes 33 | 34 | * Update iOS certs ([dd06f48](https://github.com/microservicer/flutter-pipelines/commit/dd06f485db9d9aeef7ca2d00d992a7b0af87e201)) 35 | 36 | # [0.30.0](https://github.com/microservicer/flutter-pipelines/compare/v0.29.0...v0.30.0) (2024-04-03) 37 | 38 | 39 | ### Bug Fixes 40 | 41 | * Build version for iOS ([cc47012](https://github.com/microservicer/flutter-pipelines/commit/cc4701285bf1d13e1072b5630f197f9f0fc66a54)) 42 | 43 | 44 | ### Features 45 | 46 | * Remove Shorebird ([d154f5a](https://github.com/microservicer/flutter-pipelines/commit/d154f5adff5ee1dbbe72715401498eafee960877)) 47 | 48 | # [0.29.0](https://github.com/microservicer/flutter-pipelines/compare/v0.28.0...v0.29.0) (2024-04-03) 49 | 50 | 51 | ### Features 52 | 53 | * Add pre-commit hook with flutter lint ([1991595](https://github.com/microservicer/flutter-pipelines/commit/199159534be0532921ab0afcb14f865aee09db04)) 54 | 55 | # [0.28.0](https://github.com/microservicer/flutter-pipelines/compare/v0.27.1...v0.28.0) (2023-09-27) 56 | 57 | 58 | ### Features 59 | 60 | * Add metadata folder for iOS ([66f2298](https://github.com/microservicer/flutter-pipelines/commit/66f22988013b5bb2aeaed1c539cb94704f316dba)) 61 | 62 | ## [0.27.1](https://github.com/microservicer/flutter-pipelines/compare/v0.27.0...v0.27.1) (2023-09-07) 63 | 64 | 65 | ### Bug Fixes 66 | 67 | * Revert changes to token ([8c59dbc](https://github.com/microservicer/flutter-pipelines/commit/8c59dbc648769a1e6df511f0f10e08a45d7a0e15)) 68 | * Try setting github token if GH_TOKEN is null ([2295b07](https://github.com/microservicer/flutter-pipelines/commit/2295b077ad821256e84b56fe46f638a4f23df59b)) 69 | * Typo in secrets ([33cd7f4](https://github.com/microservicer/flutter-pipelines/commit/33cd7f41164362e409ac06229ceb463659a20928)) 70 | * Use checkout v3 ([eb9372b](https://github.com/microservicer/flutter-pipelines/commit/eb9372babab1a15f4325595c96e223606bfa4555)) 71 | 72 | # [0.27.0](https://github.com/microservicer/flutter-pipelines/compare/v0.26.1...v0.27.0) (2023-09-07) 73 | 74 | 75 | ### Features 76 | 77 | * Change working directory ([3b1ca01](https://github.com/microservicer/flutter-pipelines/commit/3b1ca012e027f4f65f3e1a67ef7e26b563240cb1)) 78 | 79 | ## [0.26.1](https://github.com/microservicer/flutter-pipelines/compare/v0.26.0...v0.26.1) (2023-09-06) 80 | 81 | 82 | ### Bug Fixes 83 | 84 | * Add default working directory ([5174cc3](https://github.com/microservicer/flutter-pipelines/commit/5174cc3f5aa32249c2af13e93707b78b3e7ce099)) 85 | 86 | # [0.26.0](https://github.com/microservicer/flutter-pipelines/compare/v0.25.0...v0.26.0) (2023-09-06) 87 | 88 | 89 | ### Features 90 | 91 | * Add keystore to shorebird build ([7c62b02](https://github.com/microservicer/flutter-pipelines/commit/7c62b025695d4b9b3ca483c05e6e9489232f739e)) 92 | 93 | # [0.25.0](https://github.com/microservicer/flutter-pipelines/compare/v0.24.0...v0.25.0) (2023-09-06) 94 | 95 | 96 | ### Features 97 | 98 | * Add Shorebird android support ([#6](https://github.com/microservicer/flutter-pipelines/issues/6)) ([0965c4b](https://github.com/microservicer/flutter-pipelines/commit/0965c4bb3037c6092cde80dcc5eb0c73d678436d)) 99 | 100 | # [0.24.0](https://github.com/microservicer/flutter-pipelines/compare/v0.23.0...v0.24.0) (2023-09-06) 101 | 102 | 103 | ### Features 104 | 105 | * Uppdate the release version in pubspec.yaml ([4f752e2](https://github.com/microservicer/flutter-pipelines/commit/4f752e2e9f75928c7d1a6e0c3d2e5e9129dd8e5c)) 106 | 107 | # [0.23.0](https://github.com/microservicer/flutter-pipelines/compare/v0.22.1...v0.23.0) (2023-09-04) 108 | 109 | 110 | ### Features 111 | 112 | * Add workflow dispatch on main ([7bc2dd9](https://github.com/microservicer/flutter-pipelines/commit/7bc2dd99ecd2a49d583e1f58379c3151688a86f0)) 113 | 114 | ## [0.22.1](https://github.com/microservicer/flutter-pipelines/compare/v0.22.0...v0.22.1) (2023-08-14) 115 | 116 | 117 | ### Bug Fixes 118 | 119 | * Don't fail on no new screenshot ([b57a6ed](https://github.com/microservicer/flutter-pipelines/commit/b57a6ed7340fc27d6159a0f0bb2dcca1473fb940)) 120 | 121 | # [0.22.0](https://github.com/microservicer/flutter-pipelines/compare/v0.21.3...v0.22.0) (2023-08-14) 122 | 123 | 124 | ### Features 125 | 126 | * Add main pipeline picture ([9ef7b7a](https://github.com/microservicer/flutter-pipelines/commit/9ef7b7a4a2cd9de4975087baf4d3e6b7f8e41ab8)) 127 | 128 | ## [0.21.3](https://github.com/microservicer/flutter-pipelines/compare/v0.21.2...v0.21.3) (2023-08-12) 129 | 130 | 131 | ### Bug Fixes 132 | 133 | * Rebase before pushing screenshots ([616c213](https://github.com/microservicer/flutter-pipelines/commit/616c21364c0ce1b79c190cbadafbea6e706d94aa)) 134 | 135 | ## [0.21.2](https://github.com/microservicer/flutter-pipelines/compare/v0.21.1...v0.21.2) (2023-08-12) 136 | 137 | 138 | ### Bug Fixes 139 | 140 | * Pull before pushing screenshots ([f7e85d5](https://github.com/microservicer/flutter-pipelines/commit/f7e85d53bf39843038fa06d5447df31fc3ae5fcc)) 141 | 142 | ## [0.21.1](https://github.com/microservicer/flutter-pipelines/compare/v0.21.0...v0.21.1) (2023-08-12) 143 | 144 | 145 | ### Bug Fixes 146 | 147 | * Remove unused check ([4cfedd1](https://github.com/microservicer/flutter-pipelines/commit/4cfedd18aafaac1ec850f8df611dc3a8b7472079)) 148 | 149 | # [0.21.0](https://github.com/microservicer/flutter-pipelines/compare/v0.20.2...v0.21.0) (2023-08-12) 150 | 151 | 152 | ### Features 153 | 154 | * Split out commits to separate jobs ([e151dd1](https://github.com/microservicer/flutter-pipelines/commit/e151dd1d091ca58a9f3c61b06a4afbee34c496f7)) 155 | * Split out commits to separate jobs ([8e506c7](https://github.com/microservicer/flutter-pipelines/commit/8e506c7e9115ccf29d868aa1a8d1b3336a40e666)) 156 | 157 | ## [0.20.2](https://github.com/microservicer/flutter-pipelines/compare/v0.20.1...v0.20.2) (2023-08-09) 158 | 159 | 160 | ### Bug Fixes 161 | 162 | * GH actions not parsing boolean correctly ([1e32798](https://github.com/microservicer/flutter-pipelines/commit/1e327982a4992cf42cc62e1be4373637ff9cac71)) 163 | 164 | ## [0.20.1](https://github.com/microservicer/flutter-pipelines/compare/v0.20.0...v0.20.1) (2023-08-09) 165 | 166 | 167 | ### Bug Fixes 168 | 169 | * Test run ([739b621](https://github.com/microservicer/flutter-pipelines/commit/739b62127c610759525e7f7875191922ab8f82c0)) 170 | 171 | # [0.20.0](https://github.com/microservicer/flutter-pipelines/compare/v0.19.0...v0.20.0) (2023-08-09) 172 | 173 | 174 | ### Features 175 | 176 | * Add input variables to all builds ([b7ac695](https://github.com/microservicer/flutter-pipelines/commit/b7ac69540acdb9a93a5b08663f4b70135b7f5d49)) 177 | 178 | # [0.19.0](https://github.com/microservicer/flutter-pipelines/compare/v0.18.0...v0.19.0) (2023-08-08) 179 | 180 | 181 | ### Features 182 | 183 | * Add new screen for additional screenshot ([3bc7f0b](https://github.com/microservicer/flutter-pipelines/commit/3bc7f0ba1607477bc078ffa70c7918a0257b40bf)) 184 | 185 | # [0.18.0](https://github.com/microservicer/flutter-pipelines/compare/v0.17.8...v0.18.0) (2023-08-08) 186 | 187 | 188 | ### Features 189 | 190 | * Add new screen for additional screenshot ([a2e50a5](https://github.com/microservicer/flutter-pipelines/commit/a2e50a58637ed9c5201d00840b125ac05e1f30c4)) 191 | * Add new screen for additional screenshot ([19bf6d0](https://github.com/microservicer/flutter-pipelines/commit/19bf6d0cee67bd447e5dcc5f6fa89477fbcb0469)) 192 | 193 | ## [0.17.8](https://github.com/microservicer/flutter-pipelines/compare/v0.17.7...v0.17.8) (2023-08-08) 194 | 195 | 196 | ### Bug Fixes 197 | 198 | * Change names of artifacts ([cd27320](https://github.com/microservicer/flutter-pipelines/commit/cd273208ef554c6bfbefca43d2c363c096807a56)) 199 | 200 | ## [0.17.7](https://github.com/microservicer/flutter-pipelines/compare/v0.17.6...v0.17.7) (2023-08-08) 201 | 202 | 203 | ### Bug Fixes 204 | 205 | * Endings on builds ([b129dbc](https://github.com/microservicer/flutter-pipelines/commit/b129dbc80532f19fe14d0c63ed203d326c9e2666)) 206 | 207 | ## [0.17.6](https://github.com/microservicer/flutter-pipelines/compare/v0.17.5...v0.17.6) (2023-08-07) 208 | 209 | 210 | ### Bug Fixes 211 | 212 | * Delete all artifacts ([757ccf9](https://github.com/microservicer/flutter-pipelines/commit/757ccf9c022b9e14350cf3eff3f2c36f3aed441e)) 213 | 214 | ## [0.17.5](https://github.com/microservicer/flutter-pipelines/compare/v0.17.4...v0.17.5) (2023-08-07) 215 | 216 | 217 | ### Bug Fixes 218 | 219 | * Add keystore to build ([015912f](https://github.com/microservicer/flutter-pipelines/commit/015912f805d6a9ebd797a57d25057ffa916f8d38)) 220 | 221 | ## [0.17.4](https://github.com/microservicer/flutter-pipelines/compare/v0.17.3...v0.17.4) (2023-08-07) 222 | 223 | 224 | ### Bug Fixes 225 | 226 | * Some issues with builds ([fd95d07](https://github.com/microservicer/flutter-pipelines/commit/fd95d07968ecadbabaad0271ae5ddc34b78a4b1f)) 227 | 228 | ## [0.17.3](https://github.com/microservicer/flutter-pipelines/compare/v0.17.2...v0.17.3) (2023-08-07) 229 | 230 | 231 | ### Bug Fixes 232 | 233 | * Add secrets inherit ([456b364](https://github.com/microservicer/flutter-pipelines/commit/456b364799a8ece576c06630f56091b78d4a1c2a)) 234 | 235 | ## [0.17.2](https://github.com/microservicer/flutter-pipelines/compare/v0.17.1...v0.17.2) (2023-08-07) 236 | 237 | 238 | ### Bug Fixes 239 | 240 | * Try full run ([b485c97](https://github.com/microservicer/flutter-pipelines/commit/b485c9795661de699866e5b58d727cf6f8c919a9)) 241 | 242 | ## [0.17.1](https://github.com/microservicer/flutter-pipelines/compare/v0.17.0...v0.17.1) (2023-08-07) 243 | 244 | 245 | ### Bug Fixes 246 | 247 | * Output syntax error ([acd286c](https://github.com/microservicer/flutter-pipelines/commit/acd286c538bfe609da75001733647630830a3c05)) 248 | * Outputs ([d92c96a](https://github.com/microservicer/flutter-pipelines/commit/d92c96affc63405331817953933ef4aa0a44796e)) 249 | 250 | # [0.17.0](https://github.com/microservicer/flutter-pipelines/compare/v0.16.2...v0.17.0) (2023-08-07) 251 | 252 | 253 | ### Bug Fixes 254 | 255 | * Extra needs ([8c51e5a](https://github.com/microservicer/flutter-pipelines/commit/8c51e5a2c0a085230fc8c8a2ce4a1bb61ce9b82e)) 256 | * Issues with workflows ([1a89de9](https://github.com/microservicer/flutter-pipelines/commit/1a89de99210238755be395e20d2e2b384ed6527a)) 257 | * Pathing issue ([295afdf](https://github.com/microservicer/flutter-pipelines/commit/295afdf53b4d2e60f3dc07630a053266700f8be5)) 258 | * Typo in screenshot ([389296e](https://github.com/microservicer/flutter-pipelines/commit/389296eac4b4d1d5a89e3018b0bbd72602773a01)) 259 | 260 | 261 | ### Features 262 | 263 | * Complete workflow ([fc6c932](https://github.com/microservicer/flutter-pipelines/commit/fc6c93265f90bf63a1cf525d73fac7a3cca32da9)) 264 | 265 | ## [0.16.2](https://github.com/microservicer/flutter-pipelines/compare/v0.16.1...v0.16.2) (2023-08-07) 266 | 267 | 268 | ### Bug Fixes 269 | 270 | * Output variables ([5bf0824](https://github.com/microservicer/flutter-pipelines/commit/5bf08247619d69c2274eb6ab3354981136cc145a)) 271 | * Pipeline syntax ([5aeb014](https://github.com/microservicer/flutter-pipelines/commit/5aeb0143c9496565c4bf4fb274f52fc256ac4322)) 272 | * Unclosed section ([d9482a4](https://github.com/microservicer/flutter-pipelines/commit/d9482a4eb16f98a21823b91979e9ee9dda08f6fe)) 273 | 274 | ## [0.16.1](https://github.com/microservicer/flutter-pipelines/compare/v0.16.0...v0.16.1) (2023-08-07) 275 | 276 | 277 | ### Bug Fixes 278 | 279 | * Id on pipeline ([a46961a](https://github.com/microservicer/flutter-pipelines/commit/a46961ad31274e8d64447cd1d4c60f2273f47655)) 280 | 281 | # [0.16.0](https://github.com/microservicer/flutter-pipelines/compare/v0.15.0...v0.16.0) (2023-08-07) 282 | 283 | 284 | ### Bug Fixes 285 | 286 | * Nameing issue on pipeline ([ee3ac4d](https://github.com/microservicer/flutter-pipelines/commit/ee3ac4d861cb36a2c9b767052e5e176373bb0f81)) 287 | 288 | 289 | ### Features 290 | 291 | * Fully functioning pipeline ([3585e85](https://github.com/microservicer/flutter-pipelines/commit/3585e855c984709fb4174e4dada7af7119e1b693)) 292 | * Upload to Play store ([9019ff3](https://github.com/microservicer/flutter-pipelines/commit/9019ff397681f0f5e9718706faa6e55584e75ea7)) 293 | 294 | # [0.15.0](https://github.com/microservicer/flutter-pipelines/compare/v0.14.1...v0.15.0) (2023-08-05) 295 | 296 | 297 | ### Features 298 | 299 | * Add Deliverfile ([ee0d598](https://github.com/microservicer/flutter-pipelines/commit/ee0d59899890b78ce2554d6f8749277ed5b9b360)) 300 | 301 | ## [0.14.1](https://github.com/microservicer/flutter-pipelines/compare/v0.14.0...v0.14.1) (2023-08-05) 302 | 303 | 304 | ### Bug Fixes 305 | 306 | * Upload to testflight ([2263ae8](https://github.com/microservicer/flutter-pipelines/commit/2263ae88bb9defdf4e38a3db3f62c21e79962dbf)) 307 | 308 | # [0.14.0](https://github.com/microservicer/flutter-pipelines/compare/v0.13.1...v0.14.0) (2023-08-05) 309 | 310 | 311 | ### Features 312 | 313 | * Deploy on App Store ([6454501](https://github.com/microservicer/flutter-pipelines/commit/6454501d664e6be9cb9095e834143cb625bd4748)) 314 | 315 | ## [0.13.1](https://github.com/microservicer/flutter-pipelines/compare/v0.13.0...v0.13.1) (2023-08-05) 316 | 317 | 318 | ### Bug Fixes 319 | 320 | * Create dir if not exists ([a72ca64](https://github.com/microservicer/flutter-pipelines/commit/a72ca64f3a68f0f6532d69834e79f3e753070c5d)) 321 | 322 | # [0.13.0](https://github.com/microservicer/flutter-pipelines/compare/v0.12.2...v0.13.0) (2023-08-05) 323 | 324 | 325 | ### Features 326 | 327 | * Add screenshot commit ([96ea796](https://github.com/microservicer/flutter-pipelines/commit/96ea796f3de0e64ad20dbb7ee088a7be4d7ebab6)) 328 | 329 | ## [0.12.2](https://github.com/microservicer/flutter-pipelines/compare/v0.12.1...v0.12.2) (2023-08-04) 330 | 331 | 332 | ### Bug Fixes 333 | 334 | * Various build fixes ([4d3a286](https://github.com/microservicer/flutter-pipelines/commit/4d3a2864546ed160f12a1b55ec2cb6a6f8b7cb6c)) 335 | 336 | ## [0.12.1](https://github.com/microservicer/flutter-pipelines/compare/v0.12.0...v0.12.1) (2023-08-04) 337 | 338 | 339 | ### Bug Fixes 340 | 341 | * set Android SDK version as env ([9259849](https://github.com/microservicer/flutter-pipelines/commit/9259849d7615adb1a6ca1173da275da4791d4de9)) 342 | 343 | # [0.12.0](https://github.com/microservicer/flutter-pipelines/compare/v0.11.0...v0.12.0) (2023-08-04) 344 | 345 | 346 | ### Features 347 | 348 | * Add Android screenshot taker ([784ba12](https://github.com/microservicer/flutter-pipelines/commit/784ba1246ff5e10c80cbdc0226c2f70eb6500121)) 349 | 350 | # [0.11.0](https://github.com/microservicer/flutter-pipelines/compare/v0.10.0...v0.11.0) (2023-08-04) 351 | 352 | 353 | ### Features 354 | 355 | * Add PR linter ([b85821a](https://github.com/microservicer/flutter-pipelines/commit/b85821a011a1215172b190044dfd3076b863bfaf)) 356 | 357 | # [0.10.0](https://github.com/microservicer/flutter-pipelines/compare/v0.9.0...v0.10.0) (2023-08-04) 358 | 359 | 360 | ### Features 361 | 362 | * Clean up workflows ([9a9a17e](https://github.com/microservicer/flutter-pipelines/commit/9a9a17e570de26254dcc9b59d73bbbb310fd53b8)) 363 | 364 | # [0.9.0](https://github.com/microservicer/flutter-pipelines/compare/v0.8.0...v0.9.0) (2023-08-04) 365 | 366 | 367 | ### Features 368 | 369 | * Remove changelog to generate new! ([d6f7cc9](https://github.com/microservicer/flutter-pipelines/commit/d6f7cc993fa038ba814d39c8ae2705d102bd9e67)) 370 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flutter Mobile App Pipelines 2 | 3 |

4 | 5 | Build states 6 | 7 | 8 | semantic-release: angular 9 | 10 |

11 | 12 | This repository contains the infrastructure code for deploying a Flutter mobile app to the Play Store and App Store. 13 | 14 | It is an opinionated setup that is focused on using a native Flutter approach to building and deploying the app. 15 | It is also focused on GitOps so that all changes are tracked within this repository. 16 | The only exception is the Fastlane Match certificates and profiles that are stored in a separate repository, 17 | depending on your setup. 18 | 19 | If you like this repository, please give it a star! :star: 20 | 21 | ## Overview 22 | 23 | The Flutter mobile app pipelines are a set of pipelines that are used to build and test the Flutter mobile app. 24 | The pipelines are defined in the `.github/workflows/`directory in the root of this repository. 25 | The pipelines are run on GitHub Actions. 26 | 27 | [![Main pipeline](./docs/images/main_full.png)](./docs/images/main_full.png) 28 | 29 | ### How to trigger builds 30 | 31 | The pipelines are triggered by the semantic-release git commits. 32 | Please refer to the [semantic-release documentation](https://github.com/semantic-release/semantic-release#commit-message-format) for the conventions of the commit messages. 33 | 34 | ### Features 35 | 36 | These are the features of the pipelines: 37 | * **test** - run unit and integration tests 38 | * **analyze** - run static code analysis 39 | * **semantic versioning** - Create/append CHANGELOG.md and create a new version tag 40 | * **build** - build the app for iOS and Android 41 | * **screenshots** - take screenshots of the app and upload them to the Play Store and App Store 42 | * **deliver** - deploy the app and metadata to the Play Store internal track and App Store TestFlight. 43 | 44 | ### Pipelines 45 | 46 | In the `.github/workflows` directory you will find the pipelines used. The entrypoint is the `00-main.yml` file. 47 | It is in this file that the other pipelines are called and the environment variables are set. 48 | For basic usage, you only need to edit the `00-main.yml` file. 49 | 50 | You can also set one branch (iOS or Android) to be built and deployed. in the `00-main.yml` file. 51 | If you only want to build for one platform. 52 | 53 | If you are using any other Match repository than Google Cloud. You will need to edit the `03a-build-ios.yml` file. 54 | 55 | ### Stages 56 | 57 | The pipeline can run in 3 different modes: 58 | * **test/analyze only** - only test and analyze the code, this happens on commits that are not deemed a new release 59 | by semantic-release. 60 | * **default** - build and test the app and upload changes to the Play Store and App Store. 61 | this triggers on a new release by semantic-release. 62 | * **screenshots** - build and test the app and upload screenshots to the Play Store and App Store. 63 | this is triggered by a commit message containing a trigger word, default is "SCREENSHOT". 64 | eg. `git commit -m "feat: add new screen -m "" -m "[SCREENSHOT]"` 65 | The screenshot is an expensive operation and is therefore not run on every commit. 66 | 67 | ## Limitations 68 | 69 | - Builds can be flaky due to problems with running emulators. 70 | Tight timeouts has been added to the pipelines to reduce the risk of stuck jobs spending credits. 71 | - Only checks last commit for screenshot keyword 72 | - To be able to use the pipeline you have to build and upload the app bundle to the Play Store manually the first time. 73 | - This project only focuses on App builds since there are too many differences on how people want to deploy to web. 74 | If you are looking for an easy way with GitHub Actions to deploy to web, check out [Firebase](https://firebase.google.com/docs/hosting) 75 | 76 | ### Branch protection rules 77 | 78 | If you have branch protection rules on your repository, 79 | you will need to add a [personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) to the repository secrets. 80 | 81 | You also need to give the account permission to bypass the branch protection rules. 82 | 83 | - GH_TOKEN - A GitHub access token with either the `public_repo` or `repo` and `write:org` scope. 84 | 85 | It is highly recommended that you use a machine account for generating the token. 86 | 87 | ## Prerequisites 88 | The following prerequisites are needed to install and run the pipelines: 89 | 90 | - [Flutter SDK](https://flutter.dev/docs/get-started/install) 91 | - [Fastlane](https://docs.fastlane.tools/) 92 | - [A GitHub repository](https://github.com/) 93 | - [A Google Play Store account](https://play.google.com/console/u/0/developers) (for android builds) 94 | - [An Apple Developer account](https://appstoreconnect.apple.com/) (for ios builds) 95 | 96 | ## Installing 97 | 98 | The following steps are designed if you are going to use this project as boilerplate for a new Flutter app. 99 | If you are interested in using this project as a template for an existing Flutter app, 100 | you should be able to copy over the relevant files to your project and follow the appropriate steps below. 101 | For Android make sure you also configure your app/build.gradle file with the correct signing [configs](#setup-android-manually). 102 | 103 | ### Clean up the repository 104 | 105 | Run the following script to clean up the repository of files that need to be configured for your app: 106 | 107 | ```bash 108 | ./scripts/clean_up.sh 109 | ``` 110 | 111 | > This will rename this README.md file to README.md.old. 112 | 113 | ### Flutter 114 | Get the latest dependencies by running the following command in the root of your Flutter project: 115 | 116 | ```bash 117 | flutter pub get 118 | ``` 119 | 120 | ### Renaming the package name 121 | To rename the package name of your Flutter app, run the following command in the root of your Flutter project: 122 | Change the `com.example.new_package_name` to the package name you want to use. 123 | Change the `My New App Name` to the name you want to use for your app. 124 | 125 | ```bash 126 | flutter pub global activate rename 127 | flutter pub global run rename setBundleId -v com.example.new_package_name 128 | flutter pub global run rename setAppName -v "My New App Name" 129 | ``` 130 | Make sure that all the files in the `android/app/src/main/kotlin/org/microservicer/bootstrap` 131 | directory are moved to the new package name directory and this is added to git. 132 | 133 | ### Git Hooks 134 | You can use Git hooks to enforce commit message formatting to reduce the number of failed builds. 135 | The hooks also make sure that the Flutter project is formatted correctly according to linting rules. 136 | To install these hooks, run the following command after you clone the repository: 137 | 138 | ```bash 139 | ./scripts/install_hooks.sh 140 | ``` 141 | 142 | ### Bundler 143 | Make sure you have Ruby installed on your machine. 144 | 145 | ```bash 146 | ruby -v 147 | ``` 148 | Install the bundler gem: 149 | 150 | ```bash 151 | gem install bundler 152 | ``` 153 | 154 | ## iOS 155 | > iOS builds are very expensive to run since they required a Mac to run on. 156 | > these are billed with 10x the price of a normal build. 157 | 158 | ### Setup iOS 159 | The following steps will help you run the iOS part of the pipeline. 160 | 161 | Create a new App Store app in the [App Store Connect website](https://appstoreconnect.apple.com/). 162 | 163 | #### API Keys 164 | Generate a new App Store API key for the iOS app and store it in the GitHub repository secrets. 165 | 166 | - At the [App Store Connect website](https://appstoreconnect.apple.com/access/api) and create a new API key. 167 | - take a note of the Issuer ID and the Key ID. For later use. 168 | - Then upload it to the GitHub repository secrets. Repository Settings > Secrets and variables > Actions > New repository secret. 169 | - name: `APP_STORE_CONNECT_API_KEY` 170 | 171 | If you want to run locally you need to store the API key in a file called AuthKey.p8 in the `ios` directory. 172 | Remember to add the file to the `.gitignore` file. 173 | 174 | ##### Fastfile 175 | 176 | Make sure that you have set your API key ids in the top of the `ios/fastlane/Fastfile` file. 177 | 178 | ```ruby 179 | ... 180 | # Change this to match your app's key and issuer 181 | before_all do |lane, options| 182 | app_store_connect_api_key( 183 | key_id: '4H27D3QLG2', 184 | issuer_id: 'ec2c19af-8deb-4579-be01-5d677995d709', 185 | key_filepath: './AuthKey.p8' 186 | ) 187 | setup_ci if ENV['CI'] 188 | end 189 | ... 190 | ``` 191 | 192 | #### Fastlane 193 | Make sure to update/create the `Appfile` file in the `ios/fastlane` directory. 194 | 195 | - `Appfile` - This file contains the app identifier and the Apple ID of the developer account. 196 | It should have the following content: 197 | 198 | ```ruby 199 | app_identifier("my.bundle.id") # The bundle identifier of your app 200 | apple_id("machine@myorg.org") # Your Apple email address 201 | itc_team_id("123456789") # App Store Connect Team ID 202 | team_id("SAZY5AB444") # Developer Portal Team ID 203 | ``` 204 | 205 | #### Fastlane Match 206 | The iOS app uses [fastlane match](https://docs.fastlane.tools/actions/match/) to manage the certificates and profiles. 207 | To initialize the match repo, run the following command in the `ios` directory: 208 | 209 | ```bash 210 | bundle exec fastlane match init 211 | ``` 212 | After following the steps make sure to store the secret(s) in the GitHub repository secrets. 213 | 214 | If you have chosen to use Google Cloud Storage the secret is: 215 | - `GC_KEYS` - The key to the Google Cloud Storage bucket. 216 | 217 | To be accessed by the `03a-build-ios.yml` pipeline. Have you chosen another approach than Google Cloud Storage, 218 | you will need to edit the `03a-build-ios.yml` file. 219 | See the [Fastlane Match documentation](https://docs.fastlane.tools/actions/match/) for more information. 220 | 221 | Then run the following command to create the certificates and profiles: 222 | 223 | ```bash 224 | bundle exec fastlane register 225 | ``` 226 | Make sure that you have itc_team_id and team_id in the `Appfile` file in the `ios/fastlane` directory. 227 | 228 | Then open Xcode and go to `target` > `Signing & Capabilities` and make sure that the Match certificates and profiles are selected. 229 | 230 | ##### Push certificates 231 | 232 | If you need to enable push you should create a new push certificate using the pem command: 233 | 234 | ```bash 235 | bundle exec fastlane pem 236 | ``` 237 | 238 | Then run the register lane: 239 | 240 | ```bash 241 | bundle exec fastlane register 242 | ``` 243 | 244 | ### Running iOS build locally 245 | 246 | To run the iOS build locally you need to have a Mac with Xcode installed. 247 | 248 | You also need to make sure that you have the API key stored in a file called `AuthKey.p8` in the `ios` directory. 249 | 250 | You might also need the key to the repository that contains the Match certificates and profiles. 251 | 252 | Then run the following command in the `ios` directory: 253 | 254 | ```bash 255 | flutter build ios --release --no-codesign --config-only 256 | bundle exec fastlane versioning 257 | bundle exec fastlane build 258 | ``` 259 | 260 | ## Android 261 | Create a new app in the [Google Play Console](https://play.google.com/apps/publish/). 262 | 263 | ### API Keys 264 | Create an API key for the Google Play Store. 265 | You can use [this manual](https://docs.fastlane.tools/actions/upload_to_play_store/) 266 | 267 | - Follow the steps in [this manual](https://docs.fastlane.tools/actions/upload_to_play_store/) to create a json key 268 | - Then upload it to the GitHub repository secrets. Repository Settings > Secrets and variables > Actions > New repository secret. 269 | - name: `PLAY_STORE_CONFIG_JSON` 270 | 271 | ### Fastlane 272 | Make sure to update/create the `Appfile` file in the `android/fastlane` directory. 273 | 274 | It should have the following content: 275 | 276 | ```ruby 277 | package_name("my.package.name") 278 | ``` 279 | 280 | ### Metadata 281 | Make sure to update the `metadata/android/` directory with the correct metadata for the app. 282 | 283 | ### Upload key 284 | Generate a new upload key for the Android app and store it in the GitHub repository secrets. 285 | 286 | - Follow the steps in the [Android documentation](https://developer.android.com/studio/publish/app-signing#generate-key) to generate a new upload key. 287 | - Save the settings in the `android/key.properties` file. 288 | - `storePassword` 289 | - `keyPassword` 290 | - `keyAlias` 291 | - `storeFile` 292 | - Base64 encode the `android/app/upload-keystore.jks` file. 293 | - `base64 android/app/upload-keystore.jks` 294 | - Then upload it to the GitHub repository secrets. Repository Settings > Secrets and variables > Actions > New repository secret. 295 | - name: `PLAY_STORE_UPLOAD_KEY` 296 | - Add each of the other line from the `key.properties` as separate secrets: 297 | - `KEYSTORE_KEY_ALIAS` 298 | - `KEYSTORE_KEY_PASSWORD` 299 | - `KEYSTORE_STORE_PASSWORD` 300 | 301 | > Make sure the `key.properties` and the generated key is in the `.gitignore` file. 302 | 303 | ### Build Android locally 304 | 305 | #### First time 306 | To be able to use the pipeline you have to build and upload the app bundle to the Play Store manually the first time. 307 | 308 | You need to build the app bundle manually the first time with the following command: 309 | ```bash 310 | flutter build appbundle 311 | ``` 312 | This is because the pipeline is dependent on the app bundle name that can only be set when uploading the app bundle to the Play Store. 313 | 314 | ##### Generate signing key 315 | [Google Play Console](https://play.google.com/apps/publish/). > Your app > Testing > Internal Testing and "Choose signing key" 316 | and select "Use Google-generated key". 317 | 318 | #### After first time 319 | Make sure you have the following: 320 | 321 | - `key.properties` in your `android` directory. 322 | - your upload key in the `android/app` directory. 323 | - the API key stored in the `PLAY_STORE_CONFIG_JSON` env or in a file called `key.json` in the `android` directory. 324 | - Export your flutter project path `export FLUTTER=$FLUTTER_PATH` where `$FLUTTER_PATH` is the path to your flutter installation. 325 | 326 | Then run the following command in the `android` directory: 327 | 328 | ```bash 329 | bundle exec fastlane versioning 330 | bundle exec fastlane build 331 | ``` 332 | 333 | #### Upload manually 334 | 335 | Then upload the app bundle to the Play Store. 336 | 337 | - Create release > Upload your app bundle. 338 | - You can find the app bundle in the `build/app/outputs/bundle/release/app-release.aab` directory. 339 | 340 | ## Setup Android Manually 341 | The following steps will help you run the `03b-build-android.yml` pipeline if you only copied the files from this repository. 342 | 343 | You will need to replace the following classes in your build.gradle file: 344 | 345 | ```groovy 346 | def keystoreProperties = new Properties() 347 | def keystorePropertiesFile = rootProject.file('key.properties') 348 | if (keystorePropertiesFile.exists()) { 349 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) 350 | } 351 | 352 | android { 353 | ... 354 | signingConfigs { 355 | release { 356 | keyAlias keystoreProperties['keyAlias'] 357 | keyPassword keystoreProperties['keyPassword'] 358 | storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null 359 | storePassword keystoreProperties['storePassword'] 360 | } 361 | } 362 | buildTypes { 363 | release { 364 | signingConfig signingConfigs.release 365 | } 366 | } 367 | ... 368 | } 369 | ``` 370 | 371 | ## Common errors: 372 | 373 | - `"Failed to read key from store "../android/app/upload-keystore.jks": Tag number over 30 is not supported"` 374 | This means that you missed to upload the keystore to GitHub secrets. Remember to base64 encode it first! 375 | 376 | - `"This job failed"` on the `02-conventional-release.yml` job. 377 | This means that you missed creating a `GH_TOKEN` secret in the repository secrets. 378 | 379 | ## Take screenshots locally 380 | 381 | To take screenshots locally you can run the following commands to build and run the driver: 382 | 383 | ```bash 384 | flutter drive --driver=test_driver/screenshot_test.dart --target=integration_test/screenshot_test.dart 385 | ``` 386 | 387 | Make sure that you have a simulator running before you run the command. 388 | 389 | ## Resources 390 | - [Guide](https://keyholesoftware.com/2023/02/13/automating-flutter-deployments-part-2-screenshots/) on how to set up screenshots for the App Store and Play Store 391 | - [Flutter Integration Test](https://flutter.dev/docs/cookbook/testing/integration/introduction) 392 | - [Flutter Integration Test Repo](https://github.com/flutter/flutter/blob/master/packages/integration_test/README.md) 393 | - [emulator](https://pub.dev/packages/emulators) 394 | - [iOS screenshot sizes](https://appradar.com/blog/ios-app-screenshot-sizes-and-guidelines-for-the-apple-app-store) 395 | - [iOS emulator Action](https://github.com/marketplace/actions/launch-ios-simulator) 396 | - [Android emulator Action](https://github.com/marketplace/actions/android-emulator-runner) 397 | - [PR linter](https://github.com/amannn/action-semantic-pull-request) 398 | 399 | -------------------------------------------------------------------------------- /adr/001-CI-CD-tool.md: -------------------------------------------------------------------------------- 1 | # Title: Adopting GitHub Actions for CI/CD 2 | 3 | **Status**: Accepted 4 | 5 | **Date**: 2023-07-30 6 | 7 | ## Context 8 | There's a need for a reliable, scalable, and integrated CI/CD solution. 9 | A proper CI/CD process can streamline our development process, ensuring code quality and automating deployments. 10 | 11 | ### Decision Drivers 12 | - Integration with our current version control system (GitHub) 13 | - Flexibility to handle both CI and CD tasks 14 | - Easy configuration and maintenance 15 | - Wide community support and continuous updates 16 | - Support for matrix builds (testing on multiple platforms/versions) 17 | - Transparent cost model 18 | 19 | ## Considered Options 20 | - **Option 1**: Jenkins 21 | - Pros: Highly customizable, large plugin ecosystem 22 | - Cons: Requires dedicated infrastructure, steeper learning curve, maintenance overhead 23 | - **Option 2**: CircleCI 24 | - Pros: Docker support, strong performance metrics 25 | - Cons: Limited free tier, configuration can become complex for larger projects 26 | - **Option 3**: GitHub Actions 27 | - Pros: Seamless integration with GitHub repositories, flexible workflows, matrix builds, generous free tier for public repositories 28 | - Cons: Newer compared to other CI/CD tools (though maturing rapidly) 29 | 30 | ## Decision 31 | Selected **Option 3 - GitHub Actions**, primarily due to its seamless integration with GitHub, which reduces the need for third-party integrations or context switching. The flexibility of its workflows and the wide community support make it an ideal choice for our project's current and future CI/CD needs. 32 | 33 | ## Consequences 34 | - Reduced time spent on setting up and maintaining CI/CD infrastructure 35 | - Enhanced developer experience due to integration within the GitHub ecosystem 36 | - Easier onboarding for new contributors, as they will be familiar with the GitHub interface 37 | - Dependency on GitHub's platform and any potential changes they make to Actions' features or pricing 38 | 39 | ## Links 40 | [GitHub Actions Documentation](https://docs.github.com/en/actions) 41 | [Jenkins Documentation](https://www.jenkins.io/doc/) 42 | [CircleCI Documentation](https://circleci.com/docs/) -------------------------------------------------------------------------------- /adr/002-deploy-tool.md: -------------------------------------------------------------------------------- 1 | # Title: Adopting Fastlane for Deploying Flutter App 2 | 3 | **Status**: Accepted 4 | 5 | **Date**: 2023-07-30 6 | 7 | ## Context 8 | GitHub Actions is not enough for automating the build and deployment process for the Flutter app. 9 | Hand-coding the build and deployment process is time-consuming and error-prone. 10 | Fastlane is a tool that can be used to automate many of the steps in the build and release process. 11 | 12 | ### Decision Drivers 13 | - Need for consistent and reproducible builds 14 | - Desire to automate repetitive build and deployment tasks 15 | - Support for integrating various tools and services in the CI/CD pipeline 16 | - Compatibility with both iOS and Android platforms 17 | 18 | ## Considered Options 19 | - **Option 1**: Manual Build Process in GitHub Actions 20 | - Pros: Full control, no need to learn new tools 21 | - Cons: Time-consuming, error-prone, not scalable 22 | - **Option 2**: Codemagic 23 | - Pros: Dedicated Flutter CI/CD, integrates well with Flutter, cloud-based 24 | - Cons: More limited customization compared to Fastlane, potential cost implications 25 | - **Option 3**: Other Automation Tools 26 | - Pros: May provide some automation 27 | - Cons: Limited community support, lack of integration with all required services 28 | - **Option 4**: Fastlane 29 | - Pros: Strong community support, integration with various tools and services, cross-platform (iOS and Android), well-documented 30 | - Cons: Learning curve, potential maintenance if heavily customized 31 | 32 | ## Decision 33 | Selected **Option 4 - Fastlane**, due to its strong community support, extensive integrations, and compatibility with both iOS and Android. 34 | Its ability to automate key aspects of the build process outweighs the initial learning curve, even when compared to dedicated solutions like Codemagic. 35 | 36 | ## Consequences 37 | - Streamlined and more reliable build and deployment process 38 | - Faster release cycles and quicker time to market 39 | - Dependency on Fastlane's ongoing support and updates 40 | - Initial investment in learning and configuring Fastlane 41 | 42 | ## Links 43 | [Fastlane Documentation](https://docs.fastlane.tools/) 44 | [Flutter Integration with Fastlane](https://flutter.dev/docs/deployment/fastlane) 45 | [Codemagic Documentation](https://docs.codemagic.io/) -------------------------------------------------------------------------------- /adr/003-change-package-name-tool.md: -------------------------------------------------------------------------------- 1 | # Title: Package renaming tool 2 | 3 | **Status**: Accepted 4 | 5 | **Date**: 2023-07-30 6 | 7 | ## Context 8 | To be able to quickly change to the new app package name we want to use a well-tested tool for this. 9 | 10 | ### Decision Drivers 11 | - Package renaming has to be easy. 12 | 13 | ## Considered Options 14 | - **rename**: Version ^2.1.1 15 | - Pros: over 750 up votes 16 | - Pros: Have functionality to rename on different platforms 17 | - Cons: Requires multiple steps 18 | - **change_app_package_name**: Version ^0.1.2 19 | - Pros: Over 1000 up votes 20 | - Pros: Only one step required 21 | - cons: Only updates the Android package name 22 | 23 | ## Decision 24 | Selected **rename** for its functionality to change the package name on different platforms. 25 | 26 | ## Consequences 27 | - We depend on this package to be up-to-date with the Flutter platform and the different app stores. 28 | 29 | ## Links 30 | [rename on pub.dev](https://pub.dev/packages/rename) 31 | [change_app_package_name on pub.dev](https://pub.dev/packages/change_app_package_name) 32 | -------------------------------------------------------------------------------- /adr/004-versioning.md: -------------------------------------------------------------------------------- 1 | # Title: Adopting semantic-release for Automated Version Management and Changelog Generation 2 | 3 | **Status**: Accepted 4 | 5 | **Date**: 2023-07-30 6 | 7 | ## Context 8 | it is essential to maintain a consistent versioning system and changelog. 9 | This ensures clear communication to stakeholders about the changes in each release. 10 | Automated version management and changelog generation can help streamline this process. 11 | 12 | ### Decision Drivers 13 | - The need for consistent and semantic versioning. 14 | - Automatic changelog generation to inform stakeholders of changes. 15 | - Reducing manual errors in version bumping. 16 | - Integration with existing CI/CD tools. 17 | 18 | ## Considered Options 19 | - **Option 1**: Manual Versioning and Changelog Updates 20 | - Pros: Complete control over version numbers and changelog format. 21 | - Cons: Time-consuming, error-prone, lacks standardization. 22 | - **Option 2**: Use of other versioning tools 23 | - Pros: Some level of automation. 24 | - Cons: Might not adhere to semantic versioning, lack of comprehensive changelog generation. 25 | - **Option 3**: `semantic-release` 26 | - Pros: Fully automated version management, package publishing, adherence to semantic versioning, extensive plugins ecosystem, and continuous delivery support. 27 | - Cons: Relies on strict commit message conventions, initial configuration overhead. 28 | 29 | ## Decision 30 | Selected **Option 3 - `semantic-release`**. Its full automation, adherence to semantic versioning, 31 | extensive plugins ecosystem, and continuous delivery support make it a standout option for our project's needs. 32 | The benefits of seamless integration with CI/CD tools and automatic changelog generation further enhance the development and release processes. 33 | 34 | ## Consequences 35 | - Clearer, standardized versioning and changelog updates. 36 | - Developers will need to follow semantic commit message guidelines. 37 | - Enhanced integration with CI/CD tools for automatic releases and publishing. 38 | - A potential learning curve for those unfamiliar with semantic versioning or `semantic-release` configuration. 39 | 40 | ## Links 41 | [`semantic-release` Documentation](https://github.com/semantic-release/semantic-release) 42 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | 15 | fastlane/report.xml 16 | key.json -------------------------------------------------------------------------------- /android/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" 4 | -------------------------------------------------------------------------------- /android/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.7) 5 | base64 6 | nkf 7 | rexml 8 | addressable (2.8.7) 9 | public_suffix (>= 2.0.2, < 7.0) 10 | artifactory (3.0.17) 11 | atomos (0.1.3) 12 | aws-eventstream (1.3.0) 13 | aws-partitions (1.974.0) 14 | aws-sdk-core (3.205.0) 15 | aws-eventstream (~> 1, >= 1.3.0) 16 | aws-partitions (~> 1, >= 1.651.0) 17 | aws-sigv4 (~> 1.9) 18 | jmespath (~> 1, >= 1.6.1) 19 | aws-sdk-kms (1.91.0) 20 | aws-sdk-core (~> 3, >= 3.205.0) 21 | aws-sigv4 (~> 1.5) 22 | aws-sdk-s3 (1.162.0) 23 | aws-sdk-core (~> 3, >= 3.205.0) 24 | aws-sdk-kms (~> 1) 25 | aws-sigv4 (~> 1.5) 26 | aws-sigv4 (1.9.1) 27 | aws-eventstream (~> 1, >= 1.0.2) 28 | babosa (1.0.4) 29 | base64 (0.2.0) 30 | claide (1.1.0) 31 | colored (1.2) 32 | colored2 (3.1.2) 33 | commander (4.6.0) 34 | highline (~> 2.0.0) 35 | declarative (0.0.20) 36 | digest-crc (0.6.5) 37 | rake (>= 12.0.0, < 14.0.0) 38 | domain_name (0.6.20240107) 39 | dotenv (2.8.1) 40 | emoji_regex (3.2.3) 41 | excon (0.111.0) 42 | faraday (1.10.3) 43 | faraday-em_http (~> 1.0) 44 | faraday-em_synchrony (~> 1.0) 45 | faraday-excon (~> 1.1) 46 | faraday-httpclient (~> 1.0) 47 | faraday-multipart (~> 1.0) 48 | faraday-net_http (~> 1.0) 49 | faraday-net_http_persistent (~> 1.0) 50 | faraday-patron (~> 1.0) 51 | faraday-rack (~> 1.0) 52 | faraday-retry (~> 1.0) 53 | ruby2_keywords (>= 0.0.4) 54 | faraday-cookie_jar (0.0.7) 55 | faraday (>= 0.8.0) 56 | http-cookie (~> 1.0.0) 57 | faraday-em_http (1.0.0) 58 | faraday-em_synchrony (1.0.0) 59 | faraday-excon (1.1.0) 60 | faraday-httpclient (1.0.1) 61 | faraday-multipart (1.0.4) 62 | multipart-post (~> 2) 63 | faraday-net_http (1.0.2) 64 | faraday-net_http_persistent (1.2.0) 65 | faraday-patron (1.0.0) 66 | faraday-rack (1.0.0) 67 | faraday-retry (1.0.3) 68 | faraday_middleware (1.2.0) 69 | faraday (~> 1.0) 70 | fastimage (2.3.1) 71 | fastlane (2.222.0) 72 | CFPropertyList (>= 2.3, < 4.0.0) 73 | addressable (>= 2.8, < 3.0.0) 74 | artifactory (~> 3.0) 75 | aws-sdk-s3 (~> 1.0) 76 | babosa (>= 1.0.3, < 2.0.0) 77 | bundler (>= 1.12.0, < 3.0.0) 78 | colored (~> 1.2) 79 | commander (~> 4.6) 80 | dotenv (>= 2.1.1, < 3.0.0) 81 | emoji_regex (>= 0.1, < 4.0) 82 | excon (>= 0.71.0, < 1.0.0) 83 | faraday (~> 1.0) 84 | faraday-cookie_jar (~> 0.0.6) 85 | faraday_middleware (~> 1.0) 86 | fastimage (>= 2.1.0, < 3.0.0) 87 | gh_inspector (>= 1.1.2, < 2.0.0) 88 | google-apis-androidpublisher_v3 (~> 0.3) 89 | google-apis-playcustomapp_v1 (~> 0.1) 90 | google-cloud-env (>= 1.6.0, < 2.0.0) 91 | google-cloud-storage (~> 1.31) 92 | highline (~> 2.0) 93 | http-cookie (~> 1.0.5) 94 | json (< 3.0.0) 95 | jwt (>= 2.1.0, < 3) 96 | mini_magick (>= 4.9.4, < 5.0.0) 97 | multipart-post (>= 2.0.0, < 3.0.0) 98 | naturally (~> 2.2) 99 | optparse (>= 0.1.1, < 1.0.0) 100 | plist (>= 3.1.0, < 4.0.0) 101 | rubyzip (>= 2.0.0, < 3.0.0) 102 | security (= 0.1.5) 103 | simctl (~> 1.6.3) 104 | terminal-notifier (>= 2.0.0, < 3.0.0) 105 | terminal-table (~> 3) 106 | tty-screen (>= 0.6.3, < 1.0.0) 107 | tty-spinner (>= 0.8.0, < 1.0.0) 108 | word_wrap (~> 1.0.0) 109 | xcodeproj (>= 1.13.0, < 2.0.0) 110 | xcpretty (~> 0.3.0) 111 | xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) 112 | gh_inspector (1.1.3) 113 | google-apis-androidpublisher_v3 (0.54.0) 114 | google-apis-core (>= 0.11.0, < 2.a) 115 | google-apis-core (0.11.3) 116 | addressable (~> 2.5, >= 2.5.1) 117 | googleauth (>= 0.16.2, < 2.a) 118 | httpclient (>= 2.8.1, < 3.a) 119 | mini_mime (~> 1.0) 120 | representable (~> 3.0) 121 | retriable (>= 2.0, < 4.a) 122 | rexml 123 | google-apis-iamcredentials_v1 (0.17.0) 124 | google-apis-core (>= 0.11.0, < 2.a) 125 | google-apis-playcustomapp_v1 (0.13.0) 126 | google-apis-core (>= 0.11.0, < 2.a) 127 | google-apis-storage_v1 (0.31.0) 128 | google-apis-core (>= 0.11.0, < 2.a) 129 | google-cloud-core (1.7.1) 130 | google-cloud-env (>= 1.0, < 3.a) 131 | google-cloud-errors (~> 1.0) 132 | google-cloud-env (1.6.0) 133 | faraday (>= 0.17.3, < 3.0) 134 | google-cloud-errors (1.4.0) 135 | google-cloud-storage (1.47.0) 136 | addressable (~> 2.8) 137 | digest-crc (~> 0.4) 138 | google-apis-iamcredentials_v1 (~> 0.1) 139 | google-apis-storage_v1 (~> 0.31.0) 140 | google-cloud-core (~> 1.6) 141 | googleauth (>= 0.16.2, < 2.a) 142 | mini_mime (~> 1.0) 143 | googleauth (1.8.1) 144 | faraday (>= 0.17.3, < 3.a) 145 | jwt (>= 1.4, < 3.0) 146 | multi_json (~> 1.11) 147 | os (>= 0.9, < 2.0) 148 | signet (>= 0.16, < 2.a) 149 | highline (2.0.3) 150 | http-cookie (1.0.7) 151 | domain_name (~> 0.5) 152 | httpclient (2.8.3) 153 | jmespath (1.6.2) 154 | json (2.7.2) 155 | jwt (2.8.2) 156 | base64 157 | mini_magick (4.13.2) 158 | mini_mime (1.1.5) 159 | multi_json (1.15.0) 160 | multipart-post (2.4.1) 161 | nanaimo (0.3.0) 162 | naturally (2.2.1) 163 | nkf (0.2.0) 164 | optparse (0.5.0) 165 | os (1.1.4) 166 | plist (3.7.1) 167 | public_suffix (6.0.1) 168 | rake (13.2.1) 169 | representable (3.2.0) 170 | declarative (< 0.1.0) 171 | trailblazer-option (>= 0.1.1, < 0.2.0) 172 | uber (< 0.2.0) 173 | retriable (3.1.2) 174 | rexml (3.3.7) 175 | rouge (2.0.7) 176 | ruby2_keywords (0.0.5) 177 | rubyzip (2.3.2) 178 | security (0.1.5) 179 | signet (0.19.0) 180 | addressable (~> 2.8) 181 | faraday (>= 0.17.5, < 3.a) 182 | jwt (>= 1.5, < 3.0) 183 | multi_json (~> 1.10) 184 | simctl (1.6.10) 185 | CFPropertyList 186 | naturally 187 | terminal-notifier (2.0.0) 188 | terminal-table (3.0.2) 189 | unicode-display_width (>= 1.1.1, < 3) 190 | trailblazer-option (0.1.2) 191 | tty-cursor (0.7.1) 192 | tty-screen (0.8.2) 193 | tty-spinner (0.9.3) 194 | tty-cursor (~> 0.7) 195 | uber (0.1.0) 196 | unicode-display_width (2.5.0) 197 | word_wrap (1.0.0) 198 | xcodeproj (1.25.0) 199 | CFPropertyList (>= 2.3.3, < 4.0) 200 | atomos (~> 0.1.3) 201 | claide (>= 1.0.2, < 2.0) 202 | colored2 (~> 3.1) 203 | nanaimo (~> 0.3.0) 204 | rexml (>= 3.3.2, < 4.0) 205 | xcpretty (0.3.0) 206 | rouge (~> 2.0.7) 207 | xcpretty-travis-formatter (1.0.1) 208 | xcpretty (~> 0.2, >= 0.0.7) 209 | 210 | PLATFORMS 211 | ruby 212 | 213 | DEPENDENCIES 214 | fastlane 215 | 216 | BUNDLED WITH 217 | 2.5.18 218 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | def keystoreProperties = new Properties() 29 | def keystorePropertiesFile = rootProject.file('key.properties') 30 | if (keystorePropertiesFile.exists()) { 31 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) 32 | } 33 | 34 | android { 35 | namespace "org.microservicer.bootstrap" 36 | compileSdkVersion flutter.compileSdkVersion 37 | ndkVersion flutter.ndkVersion 38 | 39 | compileOptions { 40 | sourceCompatibility JavaVersion.VERSION_1_8 41 | targetCompatibility JavaVersion.VERSION_1_8 42 | } 43 | 44 | kotlinOptions { 45 | jvmTarget = '1.8' 46 | } 47 | 48 | sourceSets { 49 | main.java.srcDirs += 'src/main/kotlin' 50 | } 51 | 52 | defaultConfig { 53 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 54 | applicationId "org.microservicer.bootstrap" 55 | // You can update the following values to match your application needs. 56 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. 57 | minSdkVersion flutter.minSdkVersion 58 | targetSdkVersion flutter.targetSdkVersion 59 | versionCode flutterVersionCode.toInteger() 60 | versionName flutterVersionName 61 | } 62 | 63 | signingConfigs { 64 | release { 65 | keyAlias keystoreProperties['keyAlias'] 66 | keyPassword keystoreProperties['keyPassword'] 67 | storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null 68 | storePassword keystoreProperties['storePassword'] 69 | } 70 | } 71 | buildTypes { 72 | release { 73 | signingConfig signingConfigs.release 74 | } 75 | } 76 | } 77 | 78 | flutter { 79 | source '../..' 80 | } 81 | 82 | dependencies { 83 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 84 | } 85 | -------------------------------------------------------------------------------- /android/app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "835346148460", 4 | "project_id": "flutter-pipelines", 5 | "storage_bucket": "flutter-pipelines.appspot.com" 6 | }, 7 | "client": [ 8 | { 9 | "client_info": { 10 | "mobilesdk_app_id": "1:835346148460:android:05a73a422796db5635fc49", 11 | "android_client_info": { 12 | "package_name": "org.microservicer.bootstrap" 13 | } 14 | }, 15 | "oauth_client": [], 16 | "api_key": [ 17 | { 18 | "current_key": "AIzaSyCfA6KzamuuG2S6coZG1w7Z7ievodcuI8E" 19 | } 20 | ], 21 | "services": { 22 | "appinvite_service": { 23 | "other_platform_oauth_client": [] 24 | } 25 | } 26 | } 27 | ], 28 | "configuration_version": "1" 29 | } -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/org/microservicer/bootstrap/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package org.microservicer.bootstrap 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.3.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | tasks.register("clean", Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/fastlane/Appfile: -------------------------------------------------------------------------------- 1 | package_name("org.microservicer.bootstrap") -------------------------------------------------------------------------------- /android/fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # This file contains the fastlane.tools configuration 2 | # You can find the documentation at https://docs.fastlane.tools 3 | # 4 | # For a list of all available actions, check out 5 | # 6 | # https://docs.fastlane.tools/actions 7 | # 8 | # For a list of all available plugins, check out 9 | # 10 | # https://docs.fastlane.tools/plugins/available-plugins 11 | # 12 | 13 | # Uncomment the line if you want fastlane to automatically update itself 14 | # update_fastlane 15 | 16 | default_platform(:android) 17 | 18 | platform :android do 19 | 20 | before_all do |lane, options| 21 | setup_ci if ENV['CI'] 22 | end 23 | 24 | lane :versioning do 25 | json_key = ENV['PLAY_STORE_CONFIG_JSON'] ? ENV['PLAY_STORE_CONFIG_JSON'] : File.read("../key.json") 26 | previous_build_number = google_play_track_version_codes( 27 | track: "internal", 28 | json_key_data: json_key, 29 | )[0] 30 | current_build_number = previous_build_number + 1 31 | 32 | tag = last_git_tag(pattern: "v[0-9].*") 33 | 34 | version_name = tag[1..-1] 35 | version_code = current_build_number.to_s 36 | UI.message("Version name: #{version_name}") 37 | UI.message("Version code: #{version_code}") 38 | 39 | ENV["ANDROID_VERSION_NAME"] = version_name 40 | ENV["ANDROID_VERSION_CODE"] = version_code 41 | 42 | sh("echo \"ANDROID_VERSION_NAME=#{version_name}\" >> $GITHUB_ENV") if ENV['CI'] 43 | sh("echo \"ANDROID_VERSION_CODE=#{version_code}\" >> $GITHUB_ENV") if ENV['CI'] 44 | end 45 | 46 | 47 | desc "Deploy a new version to the Google Play internal track" 48 | lane :internal do 49 | json_key = ENV['PLAY_STORE_CONFIG_JSON'] ? ENV['PLAY_STORE_CONFIG_JSON'] : File.read("../key.json") 50 | # If this stage fails check if there is an existing version with the same version code 51 | # If so, delete it from the Google Play Console or manually increment the version code to a latter value 52 | upload_to_play_store( 53 | skip_upload_apk: true, 54 | track: "internal", 55 | aab: "../build/app/outputs/bundle/release/app-release.aab", 56 | json_key_data: json_key, 57 | # Change to "completed" once your app is ready to publish 58 | release_status: "draft", 59 | timeout: 600, 60 | sync_image_upload: true, 61 | ) 62 | 63 | ## Uncomment the following line to promote the internal track to alpha 64 | # upload_to_play_store( 65 | # track: "internal", 66 | # track_promote_to: "alpha", 67 | # json_key_data: json_key, 68 | # skip_upload_apk: true, 69 | # skip_upload_aab: true, 70 | # skip_upload_metadata: true, 71 | # skip_upload_changelogs: true, 72 | # skip_upload_images: true, 73 | # skip_upload_screenshots: true 74 | # ) 75 | end 76 | 77 | lane :build do 78 | UI.message("Version name: #{ENV["ANDROID_VERSION_NAME"]}") 79 | UI.message("Version code: #{ENV["ANDROID_VERSION_CODE"]}") 80 | flutter = ENV['FLUTTER'] 81 | sh("flutter", "build", "appbundle", "--build-number", ENV["ANDROID_VERSION_CODE"].to_s, "--build-name", ENV["ANDROID_VERSION_NAME"], "--target", "lib/main.dart") 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /android/fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ---- 3 | 4 | # Installation 5 | 6 | Make sure you have the latest version of the Xcode command line tools installed: 7 | 8 | ```sh 9 | xcode-select --install 10 | ``` 11 | 12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) 13 | 14 | # Available Actions 15 | 16 | ## Android 17 | 18 | ### android test 19 | 20 | ```sh 21 | [bundle exec] fastlane android test 22 | ``` 23 | 24 | Runs all the tests 25 | 26 | ### android internal 27 | 28 | ```sh 29 | [bundle exec] fastlane android internal 30 | ``` 31 | 32 | Deploy a new version to the Google Play 33 | 34 | ---- 35 | 36 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. 37 | 38 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). 39 | 40 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 41 | -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-GB/changelogs/0.31.0.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-GB/changelogs/0.31.1.txt: -------------------------------------------------------------------------------- 1 | ## [0.31.1](https://github.com/microservicer/flutter-pipelines/compare/v0.31.0...v0.31.1) (2024-09-12) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * Missing release notes generator ([e6ab135](https://github.com/microservicer/flutter-pipelines/commit/e6ab135a83bef4261e231200d622bc8831945c5e)) 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | The full description for your app -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/android/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/phoneScreenshots/pixel_6-0-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/android/fastlane/metadata/android/en-US/images/phoneScreenshots/pixel_6-0-home.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/phoneScreenshots/pixel_6-1-second.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/android/fastlane/metadata/android/en-US/images/phoneScreenshots/pixel_6-1-second.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | A short description of your app -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/title.txt: -------------------------------------------------------------------------------- 1 | My APP - title -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /docs/images/main_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/docs/images/main_full.png -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "firestore": { 3 | "rules": "firestore.rules", 4 | "indexes": "firestore.indexes.json" 5 | }, 6 | "storage": { 7 | "rules": "storage.rules" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /firestore.indexes.json: -------------------------------------------------------------------------------- 1 | { 2 | "indexes": [], 3 | "fieldOverrides": [] 4 | } 5 | -------------------------------------------------------------------------------- /firestore.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | 3 | service cloud.firestore { 4 | match /databases/{database}/documents { 5 | match /{document=**} { 6 | allow read, write: if false; 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /flutter_pipelines.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /git_hooks/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Regular expression to validate commit message against Conventional Commit specification 4 | regex="^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(.+\))?: .+" 5 | 6 | # Get the commit message 7 | message=$(cat "$1") 8 | subject=$(echo "$message" | head -n1) 9 | body=$(echo "$message" | tail -n +2) 10 | 11 | # Rule 1: No periods at the end of subject line 12 | if [[ $subject =~ \.$ ]]; then 13 | echo "ERROR: Commit message subject ends with a period" 14 | exit 1 15 | fi 16 | 17 | # Rule 2: Type Case 18 | if [[ ! $subject =~ ^[a-z]+(\(.+\))?:\ .+ ]]; then 19 | echo "ERROR: Commit type should be in lowercase" 20 | exit 1 21 | fi 22 | 23 | # Rule 3: Scope Case 24 | if [[ $subject =~ ^[a-z]+\(.+\)?:\ .+ ]]; then 25 | if [[ ! $subject =~ ^[a-z]+\([a-z]+\):\ .+ ]]; then 26 | echo "ERROR: Commit scope should be in lowercase" 27 | exit 1 28 | fi 29 | fi 30 | 31 | # Rule 4: Subject Case 32 | if [[ ! $subject =~ ^[a-z]+(\(.+\))?:\ [A-Z].* ]]; then 33 | echo "ERROR: Commit message should start with an uppercase letter" 34 | exit 1 35 | fi 36 | 37 | # Rule 5: Length Limitations 38 | subject_length=${#subject} 39 | if (( subject_length > 50 )); then 40 | echo "ERROR: Commit message subject should not exceed 50 characters" 41 | exit 1 42 | fi 43 | 44 | while read -r line; do 45 | line_length=${#line} 46 | if (( line_length > 72 )); then 47 | echo "ERROR: Each line of the commit message body should not exceed 72 characters" 48 | exit 1 49 | fi 50 | done <<< "$body" 51 | 52 | # Rule 6: Separate subject from body with a blank line 53 | second_line=$(echo "$message" | sed -n '2p') 54 | if [[ -n $body ]] && [[ -n $second_line ]]; then 55 | echo "ERROR: Commit message body should be separated from the subject with a blank line" 56 | exit 1 57 | fi 58 | 59 | # Rule 7: No Blank Commits 60 | if [[ -z $message ]]; then 61 | echo "ERROR: Empty commit message, please provide a commit message." 62 | exit 1 63 | fi 64 | 65 | # Check if the message matches the regex 66 | if [[ ! $message =~ $regex ]]; then 67 | echo "ERROR: Commit message does not follow Conventional Commit specification" 68 | exit 1 69 | fi 70 | -------------------------------------------------------------------------------- /git_hooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Moving to the Flutter project root..." 4 | PROJECT_ROOT=$(git rev-parse --show-toplevel) 5 | cd "$PROJECT_ROOT" 6 | 7 | echo "Running Flutter analyze to check for linting issues..." 8 | RESULT=$(flutter analyze) 9 | 10 | if ! echo "$RESULT" | grep -q "No issues found!"; then 11 | echo "Flutter analyze found issues. Please resolve them before committing:" 12 | echo "$RESULT" 13 | exit 1 14 | fi 15 | 16 | echo "No Flutter linting issues found. Proceeding with commit..." 17 | exit 0 18 | -------------------------------------------------------------------------------- /integration_test/screenshot_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_pipelines/main.dart' as app; 5 | import 'package:flutter_pipelines/screens/second_screen.dart'; 6 | import 'package:flutter_test/flutter_test.dart'; 7 | import 'package:integration_test/integration_test.dart'; 8 | 9 | void main() { 10 | final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 11 | group('Screenshot tests', () { 12 | setUpAll(() { 13 | return Future(() async { 14 | WidgetsApp.debugAllowBannerOverride = false; // Hide the debug banner 15 | if (Platform.isAndroid) { 16 | await binding.convertFlutterSurfaceToImage(); 17 | } 18 | }); 19 | }); 20 | 21 | testWidgets('render home', (tester) async { 22 | await testRenderHome(tester, binding); 23 | }); 24 | testWidgets('render second screen', (tester) async { 25 | await testRenderSecond(tester, binding); 26 | }); 27 | }); 28 | } 29 | 30 | Future testRenderHome( 31 | WidgetTester tester, IntegrationTestWidgetsFlutterBinding binding) async { 32 | app.main(); 33 | await tester.pumpAndSettle(); 34 | await binding.takeScreenshot('0-home'); 35 | } 36 | 37 | Future testRenderSecond( 38 | WidgetTester tester, IntegrationTestWidgetsFlutterBinding binding) async { 39 | await tester.pumpWidget(const MaterialApp(home: SecondScreen())); 40 | await tester.pumpAndSettle(); 41 | await binding.takeScreenshot('1-second'); 42 | } 43 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | 36 | fastlane/report.xml 37 | *.p8 38 | gc_keys.json 39 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" -------------------------------------------------------------------------------- /ios/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.7) 5 | base64 6 | nkf 7 | rexml 8 | addressable (2.8.7) 9 | public_suffix (>= 2.0.2, < 7.0) 10 | artifactory (3.0.17) 11 | atomos (0.1.3) 12 | aws-eventstream (1.3.0) 13 | aws-partitions (1.974.0) 14 | aws-sdk-core (3.205.0) 15 | aws-eventstream (~> 1, >= 1.3.0) 16 | aws-partitions (~> 1, >= 1.651.0) 17 | aws-sigv4 (~> 1.9) 18 | jmespath (~> 1, >= 1.6.1) 19 | aws-sdk-kms (1.91.0) 20 | aws-sdk-core (~> 3, >= 3.205.0) 21 | aws-sigv4 (~> 1.5) 22 | aws-sdk-s3 (1.162.0) 23 | aws-sdk-core (~> 3, >= 3.205.0) 24 | aws-sdk-kms (~> 1) 25 | aws-sigv4 (~> 1.5) 26 | aws-sigv4 (1.9.1) 27 | aws-eventstream (~> 1, >= 1.0.2) 28 | babosa (1.0.4) 29 | base64 (0.2.0) 30 | claide (1.1.0) 31 | colored (1.2) 32 | colored2 (3.1.2) 33 | commander (4.6.0) 34 | highline (~> 2.0.0) 35 | declarative (0.0.20) 36 | digest-crc (0.6.5) 37 | rake (>= 12.0.0, < 14.0.0) 38 | domain_name (0.6.20240107) 39 | dotenv (2.8.1) 40 | emoji_regex (3.2.3) 41 | excon (0.111.0) 42 | faraday (1.10.3) 43 | faraday-em_http (~> 1.0) 44 | faraday-em_synchrony (~> 1.0) 45 | faraday-excon (~> 1.1) 46 | faraday-httpclient (~> 1.0) 47 | faraday-multipart (~> 1.0) 48 | faraday-net_http (~> 1.0) 49 | faraday-net_http_persistent (~> 1.0) 50 | faraday-patron (~> 1.0) 51 | faraday-rack (~> 1.0) 52 | faraday-retry (~> 1.0) 53 | ruby2_keywords (>= 0.0.4) 54 | faraday-cookie_jar (0.0.7) 55 | faraday (>= 0.8.0) 56 | http-cookie (~> 1.0.0) 57 | faraday-em_http (1.0.0) 58 | faraday-em_synchrony (1.0.0) 59 | faraday-excon (1.1.0) 60 | faraday-httpclient (1.0.1) 61 | faraday-multipart (1.0.4) 62 | multipart-post (~> 2) 63 | faraday-net_http (1.0.2) 64 | faraday-net_http_persistent (1.2.0) 65 | faraday-patron (1.0.0) 66 | faraday-rack (1.0.0) 67 | faraday-retry (1.0.3) 68 | faraday_middleware (1.2.0) 69 | faraday (~> 1.0) 70 | fastimage (2.3.1) 71 | fastlane (2.222.0) 72 | CFPropertyList (>= 2.3, < 4.0.0) 73 | addressable (>= 2.8, < 3.0.0) 74 | artifactory (~> 3.0) 75 | aws-sdk-s3 (~> 1.0) 76 | babosa (>= 1.0.3, < 2.0.0) 77 | bundler (>= 1.12.0, < 3.0.0) 78 | colored (~> 1.2) 79 | commander (~> 4.6) 80 | dotenv (>= 2.1.1, < 3.0.0) 81 | emoji_regex (>= 0.1, < 4.0) 82 | excon (>= 0.71.0, < 1.0.0) 83 | faraday (~> 1.0) 84 | faraday-cookie_jar (~> 0.0.6) 85 | faraday_middleware (~> 1.0) 86 | fastimage (>= 2.1.0, < 3.0.0) 87 | gh_inspector (>= 1.1.2, < 2.0.0) 88 | google-apis-androidpublisher_v3 (~> 0.3) 89 | google-apis-playcustomapp_v1 (~> 0.1) 90 | google-cloud-env (>= 1.6.0, < 2.0.0) 91 | google-cloud-storage (~> 1.31) 92 | highline (~> 2.0) 93 | http-cookie (~> 1.0.5) 94 | json (< 3.0.0) 95 | jwt (>= 2.1.0, < 3) 96 | mini_magick (>= 4.9.4, < 5.0.0) 97 | multipart-post (>= 2.0.0, < 3.0.0) 98 | naturally (~> 2.2) 99 | optparse (>= 0.1.1, < 1.0.0) 100 | plist (>= 3.1.0, < 4.0.0) 101 | rubyzip (>= 2.0.0, < 3.0.0) 102 | security (= 0.1.5) 103 | simctl (~> 1.6.3) 104 | terminal-notifier (>= 2.0.0, < 3.0.0) 105 | terminal-table (~> 3) 106 | tty-screen (>= 0.6.3, < 1.0.0) 107 | tty-spinner (>= 0.8.0, < 1.0.0) 108 | word_wrap (~> 1.0.0) 109 | xcodeproj (>= 1.13.0, < 2.0.0) 110 | xcpretty (~> 0.3.0) 111 | xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) 112 | gh_inspector (1.1.3) 113 | google-apis-androidpublisher_v3 (0.54.0) 114 | google-apis-core (>= 0.11.0, < 2.a) 115 | google-apis-core (0.11.3) 116 | addressable (~> 2.5, >= 2.5.1) 117 | googleauth (>= 0.16.2, < 2.a) 118 | httpclient (>= 2.8.1, < 3.a) 119 | mini_mime (~> 1.0) 120 | representable (~> 3.0) 121 | retriable (>= 2.0, < 4.a) 122 | rexml 123 | google-apis-iamcredentials_v1 (0.17.0) 124 | google-apis-core (>= 0.11.0, < 2.a) 125 | google-apis-playcustomapp_v1 (0.13.0) 126 | google-apis-core (>= 0.11.0, < 2.a) 127 | google-apis-storage_v1 (0.31.0) 128 | google-apis-core (>= 0.11.0, < 2.a) 129 | google-cloud-core (1.7.1) 130 | google-cloud-env (>= 1.0, < 3.a) 131 | google-cloud-errors (~> 1.0) 132 | google-cloud-env (1.6.0) 133 | faraday (>= 0.17.3, < 3.0) 134 | google-cloud-errors (1.4.0) 135 | google-cloud-storage (1.47.0) 136 | addressable (~> 2.8) 137 | digest-crc (~> 0.4) 138 | google-apis-iamcredentials_v1 (~> 0.1) 139 | google-apis-storage_v1 (~> 0.31.0) 140 | google-cloud-core (~> 1.6) 141 | googleauth (>= 0.16.2, < 2.a) 142 | mini_mime (~> 1.0) 143 | googleauth (1.8.1) 144 | faraday (>= 0.17.3, < 3.a) 145 | jwt (>= 1.4, < 3.0) 146 | multi_json (~> 1.11) 147 | os (>= 0.9, < 2.0) 148 | signet (>= 0.16, < 2.a) 149 | highline (2.0.3) 150 | http-cookie (1.0.7) 151 | domain_name (~> 0.5) 152 | httpclient (2.8.3) 153 | jmespath (1.6.2) 154 | json (2.7.2) 155 | jwt (2.8.2) 156 | base64 157 | mini_magick (4.13.2) 158 | mini_mime (1.1.5) 159 | multi_json (1.15.0) 160 | multipart-post (2.4.1) 161 | nanaimo (0.3.0) 162 | naturally (2.2.1) 163 | nkf (0.2.0) 164 | optparse (0.5.0) 165 | os (1.1.4) 166 | plist (3.7.1) 167 | public_suffix (6.0.1) 168 | rake (13.2.1) 169 | representable (3.2.0) 170 | declarative (< 0.1.0) 171 | trailblazer-option (>= 0.1.1, < 0.2.0) 172 | uber (< 0.2.0) 173 | retriable (3.1.2) 174 | rexml (3.3.7) 175 | rouge (2.0.7) 176 | ruby2_keywords (0.0.5) 177 | rubyzip (2.3.2) 178 | security (0.1.5) 179 | signet (0.19.0) 180 | addressable (~> 2.8) 181 | faraday (>= 0.17.5, < 3.a) 182 | jwt (>= 1.5, < 3.0) 183 | multi_json (~> 1.10) 184 | simctl (1.6.10) 185 | CFPropertyList 186 | naturally 187 | terminal-notifier (2.0.0) 188 | terminal-table (3.0.2) 189 | unicode-display_width (>= 1.1.1, < 3) 190 | trailblazer-option (0.1.2) 191 | tty-cursor (0.7.1) 192 | tty-screen (0.8.2) 193 | tty-spinner (0.9.3) 194 | tty-cursor (~> 0.7) 195 | uber (0.1.0) 196 | unicode-display_width (2.5.0) 197 | word_wrap (1.0.0) 198 | xcodeproj (1.25.0) 199 | CFPropertyList (>= 2.3.3, < 4.0) 200 | atomos (~> 0.1.3) 201 | claide (>= 1.0.2, < 2.0) 202 | colored2 (~> 3.1) 203 | nanaimo (~> 0.3.0) 204 | rexml (>= 3.3.2, < 4.0) 205 | xcpretty (0.3.0) 206 | rouge (~> 2.0.7) 207 | xcpretty-travis-formatter (1.0.1) 208 | xcpretty (~> 0.2, >= 0.0.7) 209 | 210 | PLATFORMS 211 | arm64-darwin-23 212 | ruby 213 | 214 | DEPENDENCIES 215 | fastlane 216 | 217 | BUNDLED WITH 218 | 2.5.9 219 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | target 'RunnerTests' do 36 | inherit! :search_paths 37 | end 38 | end 39 | 40 | post_install do |installer| 41 | installer.pods_project.targets.each do |target| 42 | flutter_additional_ios_build_settings(target) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - integration_test (0.0.1): 4 | - Flutter 5 | 6 | DEPENDENCIES: 7 | - Flutter (from `Flutter`) 8 | - integration_test (from `.symlinks/plugins/integration_test/ios`) 9 | 10 | EXTERNAL SOURCES: 11 | Flutter: 12 | :path: Flutter 13 | integration_test: 14 | :path: ".symlinks/plugins/integration_test/ios" 15 | 16 | SPEC CHECKSUMS: 17 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 18 | integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 19 | 20 | PODFILE CHECKSUM: 7be2f5f74864d463a8ad433546ed1de7e0f29aef 21 | 22 | COCOAPODS: 1.15.2 23 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 28DC51601C551A75719AAE0E /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AA25EA42205099C18ED7628 /* Pods_RunnerTests.framework */; }; 12 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 13 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 16 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 17 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 18 | E51FAC3F5618244C756C8E96 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F050FA345BFC930A6CEBD4D2 /* Pods_Runner.framework */; }; 19 | E8A6EE2B958B662771CD1832 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 771AA3A4ADC3EA34550D62AC /* GoogleService-Info.plist */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 97C146E61CF9000F007C117D /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 97C146ED1CF9000F007C117D; 28 | remoteInfo = Runner; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXCopyFilesBuildPhase section */ 33 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 34 | isa = PBXCopyFilesBuildPhase; 35 | buildActionMask = 2147483647; 36 | dstPath = ""; 37 | dstSubfolderSpec = 10; 38 | files = ( 39 | ); 40 | name = "Embed Frameworks"; 41 | runOnlyForDeploymentPostprocessing = 0; 42 | }; 43 | /* End PBXCopyFilesBuildPhase section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 47 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 48 | 2B52DF648362465A260ACBF8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 49 | 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 50 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 3AA25EA42205099C18ED7628 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 53 | 41D1B7F1861B38810DDDE117 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 54 | 5E5C2B0828DF08FF15C5DAEE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 55 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 56 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 57 | 771AA3A4ADC3EA34550D62AC /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; 58 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 59 | 80B8BF49E13676CB100B72C0 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 60 | 91552FE124C0AEDE475E56C6 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 61 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 62 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 63 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 65 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 66 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 67 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68 | 99207BA56F6509E93C750FDF /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 69 | F050FA345BFC930A6CEBD4D2 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 70 | /* End PBXFileReference section */ 71 | 72 | /* Begin PBXFrameworksBuildPhase section */ 73 | 3EC5FE0A24D04653938D7BBA /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | 28DC51601C551A75719AAE0E /* Pods_RunnerTests.framework in Frameworks */, 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | E51FAC3F5618244C756C8E96 /* Pods_Runner.framework in Frameworks */, 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | /* End PBXFrameworksBuildPhase section */ 90 | 91 | /* Begin PBXGroup section */ 92 | 13F499B0A2959BAF169E12E5 /* Frameworks */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | F050FA345BFC930A6CEBD4D2 /* Pods_Runner.framework */, 96 | 3AA25EA42205099C18ED7628 /* Pods_RunnerTests.framework */, 97 | ); 98 | name = Frameworks; 99 | sourceTree = ""; 100 | }; 101 | 331C8082294A63A400263BE5 /* RunnerTests */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 331C807B294A618700263BE5 /* RunnerTests.swift */, 105 | ); 106 | path = RunnerTests; 107 | sourceTree = ""; 108 | }; 109 | 73A96740C5F617F953A62C65 /* Pods */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 2B52DF648362465A260ACBF8 /* Pods-Runner.debug.xcconfig */, 113 | 80B8BF49E13676CB100B72C0 /* Pods-Runner.release.xcconfig */, 114 | 5E5C2B0828DF08FF15C5DAEE /* Pods-Runner.profile.xcconfig */, 115 | 91552FE124C0AEDE475E56C6 /* Pods-RunnerTests.debug.xcconfig */, 116 | 99207BA56F6509E93C750FDF /* Pods-RunnerTests.release.xcconfig */, 117 | 41D1B7F1861B38810DDDE117 /* Pods-RunnerTests.profile.xcconfig */, 118 | ); 119 | name = Pods; 120 | path = Pods; 121 | sourceTree = ""; 122 | }; 123 | 9740EEB11CF90186004384FC /* Flutter */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 127 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 128 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 129 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 130 | ); 131 | name = Flutter; 132 | sourceTree = ""; 133 | }; 134 | 97C146E51CF9000F007C117D = { 135 | isa = PBXGroup; 136 | children = ( 137 | 9740EEB11CF90186004384FC /* Flutter */, 138 | 97C146F01CF9000F007C117D /* Runner */, 139 | 97C146EF1CF9000F007C117D /* Products */, 140 | 331C8082294A63A400263BE5 /* RunnerTests */, 141 | 73A96740C5F617F953A62C65 /* Pods */, 142 | 13F499B0A2959BAF169E12E5 /* Frameworks */, 143 | 771AA3A4ADC3EA34550D62AC /* GoogleService-Info.plist */, 144 | ); 145 | sourceTree = ""; 146 | }; 147 | 97C146EF1CF9000F007C117D /* Products */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 97C146EE1CF9000F007C117D /* Runner.app */, 151 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */, 152 | ); 153 | name = Products; 154 | sourceTree = ""; 155 | }; 156 | 97C146F01CF9000F007C117D /* Runner */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 160 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 161 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 162 | 97C147021CF9000F007C117D /* Info.plist */, 163 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 164 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 165 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 166 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 167 | ); 168 | path = Runner; 169 | sourceTree = ""; 170 | }; 171 | /* End PBXGroup section */ 172 | 173 | /* Begin PBXNativeTarget section */ 174 | 331C8080294A63A400263BE5 /* RunnerTests */ = { 175 | isa = PBXNativeTarget; 176 | buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; 177 | buildPhases = ( 178 | A5CD8C09D58DEBD0E070755E /* [CP] Check Pods Manifest.lock */, 179 | 331C807D294A63A400263BE5 /* Sources */, 180 | 331C807F294A63A400263BE5 /* Resources */, 181 | 3EC5FE0A24D04653938D7BBA /* Frameworks */, 182 | ); 183 | buildRules = ( 184 | ); 185 | dependencies = ( 186 | 331C8086294A63A400263BE5 /* PBXTargetDependency */, 187 | ); 188 | name = RunnerTests; 189 | productName = RunnerTests; 190 | productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; 191 | productType = "com.apple.product-type.bundle.unit-test"; 192 | }; 193 | 97C146ED1CF9000F007C117D /* Runner */ = { 194 | isa = PBXNativeTarget; 195 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 196 | buildPhases = ( 197 | BE8813E3F131AF7FCCE1CD9D /* [CP] Check Pods Manifest.lock */, 198 | 9740EEB61CF901F6004384FC /* Run Script */, 199 | 97C146EA1CF9000F007C117D /* Sources */, 200 | 97C146EB1CF9000F007C117D /* Frameworks */, 201 | 97C146EC1CF9000F007C117D /* Resources */, 202 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 203 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 204 | 2EDB943B50ECFA20717CBC6A /* [CP] Embed Pods Frameworks */, 205 | ); 206 | buildRules = ( 207 | ); 208 | dependencies = ( 209 | ); 210 | name = Runner; 211 | productName = Runner; 212 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 213 | productType = "com.apple.product-type.application"; 214 | }; 215 | /* End PBXNativeTarget section */ 216 | 217 | /* Begin PBXProject section */ 218 | 97C146E61CF9000F007C117D /* Project object */ = { 219 | isa = PBXProject; 220 | attributes = { 221 | LastUpgradeCheck = 1300; 222 | ORGANIZATIONNAME = ""; 223 | TargetAttributes = { 224 | 331C8080294A63A400263BE5 = { 225 | CreatedOnToolsVersion = 14.0; 226 | TestTargetID = 97C146ED1CF9000F007C117D; 227 | }; 228 | 97C146ED1CF9000F007C117D = { 229 | CreatedOnToolsVersion = 7.3.1; 230 | LastSwiftMigration = 1100; 231 | }; 232 | }; 233 | }; 234 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 235 | compatibilityVersion = "Xcode 9.3"; 236 | developmentRegion = en; 237 | hasScannedForEncodings = 0; 238 | knownRegions = ( 239 | en, 240 | Base, 241 | ); 242 | mainGroup = 97C146E51CF9000F007C117D; 243 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 244 | projectDirPath = ""; 245 | projectRoot = ""; 246 | targets = ( 247 | 97C146ED1CF9000F007C117D /* Runner */, 248 | 331C8080294A63A400263BE5 /* RunnerTests */, 249 | ); 250 | }; 251 | /* End PBXProject section */ 252 | 253 | /* Begin PBXResourcesBuildPhase section */ 254 | 331C807F294A63A400263BE5 /* Resources */ = { 255 | isa = PBXResourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | 97C146EC1CF9000F007C117D /* Resources */ = { 262 | isa = PBXResourcesBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 266 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 267 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 268 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 269 | E8A6EE2B958B662771CD1832 /* GoogleService-Info.plist in Resources */, 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | }; 273 | /* End PBXResourcesBuildPhase section */ 274 | 275 | /* Begin PBXShellScriptBuildPhase section */ 276 | 2EDB943B50ECFA20717CBC6A /* [CP] Embed Pods Frameworks */ = { 277 | isa = PBXShellScriptBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | ); 281 | inputFileListPaths = ( 282 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 283 | ); 284 | name = "[CP] Embed Pods Frameworks"; 285 | outputFileListPaths = ( 286 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | shellPath = /bin/sh; 290 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 291 | showEnvVarsInLog = 0; 292 | }; 293 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 294 | isa = PBXShellScriptBuildPhase; 295 | alwaysOutOfDate = 1; 296 | buildActionMask = 2147483647; 297 | files = ( 298 | ); 299 | inputPaths = ( 300 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 301 | ); 302 | name = "Thin Binary"; 303 | outputPaths = ( 304 | ); 305 | runOnlyForDeploymentPostprocessing = 0; 306 | shellPath = /bin/sh; 307 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 308 | }; 309 | 9740EEB61CF901F6004384FC /* Run Script */ = { 310 | isa = PBXShellScriptBuildPhase; 311 | alwaysOutOfDate = 1; 312 | buildActionMask = 2147483647; 313 | files = ( 314 | ); 315 | inputPaths = ( 316 | ); 317 | name = "Run Script"; 318 | outputPaths = ( 319 | ); 320 | runOnlyForDeploymentPostprocessing = 0; 321 | shellPath = /bin/sh; 322 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 323 | }; 324 | A5CD8C09D58DEBD0E070755E /* [CP] Check Pods Manifest.lock */ = { 325 | isa = PBXShellScriptBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | ); 329 | inputFileListPaths = ( 330 | ); 331 | inputPaths = ( 332 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 333 | "${PODS_ROOT}/Manifest.lock", 334 | ); 335 | name = "[CP] Check Pods Manifest.lock"; 336 | outputFileListPaths = ( 337 | ); 338 | outputPaths = ( 339 | "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", 340 | ); 341 | runOnlyForDeploymentPostprocessing = 0; 342 | shellPath = /bin/sh; 343 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 344 | showEnvVarsInLog = 0; 345 | }; 346 | BE8813E3F131AF7FCCE1CD9D /* [CP] Check Pods Manifest.lock */ = { 347 | isa = PBXShellScriptBuildPhase; 348 | buildActionMask = 2147483647; 349 | files = ( 350 | ); 351 | inputFileListPaths = ( 352 | ); 353 | inputPaths = ( 354 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 355 | "${PODS_ROOT}/Manifest.lock", 356 | ); 357 | name = "[CP] Check Pods Manifest.lock"; 358 | outputFileListPaths = ( 359 | ); 360 | outputPaths = ( 361 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 362 | ); 363 | runOnlyForDeploymentPostprocessing = 0; 364 | shellPath = /bin/sh; 365 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 366 | showEnvVarsInLog = 0; 367 | }; 368 | /* End PBXShellScriptBuildPhase section */ 369 | 370 | /* Begin PBXSourcesBuildPhase section */ 371 | 331C807D294A63A400263BE5 /* Sources */ = { 372 | isa = PBXSourcesBuildPhase; 373 | buildActionMask = 2147483647; 374 | files = ( 375 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, 376 | ); 377 | runOnlyForDeploymentPostprocessing = 0; 378 | }; 379 | 97C146EA1CF9000F007C117D /* Sources */ = { 380 | isa = PBXSourcesBuildPhase; 381 | buildActionMask = 2147483647; 382 | files = ( 383 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 384 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 385 | ); 386 | runOnlyForDeploymentPostprocessing = 0; 387 | }; 388 | /* End PBXSourcesBuildPhase section */ 389 | 390 | /* Begin PBXTargetDependency section */ 391 | 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { 392 | isa = PBXTargetDependency; 393 | target = 97C146ED1CF9000F007C117D /* Runner */; 394 | targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; 395 | }; 396 | /* End PBXTargetDependency section */ 397 | 398 | /* Begin PBXVariantGroup section */ 399 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 400 | isa = PBXVariantGroup; 401 | children = ( 402 | 97C146FB1CF9000F007C117D /* Base */, 403 | ); 404 | name = Main.storyboard; 405 | sourceTree = ""; 406 | }; 407 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 408 | isa = PBXVariantGroup; 409 | children = ( 410 | 97C147001CF9000F007C117D /* Base */, 411 | ); 412 | name = LaunchScreen.storyboard; 413 | sourceTree = ""; 414 | }; 415 | /* End PBXVariantGroup section */ 416 | 417 | /* Begin XCBuildConfiguration section */ 418 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 419 | isa = XCBuildConfiguration; 420 | buildSettings = { 421 | ALWAYS_SEARCH_USER_PATHS = NO; 422 | CLANG_ANALYZER_NONNULL = YES; 423 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 424 | CLANG_CXX_LIBRARY = "libc++"; 425 | CLANG_ENABLE_MODULES = YES; 426 | CLANG_ENABLE_OBJC_ARC = YES; 427 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 428 | CLANG_WARN_BOOL_CONVERSION = YES; 429 | CLANG_WARN_COMMA = YES; 430 | CLANG_WARN_CONSTANT_CONVERSION = YES; 431 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 432 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 433 | CLANG_WARN_EMPTY_BODY = YES; 434 | CLANG_WARN_ENUM_CONVERSION = YES; 435 | CLANG_WARN_INFINITE_RECURSION = YES; 436 | CLANG_WARN_INT_CONVERSION = YES; 437 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 438 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 439 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 440 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 441 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 442 | CLANG_WARN_STRICT_PROTOTYPES = YES; 443 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 444 | CLANG_WARN_UNREACHABLE_CODE = YES; 445 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 446 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 447 | COPY_PHASE_STRIP = NO; 448 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 449 | ENABLE_NS_ASSERTIONS = NO; 450 | ENABLE_STRICT_OBJC_MSGSEND = YES; 451 | GCC_C_LANGUAGE_STANDARD = gnu99; 452 | GCC_NO_COMMON_BLOCKS = YES; 453 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 454 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 455 | GCC_WARN_UNDECLARED_SELECTOR = YES; 456 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 457 | GCC_WARN_UNUSED_FUNCTION = YES; 458 | GCC_WARN_UNUSED_VARIABLE = YES; 459 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 460 | MTL_ENABLE_DEBUG_INFO = NO; 461 | SDKROOT = iphoneos; 462 | SUPPORTED_PLATFORMS = iphoneos; 463 | TARGETED_DEVICE_FAMILY = "1,2"; 464 | VALIDATE_PRODUCT = YES; 465 | }; 466 | name = Profile; 467 | }; 468 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 469 | isa = XCBuildConfiguration; 470 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 471 | buildSettings = { 472 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 473 | CLANG_ENABLE_MODULES = YES; 474 | CURRENT_PROJECT_VERSION = 2; 475 | ENABLE_BITCODE = NO; 476 | INFOPLIST_FILE = Runner/Info.plist; 477 | LD_RUNPATH_SEARCH_PATHS = ( 478 | "$(inherited)", 479 | "@executable_path/Frameworks", 480 | ); 481 | PRODUCT_BUNDLE_IDENTIFIER = org.microservicer.bootstrap; 482 | PRODUCT_NAME = "$(TARGET_NAME)"; 483 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 484 | SWIFT_VERSION = 5.0; 485 | VERSIONING_SYSTEM = "apple-generic"; 486 | }; 487 | name = Profile; 488 | }; 489 | 331C8088294A63A400263BE5 /* Debug */ = { 490 | isa = XCBuildConfiguration; 491 | baseConfigurationReference = 91552FE124C0AEDE475E56C6 /* Pods-RunnerTests.debug.xcconfig */; 492 | buildSettings = { 493 | BUNDLE_LOADER = "$(TEST_HOST)"; 494 | CODE_SIGN_STYLE = Automatic; 495 | CURRENT_PROJECT_VERSION = 2; 496 | GENERATE_INFOPLIST_FILE = YES; 497 | MARKETING_VERSION = 1.0; 498 | PRODUCT_BUNDLE_IDENTIFIER = org.microservicer.bootstrap; 499 | PRODUCT_NAME = "$(TARGET_NAME)"; 500 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 501 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 502 | SWIFT_VERSION = 5.0; 503 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 504 | }; 505 | name = Debug; 506 | }; 507 | 331C8089294A63A400263BE5 /* Release */ = { 508 | isa = XCBuildConfiguration; 509 | baseConfigurationReference = 99207BA56F6509E93C750FDF /* Pods-RunnerTests.release.xcconfig */; 510 | buildSettings = { 511 | BUNDLE_LOADER = "$(TEST_HOST)"; 512 | CODE_SIGN_STYLE = Automatic; 513 | CURRENT_PROJECT_VERSION = 2; 514 | GENERATE_INFOPLIST_FILE = YES; 515 | MARKETING_VERSION = 1.0; 516 | PRODUCT_BUNDLE_IDENTIFIER = org.microservicer.bootstrap; 517 | PRODUCT_NAME = "$(TARGET_NAME)"; 518 | SWIFT_VERSION = 5.0; 519 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 520 | }; 521 | name = Release; 522 | }; 523 | 331C808A294A63A400263BE5 /* Profile */ = { 524 | isa = XCBuildConfiguration; 525 | baseConfigurationReference = 41D1B7F1861B38810DDDE117 /* Pods-RunnerTests.profile.xcconfig */; 526 | buildSettings = { 527 | BUNDLE_LOADER = "$(TEST_HOST)"; 528 | CODE_SIGN_STYLE = Automatic; 529 | CURRENT_PROJECT_VERSION = 2; 530 | GENERATE_INFOPLIST_FILE = YES; 531 | MARKETING_VERSION = 1.0; 532 | PRODUCT_BUNDLE_IDENTIFIER = org.microservicer.bootstrap; 533 | PRODUCT_NAME = "$(TARGET_NAME)"; 534 | SWIFT_VERSION = 5.0; 535 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 536 | }; 537 | name = Profile; 538 | }; 539 | 97C147031CF9000F007C117D /* Debug */ = { 540 | isa = XCBuildConfiguration; 541 | buildSettings = { 542 | ALWAYS_SEARCH_USER_PATHS = NO; 543 | CLANG_ANALYZER_NONNULL = YES; 544 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 545 | CLANG_CXX_LIBRARY = "libc++"; 546 | CLANG_ENABLE_MODULES = YES; 547 | CLANG_ENABLE_OBJC_ARC = YES; 548 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 549 | CLANG_WARN_BOOL_CONVERSION = YES; 550 | CLANG_WARN_COMMA = YES; 551 | CLANG_WARN_CONSTANT_CONVERSION = YES; 552 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 553 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 554 | CLANG_WARN_EMPTY_BODY = YES; 555 | CLANG_WARN_ENUM_CONVERSION = YES; 556 | CLANG_WARN_INFINITE_RECURSION = YES; 557 | CLANG_WARN_INT_CONVERSION = YES; 558 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 559 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 560 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 561 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 562 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 563 | CLANG_WARN_STRICT_PROTOTYPES = YES; 564 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 565 | CLANG_WARN_UNREACHABLE_CODE = YES; 566 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 567 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 568 | COPY_PHASE_STRIP = NO; 569 | DEBUG_INFORMATION_FORMAT = dwarf; 570 | ENABLE_STRICT_OBJC_MSGSEND = YES; 571 | ENABLE_TESTABILITY = YES; 572 | GCC_C_LANGUAGE_STANDARD = gnu99; 573 | GCC_DYNAMIC_NO_PIC = NO; 574 | GCC_NO_COMMON_BLOCKS = YES; 575 | GCC_OPTIMIZATION_LEVEL = 0; 576 | GCC_PREPROCESSOR_DEFINITIONS = ( 577 | "DEBUG=1", 578 | "$(inherited)", 579 | ); 580 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 581 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 582 | GCC_WARN_UNDECLARED_SELECTOR = YES; 583 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 584 | GCC_WARN_UNUSED_FUNCTION = YES; 585 | GCC_WARN_UNUSED_VARIABLE = YES; 586 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 587 | MTL_ENABLE_DEBUG_INFO = YES; 588 | ONLY_ACTIVE_ARCH = YES; 589 | SDKROOT = iphoneos; 590 | TARGETED_DEVICE_FAMILY = "1,2"; 591 | }; 592 | name = Debug; 593 | }; 594 | 97C147041CF9000F007C117D /* Release */ = { 595 | isa = XCBuildConfiguration; 596 | buildSettings = { 597 | ALWAYS_SEARCH_USER_PATHS = NO; 598 | CLANG_ANALYZER_NONNULL = YES; 599 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 600 | CLANG_CXX_LIBRARY = "libc++"; 601 | CLANG_ENABLE_MODULES = YES; 602 | CLANG_ENABLE_OBJC_ARC = YES; 603 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 604 | CLANG_WARN_BOOL_CONVERSION = YES; 605 | CLANG_WARN_COMMA = YES; 606 | CLANG_WARN_CONSTANT_CONVERSION = YES; 607 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 608 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 609 | CLANG_WARN_EMPTY_BODY = YES; 610 | CLANG_WARN_ENUM_CONVERSION = YES; 611 | CLANG_WARN_INFINITE_RECURSION = YES; 612 | CLANG_WARN_INT_CONVERSION = YES; 613 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 614 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 615 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 616 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 617 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 618 | CLANG_WARN_STRICT_PROTOTYPES = YES; 619 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 620 | CLANG_WARN_UNREACHABLE_CODE = YES; 621 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 622 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 623 | COPY_PHASE_STRIP = NO; 624 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 625 | ENABLE_NS_ASSERTIONS = NO; 626 | ENABLE_STRICT_OBJC_MSGSEND = YES; 627 | GCC_C_LANGUAGE_STANDARD = gnu99; 628 | GCC_NO_COMMON_BLOCKS = YES; 629 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 630 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 631 | GCC_WARN_UNDECLARED_SELECTOR = YES; 632 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 633 | GCC_WARN_UNUSED_FUNCTION = YES; 634 | GCC_WARN_UNUSED_VARIABLE = YES; 635 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 636 | MTL_ENABLE_DEBUG_INFO = NO; 637 | SDKROOT = iphoneos; 638 | SUPPORTED_PLATFORMS = iphoneos; 639 | SWIFT_COMPILATION_MODE = wholemodule; 640 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 641 | TARGETED_DEVICE_FAMILY = "1,2"; 642 | VALIDATE_PRODUCT = YES; 643 | }; 644 | name = Release; 645 | }; 646 | 97C147061CF9000F007C117D /* Debug */ = { 647 | isa = XCBuildConfiguration; 648 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 649 | buildSettings = { 650 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 651 | CLANG_ENABLE_MODULES = YES; 652 | CODE_SIGN_STYLE = Manual; 653 | CURRENT_PROJECT_VERSION = 2; 654 | DEVELOPMENT_TEAM = ""; 655 | "DEVELOPMENT_TEAM[sdk=iphoneos*]" = SAZY5AB4D6; 656 | ENABLE_BITCODE = NO; 657 | INFOPLIST_FILE = Runner/Info.plist; 658 | LD_RUNPATH_SEARCH_PATHS = ( 659 | "$(inherited)", 660 | "@executable_path/Frameworks", 661 | ); 662 | PRODUCT_BUNDLE_IDENTIFIER = org.microservicer.bootstrap; 663 | PRODUCT_NAME = "$(TARGET_NAME)"; 664 | PROVISIONING_PROFILE_SPECIFIER = ""; 665 | "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development org.microservicer.bootstrap"; 666 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 667 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 668 | SWIFT_VERSION = 5.0; 669 | VERSIONING_SYSTEM = "apple-generic"; 670 | }; 671 | name = Debug; 672 | }; 673 | 97C147071CF9000F007C117D /* Release */ = { 674 | isa = XCBuildConfiguration; 675 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 676 | buildSettings = { 677 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 678 | CLANG_ENABLE_MODULES = YES; 679 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; 680 | CODE_SIGN_STYLE = Manual; 681 | CURRENT_PROJECT_VERSION = 2; 682 | DEVELOPMENT_TEAM = ""; 683 | "DEVELOPMENT_TEAM[sdk=iphoneos*]" = SAZY5AB4D6; 684 | ENABLE_BITCODE = NO; 685 | INFOPLIST_FILE = Runner/Info.plist; 686 | LD_RUNPATH_SEARCH_PATHS = ( 687 | "$(inherited)", 688 | "@executable_path/Frameworks", 689 | ); 690 | PRODUCT_BUNDLE_IDENTIFIER = org.microservicer.bootstrap; 691 | PRODUCT_NAME = "$(TARGET_NAME)"; 692 | PROVISIONING_PROFILE_SPECIFIER = ""; 693 | "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore org.microservicer.bootstrap"; 694 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 695 | SWIFT_VERSION = 5.0; 696 | VERSIONING_SYSTEM = "apple-generic"; 697 | }; 698 | name = Release; 699 | }; 700 | /* End XCBuildConfiguration section */ 701 | 702 | /* Begin XCConfigurationList section */ 703 | 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { 704 | isa = XCConfigurationList; 705 | buildConfigurations = ( 706 | 331C8088294A63A400263BE5 /* Debug */, 707 | 331C8089294A63A400263BE5 /* Release */, 708 | 331C808A294A63A400263BE5 /* Profile */, 709 | ); 710 | defaultConfigurationIsVisible = 0; 711 | defaultConfigurationName = Release; 712 | }; 713 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 714 | isa = XCConfigurationList; 715 | buildConfigurations = ( 716 | 97C147031CF9000F007C117D /* Debug */, 717 | 97C147041CF9000F007C117D /* Release */, 718 | 249021D3217E4FDB00AE95B9 /* Profile */, 719 | ); 720 | defaultConfigurationIsVisible = 0; 721 | defaultConfigurationName = Release; 722 | }; 723 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 724 | isa = XCConfigurationList; 725 | buildConfigurations = ( 726 | 97C147061CF9000F007C117D /* Debug */, 727 | 97C147071CF9000F007C117D /* Release */, 728 | 249021D4217E4FDB00AE95B9 /* Profile */, 729 | ); 730 | defaultConfigurationIsVisible = 0; 731 | defaultConfigurationName = Release; 732 | }; 733 | /* End XCConfigurationList section */ 734 | }; 735 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 736 | } 737 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | API_KEY 6 | AIzaSyAOHmixfbZSwR6c_rcQJbekbpznK-CT5FY 7 | GCM_SENDER_ID 8 | 763408879231 9 | PLIST_VERSION 10 | 1 11 | BUNDLE_ID 12 | org.microservicer.bootstrap 13 | PROJECT_ID 14 | microservicer-weld-ai 15 | STORAGE_BUCKET 16 | microservicer-weld-ai.appspot.com 17 | IS_ADS_ENABLED 18 | 19 | IS_ANALYTICS_ENABLED 20 | 21 | IS_APPINVITE_ENABLED 22 | 23 | IS_GCM_ENABLED 24 | 25 | IS_SIGNIN_ENABLED 26 | 27 | GOOGLE_APP_ID 28 | 1:763408879231:ios:6ce3cec72d940df08ab94a 29 | 30 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Flutter bootstrap project 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Flutter bootstrap project 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | UIApplicationSupportsIndirectInputEvents 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ios/fastlane/Appfile: -------------------------------------------------------------------------------- 1 | app_identifier("org.microservicer.bootstrap") # The bundle identifier of your app 2 | #apple_id("machine@myorg.org") # Your Apple email address 3 | 4 | itc_team_id("123553761") # App Store Connect Team ID 5 | team_id("SAZY5AB4D6") # Developer Portal Team ID 6 | 7 | # For more information about the Appfile, see: 8 | # https://docs.fastlane.tools/advanced/#appfile 9 | -------------------------------------------------------------------------------- /ios/fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # This file contains the fastlane.tools configuration 2 | # You can find the documentation at https://docs.fastlane.tools 3 | # 4 | # For a list of all available actions, check out 5 | # 6 | # https://docs.fastlane.tools/actions 7 | # 8 | # For a list of all available plugins, check out 9 | # 10 | # https://docs.fastlane.tools/plugins/available-plugins 11 | # 12 | 13 | # Uncomment the line if you want fastlane to automatically update itself 14 | # update_fastlane 15 | 16 | default_platform(:ios) 17 | 18 | platform :ios do 19 | 20 | # Change this to match your app's key and issuer 21 | before_all do |lane, options| 22 | app_store_connect_api_key( 23 | key_id: '4H27D3QLG2', 24 | issuer_id: 'ec2c19af-8deb-4579-be01-5d677995d709', 25 | key_filepath: './AuthKey.p8' 26 | ) 27 | setup_ci if ENV['CI'] 28 | end 29 | 30 | lane :versioning do 31 | tag = last_git_tag(pattern: 'v[0-9].*') 32 | increment_version_number( 33 | version_number: tag[1..-1] # Set a specific version number 34 | ) 35 | increment_build_number( 36 | build_number: latest_testflight_build_number + 1, 37 | xcodeproj: 'Runner.xcodeproj' 38 | ) 39 | end 40 | 41 | lane :build do 42 | match(type: 'appstore', readonly: is_ci) 43 | build_ios_app( 44 | export_method: 'app-store', 45 | ) 46 | end 47 | 48 | lane :upload_testflight do 49 | release_notes = ENV['RELEASE_NOTES'] 50 | upload_to_testflight( 51 | ipa: 'Runner.ipa', 52 | ## You can set this to true and remove the changelog if you want to save build processing time but not have change notes. 53 | skip_waiting_for_build_processing: false, 54 | # distribute_external: true, 55 | # groups: ['external_testers], 56 | reject_build_waiting_for_review: true, 57 | wait_processing_interval: 15, 58 | # notify_external_testers: true, 59 | changelog: release_notes, 60 | ) 61 | end 62 | 63 | lane :upload_metadata_app_store do 64 | upload_to_app_store( 65 | overwrite_screenshots: true, 66 | force: true, 67 | skip_binary_upload: true, 68 | precheck_include_in_app_purchases: false, 69 | ) 70 | end 71 | 72 | lane :register do 73 | register_devices(devices_file: './fastlane/devices.txt') 74 | match(type: 'appstore', readonly: false) 75 | match(type: 'development', force_for_new_devices: true, readonly: false) 76 | end 77 | 78 | end 79 | -------------------------------------------------------------------------------- /ios/fastlane/Matchfile: -------------------------------------------------------------------------------- 1 | google_cloud_bucket_name("microservicer-fastlane-cert") 2 | 3 | storage_mode("google_cloud") 4 | 5 | type("appstore") # The default type, can be: appstore, adhoc, enterprise or development 6 | 7 | # app_identifier(["tools.fastlane.app", "tools.fastlane.app2"]) 8 | # username("user@fastlane.tools") # Your Apple Developer Portal username 9 | 10 | # For all available options run `fastlane match --help` 11 | # Remove the # in the beginning of the line to enable the other options 12 | 13 | # The docs are available on https://docs.fastlane.tools/actions/match 14 | -------------------------------------------------------------------------------- /ios/fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ---- 3 | 4 | # Installation 5 | 6 | Make sure you have the latest version of the Xcode command line tools installed: 7 | 8 | ```sh 9 | xcode-select --install 10 | ``` 11 | 12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) 13 | 14 | # Available Actions 15 | 16 | ## iOS 17 | 18 | ### ios versioning 19 | 20 | ```sh 21 | [bundle exec] fastlane ios versioning 22 | ``` 23 | 24 | 25 | 26 | ### ios build 27 | 28 | ```sh 29 | [bundle exec] fastlane ios build 30 | ``` 31 | 32 | 33 | 34 | ### ios upload_testflight 35 | 36 | ```sh 37 | [bundle exec] fastlane ios upload_testflight 38 | ``` 39 | 40 | 41 | 42 | ### ios upload_metadata_app_store 43 | 44 | ```sh 45 | [bundle exec] fastlane ios upload_metadata_app_store 46 | ``` 47 | 48 | 49 | 50 | ### ios register 51 | 52 | ```sh 53 | [bundle exec] fastlane ios register 54 | ``` 55 | 56 | 57 | 58 | ---- 59 | 60 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. 61 | 62 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). 63 | 64 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 65 | -------------------------------------------------------------------------------- /ios/fastlane/devices.txt: -------------------------------------------------------------------------------- 1 | Device ID Device Name -------------------------------------------------------------------------------- /ios/fastlane/metadata/copyright.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/copyright.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/en-US/description.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/en-US/description.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/en-US/keywords.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/en-US/keywords.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/en-US/marketing_url.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/en-US/marketing_url.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/en-US/name.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/en-US/name.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/en-US/privacy_url.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/en-US/privacy_url.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/en-US/promotional_text.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/en-US/promotional_text.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/en-US/subtitle.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/en-US/subtitle.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/en-US/support_url.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/en-US/support_url.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/primary_category.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/primary_category.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/primary_first_sub_category.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/primary_first_sub_category.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/primary_second_sub_category.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/primary_second_sub_category.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/review_information/demo_password.txt: -------------------------------------------------------------------------------- 1 | N/A -------------------------------------------------------------------------------- /ios/fastlane/metadata/review_information/demo_user.txt: -------------------------------------------------------------------------------- 1 | N/A -------------------------------------------------------------------------------- /ios/fastlane/metadata/review_information/email_address.txt: -------------------------------------------------------------------------------- 1 | test@test.org -------------------------------------------------------------------------------- /ios/fastlane/metadata/review_information/first_name.txt: -------------------------------------------------------------------------------- 1 | John -------------------------------------------------------------------------------- /ios/fastlane/metadata/review_information/last_name.txt: -------------------------------------------------------------------------------- 1 | Doe -------------------------------------------------------------------------------- /ios/fastlane/metadata/review_information/notes.txt: -------------------------------------------------------------------------------- 1 | Thank you for reviewing our app. We hope you enjoy using it. -------------------------------------------------------------------------------- /ios/fastlane/metadata/review_information/phone_number.txt: -------------------------------------------------------------------------------- 1 | +44 844 209 0611 -------------------------------------------------------------------------------- /ios/fastlane/metadata/secondary_category.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/secondary_category.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/secondary_first_sub_category.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/secondary_first_sub_category.txt -------------------------------------------------------------------------------- /ios/fastlane/metadata/secondary_second_sub_category.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/metadata/secondary_second_sub_category.txt -------------------------------------------------------------------------------- /ios/fastlane/screenshots/en-US/iPhone SE (3rd generation)-0-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/screenshots/en-US/iPhone SE (3rd generation)-0-home.png -------------------------------------------------------------------------------- /ios/fastlane/screenshots/en-US/iPhone SE (3rd generation)-1-second.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/ios/fastlane/screenshots/en-US/iPhone SE (3rd generation)-1-second.png -------------------------------------------------------------------------------- /ios/firebase_app_id_file.json: -------------------------------------------------------------------------------- 1 | { 2 | "file_generated_by": "FlutterFire CLI", 3 | "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", 4 | "GOOGLE_APP_ID": "1:835346148460:ios:c1371935f7f25f1b35fc49", 5 | "FIREBASE_PROJECT_ID": "flutter-pipelines", 6 | "GCM_SENDER_ID": "835346148460" 7 | } -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_pipelines/screens/home_page.dart'; 3 | import 'package:flutter_pipelines/screens/second_screen.dart'; 4 | 5 | void main() { 6 | runApp(const MyApp()); 7 | } 8 | 9 | class MyApp extends StatelessWidget { 10 | const MyApp({super.key}); 11 | 12 | // This widget is the root of your application. 13 | @override 14 | Widget build(BuildContext context) { 15 | const title = 'Flutter Demo'; 16 | return MaterialApp( 17 | title: title, 18 | theme: ThemeData( 19 | // This is the theme of your application. 20 | // 21 | // TRY THIS: Try running your application with "flutter run". You'll see 22 | // the application has a blue toolbar. Then, without quitting the app, 23 | // try changing the seedColor in the colorScheme below to Colors.green 24 | // and then invoke "hot reload" (save your changes or press the "hot 25 | // reload" button in a Flutter-supported IDE, or press "r" if you used 26 | // the command line to start the app). 27 | // 28 | // Notice that the counter didn't reset back to zero; the application 29 | // state is not lost during the reload. To reset the state, use hot 30 | // restart instead. 31 | // 32 | // This works for code too, not just values: Most code changes can be 33 | // tested with just a hot reload. 34 | colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), 35 | useMaterial3: true, 36 | ), 37 | routes: { 38 | '/': (context) => const MyHomePage(title: title), 39 | '/second': (context) => const SecondScreen(), 40 | }, 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/screens/home_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class MyHomePage extends StatefulWidget { 4 | const MyHomePage({super.key, required this.title}); 5 | 6 | // This widget is the home page of your application. It is stateful, meaning 7 | // that it has a State object (defined below) that contains fields that affect 8 | // how it looks. 9 | 10 | // This class is the configuration for the state. It holds the values (in this 11 | // case the title) provided by the parent (in this case the App widget) and 12 | // used by the build method of the State. Fields in a Widget subclass are 13 | // always marked "final". 14 | 15 | final String title; 16 | 17 | @override 18 | State createState() => _MyHomePageState(); 19 | } 20 | 21 | class _MyHomePageState extends State { 22 | int _counter = 0; 23 | 24 | void _incrementCounter() { 25 | setState(() { 26 | // This call to setState tells the Flutter framework that something has 27 | // changed in this State, which causes it to rerun the build method below 28 | // so that the display can reflect the updated values. If we changed 29 | // _counter without calling setState(), then the build method would not be 30 | // called again, and so nothing would appear to happen. 31 | _counter++; 32 | }); 33 | } 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | // This method is rerun every time setState is called, for instance as done 38 | // by the _incrementCounter method above. 39 | // 40 | // The Flutter framework has been optimized to make rerunning build methods 41 | // fast, so that you can just rebuild anything that needs updating rather 42 | // than having to individually change instances of widgets. 43 | return Scaffold( 44 | appBar: AppBar( 45 | // TRY THIS: Try changing the color here to a specific color (to 46 | // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar 47 | // change color while the other colors stay the same. 48 | backgroundColor: Theme.of(context).colorScheme.inversePrimary, 49 | // Here we take the value from the MyHomePage object that was created by 50 | // the App.build method, and use it to set our appbar title. 51 | title: Text(widget.title), 52 | ), 53 | body: Center( 54 | // Center is a layout widget. It takes a single child and positions it 55 | // in the middle of the parent. 56 | child: Column( 57 | // Column is also a layout widget. It takes a list of children and 58 | // arranges them vertically. By default, it sizes itself to fit its 59 | // children horizontally, and tries to be as tall as its parent. 60 | // 61 | // Column has various properties to control how it sizes itself and 62 | // how it positions its children. Here we use mainAxisAlignment to 63 | // center the children vertically; the main axis here is the vertical 64 | // axis because Columns are vertical (the cross axis would be 65 | // horizontal). 66 | // 67 | // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" 68 | // action in the IDE, or press "p" in the console), to see the 69 | // wireframe for each widget. 70 | mainAxisAlignment: MainAxisAlignment.center, 71 | children: [ 72 | const Text( 73 | 'You have pushed the button this many times:', 74 | ), 75 | Text( 76 | '$_counter', 77 | style: Theme.of(context).textTheme.headlineMedium, 78 | ), 79 | ], 80 | ), 81 | ), 82 | floatingActionButton: FloatingActionButton( 83 | onPressed: _incrementCounter, 84 | tooltip: 'Increment', 85 | child: const Icon(Icons.add), 86 | ), // This trailing comma makes auto-formatting nicer for build methods. 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /lib/screens/second_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SecondScreen extends StatelessWidget { 4 | const SecondScreen({super.key}); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Scaffold( 9 | body: GridView( 10 | gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( 11 | crossAxisCount: 2, 12 | ), 13 | children: [ 14 | Container(color: Colors.red), 15 | Container(color: Colors.green), 16 | Container(color: Colors.blue), 17 | Container(color: Colors.yellow), 18 | ], 19 | ), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.1.1" 20 | change_app_package_name: 21 | dependency: "direct dev" 22 | description: 23 | name: change_app_package_name 24 | sha256: f734e127d334053873733fb61b1ecae73c09abb694b759a4afd26aa9c9547850 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.3.0" 28 | characters: 29 | dependency: transitive 30 | description: 31 | name: characters 32 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.3.0" 36 | clock: 37 | dependency: transitive 38 | description: 39 | name: clock 40 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.1.1" 44 | collection: 45 | dependency: transitive 46 | description: 47 | name: collection 48 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.18.0" 52 | fake_async: 53 | dependency: transitive 54 | description: 55 | name: fake_async 56 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "1.3.1" 60 | file: 61 | dependency: transitive 62 | description: 63 | name: file 64 | sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "7.0.0" 68 | flutter: 69 | dependency: "direct main" 70 | description: flutter 71 | source: sdk 72 | version: "0.0.0" 73 | flutter_driver: 74 | dependency: transitive 75 | description: flutter 76 | source: sdk 77 | version: "0.0.0" 78 | flutter_lints: 79 | dependency: "direct dev" 80 | description: 81 | name: flutter_lints 82 | sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" 83 | url: "https://pub.dev" 84 | source: hosted 85 | version: "4.0.0" 86 | flutter_test: 87 | dependency: "direct dev" 88 | description: flutter 89 | source: sdk 90 | version: "0.0.0" 91 | fuchsia_remote_debug_protocol: 92 | dependency: transitive 93 | description: flutter 94 | source: sdk 95 | version: "0.0.0" 96 | integration_test: 97 | dependency: "direct dev" 98 | description: flutter 99 | source: sdk 100 | version: "0.0.0" 101 | leak_tracker: 102 | dependency: transitive 103 | description: 104 | name: leak_tracker 105 | sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" 106 | url: "https://pub.dev" 107 | source: hosted 108 | version: "10.0.5" 109 | leak_tracker_flutter_testing: 110 | dependency: transitive 111 | description: 112 | name: leak_tracker_flutter_testing 113 | sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" 114 | url: "https://pub.dev" 115 | source: hosted 116 | version: "3.0.5" 117 | leak_tracker_testing: 118 | dependency: transitive 119 | description: 120 | name: leak_tracker_testing 121 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 122 | url: "https://pub.dev" 123 | source: hosted 124 | version: "3.0.1" 125 | lints: 126 | dependency: transitive 127 | description: 128 | name: lints 129 | sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" 130 | url: "https://pub.dev" 131 | source: hosted 132 | version: "4.0.0" 133 | matcher: 134 | dependency: transitive 135 | description: 136 | name: matcher 137 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 138 | url: "https://pub.dev" 139 | source: hosted 140 | version: "0.12.16+1" 141 | material_color_utilities: 142 | dependency: transitive 143 | description: 144 | name: material_color_utilities 145 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 146 | url: "https://pub.dev" 147 | source: hosted 148 | version: "0.11.1" 149 | meta: 150 | dependency: transitive 151 | description: 152 | name: meta 153 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 154 | url: "https://pub.dev" 155 | source: hosted 156 | version: "1.15.0" 157 | path: 158 | dependency: transitive 159 | description: 160 | name: path 161 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 162 | url: "https://pub.dev" 163 | source: hosted 164 | version: "1.9.0" 165 | platform: 166 | dependency: transitive 167 | description: 168 | name: platform 169 | sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" 170 | url: "https://pub.dev" 171 | source: hosted 172 | version: "3.1.5" 173 | process: 174 | dependency: transitive 175 | description: 176 | name: process 177 | sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" 178 | url: "https://pub.dev" 179 | source: hosted 180 | version: "5.0.2" 181 | sky_engine: 182 | dependency: transitive 183 | description: flutter 184 | source: sdk 185 | version: "0.0.99" 186 | source_span: 187 | dependency: transitive 188 | description: 189 | name: source_span 190 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 191 | url: "https://pub.dev" 192 | source: hosted 193 | version: "1.10.0" 194 | stack_trace: 195 | dependency: transitive 196 | description: 197 | name: stack_trace 198 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 199 | url: "https://pub.dev" 200 | source: hosted 201 | version: "1.11.1" 202 | stream_channel: 203 | dependency: transitive 204 | description: 205 | name: stream_channel 206 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 207 | url: "https://pub.dev" 208 | source: hosted 209 | version: "2.1.2" 210 | string_scanner: 211 | dependency: transitive 212 | description: 213 | name: string_scanner 214 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 215 | url: "https://pub.dev" 216 | source: hosted 217 | version: "1.2.0" 218 | sync_http: 219 | dependency: transitive 220 | description: 221 | name: sync_http 222 | sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" 223 | url: "https://pub.dev" 224 | source: hosted 225 | version: "0.3.1" 226 | term_glyph: 227 | dependency: transitive 228 | description: 229 | name: term_glyph 230 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 231 | url: "https://pub.dev" 232 | source: hosted 233 | version: "1.2.1" 234 | test_api: 235 | dependency: transitive 236 | description: 237 | name: test_api 238 | sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" 239 | url: "https://pub.dev" 240 | source: hosted 241 | version: "0.7.2" 242 | vector_math: 243 | dependency: transitive 244 | description: 245 | name: vector_math 246 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 247 | url: "https://pub.dev" 248 | source: hosted 249 | version: "2.1.4" 250 | vm_service: 251 | dependency: transitive 252 | description: 253 | name: vm_service 254 | sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" 255 | url: "https://pub.dev" 256 | source: hosted 257 | version: "14.2.5" 258 | webdriver: 259 | dependency: transitive 260 | description: 261 | name: webdriver 262 | sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" 263 | url: "https://pub.dev" 264 | source: hosted 265 | version: "3.0.3" 266 | sdks: 267 | dart: ">=3.3.0 <4.0.0" 268 | flutter: ">=3.18.0-18.0.pre.54" 269 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_pipelines 2 | description: A new Flutter project. 3 | # The following line prevents the package from being accidentally published to 4 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 5 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 6 | 7 | # The following defines the version and build number for your application. 8 | # A version number is three numbers separated by dots, like 1.2.43 9 | # followed by an optional build number separated by a +. 10 | # Both the version and the builder number may be overridden in flutter 11 | # build by specifying --build-name and --build-number, respectively. 12 | # In Android, build-name is used as versionName while build-number used as versionCode. 13 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 14 | # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. 15 | # Read more about iOS versioning at 16 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 17 | # In Windows, build-name is used as the major, minor, and patch parts 18 | # of the product and file versions while build-number is used as the build suffix. 19 | version: 0.31.1 20 | 21 | environment: 22 | sdk: '>=3.0.6 <4.0.0' 23 | 24 | # Dependencies specify other packages that your package needs in order to work. 25 | # To automatically upgrade your package dependencies to the latest versions 26 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 27 | # dependencies can be manually updated by changing the version numbers below to 28 | # the latest version available on pub.dev. To see which dependencies have newer 29 | # versions available, run `flutter pub outdated`. 30 | dependencies: 31 | flutter: 32 | sdk: flutter 33 | 34 | dev_dependencies: 35 | change_app_package_name: ^1.3.0 36 | flutter_test: 37 | sdk: flutter 38 | integration_test: 39 | sdk: flutter 40 | 41 | # The "flutter_lints" package below contains a set of recommended lints to 42 | # encourage good coding practices. The lint set provided by the package is 43 | # activated in the `analysis_options.yaml` file located at the root of your 44 | # package. See that file for information about deactivating specific lint 45 | # rules and activating additional ones. 46 | flutter_lints: ^4.0.0 47 | 48 | # For information on the generic Dart part of this file, see the 49 | # following page: https://dart.dev/tools/pub/pubspec 50 | 51 | # The following section is specific to Flutter packages. 52 | flutter: 53 | 54 | 55 | # The following line ensures that the Material Icons font is 56 | # included with your application, so that you can use the icons in 57 | # the material Icons class. 58 | uses-material-design: true 59 | 60 | # To add assets to your application, add an assets section, like this: 61 | # assets: 62 | # - images/a_dot_burr.jpeg 63 | # - images/a_dot_ham.jpeg 64 | #assets: 65 | 66 | # An image asset can refer to one or more resolution-specific "variants", see 67 | # https://flutter.dev/assets-and-images/#resolution-aware 68 | 69 | # For details regarding adding assets from package dependencies, see 70 | # https://flutter.dev/assets-and-images/#from-packages 71 | 72 | # To add custom fonts to your application, add a fonts section here, 73 | # in this "flutter" section. Each entry in this list should have a 74 | # "family" key with the font family name, and a "fonts" key with a 75 | # list giving the asset and other descriptors for the font. For 76 | # example: 77 | # fonts: 78 | # - family: Schyler 79 | # fonts: 80 | # - asset: fonts/Schyler-Regular.ttf 81 | # - asset: fonts/Schyler-Italic.ttf 82 | # style: italic 83 | # - family: Trajan Pro 84 | # fonts: 85 | # - asset: fonts/TrajanPro.ttf 86 | # - asset: fonts/TrajanPro_Bold.ttf 87 | # weight: 700 88 | # 89 | # For details regarding fonts from package dependencies, 90 | # see https://flutter.dev/custom-fonts/#from-packages 91 | -------------------------------------------------------------------------------- /screenshots/0-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microservicer/flutter-pipelines/ed701fdc57bfce43af3e7beec15a964db3d68206/screenshots/0-home.png -------------------------------------------------------------------------------- /scripts/clean_up.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Define the root directory based on the script's location 4 | ROOT_DIR="$(dirname "$(realpath "$0")")/.." 5 | 6 | # List of files and directories to delete 7 | declare -a paths_to_delete=( 8 | ".idea/" 9 | "android/fastlane/metadata/android/en-US" 10 | "android/fastlane/Appfile" 11 | "ios/fastlane/screenshots" 12 | "ios/fastlane/Appfile" 13 | "ios/fastlane/Deliverfile" 14 | "ios/fastlane/Matchfile" 15 | "docs/images" 16 | "CHANGELOG.md" 17 | "LICENSE" 18 | ) 19 | 20 | # Iterate over each item and delete if exists 21 | for relative_path in "${paths_to_delete[@]}"; do 22 | full_path="${ROOT_DIR}/${relative_path}" 23 | if [ -e "$full_path" ]; then 24 | echo "Deleting $full_path..." 25 | rm -rf "$full_path" 26 | else 27 | echo "$full_path does not exist. Skipping." 28 | fi 29 | done 30 | 31 | # Check if README.md exists in the root directory 32 | if [[ -f "${ROOT_DIR}/README.md" ]]; then 33 | # Rename it to README.md.old 34 | mv "${ROOT_DIR}/README.md" "${ROOT_DIR}/README.md.old" 35 | echo "Renamed README.md to README.md.old in the root directory." 36 | else 37 | echo "README.md not found in the root directory." 38 | fi 39 | 40 | echo "Cleanup complete." 41 | -------------------------------------------------------------------------------- /scripts/install_hooks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Define the root directory based on the script's location 4 | ROOT_DIR="$(dirname "$(realpath "$0")")/.." 5 | 6 | SRC_DIR="${ROOT_DIR}/git_hooks" 7 | DEST_DIR="${ROOT_DIR}/.git/hooks" 8 | 9 | # Ensure git_hooks directory exists 10 | if [ ! -d "$SRC_DIR" ]; then 11 | echo "Error: Directory $SRC_DIR does not exist." 12 | exit 1 13 | fi 14 | 15 | # Copy hooks from git_hooks to .git/hooks 16 | for hook in "$SRC_DIR"/*; do 17 | if [ -f "$hook" ]; then 18 | cp "$hook" "$DEST_DIR/" 19 | chmod +x "$DEST_DIR/$(basename "$hook")" 20 | echo "Copied and made executable: $(basename "$hook")" 21 | fi 22 | done 23 | 24 | echo "Hooks setup complete." 25 | -------------------------------------------------------------------------------- /shorebird.yaml: -------------------------------------------------------------------------------- 1 | # This file is used to configure the Shorebird updater used by your app. 2 | # Learn more at https://docs.shorebird.dev 3 | # This file should be checked into version control. 4 | 5 | # This is the unique identifier assigned to your app. 6 | # Your app_id is not a secret and is just used to identify your app 7 | # when requesting patches from Shorebird's servers. 8 | app_id: 6160a7d8-cc18-4928-b6ac-05b51c0bb02c 9 | 10 | # auto_update controls if Shorebird should automatically update in the background on launch. 11 | # If auto_update: false, you will need to use package:shorebird_code_push to trigger updates. 12 | # https://pub.dev/packages/shorebird_code_push 13 | # Uncomment the following line to disable automatic updates. 14 | # auto_update: false 15 | -------------------------------------------------------------------------------- /storage.rules: -------------------------------------------------------------------------------- 1 | rules_version = '2'; 2 | 3 | // Craft rules based on data in your Firestore database 4 | // allow write: if firestore.get( 5 | // /databases/(default)/documents/users/$(request.auth.uid)).data.isAdmin; 6 | service firebase.storage { 7 | match /b/{bucket}/o { 8 | match /{allPaths=**} { 9 | allow read, write: if false; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility in the flutter_test package. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:flutter_pipelines/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(const MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /test_driver/screenshot_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:integration_test/integration_test_driver_extended.dart'; 4 | 5 | Future main() async { 6 | await integrationDriver( 7 | onScreenshot: (String screenshotName, List screenshotBytes, 8 | [Map? json]) async { 9 | final File image = 10 | await File('screenshots/$screenshotName.png').create(recursive: true); 11 | image.writeAsBytesSync(screenshotBytes); 12 | return true; 13 | }, 14 | ); 15 | } 16 | --------------------------------------------------------------------------------