Skip to content

Apply configuration profiles from an environment variable - #339

Merged
hendrikmennen merged 1 commit into
mainfrom
feature/configuration-profile-env
Aug 7, 2026
Merged

Apply configuration profiles from an environment variable#339
hendrikmennen merged 1 commit into
mainfrom
feature/configuration-profile-env

Conversation

@hendrikmennen

Copy link
Copy Markdown
Contributor

Overview

Lets a deployment provision a configuration profile — settings, packages, and package sources — without any user interaction, composing with the existing OneWareStudio.defaults.json deployment defaults.

Configuration profiles could previously only be applied by hand through Extras → Import Configuration..., which doesn't fit an automated rollout. Setting ONEWARE_CONFIGURATION_PROFILE now applies one at startup.

Usage

The value is a local file path or an http(s) URL, so a profile can be served centrally and updated without touching each machine. It can be provided three ways:

// OneWareStudio.defaults.json
{
  "ONEWARE_DIR": "/workspace/OneWare",
  "ONEWARE_PACKAGE_REPOSITORY": "https://packages.example.com/oneware-packages.json",
  "ONEWARE_CONFIGURATION_PROFILE": "https://config.example.com/team.onewareconfig"
}
OneWareStudio --configuration-profile /workspace/team.onewareconfig
OneWareStudio --configuration-profile https://config.example.com/team.onewareconfig

EnvironmentDefaultsService already loads any ONEWARE_-prefixed key, so the defaults file works with no change to that class.

Applied once, not on every launch

Re-importing on every start would silently revert settings the user changed afterwards. Instead the service records a SHA-256 fingerprint of source + profile content in AppDataDirectory:

  • Unchanged profile → skipped.
  • Profile edited in place, or the variable repointed at a different profile → re-applied.
  • ONEWARE_CONFIGURATION_PROFILE_MODE=always → re-applied unconditionally, for locked-down deployments where enforcement is the goal.

Failure handling

A missing file, unreachable URL, or malformed JSON is logged and skipped — it can never prevent the IDE from starting. Only OperationCanceledException propagates. Packages already installed are left untouched.

Implementation notes

  • IConfigurationProfileService gains LoadFromSourceAsync (path or URL) and ApplyEnvironmentProfileAsync; the variable names are exposed as constants on the interface.
  • ConfigurationProfileService now takes IHttpService to fetch remote profiles.
  • The startup call sits in LoadContentAsync immediately after RegisterPackageRepositoryWithFallback, so package sources contributed by the profile are registered before ImportPackagesAsync runs its own RefreshAsync and can resolve packages from them.

Known limitation

Settings consumed during early startup — GPU cache size and X11 rendering mode, read in BuildAvaloniaApp — are read before the profile is applied, so those take effect on the next launch. Documented in the README rather than restructuring startup ordering.

Testing

  • 6 new unit tests covering local-file and URL loading, download failure, apply-once-then-skip, always mode, and the missing-profile path.
  • dotnet test OneWare.slnx — 96 tests pass across 11 projects, 0 failures.
  • dotnet build clean on OneWare.Studio.Desktop.

Allow deployments to provision a configuration profile (settings, packages,
package sources) without user interaction, composing with the existing
OneWareStudio.defaults.json deployment defaults.

ONEWARE_CONFIGURATION_PROFILE accepts a local file path or an http(s) URL, so a
profile can be served centrally. It can be set through the defaults file, as a
real environment variable, or via the new --configuration-profile argument.

Profiles are applied once by default, tracked by a SHA-256 fingerprint of the
source and content, so a deployment default does not overwrite settings the user
changed afterwards. Editing the profile or repointing the variable re-applies it.
ONEWARE_CONFIGURATION_PROFILE_MODE=always re-applies on every launch for
locked-down deployments.

A profile that cannot be downloaded or parsed is logged and skipped so it can
never prevent the IDE from starting.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@hendrikmennen
hendrikmennen merged commit 9943a46 into main Aug 7, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant