Read sentry_dsn from SENTRY_DSN environment variable

What

The runner now reads the Sentry DSN from the SENTRY_DSN environment variable when sentry_dsn is not set in config.toml. If both are set, the config file wins.

Why

The DSN was only configurable through config.toml. In containerized deployments the config is often templated or read-only, and operators expect to point error reporting at a Sentry project through an environment variable without editing the file.

Why not the env: struct tag

The runner already has an env: annotation, so the obvious question is why this doesn't use it. The env: tag is not a generic "read from the environment" mechanism. It is consumed only by golang-cli-helpers GetFlagsFromStruct, which turns command structs into urfave/cli flags, and urfave/cli is what reads the variable. It applies to fields that become command-line flags, such as those on DockerConfig and RunnerSettings.

SentryDSN lives on the global common.Config, which is populated by the TOML decoder in LoadConfig. The decoder ignores env: tags, so annotating the field would have no effect. Using the tag would mean adding a --sentry-dsn flag to the run command and then merging that flag back into the loaded config with its own precedence rules against config.toml. That is a larger change and a different feature: a flag plus a variable, rather than environment support for the existing config field.

Reading the variable in LoadConfig keeps precedence explicit and re-evaluates on every config reload, so changing the environment and reloading behaves the same as the initial load. The tradeoff is that the variable does not show up in --help the way a flag would.

Notes

The fallback uses os.LookupEnv, so an explicitly empty SENTRY_DSN="" is still treated as set. That keeps the existing nil versus non-nil contract that commands/multi.go relies on: an unset variable leaves SentryDSN nil and Sentry stays off, while an empty string is a deliberate override.

Edited by Igor

Merge request reports

Loading