Compare commits

...

12 Commits

Author SHA1 Message Date
Ian VanSchooten 21d015f1bf
Merge c1f2374daa into cc0ee7cbc2 2024-10-07 11:41:21 -04:00
Ian VanSchooten c1f2374daa Rename workflow 2024-10-07 11:41:12 -04:00
Ian VanSchooten 60337706e5 Avoid incrementing version number 2024-10-07 11:41:12 -04:00
Ian VanSchooten c770ae7e1a Use fastlane to build 2024-10-07 11:41:12 -04:00
Ian VanSchooten da5d0ba1dc Add fastlane match token 2024-10-07 11:41:12 -04:00
Ian VanSchooten dd5b929537 Add ios build step to ci 2024-10-07 11:41:12 -04:00
Ian VanSchooten e70a70c1ad Specify androidapi for gomobile 2024-10-07 11:41:12 -04:00
Ian VanSchooten eca87251ac Add build workflow 2024-10-07 11:41:12 -04:00
Ian VanSchooten 0879798426 Simplify/fix dart formatting in CI 2024-10-07 11:40:52 -04:00
Ian VanSchooten cc0ee7cbc2
Flutter format is removed, now dart format (#168)
It was removed in 3.12: https://github.com/flutter/flutter/pull/129360

This updates the README and our CI job.
2024-10-07 11:38:00 -04:00
Ian VanSchooten 13b75cdbb4
Update java to 17 (#167)
This updates the version of java used during release builds to 17, the minimum required by our version of AGP. https://developer.android.com/build/releases/gradle-plugin#compatibility

It also uses a java toolchain and resolver plugin to automatically download and use the desired version of java, which will hopefully simplify things for others to get spun up on mobile app dev.  Reference https://stefma.medium.com/sourcecompatibility-targetcompatibility-and-jvm-toolchains-in-gradle-explained-d2c17c8cff7c for some explanation of toolchains and compatibility targets, and https://docs.gradle.org/current/userguide/toolchains.html#sec:provisioning for notes about automatic provisioning via toolchain.
2024-10-07 08:22:21 -04:00
Ian VanSchooten 79795ffe63
Remove media and audio pickers (#170)
And target iphoneos 12, to avoid some warnings.

We only use the file picker to allow users to load in nebula certs/keys, we don't need access to pictures.
2024-10-01 13:25:31 -04:00
14 changed files with 207 additions and 119 deletions

View File

@ -1,10 +0,0 @@
#!/bin/sh
DIRS="lib test"
EXIT=0
for DIR in $DIRS; do
OUT="$(flutter format -l 120 --suppress-analytics "$DIR" | sed -e "s/^Formatted \(.*\)/::error file=$DIR\/\1::Not formatted/g")"
echo "$OUT" | grep "::error" && EXIT=1
done
exit $EXIT

View File

@ -23,5 +23,5 @@ jobs:
- name: Check out code
uses: actions/checkout@v3
- name: flutter format
run: $GITHUB_WORKSPACE/.github/workflows/flutterfmt.sh
- name: Check formating
run: dart format -l120 lib/ --set-exit-if-changed --suppress-analytics --output none

View File

@ -19,7 +19,7 @@ jobs:
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'
- name: Install flutter
uses: subosito/flutter-action@v2

104
.github/workflows/smoke.yml vendored Normal file
View File

@ -0,0 +1,104 @@
# This workflow builds the iOS and Android apps, just to check they build without error
name: Smoke build
on:
push:
branches:
- main
pull_request:
jobs:
build-android:
name: Android
runs-on: macos-latest
steps:
- name: Set up Go 1.22
uses: actions/setup-go@v4
with:
go-version: "1.22"
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: '17'
- name: Install flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.1'
- name: Check out code
uses: actions/checkout@v3
- name: install dependencies
env:
TOKEN: ${{ secrets.MACHINE_USER_PAT }}
run: |
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
flutter pub get
touch env.sh
- name: Build Android debug
run: flutter build appbundle --debug
build-ios:
name: iOS
runs-on: macos-latest
steps:
- name: Set up Go 1.22
uses: actions/setup-go@v4
with:
go-version: "1.22"
- name: Install flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.1'
- name: Check out code
uses: actions/checkout@v3
- name: Install the appstore connect key material
env:
AC_API_KEY_SECRET_BASE64: ${{ secrets.AC_API_KEY_SECRET_BASE64 }}
run: |
AC_API_KEY_SECRET_PATH="$RUNNER_TEMP/key.p8"
echo "APP_STORE_CONNECT_API_KEY_KEY_FILEPATH=$AC_API_KEY_SECRET_PATH" >> $GITHUB_ENV
echo -n "$AC_API_KEY_SECRET_BASE64" | base64 --decode --output "$AC_API_KEY_SECRET_PATH"
- name: Place Github token for fastlane match
env:
TOKEN: ${{ secrets.MACHINE_USER_PAT }}
run:
echo "MATCH_GIT_BASIC_AUTHORIZATION=$(echo -n "defined-machine:${TOKEN}" | base64)" >> $GITHUB_ENV
- name: install dependencies
env:
TOKEN: ${{ secrets.MACHINE_USER_PAT }}
run: |
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
flutter pub get
touch env.sh
- name: Build iOS
env:
TOKEN: ${{ secrets.MACHINE_USER_PAT }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
run: |
cd ios
pod install
fastlane checkBuild
cd -
# verify that the github token didn't make it into the output
mkdir -p build/app/test-ios
cp ios/MobileNebula.ipa build/app/test-ios
cd build/app/test-ios
unzip MobileNebula.ipa
if find . | xargs strings 2>/dev/null | grep -qF "${TOKEN}" ; then
echo "Token found in iOS build"
exit 1
fi

View File

@ -32,13 +32,16 @@ If you are having issues with iOS pods, try blowing it all away! `cd ios && rm -
# Formatting
`flutter format` can be used to format the code in `lib` and `test` but it's default is 80 char line limit, it's 2020
`dart format` can be used to format the code in `lib` and `test`. We use a line-length of 120 characters.
Use:
```sh
flutter format lib/ test/ -l 120
dart format lib/ test/ -l 120
```
In Android Studio, set the line length using Preferences -> Editor -> Code Style -> Dart -> Line length, set it to 120. Enable auto-format with Preferences -> Languages & Frameworks -> Flutter -> Format code on save.
# Release
Update `version` in `pubspec.yaml` to reflect this release, then

View File

@ -28,15 +28,6 @@ android {
compileSdkVersion 34
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
@ -72,6 +63,12 @@ android {
}
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
flutter {
source '../..'
}

View File

@ -17,6 +17,7 @@ pluginManagement {
}
plugins {
id "org.gradle.toolchains.foojay-resolver-convention" version "0.8.0"
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.6.1' apply false
id "org.jetbrains.kotlin.android" version "2.0.20" apply false

View File

@ -27,6 +27,9 @@ require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelpe
flutter_ios_podfile_setup
Pod::PICKER_MEDIA = false
Pod::PICKER_AUDIO = false
target 'Runner' do
use_frameworks!
use_modular_headers!
@ -45,7 +48,7 @@ post_install do |installer|
project.targets.each do |target|
target.build_configurations.each do |config|
if Gem::Version.new('11.0') > Gem::Version.new(config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'])
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
end
end
end

View File

@ -1,37 +1,5 @@
PODS:
- DKImagePickerController/Core (4.3.4):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
- DKImagePickerController/ImageDataManager (4.3.4)
- DKImagePickerController/PhotoGallery (4.3.4):
- DKImagePickerController/Core
- DKPhotoGallery
- DKImagePickerController/Resource (4.3.4)
- DKPhotoGallery (0.0.17):
- DKPhotoGallery/Core (= 0.0.17)
- DKPhotoGallery/Model (= 0.0.17)
- DKPhotoGallery/Preview (= 0.0.17)
- DKPhotoGallery/Resource (= 0.0.17)
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Core (0.0.17):
- DKPhotoGallery/Model
- DKPhotoGallery/Preview
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Model (0.0.17):
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Preview (0.0.17):
- DKPhotoGallery/Model
- DKPhotoGallery/Resource
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Resource (0.0.17):
- SDWebImage
- SwiftyGif
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Flutter (1.0.0)
- GoogleDataTransport (9.4.1):
@ -92,13 +60,9 @@ PODS:
- Flutter
- FlutterMacOS
- PromisesObjC (2.4.0)
- SDWebImage (5.15.5):
- SDWebImage/Core (= 5.15.5)
- SDWebImage/Core (5.15.5)
- share_plus (0.0.1):
- Flutter
- SwiftyGif (5.4.4)
- SwiftyJSON (5.0.1)
- SwiftyJSON (5.0.2)
- url_launcher_ios (0.0.1):
- Flutter
@ -114,8 +78,6 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- DKImagePickerController
- DKPhotoGallery
- GoogleDataTransport
- GoogleMLKit
- GoogleToolboxForMac
@ -128,8 +90,6 @@ SPEC REPOS:
- MLKitVision
- nanopb
- PromisesObjC
- SDWebImage
- SwiftyGif
- SwiftyJSON
EXTERNAL SOURCES:
@ -149,9 +109,7 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
file_picker: c79185e70b9b45728cde2a8d8da454e0cb43f287
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
GoogleMLKit: 97ac7af399057e99182ee8edfa8249e3226a4065
@ -168,12 +126,10 @@ SPEC CHECKSUMS:
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e
SwiftyJSON: f5b1bf1cd8dd53cd25887ac0eabcfd92301c6a5a
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
PODFILE CHECKSUM: b4b37a776e1b487bf31fc5e5014fa5a74f5a022a
PODFILE CHECKSUM: 6c27958b72564ad432c3d7024daffcc9edb8534a
COCOAPODS: 1.15.2

View File

@ -351,15 +351,11 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/DKImagePickerController/DKImagePickerController.framework",
"${BUILT_PRODUCTS_DIR}/DKPhotoGallery/DKPhotoGallery.framework",
"${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework",
"${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework",
"${BUILT_PRODUCTS_DIR}/GoogleToolboxForMac/GoogleToolboxForMac.framework",
"${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework",
"${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework",
"${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework",
"${BUILT_PRODUCTS_DIR}/SwiftyGif/SwiftyGif.framework",
"${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework",
"${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework",
"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
@ -370,15 +366,11 @@
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DKImagePickerController.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DKPhotoGallery.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleToolboxForMac.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyGif.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyJSON.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",

View File

@ -43,8 +43,6 @@
<true/>
<key>NSCameraUsageDescription</key>
<string>Camera permission is required for qr code scanning.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Just in case you store a nebula certificate as a photo, we aren't interested in your photos but a file picker might come across them</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>

View File

@ -18,6 +18,50 @@ default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :checkBuild do
# Do some things like setting up a temporary keystore to host secrets in CI
setup_ci
# Change signing behavior to work in CI
update_code_signing_settings(
# Automatic signing seems to be a good thing to have on in dev but will not work in CI
use_automatic_signing: false,
# The default value for this is iOS Development which is not appropriate for release
code_sign_identity: "Apple Distribution",
)
# Find our signing certs and profiles, these come from a private repository and managed by `fastlane match`
match(type: 'appstore', app_identifier: ["net.defined.mobileNebula","net.defined.mobileNebula.NebulaNetworkExtension"], readonly: true)
# Update our main program to have the correct provisioning profile from Apple
update_project_provisioning(
xcodeproj: "Runner.xcodeproj",
target_filter: "Runner",
# This comes from match() above
profile:ENV["sigh_net.defined.mobileNebula_appstore_profile-path"],
build_configuration: "Release"
)
# Update our network extension to have the correct provisioning profile from Apple
update_project_provisioning(
xcodeproj: "Runner.xcodeproj",
target_filter: "NebulaNetworkExtension",
# This comes from match() above
profile:ENV["sigh_net.defined.mobileNebula.NebulaNetworkExtension_appstore_profile-path"],
build_configuration: "Release"
)
build_app(
output_name: "MobileNebula.ipa",
workspace: "Runner.xcworkspace",
scheme: "Runner",
export_method: "app-store",
export_options: {
manageAppVersionAndBuildNumber: false
}
)
end
lane :build do
# Do some things like setting up a temporary keystore to host secrets in CI
setup_ci

View File

@ -85,44 +85,44 @@ class _AppState extends State<App> {
return MaterialApp(
theme: brightness == Brightness.light ? lightTheme : darkTheme,
home: Scaffold(
body: PlatformProvider(
//initialPlatform: initialPlatform,
builder: (context) => PlatformApp(
debugShowCheckedModeBanner: false,
localizationsDelegates: <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
DefaultCupertinoLocalizations.delegate,
],
title: 'Nebula',
material: (_, __) {
return new MaterialAppData(
themeMode: brightness == Brightness.light ? ThemeMode.light : ThemeMode.dark,
);
},
cupertino: (_, __) => CupertinoAppData(
theme: CupertinoThemeData(brightness: brightness),
),
onGenerateRoute: (settings) {
if (settings.name == '/') {
return platformPageRoute(context: context, builder: (context) => MainScreen(this.dnEnrolled));
}
final uri = Uri.parse(settings.name!);
if (uri.path == EnrollmentScreen.routeName) {
// TODO: maybe implement this as a dialog instead of a page, you can stack multiple enrollment screens which is annoying in dev
return platformPageRoute(
context: context,
builder: (context) =>
EnrollmentScreen(code: EnrollmentScreen.parseCode(settings.name!), stream: this.dnEnrolled),
body: PlatformProvider(
//initialPlatform: initialPlatform,
builder: (context) => PlatformApp(
debugShowCheckedModeBanner: false,
localizationsDelegates: <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
DefaultCupertinoLocalizations.delegate,
],
title: 'Nebula',
material: (_, __) {
return new MaterialAppData(
themeMode: brightness == Brightness.light ? ThemeMode.light : ThemeMode.dark,
);
}
},
cupertino: (_, __) => CupertinoAppData(
theme: CupertinoThemeData(brightness: brightness),
),
onGenerateRoute: (settings) {
if (settings.name == '/') {
return platformPageRoute(context: context, builder: (context) => MainScreen(this.dnEnrolled));
}
return null;
},
final uri = Uri.parse(settings.name!);
if (uri.path == EnrollmentScreen.routeName) {
// TODO: maybe implement this as a dialog instead of a page, you can stack multiple enrollment screens which is annoying in dev
return platformPageRoute(
context: context,
builder: (context) =>
EnrollmentScreen(code: EnrollmentScreen.parseCode(settings.name!), stream: this.dnEnrolled),
);
}
return null;
},
),
),
),
),
);
}
}

View File

@ -7,7 +7,7 @@ clean:
mobileNebula.aar: *.go go.sum
go get -d golang.org/x/mobile/cmd/gomobile
gomobile bind -trimpath -v --target=android
gomobile bind -trimpath -v --target=android -androidapi=26
MobileNebula.xcframework: *.go go.sum
go get -d golang.org/x/mobile/cmd/gomobile