Skip to content

Commit

Permalink
Merge branch 'master' into notifications-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
sjoerdlmkns authored Jul 25, 2023
2 parents 59717bb + 161b12a commit 98d3dab
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 30 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# GitHub Actions workflows

We currently have two workflows. The workflows use our Fastlane scripts. More details about the functioning of the Fastlane
scripts can be found in the [README](../../fastlane/README.md).

## Status checks
This workflow checks whether a change passes all our quality gates.

### Secrets
Below a list of the secrets that are needed. The secrets should be uploaded as repository secret to both the
[Actions context](https://github.com/privacybydesign/irmamobile/settings/secrets/actions)
and the [Dependabot context](https://github.com/privacybydesign/irmamobile/settings/secrets/dependabot).
This means you need to upload every secret twice.

- `ANDROID_DEVELOPMENT_SIGNING_KEYSTORE`: Base64 encoded Android keystore for development purposes (dummy key), check the [Fastlane docs](../../fastlane/README.md#android-signingupload-keys) for generating instructions.
- `ANDROID_DEVELOPMENT_SIGNING_KEYSTORE_PASSWORD`: password of the Android keystore (see above).
- `APPLE_DEVELOPMENT_CERTIFICATE`: Base64 encoded PKCS12 certificate of the Apple development certificate, check the [Fastlane docs](../../fastlane/README.md#generating-new-certificates) for generating instructions. This certificate expires every year and is linked to the 'IRMA Beheer' email address.
- `APPLE_DEVELOPMENT_CERTIFICATE_PASSWORD`: password of the Apple development certificate (see above).
- `APPLE_DEVELOPMENT_PROVISIONING_PROFILE`: Base64 encoded Apple provisioning profile that is linked to the development certificate (see above). This should be renewed when the development certificate is being renewed.
- `GCLOUD_SERVICE_KEY`: Google Firebase service account JSON key (for Device Test Lab access).

## Delivery
This workflow generates distribution app builds. It generates iOS builds (IPA) and Android builds (APK and App Bundle).

For iOS, an ad-hoc build is made on every merge to `master` using the alpha app ID, and an app-store build is made on every
version change in `pubspec.yaml` using the production app ID.

For Android, an APK and App Bundle are made on every merge to `master` for both the `alpha` and the `beta` flavor, being signed
with a alpha app signing key (different to production). On every version change in `pubspec.yaml` an App Bundle
is made using the upload key that is registered with Google.

### Secrets
Below a list of the secrets that are needed. The secrets should be uploaded as [environment secrets](https://github.com/privacybydesign/irmamobile/settings/environments).

Secrets for the `android-alpha` (Android master builds) and `android-beta` (Android production builds) environments:

- `ANDROID_SIGNING_KEYSTORE`: Base64 encoded Android signing/upload keystore, check the [Fastlane docs](../../fastlane/README.md#android-signingupload-keys) for generating instructions. For the `android-alpha` environment it concerns a signing keystore and for the `android-beta` environment an upload keystore.
- `ANDROID_SIGNING_KEYSTORE_PASSWORD`: password of the Android keystore (see above).
- `SENTRY_DSN`: Sentry DSN for error reporting.

Secrets for the `ad-hoc-alpha` (iOS master/alpha builds) and the `app-store-beta` (iOS production builds) environments:

- `APPLE_DISTRIBUTION_CERTIFICATE`: Base64 encoded PKCS12 certificate of the Apple distribution certificate, check the [Fastlane docs](../../fastlane/README.md#generating-new-certificates) for generating instructions. In both the `ad-hoc-alpha` and `app-store-beta` environment the same distribution certificate
should be uploaded, because there only is one. This certificate expires every year.
- `APPLE_DISTRIBUTION_CERTIFICATE_PASSWORD`: password of the Apple development certificate (see above).
- `APPLE_PROVISIONING_PROFILE`: Base64 encoded Apple provisioning profile that is linked to the distribution certificate (see above). In the `ad-hoc-alpha` environment the `GitHub Actions ad hoc alpha` ad-hoc provisioning profile should be uploaded (linked to `foundation.privacybydesign.irmamob.alpha`) and in the `app-store-beta` environment the `GitHub Actions app store beta` app store provisioning profile should be uploaded (linked to `foundation.privacybydesign.irmamob`). These should be renewed when the distribution certificate is being renewed.
- `SENTRY_DSN`: Sentry DSN for error reporting.
2 changes: 2 additions & 0 deletions .github/workflows/delivery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ jobs:
run: >
bundle exec fastlane ios_build_app
flavor:alpha
code_signing_identity:"iPhone Distribution"
certificate_path:profiles/apple_distribution.p12
certificate_password:${{ secrets.APPLE_DISTRIBUTION_CERTIFICATE_PASSWORD }}
provisioning_profile_path:profiles/ad_hoc_alpha.mobileprovision
Expand Down Expand Up @@ -191,6 +192,7 @@ jobs:
run: >
bundle exec fastlane ios_build_app
flavor:beta
code_signing_identity:"iPhone Distribution"
certificate_path:profiles/apple_distribution.p12
certificate_password:${{ secrets.APPLE_DISTRIBUTION_CERTIFICATE_PASSWORD }}
provisioning_profile_path:profiles/app_store_beta.mobileprovision
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/status-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ name: Status checks

on:
pull_request:
schedule:
# Run every sunday at noon. We run this on sunday such that we can utilize the free test minutes we get from Firebase.
# The weekly run ensures that cached resources don't expire.
- cron: "0 12 * * 0"

concurrency:
group: ${{ github.ref }}
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
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
### Fixed
- Voice over and accessibility tags are not correctly set on the PIN screen
- Required update screen refers to iTunes Store instead of Apple App Store

### Internal
- Add integration test for declining the credential offer in an issuance session

## [7.4.2] - 2023-06-22
### Fixed
- LoadingScreen StreamBuilder triggers multiple navigation actions
Expand Down
2 changes: 1 addition & 1 deletion bind_go.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env bash

gomobile bind -target android -o android/irmagobridge/irmagobridge.aar github.com/privacybydesign/irmamobile/irmagobridge
gomobile bind -target android -androidapi 23 -o android/irmagobridge/irmagobridge.aar github.com/privacybydesign/irmamobile/irmagobridge
gomobile bind -target ios -iosversion 12.0 -o ios/Runner/Irmagobridge.xcframework github.com/privacybydesign/irmamobile/irmagobridge
2 changes: 1 addition & 1 deletion ci_scripts/install_android_sdk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
set -euxo pipefail

ANDROID_SDK_CHECKSUM="124f2d5115eee365df6cf3228ffbca6fc3911d16f8025bebd5b1c6e2fcfa7faf"
ANDROID_NDK_VERSION="21.4.7075529"
ANDROID_NDK_VERSION="25.2.9519653"

if [[ -z "$ANDROID_HOME" ]]; then
echo "Environment variable ANDROID_HOME needs to be set"
Expand Down
16 changes: 14 additions & 2 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ end

lane :android_build_irmagobridge do
Dir.chdir("..") do
sh("gomobile", "bind", "-target", "android", "-o", "android/irmagobridge/irmagobridge.aar", "github.com/privacybydesign/irmamobile/irmagobridge")
sh(
"gomobile", "bind",
"-target", "android",
"-androidapi", "23",
"-o", "android/irmagobridge/irmagobridge.aar",
"github.com/privacybydesign/irmamobile/irmagobridge"
)
end
end

Expand Down Expand Up @@ -131,7 +137,13 @@ end

lane :ios_build_irmagobridge do
Dir.chdir("..") do
sh("gomobile", "bind", "-target", "ios", "-iosversion", "12.0", "-o", "ios/Runner/Irmagobridge.xcframework", "github.com/privacybydesign/irmamobile/irmagobridge")
sh(
"gomobile", "bind",
"-target", "ios",
"-iosversion", "12.0",
"-o", "ios/Runner/Irmagobridge.xcframework",
"github.com/privacybydesign/irmamobile/irmagobridge"
)
end
end

Expand Down
28 changes: 21 additions & 7 deletions fastlane/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,40 @@ remove devices. More information about adding and updating ad-hoc provisioning p
1. Go to the ./fastlane directory in irmamobile
2. Run `mkdir -p ./profiles && cd ./profiles`
3. Choose a name for your new certificate, i.e. `KEY_NAME=ios_distribution` or `KEY_NAME=ios_development`
4. Run `openssl req -nodes -newkey rsa:2048 -keyout $KEY_NAME.key -out $KEY_NAME.csr` and follow the instructions
4. Run the following and follow the instructions:
```
openssl req -nodes -newkey rsa:2048 -keyout $KEY_NAME.key -out $KEY_NAME.csr
```
There are no strict requirements about which values to use for the CSR-fields.
5. Upload the CSR to Apple: go to https://developer.apple.com/account/resources/certificates/list, press the '+' sign
and choose "iOS Distribution (App Store and Ad Hoc)" for a distribution certificate or "iOS App Development"
for a development certificate.
6. When finished, download the .cer file and save it to the directory created in step 2 as `$KEY_NAME.cer`
7. Convert the .cer file to a .pem file:
`openssl x509 -in $KEY_NAME.cer -inform DER -out $KEY_NAME.pem -outform PEM`
```
openssl x509 -in $KEY_NAME.cer -inform DER -out $KEY_NAME.pem -outform PEM
```
8. Convert the .pem to a .p12 and choose the certificate password:
`openssl pkcs12 -export -inkey $KEY_NAME.key -in $KEY_NAME.pem -out $KEY_NAME.p12`
```
openssl pkcs12 -export -inkey $KEY_NAME.key -in $KEY_NAME.pem -out $KEY_NAME.p12
```
If you use OpenSSL 3.x, then you need to add `-legacy` to the command for compatibility with OpenSSL 1.x.
9. Safely store the certificate password in a password manager or a secret vault for later use
10. You can now create a provisioning profile: go to https://developer.apple.com/account/resources/profiles/list,
press the '+' sign and follow the instructions. This can only be done by users with the 'Admin' role or the
'App Manager' role with access to certificates, identifiers and profiles in Apple App Store Connect. If you only
have the 'Developer' role, then you need to ask someone else to create the provisioning profile for you.
11. When finished, download the provisioning profile and save it to the directory created in step 2
12. In case you need to upload the assets to a secret vault, then you need to encode the files you want to upload with base64,
i.e. `cat $KEY_NAME.p12 | base64 > $KEY_NAME.p12.base64`
11. When finished, download the provisioning profile and save it to the directory created in step 2. We refer to this
as $PROVISIONING_PROFILE.mobileprovision in this README.
12. In case you need to upload the assets to a secret vault, then you need to encode the files you want to upload with base64:
```
cat $KEY_NAME.p12 | base64 > $KEY_NAME.p12.base64
cat $PROVISIONING_PROFILE.mobileprovision | base64 > $PROVISIONING_PROFILE.mobileprovision.base64
```

When generating distribution certificates for CI platforms, it's recommended to protect the certificate bundle as a secret in
protected deployment environments. In this way, you prevent that development builds get signed.
protected deployment environments. In this way, you prevent that development builds get signed. For more information about the
secrets in our GitHub Actions workflows, please check the [workflow README](../.github/workflows/README.md).

Don't forget to delete the local file copies after you've uploaded the profiles and certificates to your CI's secret vault.

Expand Down
10 changes: 6 additions & 4 deletions integration_test/helpers/helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:irmamobile/app.dart';

import 'package:irmamobile/main.dart';
import 'package:irmamobile/src/data/irma_repository.dart';
import 'package:irmamobile/src/screens/home/home_tab.dart';
Expand Down Expand Up @@ -68,6 +67,7 @@ Future<void> issueCredentials(
Locale locale = const Locale('en', 'EN'),
Map<String, String> revocationKeys = const {},
bool continueOnSecondDevice = true,
bool declineOffer = false,
}) async {
final groupedAttributes = groupBy<MapEntry<String, String>, String>(
attributes.entries,
Expand Down Expand Up @@ -117,10 +117,12 @@ Future<void> issueCredentials(
expect(attributeTexts[i * 2 + 1], attributeEntries[i].value);
}

var acceptButtonFinder = find.byKey(const Key('bottom_bar_primary'));
expect(acceptButtonFinder, findsOneWidget);
final buttonFinder = find.byKey(
declineOffer ? const Key('bottom_bar_secondary') : const Key('bottom_bar_primary'),
);
expect(buttonFinder, findsOneWidget);

await tester.tapAndSettle(acceptButtonFinder);
await tester.tapAndSettle(buttonFinder);

await tester.waitUntilDisappeared(issuancePageFinder);
}
Expand Down
27 changes: 27 additions & 0 deletions integration_test/issuance_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,32 @@ void main() {
'issue-municipality-nl',
(tester) => testIssueMunicipality(tester, const Locale('nl', 'NL')),
);

testWidgets('decline', (tester) async {
await pumpAndUnlockApp(tester, irmaBinding.repository);

// Start an issuance session for email address and decline the offer.
await issueCredentials(
tester,
irmaBinding,
{
'irma-demo.sidn-pbdf.email.email': '[email protected]',
'irma-demo.sidn-pbdf.email.domain': 'demo.com',
},
declineOffer: true,
);

// Go to data tab.
await tester.tapAndSettle(find.byKey(const Key('nav_button_data')));

// Verify that the email address has not been added.
final emailTileFinder = find.byKey(const Key('irma-demo.sidn-pbdf.email_tile'));
expect(emailTileFinder, findsNothing);

// Verify that no activity has been added.
await tester.tap(find.byKey(const Key('nav_button_activity')));
await tester.pump(const Duration(seconds: 1));
expect(find.text('There are no logged activities yet'), findsOneWidget);
});
});
}
12 changes: 6 additions & 6 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_TEAM = T5VXGLDWLZ;
Expand All @@ -560,7 +560,7 @@
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = foundation.privacybydesign.irmamob.alpha;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Mac Mini distribution";
PROVISIONING_PROFILE_SPECIFIER = "Local development profile";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
Expand Down Expand Up @@ -684,7 +684,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_TEAM = T5VXGLDWLZ;
Expand All @@ -707,7 +707,7 @@
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = foundation.privacybydesign.irmamob.alpha;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Mac Mini distribution";
PROVISIONING_PROFILE_SPECIFIER = "Local development profile";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
Expand All @@ -725,7 +725,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_TEAM = T5VXGLDWLZ;
Expand All @@ -748,7 +748,7 @@
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = foundation.privacybydesign.irmamob.alpha;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Mac Mini distribution";
PROVISIONING_PROFILE_SPECIFIER = "Local development profile";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 5.0;
Expand Down
20 changes: 11 additions & 9 deletions lib/src/screens/required_update/required_update_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@ class RequiredUpdateScreen extends StatelessWidget {
bottomNavigationBar: IrmaBottomBar(
primaryButtonLabel: FlutterI18n.translate(context, 'update.update_app'),
onPrimaryPressed: () {
switch (Platform.operatingSystem) {
case 'android':
launch('market://details?id=org.irmacard.cardemu');
break;
case 'ios':
launch('itms://itunes.apple.com/us/app/apple-store/id1294092994?mt=8');
break;
default:
throw Exception('Unsupported Platfrom.operatingSystem');
late String url;
if (Platform.isAndroid) {
url = 'https://play.google.com/store/apps/details?id=org.irmacard.cardemu';
} else if (Platform.isIOS) {
url = 'https://apps.apple.com/app/id1294092994';
} else {
throw Exception('Unsupported platform');
}
launchUrl(
Uri.parse(url),
mode: LaunchMode.externalNonBrowserApplication,
);
},
),
);
Expand Down

0 comments on commit 98d3dab

Please sign in to comment.