Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: upgrade to Flutter 3.24.3 and XCode 16.0 #289

Merged
merged 24 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
eb34db5
Chore: upgrade to flutter 3.24.3 and xcode 15.4
ivard Oct 18, 2024
b666b35
Chore: use macos-14 runner
ivard Oct 18, 2024
1a350ef
Chore: use java 17 to build Android app
ivard Oct 18, 2024
30e55a6
Chore: update README.md and CHANGELOG.md
ivard Oct 18, 2024
203f65b
Fix: app unstable when using xcode 15.4, use xcode 16.0 instead
ivard Oct 19, 2024
56a9960
Chore: set Xcode version to 16.1
w-ensink Nov 4, 2024
9ecdd10
Chore: disable Impeller rendering engine on iOS
w-ensink Nov 5, 2024
925fc4f
Docs: add point to troubleshooting about jdk verion
w-ensink Nov 5, 2024
5c7cfab
Fix: split ios integration tests up into chunks
w-ensink Nov 7, 2024
69edfc1
Fix: split disclosure test into sub tests
w-ensink Nov 7, 2024
90c9190
CI/CD: parallelize ios Firebase integration tests
w-ensink Nov 7, 2024
d039ea7
Refactor: fix formatting in new test files
w-ensink Nov 7, 2024
81ee442
Refactor: remove code duplication
w-ensink Nov 8, 2024
cf185ed
CI/CD: add `--config-only` to fastlane job
w-ensink Nov 8, 2024
4a67d87
CI/CD: run iOS integration tests in matrix
ivard Nov 8, 2024
50fbc57
Chore: use XCode 16.0 to build for iOS
ivard Nov 8, 2024
4eba9f2
CI/CD: remove whitespaces from matrix output of build-integration-tes…
ivard Nov 8, 2024
e2c9251
CI/CD: fix missing outputs in build-integration-test-ios job
ivard Nov 8, 2024
a567a58
CI/CD: fix single quote to be included in job output
ivard Nov 8, 2024
c80d410
Merge branch 'master' into upgrade-flutter-and-xcode
ivard Nov 8, 2024
c4067a3
Merge branch 'upgrade-flutter-and-xcode' of https://github.com/privac…
w-ensink Nov 11, 2024
7649083
CI/CD: add final summary job for branch protection rules
w-ensink Nov 11, 2024
46ba75a
CI/CD: make summary also fail on cancelled tests
w-ensink Nov 11, 2024
da6b0b1
Fix: correct bash syntaxt for if-statement
w-ensink Nov 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/setup-build-environment/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ runs:
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 11
java-version: 17
- uses: actions/setup-go@v5
with:
go-version: ^1.22
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/delivery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ name: Delivery

on:
push:
branches: [ master ]
branches: [master]

concurrency: ${{ github.ref }}

