refactor: remove file-based configuration, use env vars only
All checks were successful
check / check (push) Successful in 1m0s

Remove the entire pkg/config package (Viper-based YAML config file
loader) and simplify internal/config to read all settings directly from
environment variables via os.Getenv(). This eliminates the spurious
"Failed to load config" log messages that appeared when no config.yaml
file was present.

- Delete pkg/config/ (YAML loader, resolver, manager, tests)
- Delete configs/config.yaml.example
- Simplify internal/config helper functions to use os.Getenv() with
  defaults instead of falling back to pkgconfig
- Update tests to set env vars directly instead of creating in-memory
  YAML config files via afero
- Remove afero, cloud.google.com/*, aws-sdk-go dependencies from go.mod
- Update README: document env-var-only configuration, remove YAML/Viper
  references
- Keep godotenv/autoload for .env file convenience in local development

closes #27
This commit is contained in:
clawbot
2026-03-01 23:01:45 -08:00
parent 10db6c5b84
commit 49852e7506
20 changed files with 43 additions and 2312 deletions

View File

@@ -10,7 +10,6 @@ import (
"go.uber.org/fx"
"sneak.berlin/go/webhooker/internal/globals"
"sneak.berlin/go/webhooker/internal/logger"
pkgconfig "sneak.berlin/go/webhooker/pkg/config"
// Populates the environment from a ./.env file automatically for
// development configuration. Kept in one place only (here).
@@ -56,38 +55,30 @@ func (c *Config) IsProd() bool {
return c.Environment == EnvironmentProd
}
// envString returns the env var value if set, otherwise falls back to pkgconfig.
func envString(envKey, configKey string) string {
if v := os.Getenv(envKey); v != "" {
return v
}
return pkgconfig.GetString(configKey)
// envString returns the value of the named environment variable, or
// an empty string if not set.
func envString(key string) string {
return os.Getenv(key)
}
// envSecretString returns the env var value if set, otherwise falls back to pkgconfig secrets.
func envSecretString(envKey, configKey string) string {
if v := os.Getenv(envKey); v != "" {
return v
}
return pkgconfig.GetSecretString(configKey)
}
// envBool returns the env var value parsed as bool, otherwise falls back to pkgconfig.
func envBool(envKey, configKey string) bool {
if v := os.Getenv(envKey); v != "" {
// envBool returns the value of the named environment variable parsed as a
// boolean. Returns defaultValue if not set.
func envBool(key string, defaultValue bool) bool {
if v := os.Getenv(key); v != "" {
return strings.EqualFold(v, "true") || v == "1"
}
return pkgconfig.GetBool(configKey)
return defaultValue
}
// envInt returns the env var value parsed as int, otherwise falls back to pkgconfig.
func envInt(envKey, configKey string, defaultValue ...int) int {
if v := os.Getenv(envKey); v != "" {
// envInt returns the value of the named environment variable parsed as an
// integer. Returns defaultValue if not set or unparseable.
func envInt(key string, defaultValue int) int {
if v := os.Getenv(key); v != "" {
if i, err := strconv.Atoi(v); err == nil {
return i
}
}
return pkgconfig.GetInt(configKey, defaultValue...)
return defaultValue
}
// nolint:revive // lc parameter is required by fx even if unused
@@ -106,21 +97,18 @@ func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
EnvironmentDev, EnvironmentProd, environment)
}
// Set the environment in the config package (for fallback resolution)
pkgconfig.SetEnvironment(environment)
// Load configuration values — env vars take precedence over config.yaml
// Load configuration values from environment variables
s := &Config{
DBURL: envString("DBURL", "dburl"),
DataDir: envString("DATA_DIR", "dataDir"),
Debug: envBool("DEBUG", "debug"),
MaintenanceMode: envBool("MAINTENANCE_MODE", "maintenanceMode"),
DevelopmentMode: envBool("DEVELOPMENT_MODE", "developmentMode"),
DBURL: envString("DBURL"),
DataDir: envString("DATA_DIR"),
Debug: envBool("DEBUG", false),
MaintenanceMode: envBool("MAINTENANCE_MODE", false),
DevelopmentMode: envBool("DEVELOPMENT_MODE", false),
Environment: environment,
MetricsUsername: envString("METRICS_USERNAME", "metricsUsername"),
MetricsPassword: envString("METRICS_PASSWORD", "metricsPassword"),
Port: envInt("PORT", "port", 8080),
SentryDSN: envSecretString("SENTRY_DSN", "sentryDSN"),
MetricsUsername: envString("METRICS_USERNAME"),
MetricsPassword: envString("METRICS_PASSWORD"),
Port: envInt("PORT", 8080),
SentryDSN: envString("SENTRY_DSN"),
log: log,
params: &params,
}