Modernize hello-dotnet-client: .NET 8, GitHub Actions CI, MAUI apps, hello-apps spec#17
Merged
kinyoklion merged 14 commits intomainfrom Mar 5, 2026
Merged
Conversation
…I, comply with hello-apps spec - Remove CircleCI configuration - Remove deprecated Xamarin Android/iOS projects - Remove Shared project, inline code into single Program.cs file - Update target framework from netcoreapp3.1 to net8.0 - Update flag key to 'sample-feature' per spec - Add environment variable support for mobile key (LAUNCHDARKLY_MOBILE_KEY) and flag key (LAUNCHDARKLY_FLAG_KEY) - Add continuous mode with flag change listener (FlagValueChanged) - Add CI mode (CI env var) to disable continuous behavior - Add ASCII art display when flag evaluates to true - Update output format to 'The <flagKey> feature flag evaluates to <flagValue>.' - Add required code comments per spec - Add GitHub Actions workflow using verify-hello-app action - Update README.md to follow spec template - Simplify solution file to single project Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
- Use .ToString().ToLowerInvariant() for bool output to match spec's 'true'/'false' - Use Unicode full-block characters (U+2588) for ASCII art per spec Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
…th -p:TargetFrameworks Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
kinyoklion
reviewed
Mar 4, 2026
…on macOS Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
kinyoklion
reviewed
Mar 4, 2026
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
kinyoklion
reviewed
Mar 4, 2026
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
kinyoklion
reviewed
Mar 4, 2026
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
kinyoklion
reviewed
Mar 4, 2026
| run: dotnet workload install maui | ||
|
|
||
| - name: Build MAUI app (Android) | ||
| run: dotnet build MauiApp -f net8.0-android |
Member
There was a problem hiding this comment.
This is maybe a bit redundant. But it does help ensure things are working on mac.
Contributor
Author
There was a problem hiding this comment.
Agreed — it's a useful cross-platform sanity check to verify the Android build works on macOS too, even though the main Android build + emulator test runs on Ubuntu. I'll keep it as-is.
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
Co-Authored-By: rlamb@launchdarkly.com <rlamb@launchdarkly.com>
kinyoklion
approved these changes
Mar 4, 2026
kinyoklion
approved these changes
Mar 5, 2026
tanderson-ld
approved these changes
Mar 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Modernize hello-dotnet-client: .NET 8, GitHub Actions CI, MAUI apps, hello-apps spec
Summary
This PR modernizes the hello-dotnet-client repository to comply with the HELLO-hello-apps spec and adds .NET MAUI example apps for Android and iOS.
Console app modernization
netcoreapp3.1tonet8.0sample-feature(default)LAUNCHDARKLY_MOBILE_KEY,LAUNCHDARKLY_FLAG_KEY,CIFlagValueChangedlistener (disabled whenCIenv var is set)██characters) displayed when flag evaluates to trueThe <flagKey> feature flag evaluates to <flagValue>.(lowercasetrue/false)key = "example-user-key",name = "Sandy"verify-hello-app-v2.0.1action.NET MAUI app (new)
MauiApp/) targetingnet8.0-androidandnet8.0-iosnet8.0-androidis included (iOS cannot build on Linux). On macOS/Windows, both targets are included. Controlled via MSBuild conditions in the csproj.#373841(flag false) and#00844B(flag true), white text, displays flag valueFlagValueChangedlistener for real-time updates, thread-safe UI updates viaMainThread.BeginInvokeOnMainThread()appsettings.json— Mobile key and flag key are read from aResources/Raw/appsettings.jsonfile (bundled as a MauiAsset, loaded at runtime viaFileSystem.OpenAppPackageFileAsync). Anappsettings.example.jsontemplate is committed; the actualappsettings.jsonis gitignored to prevent committing keys.ubuntu-latest, iOS onmacos-latestuiautomator dump. This uses LaunchDarkly mobile key and flag key from AWS SSM Parameter Store (fetched viarelease-secretsaction).global.jsonto pin .NET 8 SDK — required because CI runners default to .NET 10, which rejectsnet8.0targets as out-of-supportHelloDotNetClient(notMauiApp) to avoid conflict withMicrosoft.Maui.Hosting.MauiAppCI & security
TargetFrameworksin the csproj — Linux builds Android only by default, macOS builds both Android and iOSEmbedAssembliesIntoApk=trueis set for Android CI builds to ensure assemblies are packaged in the APK (Debug builds use "fast deployment" by default which breaks emulator installation viaadb install)Updates since last revision
Android emulator verification (fourth reviewer comment)
Per the fourth reviewer comment, the Android MAUI app now runs on an emulator in CI and verifies flag evaluation:
android-emulator-runneraction.github/scripts/verify-maui-android.sh) installs APK, launches app, waits for SDK initialization with retries (4 attempts × 15s), captures logcat for crash debugging, and usesuiautomator dumpto verify flag evaluation text appears in the UIrelease-secretsaction and written toappsettings.jsonbefore buildingdotnet: falseto preserve .NET SDK)mono.MonoPackageManager.LoadApplicationto crash. Fixed by adding-p:EmbedAssembliesIntoApk=trueto the build command.CI result: Android emulator test now passes ✅. The app launches successfully, initializes the SDK, and displays the correct flag evaluation text.
Threading fix (Devin Review finding)
MainPage.xaml.cs:51-52— The initialUpdateUI()call afterawait LdClient.InitAsync()could resume on a background thread (if the SDK usesConfigureAwait(false)internally), causing potential crashes when accessing UI elements. Now correctly marshalled to main thread viaMainThread.BeginInvokeOnMainThread(), consistent with other UI update paths.Review & Testing Checklist for Human
appsettings.jsonfile is correctly bundled and loadedtrue/false#373841) and green (#00844B) when flag changesglobal.jsondoesn't break developer workflows — The repo now requires .NET 8 SDK. Developers with only .NET 9/10 will need to install 8.0. Confirm this aligns with team standards.Notes
DotNetConsoleAppandMauiApp(Xamarin projects removed)@<sha> # v4)5.*wildcard to auto-update to latest 5.x releases per specFlagTracker.FlagValueChanged(notFlagChanged) per SDK v5 API, same as console appCIenv var is set, the console app runs once and exits; otherwise it runs continuouslyexample-user-key/Sandy)MauiApp/directory uses namespaceHelloDotNetClient— the directory name doesn't match the namespace to avoid conflict with framework typesTargetFrameworksapproach usesRuntimeInformation.IsOSPlatform()— this is evaluated at build time, not runtimeMobileKeyandFlagKeyfromappsettings.jsonusingSystem.Text.Json. The file is loaded viaFileSystem.OpenAppPackageFileAsync()(standard MAUI raw asset access). If the file is missing or the key equals the placeholder "my-mobile-key", an error message is shown.uiautomator dumpto capture the Android UI hierarchy as XML, then greps for the expected flag evaluation text. This works because MAUI renders Labels as native AndroidTextViews. The same technique is used by thehello-androidreference repo.InitializeLaunchDarkly()isasync void(required for event handler pattern from constructor). All UI updates are marshalled to main thread viaMainThread.BeginInvokeOnMainThread(). Exceptions during SDK init are caught and displayed in UI.Session: https://app.devin.ai/sessions/4f95213b47cd415e9a9628ab59d12bba
Requested by: rlamb@launchdarkly.com