feat(build): expand env vars in target config

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 20:16:57 +00:00
parent 9b6c468d94
commit c648e981b4
4 changed files with 61 additions and 0 deletions

View file

@ -243,6 +243,7 @@ func (cfg *BuildConfig) ExpandEnv() {
cfg.Build.Cache.RestoreKeys = expandEnvSlice(cfg.Build.Cache.RestoreKeys)
cfg.Build.BuildArgs = expandEnvMap(cfg.Build.BuildArgs)
cfg.Targets = expandTargetConfigs(cfg.Targets)
cfg.Sign.ExpandEnv()
}
@ -271,6 +272,21 @@ func expandEnvMap(values map[string]string) map[string]string {
return result
}
func expandTargetConfigs(values []TargetConfig) []TargetConfig {
if len(values) == 0 {
return values
}
result := make([]TargetConfig, len(values))
for i, value := range values {
result[i] = TargetConfig{
OS: expandEnv(value.OS),
Arch: expandEnv(value.Arch),
}
}
return result
}
// CloneStringMap returns a shallow copy of a string map.
//
// clone := build.CloneStringMap(map[string]string{"VERSION": "v1.2.3"})

View file

@ -84,6 +84,27 @@ targets:
assert.Equal(t, "arm64", cfg.Targets[1].Arch)
})
t.Run("expands environment variables in target config", func(t *testing.T) {
t.Setenv("TARGET_OS", "linux")
t.Setenv("TARGET_ARCH", "arm64")
content := `
version: 1
targets:
- os: ${TARGET_OS}
arch: ${TARGET_ARCH}
`
dir := setupConfigTestDir(t, content)
cfg, err := LoadConfig(fs, dir)
require.NoError(t, err)
require.NotNil(t, cfg)
require.Len(t, cfg.Targets, 1)
assert.Equal(t, "linux", cfg.Targets[0].OS)
assert.Equal(t, "arm64", cfg.Targets[0].Arch)
})
t.Run("expands environment variables in build and signing config", func(t *testing.T) {
t.Setenv("APP_NAME", "demo-app")
t.Setenv("APP_ROOT", "./cmd/demo")

View file

@ -328,6 +328,7 @@ func (c *Config) ExpandEnv() {
c.Project.Repository = expandEnv(c.Project.Repository)
c.Build.ArchiveFormat = expandEnv(c.Build.ArchiveFormat)
c.Build.Targets = expandTargetConfigs(c.Build.Targets)
c.Publishers = expandPublisherConfigs(c.Publishers)
@ -477,6 +478,21 @@ func expandEnvMap(values map[string]string) map[string]string {
return result
}
func expandTargetConfigs(values []TargetConfig) []TargetConfig {
if len(values) == 0 {
return values
}
result := make([]TargetConfig, len(values))
for i, value := range values {
result[i] = TargetConfig{
OS: expandEnv(value.OS),
Arch: expandEnv(value.Arch),
}
}
return result
}
// expandEnv expands $VAR or ${VAR} using the current process environment.
func expandEnv(s string) string {
if !core.Contains(s, "$") {

View file

@ -123,6 +123,8 @@ project:
func TestConfig_LoadConfig_ExpandEnv_Good(t *testing.T) {
t.Setenv("RELEASE_REPO", "owner/release-app")
t.Setenv("RELEASE_ARCHIVE", "xz")
t.Setenv("RELEASE_TARGET_OS", "darwin")
t.Setenv("RELEASE_TARGET_ARCH", "arm64")
t.Setenv("HOMEBREW_TAP", "owner/homebrew-tap")
t.Setenv("SDK_SPEC", "docs/openapi.yaml")
t.Setenv("SDK_OUTPUT", "generated/sdk")
@ -134,6 +136,9 @@ project:
repository: $RELEASE_REPO
build:
archive_format: $RELEASE_ARCHIVE
targets:
- os: $RELEASE_TARGET_OS
arch: $RELEASE_TARGET_ARCH
publishers:
- type: homebrew
tap: $HOMEBREW_TAP
@ -149,6 +154,9 @@ sdk:
assert.Equal(t, "owner/release-app", cfg.Project.Repository)
assert.Equal(t, "xz", cfg.Build.ArchiveFormat)
require.Len(t, cfg.Build.Targets, 1)
assert.Equal(t, "darwin", cfg.Build.Targets[0].OS)
assert.Equal(t, "arm64", cfg.Build.Targets[0].Arch)
require.Len(t, cfg.Publishers, 1)
assert.Equal(t, "owner/homebrew-tap", cfg.Publishers[0].Tap)
require.NotNil(t, cfg.SDK)