From 4e94f81c0069defa4602332b51003af15c55b9be Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Tue, 9 Oct 2018 12:05:24 -0300 Subject: [PATCH] Update Fastlane scripts (#2231) * Upload builds to store after a successful build * Update script to build PRs --- Makefile | 34 ++++-- fastlane/Fastfile | 259 +++++++++++++++++++++++++-------------------- fastlane/plist.erb | 4 +- 3 files changed, 175 insertions(+), 122 deletions(-) diff --git a/Makefile b/Makefile index a4acdf9a8..fc700d302 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ .PHONY: check-style .PHONY: start stop .PHONY: run run-ios run-android -.PHONY: build-ios build-android unsigned-ios unsigned-android -.PHONY: build +.PHONY: build build-ios build-android unsigned-ios unsigned-android +.PHONY: build-pr can-build-pr prepare-pr .PHONY: test help POD := $(shell which pod 2> /dev/null) @@ -168,7 +168,7 @@ run-android: | check-device-android pre-run prepare-android-build ## Runs the ap fi; \ fi -build: | pre-run check-style +build: | stop pre-run check-style ## Builds the app for Android & iOS @if [ $(shell ps -ef | grep -i "cli.js start" | grep -civ grep) -eq 0 ]; then \ echo Starting React Native packager server; \ npm start & echo; \ @@ -177,7 +177,8 @@ build: | pre-run check-style @cd fastlane && BABEL_ENV=production NODE_ENV=production bundle exec fastlane build @ps -ef | grep -i "cli.js start" | grep -iv grep | awk '{print $$2}' | xargs kill -9 -build-ios: | pre-run check-style ## Creates an iOS build + +build-ios: | stop pre-run check-style ## Builds the iOS app @if [ $(shell ps -ef | grep -i "cli.js start" | grep -civ grep) -eq 0 ]; then \ echo Starting React Native packager server; \ npm start & echo; \ @@ -186,7 +187,7 @@ build-ios: | pre-run check-style ## Creates an iOS build @cd fastlane && BABEL_ENV=production NODE_ENV=production bundle exec fastlane ios build @ps -ef | grep -i "cli.js start" | grep -iv grep | awk '{print $$2}' | xargs kill -9 -build-android: | pre-run check-style prepare-android-build ## Creates an Android build +build-android: | stop pre-run check-style prepare-android-build ## Build the Android app @if [ $(shell ps -ef | grep -i "cli.js start" | grep -civ grep) -eq 0 ]; then \ echo Starting React Native packager server; \ npm start & echo; \ @@ -195,7 +196,7 @@ build-android: | pre-run check-style prepare-android-build ## Creates an Android @cd fastlane && BABEL_ENV=production NODE_ENV=production bundle exec fastlane android build @ps -ef | grep -i "cli.js start" | grep -iv grep | awk '{print $$2}' | xargs kill -9 -unsigned-ios: pre-run check-style +unsigned-ios: stop pre-run check-style ## Build an unsigned version of the iOS app @if [ $(shell ps -ef | grep -i "cli.js start" | grep -civ grep) -eq 0 ]; then \ echo Starting React Native packager server; \ npm start & echo; \ @@ -209,7 +210,7 @@ unsigned-ios: pre-run check-style @rm -rf build-ios/ @ps -ef | grep -i "cli.js start" | grep -iv grep | awk '{print $$2}' | xargs kill -9 -unsigned-android: pre-run check-style prepare-android-build +unsigned-android: stop pre-run check-style prepare-android-build ## Build an unsigned version of the Android app @if [ $(shell ps -ef | grep -i "cli.js start" | grep -civ grep) -eq 0 ]; then \ echo Starting React Native packager server; \ npm start & echo; \ @@ -222,6 +223,25 @@ unsigned-android: pre-run check-style prepare-android-build test: | pre-run check-style ## Runs tests @npm test +build-pr: | can-build-pr prepare-pr stop pre-run check-style ## Build a PR from the mattermost-mobile repo + @if [ $(shell ps -ef | grep -i "cli.js start" | grep -civ grep) -eq 0 ]; then \ + echo Starting React Native packager server; \ + npm start & echo; \ + fi + @echo "Building App from PR ${PR_ID}" + @cd fastlane && BABEL_ENV=production NODE_ENV=production bundle exec fastlane build_pr pr:PR-${PR_ID} + @ps -ef | grep -i "cli.js start" | grep -iv grep | awk '{print $$2}' | xargs kill -9 + +can-build-pr: + @if [ -z ${PR_ID} ]; then \ + echo a PR number needs to be specified; \ + exit 1; \ + fi + +prepare-pr: + @git fetch origin pull/${PR_ID}/head:PR-${PR_ID} + @git checkout PR-${PR_ID} + ## Help documentation https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 8373f9233..204965c76 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -1,15 +1,21 @@ -require 'json' fastlane_version '2.71.0' fastlane_require 'aws-sdk-s3' fastlane_require 'erb' +fastlane_require 'json' skip_docs configured = false # Executes before anything else use to setup the script -before_all do +before_all do |lane, options| + if lane.to_s == 'build_pr' + pr = options[:pr] + UI.success("Building #{pr}") + ENV['BRANCH_TO_BUILD'] = pr + end + # Raises an error is git is not clean if ENV['COMMIT_CHANGES_TO_GIT'] == 'true' ensure_git_status_clean @@ -35,7 +41,13 @@ before_all do end end -after_all do +after_all do |lane| + if lane.to_s == 'build' + submit_to_store + elsif lane.to_s == 'build_pr' + upload_to_s3 + end + if ENV['RESET_GIT_BRANCH'] == 'true' branch = ENV['BRANCH_TO_BUILD'] || 'master' package_id = ENV['MAIN_APP_IDENTIFIER'] || 'com.mattermost.rnbeta' @@ -56,6 +68,12 @@ after_all do local_branch = ENV['GIT_LOCAL_BRANCH'] || 'build' sh "git branch -D #{local_branch}" UI.success("Deleted working branch \"#{local_branch}\"") + if lane.to_s == 'build_pr' + sh 'git checkout master' + ## Remove the branch for the PR + sh "git branch -D #{branch}" + UI.success("Deleted PR branch \"#{branch}\"") + end end end end @@ -174,16 +192,16 @@ lane :unsigned do end desc 'Build the app using a PR so QA can test' -lane :build_qa do +lane :build_pr do configure # Build the android app self.runner.current_platform = :android - build_qa + build # Build the ios app self.runner.current_platform = :ios - build_qa + build end platform :ios do @@ -195,33 +213,6 @@ platform :ios do update_identifiers replace_assets build_ios - - # Submit to TestFlight if required - if ENV['SUBMIT_IOS_TO_TESTFLIGHT'] == 'true' - pilot - - # Send a build message to Mattermost - pretext = '#### New iOS released ready to be published' - msg = 'release has been cut and is on TestFlight ready to be published.' - - if ENV['BETA_BUILD'] == 'true' - pretext = '#### New iOS beta published to TestFlight' - msg = 'Sign up as a beta tester [here](https://mattermost-fastlane.herokuapp.com/)' - end - - version = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost') - build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj') - - send_message_to_mattermost( - version, - build_number, - pretext, - '', - msg, - [], - true - ) - end end desc 'Build an unsigned ipa' @@ -233,30 +224,6 @@ platform :ios do replace_assets end - lane :build_qa do - match(type: 'adhoc') - build_ios - - plist_template = File.read('plist.erb') - abbreviated_commit_hash = `git rev-parse --short head` - abbreviated_commit_hash.strip! - plist_body = ERB.new(plist_template).result(binding) - - s3 = Aws::S3::Resource.new(region: ENV['AWS_REGION']) - plist_obj = s3.bucket(ENV['AWS_BUCKET_NAME']).object("ios/#{abbreviated_commit_hash}.plist") - plist_obj.put(body: plist_body) - - ipa_obj = s3.bucket(ENV['AWS_BUCKET_NAME']).object("ios/#{abbreviated_commit_hash}.ipa") - ipa_obj.upload_file('../Mattermost.ipa') - - ios_install_url = "itms-services://?action=download-manifest&url=https://s3.#{ENV['AWS_REGION']}.amazonaws.com/#{ENV['AWS_BUCKET_NAME']}/ios/#{abbreviated_commit_hash}.plist" - - unless ENV['MATTERMOST_WEBHOOK_URL'].nil? || ENV['MATTERMOST_WEBHOOK_URL'].empty? - msg = "QA build [#{abbreviated_commit_hash}](https://github.com/mattermost/mattermost-mobile/commit/#{abbreviated_commit_hash}) — iOS: #{ios_install_url}" - mattermost(message: msg, username: 'Fastlane', icon_url: 'https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/move-to-ios-icon.png') - end - end - lane :update_identifiers do # Set the name for the app app_name = ENV['APP_NAME'] || 'Mattermost Beta' @@ -385,44 +352,6 @@ platform :android do replace_assets link_sentry_android build_android - - app_name = ENV['APP_NAME'] || 'Mattermost Beta' - apk_path = "#{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}" - - if ENV['SUBMIT_ANDROID_TO_GOOGLE_PLAY'] == 'true' - supply( - track: ENV['SUPPLY_TRACK'] || 'alpha', - apk: apk_path - ) - - build_number = android_get_version_code( - gradle_file: './android/app/build.gradle' - ) - version_number = android_get_version_name( - gradle_file: './android/app/build.gradle' - ) - - # Send a build message to Mattermost - pretext = '#### New Android released ready to be published' - msg = 'release has been cut and is on the Beta track ready to be published.' - - if ENV['BETA_BUILD'] == 'true' - pretext = '#### New Android beta published to Google Play' - msg = 'Sign up as a beta tester [here](https://play.google.com/apps/testing/com.mattermost.rnbeta)' - end - - send_message_to_mattermost( - version_number, - build_number, - pretext, - '', - msg, - [], - true - ) - end - - sh "mv #{apk_path} \"./#{app_name}.apk\"" end desc 'Build an unsigned apk' @@ -440,24 +369,6 @@ platform :android do ) end - lane :build_qa do - build_android - - abbreviated_commit_hash = last_git_commit[:abbreviated_commit_hash] - - s3 = Aws::S3::Resource.new(region: ENV['AWS_REGION']) - - apk_obj = s3.bucket(ENV['AWS_BUCKET_NAME']).object("android/#{abbreviated_commit_hash}.apk") - apk_obj.upload_file("#{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}") - - android_install_path = "https://s3.#{ENV['AWS_REGION']}.amazonaws.com/#{ENV['AWS_BUCKET_NAME']}/android/#{abbreviated_commit_hash}.apk" - - if ENV['MATTERMOST_WEBHOOK_URL'] && !ENV['MATTERMOST_WEBHOOK_URL'].nil? && !ENV['MATTERMOST_WEBHOOK_URL'].empty? - msg = "QA build [#{abbreviated_commit_hash}](https://github.com/mattermost/mattermost-mobile/commit/#{abbreviated_commit_hash}) — Android: #{android_install_path}" - mattermost(message: msg, username: 'Fastlane', icon_url: 'https://lh3.ggpht.com/XL0CrI8skkxnboGct-duyg-bZ_MxJDTrjczyjdU8OP2PM1dmj7SP4jL1K8JQeMIB3AM=w300') - end - end - lane :update_identifiers do # Set the name for the app app_name = ENV['APP_NAME'] || 'Mattermost Beta' @@ -603,3 +514,125 @@ def send_message_to_mattermost(version_number, build_number, pretext, title, msg ) end end + +def submit_to_store + app_name = ENV['APP_NAME'] || 'Mattermost Beta' + apk_path = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] + ipa_path = lane_context[SharedValues::IPA_OUTPUT_PATH] + + # Submit to Google Play if required + if !apk_path.nil? && ENV['SUBMIT_ANDROID_TO_GOOGLE_PLAY'] == 'true' + UI.success("apk file #{apk_path}") + + supply( + track: ENV['SUPPLY_TRACK'] || 'alpha', + apk: apk_path + ) + + build_number = android_get_version_code( + gradle_file: './android/app/build.gradle' + ) + version_number = android_get_version_name( + gradle_file: './android/app/build.gradle' + ) + + # Send a build message to Mattermost + pretext = '#### New Android released ready to be published' + msg = 'release has been cut and is on the Beta track ready to be published.' + + if ENV['BETA_BUILD'] == 'true' + pretext = '#### New Android beta published to Google Play' + msg = 'Sign up as a beta tester [here](https://play.google.com/apps/testing/com.mattermost.rnbeta)' + end + + send_message_to_mattermost( + version_number, + build_number, + pretext, + '', + msg, + [], + true + ) + end + + # Submit to TestFlight if required + if !ipa_path.nil? && ENV['SUBMIT_IOS_TO_TESTFLIGHT'] == 'true' + UI.success("ipa file #{ipa_path}") + + pilot + + # Send a build message to Mattermost + pretext = '#### New iOS released ready to be published' + msg = 'release has been cut and is on TestFlight ready to be published.' + + if ENV['BETA_BUILD'] == 'true' + pretext = '#### New iOS beta published to TestFlight' + msg = 'Sign up as a beta tester [here](https://mattermost-fastlane.herokuapp.com/)' + end + + version = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost') + build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj') + + send_message_to_mattermost( + version, + build_number, + pretext, + '', + msg, + [], + true + ) + end + + unless apk_path.nil? + sh "mv #{apk_path} \"../#{app_name}.apk\"" + end +end + +def upload_to_s3 + unless ENV['AWS_BUCKET_NAME'].nil? || ENV['AWS_BUCKET_NAME'].empty? || ENV['AWS_REGION'].nil? || ENV['AWS_REGION'].empty? + apk_path = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] + ipa_path = lane_context[SharedValues::IPA_OUTPUT_PATH] + s3_region = ENV['AWS_REGION'] + s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{ENV['BRANCH_TO_BUILD']}" + s3_bucket = ENV['AWS_BUCKET_NAME'] + s3 = Aws::S3::Resource.new(region: s3_region) + abbreviated_commit_hash = last_git_commit[:abbreviated_commit_hash] + + unless apk_path.nil? + apk_obj = s3.bucket(s3_bucket).object("#{s3_folder}/#{abbreviated_commit_hash}.apk") + apk_obj.upload_file("#{apk_path}") + + android_install_path = "https://#{s3_bucket}/#{s3_folder}/#{abbreviated_commit_hash}.apk" + + if ENV['MATTERMOST_WEBHOOK_URL'] && !ENV['MATTERMOST_WEBHOOK_URL'].nil? && !ENV['MATTERMOST_WEBHOOK_URL'].empty? + msg = "QA build [#{abbreviated_commit_hash}](https://github.com/mattermost/mattermost-mobile/commit/#{abbreviated_commit_hash}) — Android: #{android_install_path}" + mattermost(message: msg, username: 'Fastlane', icon_url: 'https://lh3.ggpht.com/XL0CrI8skkxnboGct-duyg-bZ_MxJDTrjczyjdU8OP2PM1dmj7SP4jL1K8JQeMIB3AM=w300') + else + UI.success("PR Built for Android: #{android_install_path}") + end + end + + unless ipa_path.nil? + current_build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj') + plist_template = File.read('plist.erb') + plist_body = ERB.new(plist_template).result(binding) + + plist_obj = s3.bucket(s3_bucket).object("#{s3_folder}/#{abbreviated_commit_hash}.plist") + plist_obj.put(body: plist_body) + + ipa_obj = s3.bucket(s3_bucket).object("#{s3_folder}/#{abbreviated_commit_hash}.ipa") + ipa_obj.upload_file("#{ipa_path}") + + ios_install_url = "itms-services://?action=download-manifest&url=https://#{s3_bucket}/#{s3_folder}/#{abbreviated_commit_hash}.plist" + + unless ENV['MATTERMOST_WEBHOOK_URL'].nil? || ENV['MATTERMOST_WEBHOOK_URL'].empty? + msg = "QA build [#{abbreviated_commit_hash}](https://github.com/mattermost/mattermost-mobile/commit/#{abbreviated_commit_hash}) — iOS: #{ios_install_url}" + mattermost(message: msg, username: 'Fastlane', icon_url: 'https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/move-to-ios-icon.png') + else + UI.success("PR Built for iOS: #{ios_install_url}") + end + end + end +end diff --git a/fastlane/plist.erb b/fastlane/plist.erb index d337356fe..8befa7ae4 100644 --- a/fastlane/plist.erb +++ b/fastlane/plist.erb @@ -11,7 +11,7 @@ kind software-package url - https://s3.<%= ENV['AWS_REGION'] %>.amazonaws.com/<%= ENV['AWS_BUCKET_NAME'] %>/ios/<%= abbreviated_commit_hash %>.ipa + https://<%= s3_bucket %>/<%= s3_folder %>/<%= abbreviated_commit_hash %>.ipa kind @@ -19,7 +19,7 @@ needs-shine url - https://s3.<%= ENV['AWS_REGION'] %>.amazonaws.com/<%= ENV['AWS_BUCKET_NAME'] %>/beta-logo.png + https://<%= s3_bucket %>/<%= ENV['AWS_FOLDER_NAME'] %>/beta-logo.png metadata