feat(options): Wire up sentry-options for dynamic config - #668
Merged
Conversation
Launchpad had no dynamic configuration system: every runtime knob was a process-start environment variable, so changing one required a redeploy. This adds the sentry-options client (Sentry's file/ConfigMap-backed options system) so values can be set live via sentry-options-automator. The integration defines a `launchpad` namespace with a single option, `projects.skip`, and reads it in get_service_config(), unioning it with the existing PROJECT_IDS_TO_SKIP env var. The option defaults to an empty list, so there is no behavior change until values are set in the automator; from then on the skip list can be updated without a redeploy. Option reads are defensive: init and every read fall back to the caller's default on any error, so a missing schema dir or library failure can never break artifact processing (verified against the forkserver worker path). Schemas are baked into the image at /etc/sentry-options and read via SENTRY_OPTIONS_DIR; tests and local dev point the same var at the in-repo schemas directory.
Contributor
Size Analysis2 components analyzed iOS Builds
Android Builds
|
Contributor
📲 Install BuildsiOS
Android
|
Remove the init_options() call from the top-level CLI group. It ran for every subcommand including `launchpad size`, which reads no options, so on any shell without SENTRY_OPTIONS_DIR set it logged a full init traceback for an expected condition — and duplicated the init the worker already does in run_worker(). The worker path keeps its startup init, and worker children lazily initialize on first read, so nothing that actually reads an option loses coverage. Add a test for the defensive fallback: get_option() returns the caller's fallback when init() raises. This was the one untested branch of the helper's whole reason to exist.
Trim each comma-split entry and drop empties, so " env-1 , env-2 ," yields ["env-1", "env-2"]. Unioning the env var with the projects.skip option makes near-duplicate mismatches (e.g. " 123" vs "123") more likely, and stripping keeps both sources comparable.
kenzoengineer
approved these changes
Sep 3, 2026
kenzoengineer
left a comment
Member
There was a problem hiding this comment.
sentry options related changes lgtm!
This was referenced Sep 3, 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.
Launchpad has had no dynamic configuration system — every runtime knob is a process-start environment variable, so changing one means a redeploy. This wires up sentry-options (Sentry's file/ConfigMap-backed options library) so launchpad can read values that are set live through sentry-options-automator, without shipping a new image.
The integration defines a
launchpadnamespace (sentry-options/schemas/launchpad/schema.json) with a single option to start,projects.skip.get_service_config()reads it and unions it with the existingPROJECT_IDS_TO_SKIPenv var (deduped, order-preserving). The option defaults to an empty list, so this is a no-op until values are set in the automator — from then on the skip list becomes a dynamic control that no longer needs a redeploy. Env stays authoritative for whatever it already sets; the option is purely additive.Reads are defensive by construction: a small
launchpad/options.pyhelper caches an idempotentinit()and every read falls back to the caller's default on any error, so a missing schema dir or a library hiccup can never break artifact processing. This matters because the actual read happens in the forkserver worker children; init runs lazily in whichever process reads first (plus explicitinit_options()at the CLI group andrun_workerstartup for early validation). I verified the graceful-degradation path end-to-end — the CLI still runs cleanly even when the schema dir is absent.Schemas are baked into the image at
/etc/sentry-optionsand read viaSENTRY_OPTIONS_DIR(set in the Dockerfile); tests and local dev point the same var at the in-reposentry-options/directory. The package shipspy.typed, sotyneeds no extra config. Schema validity is enforced byinit()during the test suite, so a malformed schema fails CI.Part of a three-repo change. Two follow-ups make the option actually settable in production: a sentry-options-automator PR registering launchpad in
repos.json(pinned to this branch) and addingoption-values/launchpad/, and an ops PR adding theoptions.sentry.io/{inject,namespace}injector annotations to the launchpad taskworker deployment. This PR is safe to merge on its own — with no values set anywhere, behavior is unchanged.Testing: added unit coverage for the options helper (default, override, fallback) and for the env/option union in
get_service_config; full unit suite (362) passes, along with lint, format, and types.