Skip to content

integration-tests-app-ci #633

integration-tests-app-ci

integration-tests-app-ci #633

# Copyright (c) 2022 Sharezone UG (haftungsbeschränkt)
# Licensed under the EUPL-1.2-or-later.
#
# You may obtain a copy of the Licence at:
# https://joinup.ec.europa.eu/software/page/eupl
#
# SPDX-License-Identifier: EUPL-1.2
# This workflow is used to run integration tests on the app.
#
# We only run the integration tests in our merge group to save macOS machines.
name: integration-tests-app-ci
on:
pull_request:
paths:
# We trigger also this workflow, if this workflow is changed, so that new
# changes can be tested.
- ".github/workflows/integration_tests_app_ci.yml"
merge_group:
types:
- checks_requested
# Set permissions to none.
#
# Using the broad default permissions is considered a bad security practice
# and would cause alerts from our scanning tools.
permissions: {}
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# We can't use the official "paths" filter because it has no support for merge
# groups and we would need some kind of fallback CI when a check is required
# but ignored because of the path filter.
#
# See:
# * https://github.com/community/community/discussions/45899 (merge groups)
# * https://github.com/github/docs/commit/4364076e0fb56c2579ae90cd048939eaa2c18954
# (workaround for required checks with path filters)
changes:
runs-on: ubuntu-22.04
outputs:
changesFound: ${{ steps.filter.outputs.changesFound }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- uses: AurorNZ/paths-filter@7c547bdd24124b0d69e07c96b62fd7fec5ced19a
id: filter
with:
filters: |
changesFound:
# When we change the Flutter version, we need to trigger this workflow.
- ".fvm/fvm_config.json"
# We only build and deploy a new version, when user relevant files
# or integration test files changed.
- "app/**"
- "lib/**"
- "app/integration_test/**"
# We trigger also this workflow, if this workflow is changed, so that new
# changes will be applied.
- ".github/workflows/integration_tests_app_ci.yml"
# The following paths are excluded from the above paths. It's important to
# list the paths at the end of the file, so that the exclude paths are
# applied.
#
# See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-including-and-excluding-paths.
- "!**/*.md"
- "!**/*.mdx"
- "!**/*.gitignore"
- "!**/firebase.json"
- "!**/.firebaserc"
- "!app/android/fastlane/**"
android-integration-test:
needs: changes
runs-on: ubuntu-22.04
if: ${{ needs.changes.outputs.changesFound == 'true' }}
# Don't use less than 90 minutes. Often 40 minutes are enough but sometimes
# (~5% of the time) build takes longer and then is a long timeout needed.
defaults:
run:
working-directory: app
timeout-minutes: 90
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
# Java is needed for building the APK, see
# https://github.com/marketplace/actions/flutter-action.
- uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
with:
distribution: "temurin"
java-version: "11"
- name: Set Flutter version from FVM config file to environment variables
uses: kuhnroyal/flutter-fvm-config-action@6ffa30473b346f7d7c63cf9e03e6a886f940a72b
- uses: subosito/flutter-action@main
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: ${{ env.FLUTTER_CHANNEL }}
- name: Install patrol cli
run: flutter pub global activate patrol_cli 2.2.1
- name: Run Flutter build
run: |
# Flutter build is required to generate files in android/ to build the
# gradle project.
#
# We are using the prod flavor because we were not able to set up
# Firebase Test Lab with the dev flavor. We always got "No tests
# found.".
flutter build apk \
--target=lib/main_prod.dart \
--flavor prod \
--config-only
- name: Build Instrumentation Test
run: |
patrol build android \
--flavor prod \
--dart-define USER_1_EMAIL=${{ secrets.INTEGRATION_TEST_USER_1_EMAIL }} \
--dart-define USER_1_PASSWORD=${{ secrets.INTEGRATION_TEST_USER_1_PASSWORD }} \
-t integration_test/app_test.dart
- name: Setup credentials
env:
TEST_LAB_CREDENTIALS: ${{ secrets.FIREBASE_TEST_LAB_DEV_KEY }}
run: |
echo $TEST_LAB_CREDENTIALS > firebase-test-lab.json
gcloud auth activate-service-account --key-file=firebase-test-lab.json
gcloud --quiet config set project sharezone-debug
# Runs our integration tests with Firebase Test Lab.
#
# Advantages of Firebase Test Lab:
# * We can use a Linux runner instead of a macOS runner in
# Github Actions (macOS runner is required for using an Android emulator).
# * We can run the tests on a real device instead of an emulator.
# * We get a screen recording of the test run which we can use to
# investigate test failures.
# * Increases the speed of the CI by 10 minutes (compared to running the
# tests on a macOS runner).
#
# Helpful documentation:
# * https://firebase.google.com/docs/test-lab/android/command-line
- name: Run Integration tests
run: |
gcloud firebase test android run \
--type instrumentation \
--app build/app/outputs/apk/prod/debug/app-prod-debug.apk \
--test build/app/outputs/apk/androidTest/prod/debug/app-prod-debug-androidTest.apk \
--device model=Pixel2,version=30,locale=en,orientation=portrait \
--timeout 10m \
--use-orchestrator \
--environment-variables clearPackageData=true
# It can easily happen that a dependency changed but the .lock file is not
# updated. Or other cases where files are changed during a build.
# Therefore, fails this check if there are Git changes.
- name: Fail if there are Git diffs
run: |
# Fail if there are Git diffs and print the diff.
git diff --exit-code
# Print the Git diff with the file names and their status as a
# summary.
git diff --name-status
ios-integration-test:
needs: changes
# We are using macos-12 instead macos-13 because with macos-13 we have job
# times of 40 - 120 minutes.
#
# Before switching back to macos-13, we should check if the job times are
# still that long by running the job with a matrix (3 runs).
runs-on: macos-12
if: ${{ needs.changes.outputs.changesFound == 'true' }}
timeout-minutes: 60
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Set Flutter version from FVM config file to environment variables
uses: kuhnroyal/flutter-fvm-config-action@6ffa30473b346f7d7c63cf9e03e6a886f940a72b
- uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: ${{ env.FLUTTER_CHANNEL }}
# Use format expected by FVM.
# Else this won't be recognized as an installed version when setting
# '.../flutter' as the FVM Flutter version cache folder.
cache-path: "${{ runner.tool_cache }}/flutter/:version:"
- name: Install FVM
run: |
flutter pub global activate fvm 2.4.1
fvm config --cache-path '${{ runner.tool_cache }}/flutter'
# Because macos-12 doesn't have Metal support, we need to disable Impeller
# https://github.com/flutter/flutter/issues/126768
- name: Disable Impeller
working-directory: app/ios/Runner
run: /usr/libexec/PlistBuddy -c "Add :FLTEnableImpeller bool false" Info.plist
- uses: futureware-tech/simulator-action@427329dea8e4d6417cba1273ebb5c9ad4720082d
id: simulator
with:
model: "iPhone 13"
- name: Run integration tests
working-directory: app
env:
USER_1_EMAIL: ${{ secrets.INTEGRATION_TEST_USER_1_EMAIL }}
USER_1_PASSWORD: ${{ secrets.INTEGRATION_TEST_USER_1_PASSWORD }}
SIMULATOR_UDID: ${{ steps.simulator.outputs.udid }}
# We use the `flutter drive` instead of the `flutter test` command
# because the test command times out after 12 minutes. But building the
# app takes more than 12 minutes... It seems so that there is no way to
# set the timeout (the --timeout argument has not effect). Tracking
# issue: https://github.com/flutter/flutter/issues/105913
run: |
# We need to run the integration tests with the prod flavor because
# using not the default flavor will cause an exception when
# uninstalling the app, see:
# https://github.com/flutter/flutter/issues/88690
fvm flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/integration_test_old.dart \
--flavor prod \
--dart-define=USER_1_EMAIL=$USER_1_EMAIL \
--dart-define=USER_1_PASSWORD=$USER_1_PASSWORD \
-d $SIMULATOR_UDID
web-integration-test:
needs: changes
runs-on: ubuntu-22.04
if: ${{ needs.changes.outputs.changesFound == 'true' }}
timeout-minutes: 30
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Set Flutter version from FVM config file to environment variables
uses: kuhnroyal/flutter-fvm-config-action@6ffa30473b346f7d7c63cf9e03e6a886f940a72b
- uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: ${{ env.FLUTTER_CHANNEL }}
# Use format expected by FVM.
# Else this won't be recognized as an installed version when setting
# '.../flutter' as the FVM Flutter version cache folder.
cache-path: "${{ runner.tool_cache }}/flutter/:version:"
- name: Install FVM
run: |
flutter pub global activate fvm 2.4.1
fvm config --cache-path '${{ runner.tool_cache }}/flutter'
- name: Install chromedriver
uses: nanasess/setup-chromedriver@480d644e773cd6d53e4cb76557c8ad5e5806d7da
- name: Run integration tests
working-directory: app
env:
USER_1_EMAIL: ${{ secrets.INTEGRATION_TEST_USER_1_EMAIL }}
USER_1_PASSWORD: ${{ secrets.INTEGRATION_TEST_USER_1_PASSWORD }}
# We use the `flutter drive` command because `flutter test` is not
# available for the web yet.
run: |
chromedriver --port=4444 &
fvm flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/integration_test_old.dart \
--flavor dev \
--dart-define=USER_1_EMAIL=$USER_1_EMAIL \
--dart-define=USER_1_PASSWORD=$USER_1_PASSWORD \
-d web-server
# At the moment, Flutter Integration Tests are not working with GitHub Actions
# and Flutter +3.7 (see https://github.com/flutter/flutter/issues/118469).
#
# To still have a verification that the app can be built, we just build the
# macOS app.
macos-build-test:
needs: changes
runs-on: macos-13
if: ${{ needs.changes.outputs.changesFound == 'true' }}
timeout-minutes: 60
defaults:
run:
working-directory: app
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Install Codemagic CLI Tools
run: pip3 install codemagic-cli-tools==0.47.0
- name: Setup signing
env:
# The following secrets are used by the Codemagic CLI tool. It's important
# to use the same names as the CLI tool expects.
CERTIFICATE_PRIVATE_KEY: ${{ secrets.SHAREZONE_CERTIFICATE_PRIVATE_KEY }}
APP_STORE_CONNECT_KEY_IDENTIFIER: ${{ secrets.SHAREZONE_APP_STORE_CONNECT_KEY_IDENTIFIER }}
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.SHAREZONE_APP_STORE_CONNECT_ISSUER_ID }}
APP_STORE_CONNECT_PRIVATE_KEY: ${{ secrets.SHAREZONE_APP_STORE_CONNECT_PRIVATE_KEY }}
BUNDLE_ID: de.codingbrain.sharezone.app
run: |
# Even when are trying to build app, we need to use "--platform IOS".
# The reason for this that our production bundle ID was created for
# IOS only. However, it's still possible to sign a macOS app with an
# iOS bundle ID (requires "--strict-match-identifier", otherwise the
# tool would try to use our de.codingbrain.sharezone.app.dev bundle ID
# which is a universal bundle ID and has no specific platform).
#
# See https://github.com/codemagic-ci-cd/cli-tools/issues/314
app-store-connect fetch-signing-files $BUNDLE_ID \
--platform IOS \
--type MAC_APP_STORE \
--strict-match-identifier \
--create
keychain initialize
keychain add-certificates
xcode-project use-profiles
- name: Set Flutter version from FVM config file to environment variables
uses: kuhnroyal/flutter-fvm-config-action@6ffa30473b346f7d7c63cf9e03e6a886f940a72b
- uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: ${{ env.FLUTTER_CHANNEL }}
- name: Build macOS app
run: |
flutter build macos \
-t lib/main_prod.dart