jobs:
build-irmagobridge-ios:
runs-on: macos-13
runs-on: macos-14
steps:
- name: Check out repository
uses: actions/checkout@v4
Expand All @@ -35,7 +35,7 @@ jobs:
path: android/irmagobridge/irmagobridge.aar
build-app-ios-alpha:
# Ad Hoc builds do not require unique build numbers, so we can build this on every push.
runs-on: macos-13
runs-on: macos-14
needs: build-irmagobridge-ios
environment: ad-hoc-alpha
steps:
Expand Down Expand Up @@ -80,8 +80,8 @@ jobs:
# beta flavor Android app in the intent:// links.
strategy:
matrix:
flavor: [ alpha, beta ]
type: [ apk, appbundle ]
flavor: [alpha, beta]
type: [apk, appbundle]
steps:
- name: Check out repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -118,8 +118,8 @@ jobs:
bundle-app-alpha:
runs-on: ubuntu-latest
needs:
- build-app-ios-alpha
- build-app-android-alpha
- build-app-ios-alpha
- build-app-android-alpha
steps:
- name: Download app-alpha-ios artifact
uses: actions/download-artifact@v4
Expand Down Expand Up @@ -164,7 +164,7 @@ jobs:
shell: bash
continue-on-error: true
build-app-ios-beta:
runs-on: macos-13
runs-on: macos-14
needs: version-check
if: needs.version-check.outputs.version-changed == 'true'
environment: app-store-beta
Expand Down
49 changes: 39 additions & 10 deletions .github/workflows/status-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
uses: ./.github/actions/setup-build-environment
- run: bundle exec fastlane unit_test
build-irmagobridge-ios:
runs-on: macos-13 # MacOS version is pinned, because it determines which XCode version is used.
runs-on: macos-14 # MacOS version is pinned, because it determines which XCode version is used.
needs: lint
steps:
- name: Check out repository
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:
name: prototypes-alpha-android
path: ./build/app/outputs/apk/alpha/release/*.apk
build-app-ios-alpha:
runs-on: macos-13 # MacOS version is pinned, because it determines which XCode version is used.
runs-on: macos-14 # MacOS version is pinned, because it determines which XCode version is used.
needs: build-irmagobridge-ios
steps:
- name: Check out repository
Expand Down Expand Up @@ -119,8 +119,8 @@ jobs:
needs: build-irmagobridge-android
strategy:
matrix:
flavor: [ alpha, beta ]
type: [ apk, appbundle ]
flavor: [alpha, beta]
type: [apk, appbundle]
steps:
- name: Check out repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -152,8 +152,10 @@ jobs:
name: app-${{ matrix.flavor }}-android-${{ matrix.type }}
path: ./fastlane/build/*
build-integration-test-ios:
runs-on: macos-13 # MacOS version is pinned, because it determines which XCode version is used.
runs-on: macos-14 # MacOS version is pinned, because it determines which XCode version is used.
needs: build-irmagobridge-ios
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Check out repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -185,6 +187,10 @@ jobs:
with:
name: integration-test-ios
path: ./fastlane/build/*.zip
- name: Dynamically generate matrix for running integration tests
id: set-matrix
# This oneliner gets every test zip generated by Fastlane and writes this as output to GitHub. This is used for the matrix in the integration-test-ios job below.
run: echo "matrix=$(for file in $(ls ./fastlane/build/*.zip); do basename "$file"; done | jq -R . | jq -sc .)" >> $GITHUB_OUTPUT
build-integration-test-android:
runs-on: ubuntu-latest
needs: build-irmagobridge-android
Expand All @@ -211,7 +217,10 @@ jobs:
needs:
- build-integration-test-ios
- unit-test # To prevent that test resources are used when we already know there is an issue.
concurrency: integration-test-ios # To prevent that we use too much test resources at the same time.
strategy:
matrix:
file_name: ${{ fromJson(needs.build-integration-test-ios.outputs.matrix) }}
concurrency: integration-test-ios-${{ matrix.file_name }} # To prevent that we use too much test resources at the same time.
steps:
- name: Download test artifacts
uses: actions/download-artifact@v4
Expand All @@ -225,14 +234,34 @@ jobs:
shell: bash
- name: Set Firebase project
run: gcloud config set project ${{ secrets.GCLOUD_PROJECT_NAME }}
- name: Run integration tests
run: gcloud firebase test ios run --test ios_tests.zip --timeout 20m --device=model=iphone8,orientation=portrait --device=model=iphone8,orientation=landscape
- name: Run integration tests for each zip file
run: |
gcloud firebase test ios run \
--test ${{ matrix.file_name }} \
--timeout 7m \
--device=model=iphone8,orientation=portrait \
--device=model=iphone8,orientation=landscape
# this summary is needed to report a final result for the ios test matrix
# this job is added to the branch protection rules, so the matrix has to fully pass before merge
integration-test-ios-summary:
runs-on: ubuntu-latest
needs: integration-test-ios # Wait for all matrix jobs
if: ${{ always() }} # Run even if a matrix job fails
steps:
- name: Check integration test results
run: |
if [ "${{ needs.integration-test-ios.result }}" == "failure" ] || [ "${{ needs.integration-test-ios.result }}" == "cancelled" ]; then
echo "One or more integration tests failed."
exit 1
else
echo "All integration tests passed."
fi
integration-test-android:
runs-on: ubuntu-latest
container: google/cloud-sdk:latest
needs:
- build-integration-test-android
- unit-test # To prevent that test resources are used when we already know there is an issue.
- build-integration-test-android
- unit-test # To prevent that test resources are used when we already know there is an issue.
concurrency: integration-test-android # To prevent that we use too much test resources at the same time.
steps:
- name: Download test artifacts
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
### Changed
- Upgrade Flutter to 3.24.6
- Upgrade XCode to 16.0
- Use Java 17 to build for Android

## [7.5.6] - 2024-07-22
### Changed
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ attaching data to signed statements. These data can be relevant properties, such
git submodule init
git submodule update

* Install Java development kit. Java 11 _should_ work. Java 8 is not supported anymore.
* Install Java development kit. We recommend to use Java 17.

# On Debian / Ubuntu
apt install openjdk-11-jdk
apt install openjdk-17-jdk

# On MacOS
# TODO: Install via `brew install openjdk@11`, but how to replace system Java?
# TODO: Install via `brew install openjdk@17`, but how to replace system Java?

* Install the Android SDK tools by going to the [Android developer download page](https://developer.android.com/studio/).
Make sure to install the build-tools and platform for Android >= 28. In addition
Expand Down Expand Up @@ -172,6 +172,7 @@ workflows in .github/workflows). Documentation about the Fastlane scripting can
* When you get an error related to `x_cgo_inittls` while running `./bind_go.sh`, you probably use an incorrect version of the Android NDK or your Go version is too old.
* When the flutter tool cannot find the generated apk after building for Android, the flavor is probably omitted. You need to run `flutter run --flavor alpha` or `flutter run --flavor beta`.
* When you are working with Windows, you need to manually make a symlink between the configuration folders. You can do this by opening a terminal as administrator and use the following command: `mklink /d .\android\app\src\main\assets\irma_configuration .\irma_configuration`.
* When Java jdk version is not compatible: set the jdk version flutter uses with `flutter config --jdk-dir <jdk_dir>`. Version 17 is recommended for this app (don't try to fiddle with gradle versions).
* When you are building for iOS using XCode and you get `Dart Error: Can't load Kernel binary: Invalid kernel binary format version.`, then likely your Flutter cache is corrupted. You can empty and reload the Flutter cache in the following way:
```shell
pushd $(which flutter)/../
Expand Down
14 changes: 6 additions & 8 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
Expand All @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
Expand All @@ -21,9 +22,6 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 34

Expand Down
17 changes: 0 additions & 17 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,20 +1,3 @@
buildscript {
/*
Because we depend on the packages flutter_privacy_screen and mobile_scanner
that do not specify the correct Kotlin versions themselves we have to include it here.
*/
ext.kotlin_version = '1.6.20'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:7.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

