From df81f7ece7407c79c701eb83a8ad6b1a39905791 Mon Sep 17 00:00:00 2001 From: Shawn Lauzon Date: Fri, 26 Apr 2024 20:54:31 -0500 Subject: [PATCH 1/3] fix: Missing BuildConfig during android build We were using the old com.oneboulder package, and should be using one.oneboulder.one. --- android/app/build.gradle | 24 ++++++++++++++----- .../oneboulder/one}/MainActivity.kt | 2 +- .../oneboulder/one}/MainApplication.kt | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) rename android/app/src/main/java/{com/oneboulder => one/oneboulder/one}/MainActivity.kt (96%) rename android/app/src/main/java/{com/oneboulder => one/oneboulder/one}/MainApplication.kt (98%) diff --git a/android/app/build.gradle b/android/app/build.gradle index ac7ab95f3..99316d445 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -74,13 +74,17 @@ android { buildToolsVersion rootProject.ext.buildToolsVersion compileSdk rootProject.ext.compileSdkVersion - namespace "com.oneboulder" + buildFeatures { + buildConfig true + } + + namespace "one.oneboulder.one" defaultConfig { - applicationId "com.oneboulder" + applicationId "one.oneboulder.one" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1 - versionName "1.0" + versionCode 7 + versionName "1.0.4" missingDimensionStrategy 'react-native-camera', 'general' } signingConfigs { @@ -90,17 +94,25 @@ android { keyAlias 'androiddebugkey' keyPassword 'android' } + release { + storeFile file('debug.keystore') + storePassword 'android' + keyAlias 'androiddebugkey' + keyPassword 'android' + } } buildTypes { debug { signingConfig signingConfigs.debug + applicationIdSuffix ".debug" + debuggable true } release { // Caution! In production, you need to generate your own keystore file. // see https://reactnative.dev/docs/signed-apk-android. - signingConfig signingConfigs.debug + signingConfig signingConfigs.release minifyEnabled enableProguardInReleaseBuilds - proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" } } } diff --git a/android/app/src/main/java/com/oneboulder/MainActivity.kt b/android/app/src/main/java/one/oneboulder/one/MainActivity.kt similarity index 96% rename from android/app/src/main/java/com/oneboulder/MainActivity.kt rename to android/app/src/main/java/one/oneboulder/one/MainActivity.kt index 8b74b127c..e530d76cf 100644 --- a/android/app/src/main/java/com/oneboulder/MainActivity.kt +++ b/android/app/src/main/java/one/oneboulder/one/MainActivity.kt @@ -1,4 +1,4 @@ -package com.oneboulder +package one.oneboulder.one import com.facebook.react.ReactActivity import com.facebook.react.ReactActivityDelegate diff --git a/android/app/src/main/java/com/oneboulder/MainApplication.kt b/android/app/src/main/java/one/oneboulder/one/MainApplication.kt similarity index 98% rename from android/app/src/main/java/com/oneboulder/MainApplication.kt rename to android/app/src/main/java/one/oneboulder/one/MainApplication.kt index 7718b226e..7555b4f86 100644 --- a/android/app/src/main/java/com/oneboulder/MainApplication.kt +++ b/android/app/src/main/java/one/oneboulder/one/MainApplication.kt @@ -1,4 +1,4 @@ -package com.oneboulder +package one.oneboulder.one import android.app.Application import com.facebook.react.PackageList From 58e9ffb336972c06cffd867a0859a9dd45d5339e Mon Sep 17 00:00:00 2001 From: Shawn Lauzon Date: Sat, 27 Apr 2024 00:16:28 -0500 Subject: [PATCH 2/3] ci: Build and Deploy Android app --- .../workflows/dev-build-upload-android.yml | 69 ++++++++++++++ .github/workflows/dev-build-upload-ios.yaml | 2 +- android/Gemfile | 8 ++ android/Gemfile.lock | 9 ++ android/app/build.gradle | 10 ++ android/app/proguard-rules.pro | 54 ++++++++++- .../src/androidTest/ExampleInstrumentedTest | 61 ++++++++++++ android/app/src/debug/AndroidManifest.xml | 14 +++ android/fastlane/Fastfile | 95 ++++++++++++++----- android/fastlane/Pluginfile | 5 + android/fastlane/README.md | 26 +++-- android/fastlane/Screengrabfile | 18 ++++ android/gradle.properties | 2 +- ios/fastlane/Fastfile | 2 + 14 files changed, 338 insertions(+), 37 deletions(-) create mode 100644 .github/workflows/dev-build-upload-android.yml create mode 100644 android/app/src/androidTest/ExampleInstrumentedTest create mode 100644 android/fastlane/Pluginfile create mode 100644 android/fastlane/Screengrabfile diff --git a/.github/workflows/dev-build-upload-android.yml b/.github/workflows/dev-build-upload-android.yml new file mode 100644 index 000000000..aacf58a7b --- /dev/null +++ b/.github/workflows/dev-build-upload-android.yml @@ -0,0 +1,69 @@ +name: Android Build & Deploy + +on: + workflow_dispatch: +# push: +# branches: ["dev"] + +jobs: + deploy: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [18.x] + ruby-version: [3.3] + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + - name: "Set login password for downloading mapbox SDK" + uses: extractions/netrc@v2 + with: + machine: api.mapbox.com + username: mapbox + password: ${{ secrets.MAPBOX_SDK_REGISTRY_TOKEN }} + - run: npm ci + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true + working-directory: android + + - name: Run tests + run: bundle exec fastlane android test + + - name: Decode Service Account Key JSON File + uses: timheuer/base64-to-file@v1 + id: service_account_json_file + with: + fileName: "serviceAccount.json" + encodedString: ${{ secrets.GPLAY_SERVICE_ACCOUNT_KEY_JSON }} + + - name: Decode Keystore File + uses: timheuer/base64-to-file@v1 + id: android_keystore + with: + fileName: "android_keystore.keystore" + encodedString: ${{ secrets.KEYSTORE_FILE }} + + - name: Build & deploy Android release + run: bundle exec fastlane android deploy + env: + KEYSTORE_FILE: ${{ steps.android_keystore.outputs.filePath }} + KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} + KEY_ALIAS: ${{ secrets.KEY_ALIAS}} + KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} + ANDROID_JSON_KEY_FILE: ${{ steps.service_account_json_file.outputs.filePath }} + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: assets + path: | + ${{ github.workspace }}/android/app/build/outputs/bundle/release diff --git a/.github/workflows/dev-build-upload-ios.yaml b/.github/workflows/dev-build-upload-ios.yaml index 851205d2b..5b88f2fea 100644 --- a/.github/workflows/dev-build-upload-ios.yaml +++ b/.github/workflows/dev-build-upload-ios.yaml @@ -1,6 +1,6 @@ # See https://www.runway.team/blog/how-to-set-up-a-ci-cd-pipeline-for-your-ios-app-fastlane-github-actions -name: Build iOS and upload to Testflight +name: iOS Build and Deploy on: push: diff --git a/android/Gemfile b/android/Gemfile index 7a118b49b..883354277 100644 --- a/android/Gemfile +++ b/android/Gemfile @@ -1,3 +1,11 @@ source "https://rubygems.org" gem "fastlane" +gem "screengrab" + +# To Resolve warnings about libraries removed in Ruby 3.4.0 +gem "mutex_m" +gem "abbrev" + +plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') +eval_gemfile(plugins_path) if File.exist?(plugins_path) diff --git a/android/Gemfile.lock b/android/Gemfile.lock index 6f642cb3c..bd2f43d8c 100644 --- a/android/Gemfile.lock +++ b/android/Gemfile.lock @@ -5,6 +5,7 @@ GEM base64 nkf rexml + abbrev (0.1.2) addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) artifactory (3.0.17) @@ -109,6 +110,7 @@ GEM xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) + fastlane-plugin-increment_version_code (0.4.3) gh_inspector (1.1.3) google-apis-androidpublisher_v3 (0.54.0) google-apis-core (>= 0.11.0, < 2.a) @@ -158,6 +160,7 @@ GEM mini_mime (1.1.5) multi_json (1.15.0) multipart-post (2.4.0) + mutex_m (0.2.0) nanaimo (0.3.0) naturally (2.2.1) nkf (0.2.0) @@ -175,6 +178,8 @@ GEM rouge (2.0.7) ruby2_keywords (0.0.5) rubyzip (2.3.2) + screengrab (1.0.0) + fastlane (>= 2.0.0, < 3.0.0) security (0.1.5) signet (0.19.0) addressable (~> 2.8) @@ -212,7 +217,11 @@ PLATFORMS ruby DEPENDENCIES + abbrev fastlane + fastlane-plugin-increment_version_code + mutex_m + screengrab BUNDLED WITH 2.5.4 diff --git a/android/app/build.gradle b/android/app/build.gradle index 99316d445..f9d4bfc80 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -86,6 +86,7 @@ android { versionCode 7 versionName "1.0.4" missingDimensionStrategy 'react-native-camera', 'general' + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } signingConfigs { debug { @@ -127,6 +128,15 @@ dependencies { } else { implementation jscFlavor } + + testImplementation 'junit:junit:4.13.2' + + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + androidTestImplementation 'androidx.test:rules:1.5.0' + + androidTestImplementation 'tools.fastlane:screengrab:2.1.1' + androidTestImplementation 'com.jraska:falcon:2.2.0' } apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index 11b025724..b6224d537 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -1,6 +1,6 @@ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified -# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt +# in /usr/local/opt/android-sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # @@ -8,3 +8,55 @@ # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile + +-dontwarn okio.** +# Platform calls Class.forName on types which do not exist on Android to determine platform. +-dontnote retrofit2.Platform +# Platform used when running on Java 8 VMs. Will not be used at runtime. +-dontwarn retrofit2.Platform$Java8 +# Retain generic type information for use by reflection by converters and adapters. +-keepattributes Signature +# Retain declared checked exceptions for use by a Proxy instance. +-keepattributes Exceptions + + +# OkHttp rules + +# JSR 305 annotations are for embedding nullability information. +-dontwarn javax.annotation.** + +# A resource is loaded with a relative path so the package of this class must be preserved. +-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase + +# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. +-dontwarn org.codehaus.mojo.animal_sniffer.* + +# OkHttp platform used only on JVM and when Conscrypt dependency is available. +-dontwarn okhttp3.internal.platform.ConscryptPlatform + + +# Retrofit rules + +# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items). +-keep,allowobfuscation,allowshrinking interface retrofit2.Call +-keep,allowobfuscation,allowshrinking class retrofit2.Response + +# With R8 full mode generic signatures are stripped for classes that are not +# kept. Suspend functions are wrapped in continuations where the type argument +# is used. +-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation \ No newline at end of file diff --git a/android/app/src/androidTest/ExampleInstrumentedTest b/android/app/src/androidTest/ExampleInstrumentedTest new file mode 100644 index 000000000..697a09612 --- /dev/null +++ b/android/app/src/androidTest/ExampleInstrumentedTest @@ -0,0 +1,61 @@ +package one.oneboulder.one + +import androidx.test.espresso.Espresso +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.rule.ActivityTestRule + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* +import org.junit.Rule +import tools.fastlane.screengrab.Screengrab +import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy +import tools.fastlane.screengrab.locale.LocaleTestRule + +/** +* Instrumented test, which will execute on an Android device. +* +* See [testing documentation](http://d.android.com/tools/testing). +*/ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + + // JVMField needed! + @Rule + @JvmField + val localeTestRule = LocaleTestRule() + + @get:Rule + var activityRule = ActivityTestRule(MainActivity::class.java, false, false) + + @Test + fun testTakeScreenshot() { + activityRule.launchActivity(null) + //prepares to take a screenshot of the app + Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy()) + + Espresso.onView(ViewMatchers.withId(R.id.generateButton)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + //Takes screenshot of the first screen + Screengrab.screenshot("myAvatar_before_click") + + //Trigger the generate button onClick function + Espresso.onView(ViewMatchers.withId(R.id.genrateButton)) + .perform(ViewActions.click()) + + //Takes another screenshot + Screengrab.screenshot("myAvatar_after_click") + } + + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("one.oneboulder.one", appContext.packageName) + } +} \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index eb98c01af..950f53f4a 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -2,6 +2,20 @@ + + + + + + + + + + + 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 "Runs all the tests" lane :test do gradle(task: "test") end - desc "Submit a new Beta Build to Crashlytics Beta" - lane :beta do - gradle(task: "clean assembleRelease") - crashlytics - - # sh "your_script.sh" - # You can also use other beta testing services here + desc "Build debug, test APK for screenshots and grab screenshots" + lane :grab_screens do + gradle( + task: 'clean' + ) + gradle( + task: 'assemble', + build_type: 'Debug' + ) + gradle( + task: 'assemble', + build_type: 'AndroidTest' + ) + screengrab end - desc "Deploy a new version to the Google Play" - lane :deploy do - gradle(task: "clean assembleRelease") - upload_to_play_store + lane :upload_internal_track do + upload_to_play_store( + track: "internal", + json_key: ENV["ANDROID_JSON_KEY_FILE"] + ) end + + private_lane :build_upload_play_store do + fetch_and_increment_build_number + build + upload_internal_track + end + + desc "Connect to DEV server, build and upload to Play Store" + lane :build_dev_upload_play_store do + ENV['API_URL'] = 'https://dev.onelocal.one/api' + build_upload_play_store + end + + desc "Connect to BETA server, Build and upload to Play Store" + lane :build_beta_upload_play_store do + ENV['API_URL'] = 'https://beta.onelocal.one/api' + build_upload_play_store + end end diff --git a/android/fastlane/Pluginfile b/android/fastlane/Pluginfile new file mode 100644 index 000000000..412c2ff98 --- /dev/null +++ b/android/fastlane/Pluginfile @@ -0,0 +1,5 @@ +# Autogenerated by fastlane +# +# Ensure this file is checked in to source control! + +gem 'fastlane-plugin-increment_version_code' diff --git a/android/fastlane/README.md b/android/fastlane/README.md index 7ec1207f1..cd770e81d 100644 --- a/android/fastlane/README.md +++ b/android/fastlane/README.md @@ -15,29 +15,37 @@ For _fastlane_ installation instructions, see [Installing _fastlane_](https://do ## Android -### android test +### android increment_vc ```sh -[bundle exec] fastlane android test +[bundle exec] fastlane android increment_vc ``` -Runs all the tests +Increment version code -### android beta +### android build ```sh -[bundle exec] fastlane android beta +[bundle exec] fastlane android build ``` -Submit a new Beta Build to Crashlytics Beta +Build + +### android test + +```sh +[bundle exec] fastlane android test +``` + +Runs all the tests -### android deploy +### android grab_screens ```sh -[bundle exec] fastlane android deploy +[bundle exec] fastlane android grab_screens ``` -Deploy a new version to the Google Play +Build debug, test APK for screenshots and grab screenshots ---- diff --git a/android/fastlane/Screengrabfile b/android/fastlane/Screengrabfile new file mode 100644 index 000000000..cca05f381 --- /dev/null +++ b/android/fastlane/Screengrabfile @@ -0,0 +1,18 @@ +# Set the path to the Android SDK +android_home('$PATH') + +# Start ADB in root mode, giving you elevated permissions to write to the device +# use_adb_root(true) + +# Your project's package name +app_package_name('one.oneboulder.one') + +# Paths for APK files, which you are creating via fastlane +app_apk_path('app/build/outputs/apk/debug/app-debug.apk') +tests_apk_path('app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk') + +# Locations where you want to create screenshots. Add locales as required. +locales(['en-US']) + +# Clears all previously generated screenshots before creating new ones +clear_previous_screenshots(true) diff --git a/android/gradle.properties b/android/gradle.properties index a46a5b90f..4bf629260 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -10,7 +10,7 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m -org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m +org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile index 22fd6a155..651ccfda6 100644 --- a/ios/fastlane/Fastfile +++ b/ios/fastlane/Fastfile @@ -13,6 +13,8 @@ # Uncomment the line if you want fastlane to automatically update itself # update_fastlane +default_platform(:ios) + fastlane_require "dotenv" Dotenv.load ".env.secret" From 2f1243d5b6347a8b6d2a7e8a5088a132c6baf0aa Mon Sep 17 00:00:00 2001 From: Shawn Lauzon Date: Sat, 27 Apr 2024 00:16:43 -0500 Subject: [PATCH 3/3] chore: Upgrade stripe-react-native --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 568d01fa6..7a53af405 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "@react-navigation/stack": "^6.3.17", "@reduxjs/toolkit": "^1.9.5", "@rnmapbox/maps": "^10.1.18", - "@stripe/stripe-react-native": "^0.37.0", + "@stripe/stripe-react-native": "^0.37.3", "@tanstack/react-query": "^4.29.19", "axios": "^1.4.0", "jwt-decode": "^4.0.0", @@ -4927,9 +4927,9 @@ } }, "node_modules/@stripe/stripe-react-native": { - "version": "0.37.0", - "resolved": "https://registry.npmjs.org/@stripe/stripe-react-native/-/stripe-react-native-0.37.0.tgz", - "integrity": "sha512-9pQNog+hMqeSiEE/9Q9OSNEmyq7enqDkTQClXWgFCXYDOjX/FjUoV+3VFTxbEPJANAvFX1Vs43pI2j4t6M5Enw==", + "version": "0.37.3", + "resolved": "https://registry.npmjs.org/@stripe/stripe-react-native/-/stripe-react-native-0.37.3.tgz", + "integrity": "sha512-9OReixY4bP3ogHUoAmDs+FRKxTCCDz6APep6fn8LAzs5xG5IGDetFb7UlZkigFYqtJgbe3+n4kMS5wIcxKgnLQ==", "peerDependencies": { "expo": ">=46.0.9", "react": "*", diff --git a/package.json b/package.json index a8a36f9dc..ddd8bd498 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@react-navigation/stack": "^6.3.17", "@reduxjs/toolkit": "^1.9.5", "@rnmapbox/maps": "^10.1.18", - "@stripe/stripe-react-native": "^0.37.0", + "@stripe/stripe-react-native": "^0.37.3", "@tanstack/react-query": "^4.29.19", "axios": "^1.4.0", "jwt-decode": "^4.0.0",