Skip to content
This repository has been archived by the owner on Apr 22, 2024. It is now read-only.

Figure out 'dotnet run' CLI experience for iOS and Android #26

Open
jonathanpeppers opened this issue Jan 7, 2021 · 23 comments
Open

Figure out 'dotnet run' CLI experience for iOS and Android #26

jonathanpeppers opened this issue Jan 7, 2021 · 23 comments

Comments

@jonathanpeppers
Copy link
Member

CLI experience

If you try the samples here, you can run iOS/Android projects at the command-line with:

$ dotnet build HelloAndroid.csproj -t:Run
$ dotnet build HelloiOS.csproj -t:Run
$ dotnet run --project HelloAndroid.csproj

iOS behavior

iOS launches the first simulator it finds in the list (which is currently an iPad) and prints the iOS console output at the command-line and blocks. You have to Ctrl+C to get the dotnet command to exit. You get an MSBuild error message after hitting Ctrl+C.

@rolfbjarne feel free to chime in 😄, there might be a way to select which simulator you want.

Android behavior

Android uses the existing adb connection along with the AdbTarget property if you need to select which device/emulator to use when there are multiple. The dotnet command exits successfully when the app is launched, giving no console output for the app.

The Xamarin.Android SDK does not have any logic for locating emulators and launching them from MSBuild, as the IDEs do this for Android, currently. There is not any logic for giving adb logcat (console) output either.

Can you dotnet run apps? Like .apk, .aab, .app, or .ipa files?

There does not currently seem to be a way to do something like:

$ dotnet run bin/Debug/HelloAndroid.apk
$ dotnet run bin/Debug/HelloiOS.app

I think we would need some new behavior for the dotnet run command for this to be possible. --project runs MSBuild, so that is why we were able to get this part to work.

Conclusion

What should the behavior be here? Both iOS/Android behaviors are reasonable in their own way.

@rolfbjarne
Copy link
Member

@rolfbjarne feel free to chime in 😄, there might be a way to select which simulator you want.

Yes, there is a way, but it's not very user-friendly at the moment.

  1. Use /Applications/Xcode.app/Contents/Developer/usr/bin/simctl list to get a list of all the simulators.

  2. Choose one, and copy the corresponding UDID.

  3. Set the _DeviceName property like this to select the simulator:

     dotnet build -t:Run /p:_DeviceName=:v2:udid=<UDID>
    

You have to Ctrl+C to get the dotnet command to exit.

You can hit Enter to terminate the app.

@Silic0nS0ldier
Copy link

Thoughts from a stranger on the internet;

  • Try to match existing dotnet CLI conventions. Deviations (even to match established Xamarin specific conventions) should be avoided to keep everything idiomatic.
  • The dotnet CLI run semantics lean more towards running on the current device (local machine). With iOS and Android app development, I think this needs to be addressed. A new flag to explicitly specify what device to deploy to may address this (ideally this would not be Xamarin specific, realistically there is no reason for it to be long-term).
  • dotnet run target device discovery should be easy. Scenarios like connecting to a MacOS agent complicate this somewhat as ideally the connection should stay open during development (being a slow resource to prepare after all). It may be necessary delegate responsibility elsewhere to avoid creating a difficult to debug black-box, given the number of moving parts here.

As for the commands and their expected outcomes...

dotnet build

Builds a project and all of its dependencies.

IMO under existing dotnet CLI behaviour this doesn't need to produce an app package, just something that can be run (there are ways to get code running on a target without needing something link an APK, handy for alternative deploy approaches like a certain now dead Xamarin debug app).

A noted behaviour with Android deploys however is that it dumps an APK in bin. In a CLI setting where a more customised workflow might be at play, it may be preferrable to at the very least expose a switch to do this up front. Though such behaviour could still be delegated to dotnet publish.

dotnet run

Runs source code without any explicit compile or launch commands.

There are 3 ways I've used this command.

  1. dotnet run in project directory, to run said project
  2. dotnet run ./somepath/some.csproj to run a specific project
  3. dotnet run ./somepath/some.dll to run a specific assembly (be interesting if this could somehow be mapped to dotnet build outputs with this new target platforms)