allprojects {
repositories {
google()
Expand Down
30 changes: 20 additions & 10 deletions android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
include ':app', ':irmagobridge'
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()

def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}

plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.4.0" apply false
id "org.jetbrains.kotlin.android" version "1.7.21" apply false
}

include ':app', ':irmagobridge'
6 changes: 3 additions & 3 deletions ci_scripts/install_flutter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
# The environment variables FLUTTER_HOME needs to be set and "$FLUTTER_HOME/bin" needs to be added to the PATH.
set -euxo pipefail

FLUTTER_VERSION="3.13.5"
FLUTTER_VERSION="3.24.3"
FLUTTER_CHANNEL="stable"
FLUTTER_CHECKSUM_LINUX="0f68460f2bf9f09df7d19711517949a2625c5eaf07a55d41746d6f2a25aaa769"
FLUTTER_CHECKSUM_MACOS="31da5a8328792bd55b52f21f96a1c64855b9afb1597717c5ccb1803b50d58333"
FLUTTER_CHECKSUM_LINUX="f4e2369afaf38a8e381c9243fad2ca04b8514194c40ec946825d1f4c5539a095"
FLUTTER_CHECKSUM_MACOS="c7947ac3162acc580d9ba55d16ce4a3e51966f5b8799bf0344f455e8ec3df242"

if [[ -z "$FLUTTER_HOME" ]]; then
echo "Environment variable FLUTTER_HOME needs to be set"
Expand Down
4 changes: 2 additions & 2 deletions ci_scripts/select_xcode.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
set -euxo pipefail

XCODE_VERSION="14.3.1"
XCODE_VERSION="16.0"

# Location is based on the Xcode versions bundled with the macOS runners in GitHub Actions.
# https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md#xcode
# https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md#xcode
sudo xcode-select -s /Applications/Xcode_${XCODE_VERSION}.app/Contents/Developer
61 changes: 41 additions & 20 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -215,29 +215,50 @@ lane :ios_build_integration_test do |options|
certificate_password: options[:certificate_password],
code_signing_identity: options[:code_signing_identity]
)

# Navigate to the Flutter project root directory
Dir.chdir("..") do
sh(
"flutter", "build", "ios",
"--release",
"./integration_test/test_all.dart"
)
Dir.chdir("./ios") do
# Get a list of all Dart test files in the integration_test directory
test_files = Dir["integration_test/**/*_test.dart"]

test_files.each do |test_file|
# Extract the base name of the test file to use for naming zip files
test_name = File.basename(test_file, ".dart")

# Run Flutter build for each test file
sh(
"xcodebuild",
"-workspace", "Runner.xcworkspace",
"-scheme", "Runner",
"-config", "Flutter/Release.xcconfig",
"-derivedDataPath", "../build/ios_integ",
"-sdk", "iphoneos",
"build-for-testing",
"flutter", "build", "ios",
"--release",
"--config-only",
test_file
)
end
Dir.chdir("./build/ios_integ/Build/Products") do
# XCode does not clean left-over build artifacts created by earlier XCode versions.
# Therefore, we ensure only the xctestrun file for the latest iOS SDK is included.
test_run_name = sh("ls -r1 *.xctestrun | head -n 1")
sh("rm -f ../../../../fastlane/build/ios_tests.zip")
sh("zip -r ../../../../fastlane/build/ios_tests.zip Release-iphoneos #{test_run_name}")

# Navigate to the ios directory and run xcodebuild for each test
Dir.chdir("./ios") do
sh(
"xcodebuild",
"-workspace", "Runner.xcworkspace",
"-scheme", "Runner",
"-config", "Flutter/Release.xcconfig",
"-derivedDataPath", "../build/ios_integ",
"-sdk", "iphoneos",
"build-for-testing"
)
end

# Create a zip for each test output
Dir.chdir("./build/ios_integ/Build/Products") do
# XCode does not clean left-over build artifacts created by earlier XCode versions.
# Therefore, we ensure only the xctestrun file for the latest iOS SDK is included.
# Get the latest .xctestrun file (assumes the latest file is the one just built)
test_run_name = sh("ls -r1 *.xctestrun | head -n 1").strip

# Remove any existing zip file with the same name
sh("rm -f ../../../../fastlane/build/#{test_name}_ios_tests.zip")

# Zip the build artifacts for the current test file
sh("zip -r ../../../../fastlane/build/#{test_name}_ios_tests.zip Release-iphoneos #{test_run_name}")
end
end
end
end
Expand Down
Loading