verdnatura-chat/.circleci/config.yml

645 lines
19 KiB
YAML

defaults: &defaults
working_directory: ~/repo
macos: &macos
macos:
xcode: "12.5.0"
resource_class: large
bash-env: &bash-env
BASH_ENV: "~/.nvm/nvm.sh"
android-env: &android-env
JAVA_OPTS: '-Xms512m -Xmx2g'
GRADLE_OPTS: '-Xmx3g -Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-Xmx2g -XX:+HeapDumpOnOutOfMemoryError"'
TERM: dumb
install-npm-modules: &install-npm-modules
name: Install NPM modules
command: yarn
restore-npm-cache-linux: &restore-npm-cache-linux
name: Restore NPM cache
key: node-modules-{{ checksum "yarn.lock" }}
save-npm-cache-linux: &save-npm-cache-linux
key: node-modules-{{ checksum "yarn.lock" }}
name: Save NPM cache
paths:
- ./node_modules
restore-npm-cache-mac: &restore-npm-cache-mac
name: Restore NPM cache
key: node-v1-mac-{{ checksum "yarn.lock" }}
save-npm-cache-mac: &save-npm-cache-mac
key: node-v1-mac-{{ checksum "yarn.lock" }}
name: Save NPM cache
paths:
- ./node_modules
restore-gems-cache: &restore-gems-cache
name: Restore gems cache
key: bundle-v1-{{ checksum "ios/Gemfile.lock" }}
save-gems-cache: &save-gems-cache
name: Save gems cache
key: bundle-v1-{{ checksum "ios/Gemfile.lock" }}
paths:
- vendor/bundle
update-fastlane-ios: &update-fastlane-ios
name: Update Fastlane
command: |
echo "ruby-2.6.4" > ~/.ruby-version
bundle install
working_directory: ios
update-fastlane-android: &update-fastlane-android
name: Update Fastlane
command: |
echo "ruby-2.6.4" > ~/.ruby-version
bundle install
working_directory: android
save-gradle-cache: &save-gradle-cache
name: Save gradle cache
key: android-{{ checksum "android/build.gradle" }}-{{ checksum "android/app/build.gradle" }}
paths:
- ~/.gradle
restore_cache: &restore-gradle-cache
name: Restore gradle cache
key: android-{{ checksum "android/build.gradle" }}-{{ checksum "android/app/build.gradle" }}
# COMMANDS
commands:
manage-pods:
description: "Restore/Get/Save cache of pods libs"
steps:
- restore_cache:
name: Restore pods
# TODO: CircleCI isn't caching Podfile.lock correctly, because checksum changes after install
# key: pods-v1-{{ checksum "ios/Podfile.lock" }}
key: pods-v1-{{ checksum "ios/Podfile" }}
- run:
name: Install pods libs
command: |
bundle exec pod install
working_directory: ios
- save_cache:
name: Save pods specs and pods cache
# key: pods-v1-{{ checksum "ios/Podfile.lock" }}
key: pods-v1-{{ checksum "ios/Podfile" }}
paths:
- ~/.pods
- ios/Pods
android-build:
description: "Build Android app"
steps:
- checkout
- restore_cache: *restore-npm-cache-linux
- run: *install-npm-modules
- restore_cache: *restore-gradle-cache
- run:
name: Configure Gradle
command: |
echo -e "" > ./gradle.properties
# echo -e "android.enableAapt2=false" >> ./gradle.properties
echo -e "android.useAndroidX=true" >> ./gradle.properties
echo -e "android.enableJetifier=true" >> ./gradle.properties
echo -e "FLIPPER_VERSION=0.51.0" >> ./gradle.properties
echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
echo -e "APPLICATION_ID=chat.rocket.android" >> ./gradle.properties
echo -e "BugsnagAPIKey=$BUGSNAG_KEY_OFFICIAL" >> ./gradle.properties
echo $CHAT_ROCKET_ANDROID_STORE_FILE_BASE64_JKS | base64 --decode > ./app/$KEYSTORE_OFFICIAL
echo -e "KEYSTORE=$KEYSTORE_OFFICIAL" >> ./gradle.properties
echo -e "KEYSTORE_PASSWORD=$CHAT_ROCKET_ANDROID_STORE_PASSWORD" >> ./gradle.properties
echo -e "KEY_ALIAS=$CHAT_ROCKET_ANDROID_KEY_ALIAS" >> ./gradle.properties
echo -e "KEY_PASSWORD=$CHAT_ROCKET_ANDROID_KEY_PASSWORD" >> ./gradle.properties
else
echo -e "APPLICATION_ID=chat.rocket.reactnative" >> ./gradle.properties
echo -e "BugsnagAPIKey=$BUGSNAG_KEY" >> ./gradle.properties
echo $KEYSTORE_BASE64 | base64 --decode > ./app/$KEYSTORE
echo -e "KEYSTORE=$KEYSTORE" >> ./gradle.properties
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
echo -e "KEY_ALIAS=$KEY_ALIAS" >> ./gradle.properties
echo -e "KEY_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
fi
working_directory: android
- run:
name: Set Google Services
command: |
if [[ $KEYSTORE ]]; then
echo $GOOGLE_SERVICES_ANDROID | base64 --decode > google-services.json
fi
working_directory: android/app
- run:
name: Build App
no_output_timeout: 30m
command: |
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
./gradlew bundleOfficialPlayRelease
fi
if [[ $CIRCLE_JOB == "android-build-experimental" ]]; then
./gradlew bundleExperimentalPlayRelease
fi
if [[ $CIRCLE_JOB == "android-build-e2e" ]]; then
./gradlew app:assembleE2ePlayRelease app:assembleE2ePlayReleaseAndroidTest -DtestBuildType=release
fi
if [[ ! $KEYSTORE ]]; then
./gradlew assembleExperimentalPlayDebug
fi
working_directory: android
- run:
name: Upload sourcemaps to Bugsnag
command: |
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
npx bugsnag-source-maps upload-react-native \
--api-key=$BUGSNAG_KEY_OFFICIAL \
--app-version-code=$CIRCLE_BUILD_NUM \
--platform android \
--source-map=android/app/build/generated/sourcemaps/react/officialPlay/release/app.bundle.map \
--bundle android/app/build/generated/assets/react/officialPlay/release/app.bundle
fi
if [[ $CIRCLE_JOB == "android-build-experimental" ]]; then
npx bugsnag-source-maps upload-react-native \
--api-key=$BUGSNAG_KEY \
--app-version-code=$CIRCLE_BUILD_NUM \
--platform android \
--source-map=android/app/build/generated/sourcemaps/react/experimentalPlay/release/app.bundle.map \
--bundle android/app/build/generated/assets/react/experimentalPlay/release/app.bundle
fi
- store_artifacts:
path: android/app/build/outputs
- save_cache: *save-npm-cache-linux
- save_cache: *save-gradle-cache
- persist_to_workspace:
root: .
paths:
- android/app/build/outputs
android-e2e-test:
description: "End-to-End testing for Android using detox"
parameters:
folder:
type: string
default: ""
steps:
- checkout
- node/install:
install-yarn: true
- restore_cache: *restore-npm-cache-linux
- run: *install-npm-modules
- run:
name: Create avd
command: |
SYSTEM_IMAGES="system-images;android-28;default;x86"
sdkmanager "$SYSTEM_IMAGES"
echo "no" | avdmanager --verbose create avd -n "PIXEL_API_28_AOSP" -k "$SYSTEM_IMAGES" -d "pixel"
- run:
name: Launch emulator
command: |
emulator -avd "PIXEL_API_28_AOSP" -delay-adb -verbose -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim
background: true
- run:
name: Run the test
command: |
yarn detox test <<parameters.folder>> -c and.emu.release --cleanup
ios-build:
description: "Build iOS app"
steps:
- checkout
- restore_cache: *restore-gems-cache
- restore_cache: *restore-npm-cache-mac
- run: *install-npm-modules
- run: *update-fastlane-ios
- manage-pods
- run:
name: Set Google Services
command: |
if [[ $KEYSTORE ]]; then
echo $GOOGLE_SERVICES_IOS | base64 --decode > GoogleService-Info.plist
fi
working_directory: ios
- run:
name: Fastlane Build
no_output_timeout: 40m
command: |
agvtool new-version -all $CIRCLE_BUILD_NUM
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
/usr/libexec/PlistBuddy -c "Set :bugsnag:apiKey $BUGSNAG_KEY_OFFICIAL" ./RocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set :bugsnag:apiKey $BUGSNAG_KEY_OFFICIAL" ./ShareRocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL YES" ./RocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL YES" ./ShareRocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL YES" ./NotificationService/Info.plist
else
/usr/libexec/PlistBuddy -c "Set :bugsnag:apiKey $BUGSNAG_KEY" ./RocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set :bugsnag:apiKey $BUGSNAG_KEY" ./ShareRocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./RocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./ShareRocketChatRN/Info.plist
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./NotificationService/Info.plist
fi
if [[ $APP_STORE_CONNECT_API_BASE64 ]]; then
echo $APP_STORE_CONNECT_API_BASE64 | base64 --decode > ./fastlane/app_store_connect_api_key.p8
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
bundle exec fastlane ios build_official
else
if [[ $KEYSTORE ]]; then
bundle exec fastlane ios build_experimental
else
bundle exec fastlane ios build_fork
fi
fi
fi
working_directory: ios
- save_cache: *save-npm-cache-mac
- save_cache: *save-gems-cache
- store_artifacts:
path: ios/Rocket.Chat.ipa
- store_artifacts:
path: ios/Rocket.Chat.app.dSYM.zip
- persist_to_workspace:
root: .
paths:
- ios/*.ipa
- ios/*.zip
upload-to-google-play-beta:
description: "Upload to Google Play beta"
parameters:
official:
type: boolean
steps:
- checkout
- attach_workspace:
at: android
- run:
name: Store the google service account key
command: echo "$FASTLANE_GOOGLE_SERVICE_ACCOUNT" | base64 --decode > service_account.json
working_directory: android
- run: *update-fastlane-android
- run:
name: Fastlane Play Store Upload
command: bundle exec fastlane android beta official:<< parameters.official >>
working_directory: android
# EXPERIMENTAL ONLY
upload-to-internal-app-sharing:
description: "Upload to Internal App Sharing"
steps:
- checkout
- attach_workspace:
at: android
- run:
name: Store the google service account key
command: echo "$FASTLANE_GOOGLE_SERVICE_ACCOUNT" | base64 --decode > service_account.json
working_directory: android
- run: *update-fastlane-android
- run:
name: Fastlane Play Store Upload
command: bundle exec fastlane android internal_app_sharing
working_directory: android
# EXPERIMENTAL ONLY
# No plans to do it for Official
upload-to-google-play-production:
description: "Upload to Google Play production"
steps:
- checkout
- attach_workspace:
at: android
- run:
name: Store the google service account key
command: echo "$FASTLANE_GOOGLE_SERVICE_ACCOUNT" | base64 --decode > service_account.json
working_directory: android
- run: *update-fastlane-android
- run:
name: Fastlane Play Store Upload
command: bundle exec fastlane android production
working_directory: android
upload-to-testflight:
description: "Upload to TestFlight"
parameters:
official:
type: boolean
steps:
- checkout
- attach_workspace:
at: ios
- restore_cache: *restore-gems-cache
- restore_cache: *restore-npm-cache-mac
- run: *update-fastlane-ios
- manage-pods
- run:
name: Fastlane Tesflight Upload
command: |
echo $APP_STORE_CONNECT_API_BASE64 | base64 --decode > ./fastlane/app_store_connect_api_key.p8
bundle exec fastlane ios beta official:<< parameters.official >>
working_directory: ios
- save_cache: *save-gems-cache
version: 2.1
orbs:
node: circleci/node@4.6.0
# EXECUTORS
executors:
mac-env:
<<: *macos
environment:
<<: *bash-env
# JOBS
jobs:
lint-testunit:
<<: *defaults
docker:
- image: circleci/node:15
environment:
CODECOV_TOKEN: caa771ab-3d45-4756-8e2a-e1f25996fef6
steps:
- checkout
- restore_cache: *restore-npm-cache-linux
- run: *install-npm-modules
- run:
name: Lint
command: |
yarn lint
- run:
name: Test
command: |
yarn test
- run:
name: Codecov
command: |
yarn codecov
- save_cache: *save-npm-cache-linux
# Android builds
android-build-experimental:
<<: *defaults
docker:
- image: circleci/android:api-29-node
environment:
<<: *android-env
<<: *bash-env
steps:
- android-build
android-build-official:
<<: *defaults
docker:
- image: circleci/android:api-29-node
environment:
<<: *android-env
<<: *bash-env
steps:
- android-build
android-build-e2e:
<<: *defaults
docker:
- image: circleci/android:api-29-node
resource_class: large
environment:
<<: *android-env
<<: *bash-env
steps:
- android-build
android-e2e-test-assorted:
<<: *defaults
machine:
image: android:202102-01
resource_class: large
environment:
<<: *android-env
<<: *bash-env
steps:
- android-e2e-test:
folder: "./e2e/tests/assorted/"
android-e2e-test-onboarding:
<<: *defaults
machine:
image: android:202102-01
resource_class: large
environment:
<<: *android-env
<<: *bash-env
steps:
- android-e2e-test:
folder: "./e2e/tests/onboarding/"
android-e2e-test-room:
<<: *defaults
machine:
image: android:202102-01
resource_class: large
environment:
<<: *android-env
<<: *bash-env
steps:
- android-e2e-test:
folder: "./e2e/tests/room/"
android-e2e-test-team:
<<: *defaults
machine:
image: android:202102-01
resource_class: large
environment:
<<: *android-env
<<: *bash-env
steps:
- android-e2e-test:
folder: "./e2e/tests/team/"
android-internal-app-sharing-experimental:
<<: *defaults
docker:
- image: circleci/android:api-28-node
steps:
- upload-to-internal-app-sharing
android-google-play-beta-experimental:
<<: *defaults
docker:
- image: circleci/android:api-29-node
steps:
- upload-to-google-play-beta:
official: false
android-google-play-production-experimental:
<<: *defaults
docker:
- image: circleci/android:api-29-node
steps:
- upload-to-google-play-production
android-google-play-beta-official:
<<: *defaults
docker:
- image: circleci/android:api-29-node
steps:
- upload-to-google-play-beta:
official: true
# iOS builds
ios-build-experimental:
executor: mac-env
steps:
- ios-build
ios-build-official:
executor: mac-env
steps:
- ios-build
ios-testflight-experimental:
executor: mac-env
steps:
- upload-to-testflight:
official: false
ios-testflight-official:
executor: mac-env
steps:
- upload-to-testflight:
official: true
workflows:
build-and-test:
jobs:
- lint-testunit
# iOS Experimental
- ios-hold-build-experimental:
type: approval
requires:
- lint-testunit
- ios-build-experimental:
requires:
- ios-hold-build-experimental
- ios-testflight-experimental:
requires:
- ios-build-experimental
# iOS Official
- ios-hold-build-official:
type: approval
requires:
- lint-testunit
- ios-build-official:
requires:
- ios-hold-build-official
- ios-hold-testflight-official:
type: approval
requires:
- ios-build-official
- ios-testflight-official:
requires:
- ios-hold-testflight-official
# Android Experimental
- android-hold-build-experimental:
type: approval
requires:
- lint-testunit
- android-build-experimental:
requires:
- android-hold-build-experimental
- android-internal-app-sharing-experimental:
requires:
- android-build-experimental
- android-hold-google-play-beta-experimental:
type: approval
requires:
- android-build-experimental
- android-google-play-beta-experimental:
requires:
- android-hold-google-play-beta-experimental
- android-hold-google-play-production-experimental:
type: approval
requires:
- android-build-experimental
- android-google-play-production-experimental:
requires:
- android-hold-google-play-production-experimental
# Android Official
- android-hold-build-official:
type: approval
requires:
- lint-testunit
- android-build-official:
requires:
- android-hold-build-official
- android-hold-google-play-beta-official:
type: approval
requires:
- android-build-official
- android-google-play-beta-official:
requires:
- android-hold-google-play-beta-official
# Aandroid E2E Testing
- android-hold-e2e:
type: approval
requires:
- lint-testunit
- android-build-e2e:
requires:
- android-hold-e2e
- android-e2e-test-assorted:
requires:
- android-build-e2e
- android-e2e-test-onboarding:
requires:
- android-build-e2e
- android-e2e-test-room:
requires:
- android-build-e2e
- android-e2e-test-team:
requires:
- android-build-e2e