@richlander
Copy link
Member

@Silic0nS0ldier Good feedback, but I'm pretty sure that the experience that @rolfbjarne raises is very much an "at the moment" sort of issue. We'll get this sorted, and it will end up being very similar to what you've written.

IMO under existing dotnet CLI behaviour this doesn't need to produce an app package, just something that can be run

I like this. Yes, the key task of dotnet build should be creating runnable assets that will run in a well-defined environment.

@balbarak
Copy link

What about that, you should specify emulator or target device when you call dotnet run for iOS or Android

If there is no target device it should failed to run

Ex
dotnet run -t emulatorname

@Thibaultce
Copy link

@rolfbjarne feel free to chime in 😄, there might be a way to select which simulator you want.

Yes, there is a way, but it's not very user-friendly at the moment.

  1. Use /Applications/Xcode.app/Contents/Developer/usr/bin/simctl list to get a list of all the simulators.
  2. Choose one, and copy the corresponding UDID.
  3. Set the _DeviceName property like this to select the simulator:
     dotnet build -t:Run /p:_DeviceName=:v2:udid=<UDID>
    

You have to Ctrl+C to get the dotnet command to exit.

You can hit Enter to terminate the app.

Thanks for the tip, it works like a charm with the emulators.
But I'm not able to use the dotnet build command with an actual device. Is the call different ? I tried to replace the UDID by the UDID of the IPhone connected.

@rolfbjarne
Copy link
Member

But I'm not able to use the dotnet build command with an actual device. Is the call different ? I tried to replace the UDID by the UDID of the IPhone connected.

Try doing this for device:

dotnet build -t:Run /p:_DeviceName=<UDID>

if that doesn't work, please show the output.

@Thibaultce
Copy link

It's working, thanks !

@PureWeen
Copy link
Member

PureWeen commented Jul 22, 2021

msbuild.binlog.zip
@rolfbjarne I'm trying to launch our maui samples to a physical device but it's just failing with the attached exceptions

https://github.com/dotnet/maui/blob/main/src/Controls/samples/Controls.Sample.iOS/Maui.Controls.Sample.iOS-net6.csproj

@rolfbjarne
Copy link
Member

msbuild.binlog.zip
@rolfbjarne I'm trying to launch our maui samples to a physical device but it's just failing with the attached exceptions

https://github.com/dotnet/maui/blob/main/src/Controls/samples/Controls.Sample.iOS/Maui.Controls.Sample.iOS-net6.csproj

I believe you can work around that by executing this locally:

sudo chmod a+x /usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.ios-arm64/6.0.0-preview.6.21352.12/Sdk/../tools/mono-aot-cross

