diff --git a/.github/actions/setup-android-signing-config/action.yml b/.github/actions/setup-android-signing-config/action.yml new file mode 100644 index 0000000..ae7bf9a --- /dev/null +++ b/.github/actions/setup-android-signing-config/action.yml @@ -0,0 +1,30 @@ +name: "Setup android signing config" +description: "Writes credentials from environment into files" +inputs: + release-keystore: + description: 'Encrypted keystore contents' + required: true + release-keystore-passphrase: + description: 'Keystore encryption passphrase' + required: true + keystore-key-alias: + description: 'key.properties keyAlias' + required: true + keystore-key-password: + description: 'key.properties keyPassword' + required: true + keystore-store-password: + description: 'key.properties storePassword' + required: true +runs: + using: "composite" + steps: + - run: | + echo "$${{ inputs.release-keystore }}" > ${{ inputs.keystore-key-alias }}-keystore.jks.asc + gpg --batch --passphrase "${{ inputs.release-keystore-passphrase }}" -d -o app/${{ inputs.keystore-key-alias }}-keystore.jks ${{ inputs.keystore-key-alias }}-keystore.jks.asc + echo "storeFile=${{ inputs.keystore-key-alias }}-keystore.jks" >> key.properties + echo "keyAlias=$KEYSTORE_KEY_ALIAS" >> key.properties + echo "storePassword=$KEYSTORE_STORE_PASSWORD" >> key.properties + echo "keyPassword=$KEYSTORE_KEY_PASSWORD" >> key.properties + shell: bash + working-directory: android \ No newline at end of file diff --git a/.github/workflows/release_deploy_play_store.yml b/.github/workflows/release_deploy_play_store.yml index 3e98822..b7aec4e 100644 --- a/.github/workflows/release_deploy_play_store.yml +++ b/.github/workflows/release_deploy_play_store.yml @@ -1,6 +1,6 @@ ## See https://github.com/flutter/gallery/blob/main/.github/workflows/release_deploy_play_store.yml -name: Deploy to Play Store +name: Deploy to Play Store and draft new GitHub release on: # Enable manual run workflow_dispatch: @@ -18,61 +18,104 @@ on: - beta - promote_to_production - production + version_tag: + description: "Tag for the release" + required: true + type: string + is_draft: + description: "Only create a draft and don't automatically publish?" + required: true + default: true + type: boolean # Declare default permissions as read only. permissions: read-all jobs: - fastlane-deploy: + + fastlane-deploy-to-play-store: runs-on: ubuntu-latest steps: - # Set up Flutter. - - name: Clone Flutter repository with stable channel - uses: subosito/flutter-action@dbf1fa04f4d2e52c33185153d06cdb5443aa189d + + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Clone flutter repository + uses: subosito/flutter-action@v2 with: channel: stable - run: flutter doctor -v - # Clone repository - - name: Checkout Paperless mobile, get packages and run code generators - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - name: Setup signing config + uses: ./.github/actions/setup-android-signing-config + with: + keystore-key-alias: ${{ secrets.KEYSTORE_KEY_ALIAS }} + keystore-key-password: ${{ secrets.KEYSTORE_KEY_PASSWORD }} + keystore-store-password: ${{ secrets.KEYSTORE_STORE_PASSWORD }} + release-keystore: ${{ secrets.RELEASE_KEYSTORE }} + release-keystore-passphrase: ${{ secrets.RELEASE_KEYSTORE_PASSPHRASE }} - # Extract secrets into corresponding files - - name: Configure Keystore - run: | - echo "$RELEASE_KEYSTORE" > upload-keystore.jks.asc - gpg --batch --passphrase "$RELEASE_KEYSTORE_PASSPHRASE" -d -o app/upload-keystore.jks upload-keystore.jks.asc - echo "storeFile=upload-keystore.jks" >> key.properties - echo "keyAlias=$KEYSTORE_KEY_ALIAS" >> key.properties - echo "storePassword=$KEYSTORE_STORE_PASSWORD" >> key.properties - echo "keyPassword=$KEYSTORE_KEY_PASSWORD" >> key.properties - env: - PLAY_STORE_UPLOAD_KEY: ${{ secrets.PLAY_STORE_UPLOAD_KEY }} - KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }} - KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }} - KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }} - RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }} - RELEASE_KEYSTORE_PASSPHRASE: ${{ secrets.RELEASE_KEYSTORE_PASSPHRASE }} - working-directory: android - - # Run codegen - - name: Run Codegen + - name: Get packages and run codegen run: | bash install_dependencies.sh working-directory: scripts - # Setup Ruby, Bundler, and Gemfile dependencies - name: Setup Fastlane - uses: ruby/setup-ruby@8df78e55761745aad83acaf3ff12976382356e6d + uses: ruby/setup-ruby@v1 with: ruby-version: "2.6" bundler-cache: true working-directory: android - - # Build and deploy with Fastlane (by default, to alpha track) 🚀. - # Naturally, promote_to_production only deploys. - - run: bundle exec fastlane ${{ github.event.inputs.lane || 'alpha' }} + # Build and deploy with Fastlane + # Naturally, promote_to_{alpha|beta|production} only deploys. + - run: bundle exec fastlane ${{ github.event.inputs.lane }} env: PLAY_STORE_CREDENTIALS: ${{ secrets.PLAY_STORE_CREDENTIALS }} working-directory: android + + create-github-release: + runs-on: ubuntu-latest + steps: + # Setup Ruby, Bundler, and Gemfile dependencies + + - name: Extract branch name + shell: bash + run: echo "branch=$(echo ${GITHUB_REF#refs/heads/})" >>$GITHUB_OUTPUT + id: extract_branch + + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Clone flutter repository + uses: subosito/flutter-action@v2 + with: + channel: stable + - run: flutter doctor -v + + - name: Setup signing config + uses: ./.github/actions/setup-android-signing-config + with: + keystore-key-alias: ${{ secrets.KEYSTORE_KEY_ALIAS }} + keystore-key-password: ${{ secrets.KEYSTORE_KEY_PASSWORD }} + keystore-store-password: ${{ secrets.KEYSTORE_STORE_PASSWORD }} + release-keystore: ${{ secrets.RELEASE_KEYSTORE }} + release-keystore-passphrase: ${{ secrets.RELEASE_KEYSTORE_PASSPHRASE }} + + - name: Get packages and run codegen + run: | + bash install_dependencies.sh + working-directory: scripts + + - name: Setup Fastlane + uses: ruby/setup-ruby@v1 + with: + ruby-version: "2.6" + bundler-cache: true + working-directory: android + + - run: bundle exec fastlane github branch:${{ steps.extract_branch.outputs.branch }} is_draft:${{ github.event.inputs.is_draft }} + env: + GH_ACCESS_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} + working-directory: android + diff --git a/.gitignore b/.gitignore index 1a1c827..baefb01 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,9 @@ android/key.properties .pub/ /build/ +# Fastlane related +android/fastlane/report.xml + # Web related lib/generated_plugin_registrant.dart @@ -65,4 +68,5 @@ untranslated_messages.txt docker/ -crowdin_credentials.yml \ No newline at end of file +crowdin_credentials.yml + diff --git a/android/Gemfile b/android/Gemfile index adc90d9..cf6dd98 100644 --- a/android/Gemfile +++ b/android/Gemfile @@ -1,3 +1,5 @@ source "https://rubygems.org" -gem "fastlane" \ No newline at end of file +gem "fastlane" + +gem 'fastlane-plugin-flutter_version', '~> 1.1', '>= 1.1.15' \ No newline at end of file diff --git a/android/Gemfile.lock b/android/Gemfile.lock index c271406..6326df6 100644 --- a/android/Gemfile.lock +++ b/android/Gemfile.lock @@ -3,21 +3,21 @@ GEM specs: CFPropertyList (3.0.6) rexml - addressable (2.8.1) + addressable (2.8.4) public_suffix (>= 2.0.2, < 6.0) artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.716.0) - aws-sdk-core (3.170.0) + aws-partitions (1.755.0) + aws-sdk-core (3.171.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.5) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.62.0) + aws-sdk-kms (1.63.0) aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.119.1) + aws-sdk-s3 (1.121.0) aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) @@ -66,7 +66,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.2.6) - fastlane (2.212.1) + fastlane (2.212.2) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -105,9 +105,10 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) + fastlane-plugin-flutter_version (1.1.15) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.34.0) - google-apis-core (>= 0.9.1, < 2.a) + google-apis-androidpublisher_v3 (0.40.0) + google-apis-core (>= 0.11.0, < 2.a) google-apis-core (0.11.0) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) @@ -119,8 +120,8 @@ GEM webrick google-apis-iamcredentials_v1 (0.17.0) google-apis-core (>= 0.11.0, < 2.a) - google-apis-playcustomapp_v1 (0.12.0) - google-apis-core (>= 0.9.1, < 2.a) + google-apis-playcustomapp_v1 (0.13.0) + google-apis-core (>= 0.11.0, < 2.a) google-apis-storage_v1 (0.19.0) google-apis-core (>= 0.9.0, < 2.a) google-cloud-core (1.6.0) @@ -128,7 +129,7 @@ GEM google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.3.0) + google-cloud-errors (1.3.1) google-cloud-storage (1.44.0) addressable (~> 2.8) digest-crc (~> 0.4) @@ -137,7 +138,7 @@ GEM google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - googleauth (1.3.0) + googleauth (1.5.2) faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -215,6 +216,7 @@ PLATFORMS DEPENDENCIES fastlane + fastlane-plugin-flutter_version (~> 1.1, >= 1.1.15) BUNDLED WITH 2.1.4 diff --git a/android/fastlane/Fastfile b/android/fastlane/Fastfile index 8afb0c3..d3d0adc 100644 --- a/android/fastlane/Fastfile +++ b/android/fastlane/Fastfile @@ -15,26 +15,26 @@ default_platform(:android) -platform :android do +platform :android do |options| desc "Runs all the tests" lane :test do gradle(task: "test") end desc "Submit a new internal build to Google Play" - lane :internal do + lane :internal do |options| sh "flutter build appbundle -v" upload_to_play_store( track: 'internal', aab: '../build/app/outputs/bundle/release/app-release.aab', json_key_data: ENV['PLAY_STORE_CREDENTIALS'], - release_status: "draft", + release_status: options[:is_draft] ? "draft" : "completed", ) end desc "Promote internal track to alpha" - lane :promote_to_alpha do + lane :promote_to_alpha do |options| upload_to_play_store( track: 'internal', track_promote_to: 'alpha', @@ -43,18 +43,18 @@ platform :android do end desc "Submit a new alpha build to Google Play" - lane :alpha do + lane :alpha do |options| sh "flutter build appbundle -v" upload_to_play_store( track: 'alpha', aab: '../build/app/outputs/bundle/release/app-release.aab', json_key_data: ENV['PLAY_STORE_CREDENTIALS'], - release_status: "draft", + release_status: options[:is_draft] ? "draft" : "completed", ) end desc "Promote alpha track to beta" - lane :promote_to_beta do + lane :promote_to_beta do |options| upload_to_play_store( track: 'alpha', track_promote_to: 'beta', @@ -63,18 +63,18 @@ platform :android do end desc "Submit a new beta build to Google Play" - lane :beta do + lane :beta do |options| sh "flutter build appbundle -v" upload_to_play_store( track: 'beta', aab: '../build/app/outputs/bundle/release/app-release.aab', json_key_data: ENV['PLAY_STORE_CREDENTIALS'], - release_status: "draft", + release_status: options[:is_draft] ? "draft" : "completed", ) end desc "Promote beta track to prod" - lane :promote_to_production do + lane :promote_to_production do |options| upload_to_play_store( track: 'beta', track_promote_to: 'production', @@ -83,13 +83,34 @@ platform :android do end desc "Submit a new production build to Google Play" - lane :production do + lane :production do |options| sh "flutter build appbundle -v" upload_to_play_store( track: 'production', aab: '../build/app/outputs/bundle/release/app-release.aab', json_key_data: ENV['PLAY_STORE_CREDENTIALS'], - release_status: "draft", + release_status: options[:is_draft] ? "draft" : "completed", + ) + end + + desc "Builds apks and creates a new release on GitHub" + lane :github do |options| + sh "flutter build apk --split-per-abi --release" + sh "flutter build apk --release" + set_github_release( + repository_name: "astubenbord/paperless-mobile", + api_token: ENV["GH_ACCESS_TOKEN"], + name: "v" + flutter_version()["version_name"], + tag_name: "v" + flutter_version()["version_name"], + is_generate_release_notes: true, + is_draft: options[:is_draft], + commitish: options[:branch], + upload_assets: [ + "../build/app/outputs/flutter-apk/app-x86_64-release.apk", + "../build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk", + "../build/app/outputs/flutter-apk/app-arm64-v8a-release.apk", + "../build/app/outputs/flutter-apk/app-release.apk" + ], ) end end \ No newline at end of file diff --git a/android/fastlane/README.md b/android/fastlane/README.md index 7ec1207..21d51b3 100644 --- a/android/fastlane/README.md +++ b/android/fastlane/README.md @@ -23,21 +23,69 @@ For _fastlane_ installation instructions, see [Installing _fastlane_](https://do Runs all the tests +### android internal + +```sh +[bundle exec] fastlane android internal +``` + +Submit a new internal build to Google Play + +### android promote_to_alpha + +```sh +[bundle exec] fastlane android promote_to_alpha +``` + +Promote internal track to alpha + +### android alpha + +```sh +[bundle exec] fastlane android alpha +``` + +Submit a new alpha build to Google Play + +### android promote_to_beta + +```sh +[bundle exec] fastlane android promote_to_beta +``` + +Promote alpha track to beta + ### android beta ```sh [bundle exec] fastlane android beta ``` -Submit a new Beta Build to Crashlytics Beta +Submit a new beta build to Google Play -### android deploy +### android promote_to_production ```sh -[bundle exec] fastlane android deploy +[bundle exec] fastlane android promote_to_production ``` -Deploy a new version to the Google Play +Promote beta track to prod + +### android production + +```sh +[bundle exec] fastlane android production +``` + +Submit a new production build to Google Play + +### android github + +```sh +[bundle exec] fastlane android github +``` + +Builds apks and creates a new release on GitHub ---- diff --git a/android/fastlane/report.xml b/android/fastlane/report.xml index b246d30..f258987 100644 --- a/android/fastlane/report.xml +++ b/android/fastlane/report.xml @@ -2,15 +2,32 @@ - - - - + - + + + + + + + + + + + + + + + + + + + + +