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

@@ -4,58 +4,14 @@ import (
"os"
"testing"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/fx"
"go.uber.org/fx/fxtest"
"sneak.berlin/go/webhooker/internal/globals"
"sneak.berlin/go/webhooker/internal/logger"
pkgconfig "sneak.berlin/go/webhooker/pkg/config"
)
// createTestConfig creates a test configuration file in memory
func createTestConfig(fs afero.Fs) error {
configYAML := `
environments:
dev:
config:
port: 8080
debug: true
maintenanceMode: false
developmentMode: true
environment: dev
dburl: postgres://test:test@localhost:5432/test_dev?sslmode=disable
metricsUsername: testuser
metricsPassword: testpass
secrets:
sentryDSN: ""
prod:
config:
port: $ENV:PORT
debug: $ENV:DEBUG
maintenanceMode: $ENV:MAINTENANCE_MODE
developmentMode: false
environment: prod
dburl: $ENV:DBURL
metricsUsername: $ENV:METRICS_USERNAME
metricsPassword: $ENV:METRICS_PASSWORD
secrets:
sentryDSN: $ENV:SENTRY_DSN
configDefaults:
port: 8080
debug: false
maintenanceMode: false
developmentMode: false
environment: dev
metricsUsername: ""
metricsPassword: ""
`
return afero.WriteFile(fs, "config.yaml", []byte(configYAML), 0644)
}
func TestEnvironmentConfig(t *testing.T) {
tests := []struct {
name string
@@ -68,6 +24,7 @@ func TestEnvironmentConfig(t *testing.T) {
{
name: "default is dev",
envValue: "",
envVars: map[string]string{"DBURL": "file::memory:?cache=shared"},
expectError: false,
isDev: true,
isProd: false,
@@ -75,6 +32,7 @@ func TestEnvironmentConfig(t *testing.T) {
{
name: "explicit dev",
envValue: "dev",
envVars: map[string]string{"DBURL": "file::memory:?cache=shared"},
expectError: false,
isDev: true,
isProd: false,
@@ -92,21 +50,19 @@ func TestEnvironmentConfig(t *testing.T) {
{
name: "invalid environment",
envValue: "staging",
envVars: map[string]string{"DBURL": "file::memory:?cache=shared"},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create in-memory filesystem with test config
fs := afero.NewMemMapFs()
require.NoError(t, createTestConfig(fs))
pkgconfig.SetFs(fs)
// Set environment variable if specified
if tt.envValue != "" {
os.Setenv("WEBHOOKER_ENVIRONMENT", tt.envValue)
defer os.Unsetenv("WEBHOOKER_ENVIRONMENT")
} else {
os.Unsetenv("WEBHOOKER_ENVIRONMENT")
}
// Set additional environment variables