Skip to content

Commit

Permalink
Merge pull request #289 from privacybydesign/upgrade-flutter-and-xcode
Browse files Browse the repository at this point in the history
Chore: upgrade to Flutter 3.24.3 and XCode 16.0
  • Loading branch information
w-ensink authored Nov 11, 2024
2 parents 2739144 + da6b0b1 commit e884b60
Show file tree
Hide file tree
Showing 30 changed files with 686 additions and 530 deletions.
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

0 comments on commit e884b60

Please sign in to comment.