From e848d8ea6e266b2ef3493294e0d2bcb6654e1cce Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Tue, 5 Nov 2019 08:44:36 -0300 Subject: [PATCH] Update unsigned android and ios builds (#3508) * Update unsigned android and ios builds * Fix attach_workspace path * attach_workspace to ~/ * Remove unnecessary exit 1 --- .circleci/config.yml | 83 ++++++++++++++++++++++++++++++- Makefile | 12 ----- android/app/build.gradle | 2 +- fastlane/Fastfile | 64 ++++++++++++++++-------- fastlane/Gemfile.lock | 22 ++++---- fastlane/metadata/changelog | 5 ++ patches/react-native+0.59.9.patch | 25 ---------- patches/react-native+0.61.2.patch | 78 +++++++++++++++++++++++++++++ 8 files changed, 219 insertions(+), 72 deletions(-) create mode 100644 fastlane/metadata/changelog delete mode 100644 patches/react-native+0.59.9.patch diff --git a/.circleci/config.yml b/.circleci/config.yml index 3225b8f63..d2b61f1fb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -141,7 +141,7 @@ commands: working_directory: fastlane name: Run fastlane to build android no_output_timeout: 30m - command: bundle exec fastlane android build || exit 1 + command: bundle exec fastlane android build build-ios: description: "Build the iOS app" @@ -157,7 +157,7 @@ commands: working_directory: fastlane name: Run fastlane to build iOS no_output_timeout: 30m - command: bundle exec fastlane ios build || exit 1 + command: bundle exec fastlane ios build deploy-to-store: description: "Deploy build to store" @@ -238,6 +238,25 @@ jobs: - save: filename: "Mattermost_Beta.apk" + build-android-unsigned: + executor: android + steps: + - checkout: + path: ~/mattermost-mobile + - npm-dependencies + - assets + - fastlane-dependencies: + for: android + - gradle-dependencies + - run: + working_directory: fastlane + name: Run fastlane to build unsigned android + no_output_timeout: 30m + command: bundle exec fastlane android unsigned + - persist + - save: + filename: "Mattermost-unsigned.apk" + build-ios-beta: executor: ios steps: @@ -263,6 +282,25 @@ jobs: - save: filename: "Mattermost_Beta.ipa" + build-ios-unsigned: + executor: ios + steps: + - checkout: + path: ~/mattermost-mobile + - npm-dependencies + - pods-dependencies + - assets + - fastlane-dependencies: + for: ios + - run: + working_directory: fastlane + name: Run fastlane to build unsigned iOS + no_output_timeout: 30m + command: bundle exec fastlane ios unsigned + - persist + - save: + filename: "Mattermost-unsigned.ipa" + deploy-android-release: executor: name: android @@ -299,6 +337,18 @@ jobs: target: ios file: Mattermost_Beta.ipa + github-release: + executor: + name: android + resource_class: medium + steps: + - attach_workspace: + at: ~/ + - run: + name: Create GitHub release + working_directory: fastlane + command: bundle exec fastlane github + workflows: version: 2 build: @@ -403,3 +453,32 @@ workflows: filters: branches: only: /^build-pr-.*/ + + - build-android-unsigned: + context: mattermost-mobile-unsigned + requires: + - test + filters: + tags: + only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/ + branches: + ignore: /.*/ + - build-ios-unsigned: + context: mattermost-mobile-unsigned + requires: + - test + filters: + tags: + only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/ + branches: + ignore: /.*/ + - github-release: + context: mattermost-mobile-unsigned + requires: + - build-android-unsigned + - build-ios-unsigned + filters: + tags: + only: /^v(\d+\.)(\d+\.)(\d+)(.*)?$/ + branches: + ignore: /.*/ \ No newline at end of file diff --git a/Makefile b/Makefile index af3a95c2b..33549d57c 100644 --- a/Makefile +++ b/Makefile @@ -186,14 +186,7 @@ build-android: | stop pre-build check-style i18n-extract-ci prepare-android-buil unsigned-ios: stop pre-build check-style ## Build an unsigned version of the iOS app $(call start_packager) - @echo "Building unsigned iOS app" @cd fastlane && NODE_ENV=production bundle exec fastlane ios unsigned - @mkdir -p build-ios - @cd ios/ && xcodebuild -workspace Mattermost.xcworkspace/ -scheme Mattermost -sdk iphoneos -configuration Release -parallelizeTargets -resultBundlePath ../build-ios/result -derivedDataPath ../build-ios/ CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO - @cd build-ios/ && mkdir -p Payload && cp -R Build/Products/Release-iphoneos/Mattermost.app Payload/ && zip -r Mattermost-unsigned.ipa Payload/ - @mv build-ios/Mattermost-unsigned.ipa . - @cd fastlane && bundle exec fastlane upload_file_to_s3 file:Mattermost-unsigned.ipa os_type:iOS - @rm -rf build-ios/ $(call stop_packager) ios-sim-x86_64: stop pre-build check-style ## Build an unsigned x86_64 version of the iOS app for iPhone simulator @@ -209,12 +202,7 @@ ios-sim-x86_64: stop pre-build check-style ## Build an unsigned x86_64 version o $(call stop_packager) unsigned-android: stop pre-build check-style prepare-android-build ## Build an unsigned version of the Android app - $(call start_packager) - @echo "Building unsigned Android app" @cd fastlane && NODE_ENV=production bundle exec fastlane android unsigned - @mv android/app/build/outputs/apk/unsigned/app-unsigned-unsigned.apk ./Mattermost-unsigned.apk - @cd fastlane && bundle exec fastlane upload_file_to_s3 file:Mattermost-unsigned.apk os_type:Android - $(call stop_packager) test: | pre-run check-style ## Runs tests @npm test diff --git a/android/app/build.gradle b/android/app/build.gradle index a1d5039a6..35cd1ccb1 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -179,7 +179,7 @@ android { unsigned.initWith(buildTypes.release) unsigned { signingConfig null - matchingFallbacks = ['debug', 'release'] + matchingFallbacks = ['release'] } } // applicationVariants are e.g. debug, release diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 7de9d94d8..26d1a3e01 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -17,8 +17,6 @@ before_all do ENV['BRANCH_TO_BUILD'] = ENV['CIRCLE_BRANCH'] end - UI.success("Building for release #{ENV['BUILD_FOR_RELEASE']}") - if ENV['CIRCLECI'] != 'true' # Raises an error is git is not clean if ENV['COMMIT_CHANGES_TO_GIT'] == 'true' @@ -187,19 +185,6 @@ lane :build do |options| build end -desc 'Build the app for Android and iOS unsigned' -lane :unsigned do - configure - - # Build the android app - self.runner.current_platform = :android - unsigned - - # Build the ios app - self.runner.current_platform = :ios - unsigned -end - desc 'Upload file to s3' lane :upload_file_to_s3 do |options| os_type = options[:os_type] @@ -288,6 +273,29 @@ lane :upload_file_to_s3 do |options| end end +desc 'Create GitHub release' +lane :github do + tag = ENV['CIRCLE_TAG'] || ENV['TAG'] + + if tag + version = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost') + build = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj') + changelog = File.read("metadata/changelog") + changelog.concat("* Android [Mattermost.apk](https://releases.mattermost.com/mattermost-mobile/#{version}/#{build}/Mattermost.apk)\n") + changelog.concat("* iOS [Mattermost.ipa](https://releases.mattermost.com/mattermost-mobile/#{version}/#{build}/Mattermost.ipa)") + + github_release = set_github_release( + repository_name: "mattermost/mattermost-mobile", + api_token: ENV["GITHUB_TOKEN"], + name: "Mobile Version #{version}", + tag_name: tag, + description: changelog, + upload_assets: ["./Mattermost-unsigned.ipa", "./Mattermost-unsigned.apk"], + is_draft: true + ) + end +end + platform :ios do before_all do if ENV['CIRCLECI'] == 'true' @@ -317,11 +325,20 @@ platform :ios do desc 'Build an unsigned ipa' lane :unsigned do - unless configured - configure - end + UI.success('Building unsigned iOS app') + + ENV['APP_NAME'] = 'Mattermost' + ENV['REPLACE_ASSETS'] = 'true' + ENV['BUILD_FOR_RELEASE'] = 'true' + update_identifiers replace_assets + + sh 'mkdir -p ../build-ios' + sh 'cd ../ios/ && xcodebuild -workspace Mattermost.xcworkspace/ -scheme Mattermost -sdk iphoneos -configuration Release -parallelizeTargets -resultBundlePath ../build-ios/result -derivedDataPath ../build-ios/ CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO' + sh 'cd ../build-ios/ && mkdir -p Payload && cp -R Build/Products/Release-iphoneos/Mattermost.app Payload/ && zip -r Mattermost-unsigned.ipa Payload/' + sh 'mv ../build-ios/Mattermost-unsigned.ipa ../' + sh 'rm -rf ../build-ios/' end lane :update_identifiers do @@ -516,9 +533,12 @@ platform :android do desc 'Build an unsigned apk' lane :unsigned do - unless configured - configure - end + UI.success('Building unsigned Android app') + + ENV['APP_NAME'] = 'Mattermost' + ENV['REPLACE_ASSETS'] = 'true' + ENV['BUILD_FOR_RELEASE'] = 'true' + update_identifiers replace_assets @@ -527,6 +547,8 @@ platform :android do build_type: 'Unsigned', project_dir: 'android/' ) + + sh "mv #{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]} #{Pathname.new(File.expand_path(File.dirname(__FILE__))).parent.to_s}/Mattermost-unsigned.apk" end desc 'Update config and module/listener for Android telemetry' diff --git a/fastlane/Gemfile.lock b/fastlane/Gemfile.lock index b487cd04b..b1a6653c8 100644 --- a/fastlane/Gemfile.lock +++ b/fastlane/Gemfile.lock @@ -6,17 +6,17 @@ GEM public_suffix (>= 2.0.2, < 5.0) atomos (0.1.3) aws-eventstream (1.0.3) - aws-partitions (1.223.0) - aws-sdk-core (3.68.1) + aws-partitions (1.228.0) + aws-sdk-core (3.72.0) aws-eventstream (~> 1.0, >= 1.0.2) - aws-partitions (~> 1.0) + aws-partitions (~> 1, >= 1.228.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.24.0) - aws-sdk-core (~> 3, >= 3.61.1) + aws-sdk-kms (1.25.0) + aws-sdk-core (~> 3, >= 3.71.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.49.0) - aws-sdk-core (~> 3, >= 3.61.1) + aws-sdk-s3 (1.51.0) + aws-sdk-core (~> 3, >= 3.71.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) aws-sigv4 (1.1.0) @@ -34,7 +34,7 @@ GEM unf (>= 0.0.5, < 1.0.0) dotenv (2.7.5) emoji_regex (1.0.1) - excon (0.67.0) + excon (0.68.0) faraday (0.17.0) multipart-post (>= 1.2, < 3) faraday-cookie_jar (0.0.6) @@ -94,9 +94,9 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.0) signet (~> 0.9) - google-cloud-core (1.3.1) + google-cloud-core (1.4.0) google-cloud-env (~> 1.0) - google-cloud-env (1.2.1) + google-cloud-env (1.3.0) faraday (~> 0.11) google-cloud-storage (1.16.0) digest-crc (~> 0.4) @@ -163,7 +163,7 @@ GEM unf_ext (0.0.7.6) unicode-display_width (1.6.0) word_wrap (1.0.0) - xcodeproj (1.12.0) + xcodeproj (1.13.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) diff --git a/fastlane/metadata/changelog b/fastlane/metadata/changelog new file mode 100644 index 000000000..b3b7c8322 --- /dev/null +++ b/fastlane/metadata/changelog @@ -0,0 +1,5 @@ +This version is compatible with Mattermost servers v5.9+. + +Please see [changelog](https://github.com/mattermost/mattermost-mobile/blob/master/CHANGELOG.md) for full release notes. If you're interested in helping beta test upcoming versions before they are released, please see our [documentation](https://github.com/mattermost/mattermost-mobile#testing). + +### Downloads diff --git a/patches/react-native+0.59.9.patch b/patches/react-native+0.59.9.patch deleted file mode 100644 index a846cd491..000000000 --- a/patches/react-native+0.59.9.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m b/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m -index d464e6a..6c397c5 100644 ---- a/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m -+++ b/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m -@@ -170,6 +170,12 @@ - (void)postprocessAttributedText:(NSMutableAttributedString *)attributedText - - - (NSAttributedString *)attributedTextWithMeasuredAttachmentsThatFitSize:(CGSize)size - { -+ static UIImage *placeholderImage; -+ static dispatch_once_t onceToken; -+ dispatch_once(&onceToken, ^{ -+ placeholderImage = [UIImage new]; -+ }); -+ - NSMutableAttributedString *attributedText = - [[NSMutableAttributedString alloc] initWithAttributedString:[self attributedTextWithBaseTextAttributes:nil]]; - -@@ -188,6 +194,7 @@ - (NSAttributedString *)attributedTextWithMeasuredAttachmentsThatFitSize:(CGSize - maximumSize:size]; - NSTextAttachment *attachment = [NSTextAttachment new]; - attachment.bounds = (CGRect){CGPointZero, fittingSize}; -+ attachment.image = placeholderImage; - [attributedText addAttribute:NSAttachmentAttributeName value:attachment range:range]; - } - ]; diff --git a/patches/react-native+0.61.2.patch b/patches/react-native+0.61.2.patch index fffcc60b3..78a6a06fa 100644 --- a/patches/react-native+0.61.2.patch +++ b/patches/react-native+0.61.2.patch @@ -1,3 +1,43 @@ +diff --git a/node_modules/react-native/react.gradle b/node_modules/react-native/react.gradle +index 14f0746..054f652 100644 +--- a/node_modules/react-native/react.gradle ++++ b/node_modules/react-native/react.gradle +@@ -116,7 +116,7 @@ afterEvaluate { + + // Set up dev mode + def devEnabled = !(config."devDisabledIn${targetName}" +- || targetName.toLowerCase().contains("release")) ++ || targetName.toLowerCase().contains("release") || targetName.toLowerCase().contains("unsigned")) + + def extraArgs = extraPackagerArgs; + +@@ -141,7 +141,7 @@ afterEvaluate { + def hermesFlags; + def hbcTempFile = file("${jsBundleFile}.hbc") + exec { +- if (targetName.toLowerCase().contains("release")) { ++ if (targetName.toLowerCase().contains("release") || targetName.toLowerCase().contains("unsigned")) { + // Can't use ?: since that will also substitute valid empty lists + hermesFlags = config.hermesFlagsRelease + if (hermesFlags == null) hermesFlags = ["-O", "-output-source-map"] +@@ -180,7 +180,7 @@ afterEvaluate { + ? config."bundleIn${targetName}" + : config."bundleIn${variant.buildType.name.capitalize()}" != null + ? config."bundleIn${variant.buildType.name.capitalize()}" +- : targetName.toLowerCase().contains("release") ++ : (targetName.toLowerCase().contains("release") || targetName.toLowerCase().contains("unsigned")) + } + + // Expose a minimal interface on the application variant and the task itself: +@@ -272,7 +272,7 @@ afterEvaluate { + // This should really be done by packaging all Hermes releated libs into + // two separate HermesDebug and HermesRelease AARs, but until then we'll + // kludge it by deleting the .so files out of the /transforms/ directory. +- def isRelease = targetName.toLowerCase().contains("release") ++ def isRelease = targetName.toLowerCase().contains("release") || targetName.toLowerCase().contains("unsigned") + def libDir = "$buildDir/intermediates/transforms/" + def vmSelectionAction = { + fileTree(libDir).matching { diff --git a/node_modules/react-native/Libraries/Lists/VirtualizedList.js b/node_modules/react-native/Libraries/Lists/VirtualizedList.js index 7dffc17..548e7bb 100644 --- a/node_modules/react-native/Libraries/Lists/VirtualizedList.js @@ -19,6 +59,31 @@ index 7dffc17..548e7bb 100644 }, horizontallyInverted: { transform: [{scaleX: -1}], +diff --git a/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m b/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m +index 1543bca..a4502b7 100644 +--- a/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m ++++ b/node_modules/react-native/Libraries/Text/Text/RCTTextShadowView.m +@@ -177,6 +177,12 @@ - (void)postprocessAttributedText:(NSMutableAttributedString *)attributedText + + - (NSAttributedString *)attributedTextWithMeasuredAttachmentsThatFitSize:(CGSize)size + { ++ static UIImage *placeholderImage; ++ static dispatch_once_t onceToken; ++ dispatch_once(&onceToken, ^{ ++ placeholderImage = [UIImage new]; ++ }); ++ + NSMutableAttributedString *attributedText = + [[NSMutableAttributedString alloc] initWithAttributedString:[self attributedTextWithBaseTextAttributes:nil]]; + +@@ -195,6 +201,7 @@ - (NSAttributedString *)attributedTextWithMeasuredAttachmentsThatFitSize:(CGSize + maximumSize:size]; + NSTextAttachment *attachment = [NSTextAttachment new]; + attachment.bounds = (CGRect){CGPointZero, fittingSize}; ++ attachment.image = placeholderImage; + [attributedText addAttribute:NSAttachmentAttributeName value:attachment range:range]; + } + ]; diff --git a/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.h b/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.h index 1b17cff..9efa98e 100644 --- a/node_modules/react-native/Libraries/WebSocket/RCTSRWebSocket.h @@ -150,3 +215,16 @@ index 35f0757..a0205fc 100644 } get binaryType(): ?BinaryType { +diff --git a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java +index ef2ae93..2795802 100644 +--- a/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java ++++ b/node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java +@@ -92,7 +92,7 @@ public class AndroidInfoModule extends ReactContextBaseJavaModule implements Tur + + private Boolean isRunningScreenshotTest() { + try { +- Class.forName("android.support.test.rule.ActivityTestRule"); ++ Class.forName("androidx.test.rule.ActivityTestRule"); + return true; + } catch (ClassNotFoundException ignored) { + return false;