diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 23afc2ba7..15e813f03 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -1,4 +1,4 @@ -name: iOS CD +name: Mobile CD on: # Allows you to run this workflow manually from the Actions a tab workflow_dispatch: @@ -68,7 +68,141 @@ jobs: - name: Upload app-store ipa and dsyms to artifacts uses: actions/upload-artifact@v3 with: - name: app-store ipa & dsyms + name: Tonkeeper ipa & dsyms ${{ env.VERSION_CODE }} path: | ./packages/mobile/ios/ton_keeper.ipa ./packages/mobile/ios/*.app.dSYM.zip + + android-store-build: + name: android-store-build + strategy: + matrix: + os: [macos-13] + node-version: [18.18.0] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout to git repository + uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v3 + with: + cache: 'yarn' + node-version: ${{ matrix.node-version }} + + - name: Install yarn dependencies + run: yarn + + - name: Set up Ruby and Gemfile dependencies + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true + working-directory: './packages/mobile' + + - name: Update Java home to 11 version + run: export JAVA_HOME=$JAVA_HOME_11_X64 + + - name: Decode signing certificate into a file + working-directory: './packages/mobile/android/app' + env: + CERTIFICATE_BASE64: ${{ secrets.ANDROID_DIST_SIGNING_KEY }} + run: | + echo $CERTIFICATE_BASE64 | base64 --decode > google-release.keystore + + - name: Decode service account into a file + working-directory: './packages/mobile/android' + env: + CREDENTIALS: ${{ secrets.ANDROID_PUBLISHER_CREDENTIALS }} + run: | + echo $CREDENTIALS > service-account.json + + - name: Patch for Google Play (remove REQUEST_INSTALL_PACKAGES) + run: | + git apply ./patches/google-play-release.patch + + - name: Build & deploy Android release + working-directory: './packages/mobile/android' + run: bundle exec fastlane android beta + env: + KEYSTORE_FILE: ${{ github.workspace }}/packages/mobile/android/app/google-release.keystore + KEYSTORE_PASSWORD: ${{ secrets.TONKEEPER_UPLOAD_STORE_PASSWORD }} + KEY_ALIAS: ${{ secrets.TONKEEPER_UPLOAD_KEY_ALIAS}} + KEY_PASSWORD: ${{ secrets.TONKEEPER_UPLOAD_KEY_PASSWORD }} + ANDROID_JSON_KEY_FILE: service-account.json + + - name: Upload android google play release to artifacts + uses: actions/upload-artifact@v3 + with: + name: Tonkeeper aab ${{ env.VERSION_CODE }} + path: | + ${{ github.workspace }}/packages/mobile/android/app/build/outputs + + android-site-build: + name: android-site-build + strategy: + matrix: + os: [macos-13] + node-version: [18.18.0] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout to git repository + uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v3 + with: + cache: 'yarn' + node-version: ${{ matrix.node-version }} + + - name: Install yarn dependencies + run: yarn + + - name: Set up Ruby and Gemfile dependencies + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true + working-directory: './packages/mobile' + + - name: Update Java home to 11 version + run: export JAVA_HOME=$JAVA_HOME_11_X64 + + - name: Update ENVFILE for site + working-directory: './packages/mobile' + run: cp .env.site .env + + - name: Decode signing certificate into a file + working-directory: './packages/mobile/android/app' + env: + CERTIFICATE_BASE64: ${{ secrets.ANDROID_DIST_SIGNING_KEY }} + run: | + echo $CERTIFICATE_BASE64 | base64 --decode > google-release.keystore + + - name: Decode service account into a file + working-directory: './packages/mobile/android' + env: + CREDENTIALS: ${{ secrets.ANDROID_PUBLISHER_CREDENTIALS }} + run: | + echo $CREDENTIALS > service-account.json + + - name: Build android apk + working-directory: './packages/mobile/android' + run: bundle exec fastlane android apk + env: + KEYSTORE_FILE: ${{ github.workspace }}/packages/mobile/android/app/google-release.keystore + KEYSTORE_PASSWORD: ${{ secrets.TONKEEPER_UPLOAD_STORE_PASSWORD }} + KEY_ALIAS: ${{ secrets.TONKEEPER_UPLOAD_KEY_ALIAS}} + KEY_PASSWORD: ${{ secrets.TONKEEPER_UPLOAD_KEY_PASSWORD }} + ANDROID_JSON_KEY_FILE: service-account.json + + - name: Upload android apk to artifacts + uses: actions/upload-artifact@v3 + with: + name: Tonkeeper apk ${{ env.VERSION_CODE }} + path: | + ${{ github.workspace }}/packages/mobile/android/app/build/outputs \ No newline at end of file diff --git a/packages/mobile/Gemfile b/packages/mobile/Gemfile index a7d1efafa..5d0a3998e 100644 --- a/packages/mobile/Gemfile +++ b/packages/mobile/Gemfile @@ -3,4 +3,5 @@ source 'https://rubygems.org' ruby ">= 2.6.10" gem 'cocoapods', '~> 1.13' gem 'activesupport', '>= 6.1.7.3', '< 7.1.0' -gem "fastlane" \ No newline at end of file +gem "fastlane" +gem "fastlane-plugin-increment_version_code" diff --git a/packages/mobile/Gemfile.lock b/packages/mobile/Gemfile.lock index e32a973e7..1577ec178 100644 --- a/packages/mobile/Gemfile.lock +++ b/packages/mobile/Gemfile.lock @@ -16,8 +16,8 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.847.0) - aws-sdk-core (3.186.0) + aws-partitions (1.855.0) + aws-sdk-core (3.187.1) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.5) @@ -25,7 +25,7 @@ GEM aws-sdk-kms (1.72.0) aws-sdk-core (~> 3, >= 3.184.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.136.0) + aws-sdk-s3 (1.138.0) aws-sdk-core (~> 3, >= 3.181.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.6) @@ -78,8 +78,7 @@ GEM declarative (0.0.20) digest-crc (0.6.5) rake (>= 12.0.0, < 14.0.0) - domain_name (0.5.20190701) - unf (>= 0.0.5, < 1.0.0) + domain_name (0.6.20231109) dotenv (2.8.1) emoji_regex (3.2.3) escape (0.0.4) @@ -115,7 +114,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.2.7) - fastlane (2.216.0) + fastlane (2.217.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -155,11 +154,12 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) + fastlane-plugin-increment_version_code (0.4.3) ffi (1.16.1) fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.51.0) + google-apis-androidpublisher_v3 (0.53.0) google-apis-core (>= 0.11.0, < 2.a) google-apis-core (0.11.2) addressable (~> 2.5, >= 2.5.1) @@ -252,9 +252,6 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) uber (0.1.0) - unf (0.1.4) - unf_ext - unf_ext (0.0.8.2) unicode-display_width (2.5.0) webrick (1.8.1) word_wrap (1.0.0) @@ -278,6 +275,7 @@ DEPENDENCIES activesupport (>= 6.1.7.3, < 7.1.0) cocoapods (~> 1.13) fastlane + fastlane-plugin-increment_version_code RUBY VERSION ruby 3.2.2p53 diff --git a/packages/mobile/android/app/build.gradle b/packages/mobile/android/app/build.gradle index fdd93c319..659035efe 100644 --- a/packages/mobile/android/app/build.gradle +++ b/packages/mobile/android/app/build.gradle @@ -96,6 +96,15 @@ android { missingDimensionStrategy 'react-native-camera', 'general' } + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget=11 + } + signingConfigs { release { if (project.hasProperty('TONKEEPER_UPLOAD_STORE_FILE')) { @@ -103,6 +112,11 @@ android { storePassword TONKEEPER_UPLOAD_STORE_PASSWORD keyAlias TONKEEPER_UPLOAD_KEY_ALIAS keyPassword TONKEEPER_UPLOAD_KEY_PASSWORD + } else { + storeFile file(project.property('android.injected.signing.store.file')) + storePassword project.property('android.injected.signing.store.password') + keyAlias project.property('android.injected.signing.key.alias') + keyPassword project.property('android.injected.signing.key.password') } } debug { diff --git a/packages/mobile/android/fastlane/Appfile b/packages/mobile/android/fastlane/Appfile new file mode 100644 index 000000000..f1d2d100b --- /dev/null +++ b/packages/mobile/android/fastlane/Appfile @@ -0,0 +1,2 @@ +app_identifier('com.ton_keeper') + diff --git a/packages/mobile/android/fastlane/Fastfile b/packages/mobile/android/fastlane/Fastfile new file mode 100644 index 000000000..05be5e20a --- /dev/null +++ b/packages/mobile/android/fastlane/Fastfile @@ -0,0 +1,92 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +# Uncomment the line if you want fastlane to automatically update itself +# update_fastlane + + +platform :android do + + desc "Fetches the latest version code from the Play Console and increments it by 1" + lane :fetch_and_increment_build_number do + app_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) + + version_codes = google_play_track_version_codes( + package_name: app_identifier, + track: "internal", + json_key: ENV["ANDROID_JSON_KEY_FILE"] + ) + + updated_version_code = version_codes[0] + 1 + + increment_version_code( + gradle_file_path: "./app/build.gradle", + version_code: updated_version_code + ) + + sh("echo VERSION_CODE=#{updated_version_code} >> $GITHUB_ENV") + end + + desc "Build the android aab for release" + lane :build_release do |options| + gradle( + task: "bundle", + build_type: "Release", + properties: { + "android.injected.signing.store.file" => ENV["KEYSTORE_FILE"], + "android.injected.signing.store.password" => ENV["KEYSTORE_PASSWORD"], + "android.injected.signing.key.alias" => ENV["KEY_ALIAS"], + "android.injected.signing.key.password" => ENV["KEY_PASSWORD"], + } + ) + end + + desc "Build the android apk" + lane :assemble_release do |options| + gradle( + task: "assemble", + build_type: "Release", + properties: { + "android.injected.signing.store.file" => ENV["KEYSTORE_FILE"], + "android.injected.signing.store.password" => ENV["KEYSTORE_PASSWORD"], + "android.injected.signing.key.alias" => ENV["KEY_ALIAS"], + "android.injected.signing.key.password" => ENV["KEY_PASSWORD"], + } + ) + end + + desc "Upload to GooglePlay" + lane :upload_release do + aab_path = lane_context[SharedValues::GRADLE_AAB_OUTPUT_PATH] + app_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) + + upload_to_play_store( + track: "internal", + json_key: ENV["ANDROID_JSON_KEY_FILE"], + aab: aab_path, + package_name: app_identifier, + ) + end + + desc "Build and upload to GooglePlay" + lane :beta do + fetch_and_increment_build_number + build_release + upload_release + end + + desc "Build APK" + lane :apk do + fetch_and_increment_build_number + assemble_release + end +end \ No newline at end of file diff --git a/packages/mobile/ios/fastlane/Fastfile b/packages/mobile/ios/fastlane/Fastfile index c4c45d524..5b8ea5ef0 100644 --- a/packages/mobile/ios/fastlane/Fastfile +++ b/packages/mobile/ios/fastlane/Fastfile @@ -81,9 +81,13 @@ platform :ios do app_identifier: app_identifier ) + updated_version_code = latest_build_number + 1 + increment_build_number( - build_number: (latest_build_number + 1), + build_number: updated_version_code, ) + + sh("echo VERSION_CODE=#{updated_version_code} >> $GITHUB_ENV") end desc "Build the iOS app for release"