This is already fixed, and the problem should go away in a future preview (not sure if it'll be in preview7 or rc1).

@tmarkovski
Copy link

But I'm not able to use the dotnet build command with an actual device. Is the call different ? I tried to replace the UDID by the UDID of the IPhone connected.

Try doing this for device:

dotnet build -t:Run /p:_DeviceName=<UDID>

if that doesn't work, please show the output.

Using net6.0 (6.0.100) this command doesn't work.

EXEC : error MT1212: Failed to create a simulator where type = iPhone 4s (com.apple.CoreSimulator.SimDeviceType.iPhone-4s) and runtime = iOS 15.0 (15.0 - 19A339) - com.apple.CoreSimulator.SimRuntime.iOS-15-0. [/Users/tomislav/Git/DELETEME/tfmtest/ButtonDemos/ButtonDemos.csproj]
          
/usr/local/share/dotnet/sdk/6.0.100/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(897,5): error MSB3073: The command "/usr/local/share/dotnet/packs/Microsoft.iOS.Sdk/15.0.101-preview.10.251/tools/bin/mlaunch --launchsim bin/Debug/net6.0-ios/iossimulator-x64/ButtonDemos.app/ --device 12214EEA-4CC2-4C4B-A0C3-A52153C32249 --stdout /dev/ttys003 --stderr /dev/ttys003 --wait-for-exit" exited with code 1. [/Users/tomislav/Git/DELETEME/tfmtest/ButtonDemos/ButtonDemos.csproj]

Specifying it as /p:_DeviceName=:v2:udid=<UDID> does work.

@hflexgrig
Copy link

I'm getting

/usr/local/share/dotnet/packs/Microsoft.iOS.Sdk/15.0.101-preview.12.710/targets/Xamarin.Shared.Sdk.targets(1244,3): error MSB4044: The "GetMlaunchArguments" task was not given a value for the required parameter "AppBundlePath". [/Users/haykgrigoryan/RiderProjects/MauiApp1Silicon/MauiApp1Silicon/MauiApp1Silicon.csproj]

When runninng

dotnet build -t:RUN -f net6.0-ios

Any ideas how can I make MAUI app run on IOS device on my M1 mac ?

@rolfbjarne
Copy link
Member

@hflexgrig can you try getting a binlog (by passing -bl: dotnet build -t:Run -f net6.0-ios -bl:msbuild.binlog), and then attaching that binlog here?

@lhughey
Copy link

lhughey commented Jan 5, 2022

What worked for me on Mac targeting iOS is this.
dotnet build -t:Run -f net6.0-ios /p:_DeviceName=:v2:udid=362528C6-A6A2-4A39-A630-420D714C4A3D

The '-f net6.0-ios' part was necessary

@anpin
Copy link

anpin commented Jan 11, 2022

@rolfbjarne I'm getting the same issue as @hflexgrig, please find the binlog attached below (I had to change extension to upload here as binlog is not supported by Github, so please remove the .log part at the end of the filename) . The command I'm running is

dotnet build MyProject.Mobile/MyProject.Mobile.csproj  -t:Run -f net6.0-ios -r ios-arm64 -p:_DeviceName=:v2:udid=$UDID -bl:msbuild.binlog

I've also tried to add ```--self-contained" flag as it was giving me warning, but same result

msbuild.binlog.log

@rolfbjarne
Copy link
Member

@anpin can you try changing OutputType to Exe in your project file to see if that works?

@lhughey
Copy link

lhughey commented Jan 11, 2022

@anpin Can you do a terminal cd into the directory rather than supplying the path to the solution? Please try that and include what I did above (your device UDID might differ). I had all trouble with even small variations of the script.

@anpin
Copy link

anpin commented Jan 12, 2022

@rolfbjarne after changing OutputType to Exe and fiddling with provisioning and entitlements details I'm now faced with lots of

  Optimizing assemblies for size, which may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
  Tool xcrun execution finished (exit code = 1).
          
  /Users/pa/Projects/uno-demo/DynamicMvu.Mobile/obj/Debug/net6.0-ios/ios-arm64/nativelibraries/aot-output/x86_64/System.Private.CoreLib.dll.s:127:7: error: out of range literal value in '.word' directive
  .word 0xa9b67bfd
        ^
  /Users/pa/Projects/uno-demo/DynamicMvu.Mobile/obj/Debug/net6.0-ios/ios-arm64/nativelibraries/aot-output/x86_64/System.Private.CoreLib.dll.s:128:7: error: out of range literal value in '.word' directive
  .word 0x910003fd
        ^
 ...

and then finally

/usr/local/share/dotnet/packs/Microsoft.iOS.Sdk/15.0.101-preview.12.710/targets/Xamarin.Shared.Sdk.targets(951,3): error : clang exited with code 1 [/Users/pa/Projects/uno-demo/DynamicMvu.Mobile/DynamicMvu.Mobile.csproj]
/usr/local/share/dotnet/packs/Microsoft.iOS.Sdk/15.0.101-preview.12.710/targets/Xamarin.Shared.Sdk.targets(951,3): error :          [/Users/pa/Projects/uno-demo/DynamicMvu.Mobile/DynamicMvu.Mobile.csproj]

I also see a lot of compatibility warnings for MacCatalyst such as below, but even if I exclude the net6.0-maccatalyst target from csproj above error stays the same

 'Uno.WinUI.RemoteControl 4.0.11' was resolved as a dependency of 'DynamicMvu.Mobile', but the dependency is using 'Xamarin.iOS' while 'DynamicMvu.Mobile' is using 'net6.0-maccatalyst15.0' as its TargetFramework. There might be compatibility issues when MacCatalyst projects depend on Xamarin.iOS projects.

Please find the binlog here -> msbuild.binlog.log

@lhughey running dotnet build from inside of the Mobile project doesn't make any difference for me

@rolfbjarne
Copy link
Member

@anpin you need to remove the following line from your csproj:

<MtouchArch>x86_64</MtouchArch>

it conflicts with this line:

<RuntimeIdentifier Condition="'$(TargetFramework)' == 'net6.0-ios'">ios-arm64</RuntimeIdentifier>

If you want to build for the simulator (x86_64), you need to do this instead:

<RuntimeIdentifier Condition="'$(TargetFramework)' == 'net6.0-ios'">iossimulator-x64</RuntimeIdentifier>

@anpin
Copy link

anpin commented Jan 12, 2022

@rolfbjarne sorry my bad, was copying configuration for signing from a working Xamarin.Forms project and overlooked this. I'm interested in having the app built and deployed on device, not simulator, so it builds without error after your sugestion, but deploy to device never starts. It hangs with

 2022-01-12 15:11:36.807 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.IDEDebugger.VariablesViewQuickLookProvider for extension Xcode.IDEDebugger.SpriteKitQuickLookProvider of plug-in com.apple.IDESpriteKitParticleEditor
  2022-01-12 15:11:36.810 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.IDEDebugger.VariablesViewQuickLookProvider for extension Xcode.SpriteKit.GKStateMachineQuickLookProvider of plug-in com.apple.IDESpriteKitParticleEditor
  2022-01-12 15:11:36.824 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.IDEDebugger.VariablesViewQuickLookProvider for extension Xcode.IDEDebugger.GPUMatrixQuickLookProvider of plug-in com.apple.dt.gpu.GPUDebugger
  2022-01-12 15:11:36.824 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.IDEDebugger.VariablesViewQuickLookProvider for extension Xcode.IDEDebugger.MTLDebugSamplerState of plug-in com.apple.dt.gpu.GPUDebugger
  2022-01-12 15:11:36.824 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.IDEDebugger.VariablesViewQuickLookProvider for extension Xcode.IDEDebugger.MTLDebugTexture of plug-in com.apple.dt.gpu.GPUDebugger
  2022-01-12 15:11:36.824 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.IDEDebugger.VariablesViewQuickLookProvider for extension Xcode.IDEDebugger.GPUIssueQuickLookProvider of plug-in com.apple.dt.gpu.GPUDebugger
  2022-01-12 15:11:36.825 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.IDEDebugger.VariablesViewQuickLookProvider for extension Xcode.IDEDebugger.MTLDebugBuffer of plug-in com.apple.dt.gpu.GPUDebugger
  2022-01-12 15:11:36.826 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.DebuggerFoundation.ViewDescriber for extension Xcode.DebuggerFoundation.watchOSSimulator.ViewDescriber of plug-in com.apple.dt.IDEWatchSupportUI
  2022-01-12 15:11:36.826 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.DebuggerFoundation.DataSourceConnection for extension Xcode.DebuggerFoundation.watchOSSimulator.DataSourceConnectionTargetHub of plug-in com.apple.dt.IDEWatchSupportUI
  2022-01-12 15:11:36.826 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.DebuggerFoundation.ViewDescriber for extension Xcode.DebuggerFoundation.watchOS.ViewDescriber of plug-in com.apple.dt.IDEWatchSupportUI
  2022-01-12 15:11:36.826 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.DebuggerFoundation.DataSourceConnection for extension Xcode.DebuggerFoundation.watchOS.DataSourceConnectionTargetHub of plug-in com.apple.dt.IDEWatchSupportUI
  2022-01-12 15:11:36.827 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.DebuggerFoundation.DataSourceConnection for extension Xcode.DebuggerFoundation.tvOSSimulator.DataSourceConnectionTargetHub of plug-in com.apple.dt.IDEAppleTVSupportUI
  2022-01-12 15:11:36.828 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.DebuggerFoundation.ViewDescriber for extension Xcode.DebuggerFoundation.ATVSimulator.ViewDescriber of plug-in com.apple.dt.IDEAppleTVSupportUI
  2022-01-12 15:11:36.828 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.DebuggerFoundation.ViewDescriber for extension Xcode.DebuggerFoundation.ATV.ViewDescriber of plug-in com.apple.dt.IDEAppleTVSupportUI
  2022-01-12 15:11:36.828 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.DebuggerFoundation.DataSourceConnection for extension Xcode.DebuggerFoundation.tvOS.DataSourceConnectionTargetHub of plug-in com.apple.dt.IDEAppleTVSupportUI
  2022-01-12 15:11:36.828 mlaunch[9347:171255] Requested but did not find extension point with identifier Xcode.DebuggerFoundation.DeviceIconProvider for extension Xcode.DebuggerFoundation.DeviceIconProvider.AppleTV of plug-in com.apple.dt.IDEAppleTVSupportUI
  Please connect the device ':v2:udid=00000000-000000000000002E'...

image

@rolfbjarne
Copy link
Member

@anpin for running on device, omit the :v2:udid= part, and just pass the UDID directly (/p:_DeviceName=UDID).

@anpin
Copy link

anpin commented Jan 12, 2022

@rolfbjarne that did the job! Even though it crashed on startup, but I will file it elsewhere. The final command for running it on device looked like this

dotnet build MyProject.Mobile/MyProject.Mobile.csproj  -t:Run -f net6.0-ios -p:_DeviceName={UDID}

with following lines found in the MyProject.Mobile.csproj

<OutputType>Exe</OutputType>
<RuntimeIdentifier Condition="'$(TargetFramework)' == 'net6.0-ios'">ios-arm64</RuntimeIdentifier>
<PropertyGroup Condition="'$(TargetFramework)'=='net6.0-ios'">
    <ProvisioningType>manual</ProvisioningType>    
    <CodesignKey>YourKey</CodesignKey>
    <CodesignProvision>YourProvission</CodesignProvision>
    <CodesignEntitlements>iOS/Entitlements.plist</CodesignEntitlements>    
    <CodesignExtraArgs />
    <CodesignResourceRules />
    <DeviceSpecificBuild>true</DeviceSpecificBuild>
    <AutoGenerateBindingRedirects>True</AutoGenerateBindingRedirects>
    <MonoSymbolArchive>True</MonoSymbolArchive>
    <MtouchLink>SdkOnly</MtouchLink>
    <MtouchDebug>true</MtouchDebug>
    <MtouchFastDev>true</MtouchFastDev>
    <MtouchExtraArgs>--linksdkonly</MtouchExtraArgs>
</PropertyGroup>

Thank you very much for your generous assistance.

TetsuOtter added a commit to AirTotes/AirTote that referenced this issue Jul 3, 2022
* MAUIに移行

とりあえずビルドに通るというだけの段階。現状だと、起動しようとすると落ちる。

* MacCatalystサポートを削除

ビルドエラーが起きるため

* 不要な処理記述を削除

* アイコンファイル名を変え忘れていたので修正

* 不要な`SupportedOSPlatformVersion`指定を削除

* iPad実機でデバッグできるように設定を追加

ref: dotnet/xamarin#26 (comment)

* XamarinからMauiに参照を修正

とりあえずこれでAndroidでは動作するようになった。
iPadだとまだブラックアウトする

* iOSでうまく表示されないバグを修正

おそらくLaunchScreenを読み込めずに固まってた。
それ以外にも、念の為テンプレートで生成されるkey-valueも追加しておいた。

* MAUIにあわせてアセットの保存位置と読み込み方法を変更

* iOSでXAMLからmscorlibへの参照ができない場合があったので修正

* 不要な実装を削除

* iOSデバッグでリンカを走らせないように修正

XAMLのHotReloadと、ビルド時間の短縮のため

* ファイル名ミスを修正

* Mapsui.Mauiを使用するためのおまじないを追加

SkiaSharpを初期化しないといけないため
(Quickstart読むのをサボってた)

* バージョン表示をFlyoutのFooterに追加

* 不要なRoute設定を削除

* Create appicon.svg

とりあえず外周の丸だけを追加。
日本地図や飛行機、コンパス等は後で追加する

* 飛行機アイコンを追加

* XMLフォーマットを修正

* コンパスを追加

* 日本地図を追加

* 白色での塗りつぶしを忘れていたので修正

* mergeでの消し忘れを修正

* migrate to maui / net6.0

* コードスタイルを修正

* 抜けていた半角スペースを追加

一応、ファイル内の表記と合わせた

* Create CalloutText.cs

多段のテキストを表現するためのクラス

* Create CustomTextCalloutPin.cs

自由なテキストを持てるCalloutを楽に扱うためのクラス

* CustomCalloutを使う仕様に変更

MAUIでもSEGVが起きなくなった

* Set Bundle Version to `1.0.11`

* iOS Release用の設定を追加

* Paddingがおかしいバグを修正

Paddingの設定が、MAUIでは全方向で同じ値でないといけなくなったらしい。

* ButtonのMarginを調整

* Corner Radiusを設定

* MapをTapしてもCalloutが消えないバグを修正

* AndroidでSplashScreenの背景色がおかしくなっているバグを修正

* AndroidでAppIconが正常に表示されないバグを修正

iOSでアイコンが若干バグる

* AdaptiveAppIcon対応に向け、Foregroundを分離

* Create appicon.svg

* AppIconをsvgに変更

* MAUIにあわせてファイル配置を修正

(Custom Calloutのフォント設定)
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 6, 2022
Context: dotnet/xamarin#26

The following does not work as expected:

    dotnet new android
    dotnet run -c Release

You end up with a `Debug` app in this case.

The way we implemented `dotnet run` was to make `$(RunCommand)` and
`$(RunArguments)` invoke `dotnet build -t:Run`.

We were losing the `$(Configuration)` value in this example.
jonpryor pushed a commit to dotnet/android that referenced this issue Sep 6, 2022
Context: dotnet/xamarin#26

The following does not work as expected:

	dotnet new android
	dotnet run -c Release

You end up with a `Debug` app in this case.

The way we implemented `dotnet run` was to make `$(RunCommand)` and
`$(RunArguments)` invoke `dotnet build -t:Run`.

We were losing the `$(Configuration)` value in this example.

Update `Microsoft.Android.Sdk.Application.targets` so that
`$(Configuration)` is forwarded to the `dotnet build -t:Run`
command line.
@bgever
Copy link

bgever commented Nov 22, 2023

For automated lookup of the UDID:

This command picks the first iPhone device ID from the available list. Currently iPhone SE (3rd generation) in my case.

dotnet build -t:Run -f net8.0-ios -p _DeviceName=:v2:udid:$(xcrun simctl list devices iPhone available | grep -om1 '[0-9A-F-]\{36\}')

To select a specific device, update the search query. For iPhone 15:

dotnet build -t:Run -f net8.0-ios -p _DeviceName=:v2:udid:$(xcrun simctl list devices 'iPhone 15' available | grep -om1 '[0-9A-F-]\{36\}')

And since the simctl command lists out the devices usually in order with the most powerful devices last, you can also reverse the results, so it always picks the latest and greatest whenever Xcode updates.

dotnet build -t:Run -f net8.0-ios -p _DeviceName=:v2:udid:$(xcrun simctl list devices iPhone available | tail -r | grep -om1 '[0-9A-F-]\{36\}')

@bruno-garcia
Copy link
Member

To run on a real device, using .NET 8 SDK I needed to specify RuntimeIdentifier (thanks @rolfbjarne):

dotnet build -t:Run -f net8.0-ios -p _DeviceName=00009999-000FFFFFFFFFFFFF -p:RuntimeIdentifier=ios-arm64

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests