Files
pack/core/core_test.go
T
c533d61811 fix: preserve --env secrets when config defines secrets (#460)
* fix: preserve --env secrets when config defines secrets

Union env-derived secret names with merged config secrets so file-level  no longer drops build-time env vars. Add a regression test that covers this merge behavior.

* refactor(core): use slices.Concat for merging secrets and update tests

Generated-by: aiautocommit

* refactor(core): inline mergeSecrets helper function

Generated-by: aiautocommit

---------

Co-authored-by: Michael Bianco <[email protected]>
2026-07-30 07:54:37 -06:00

137 lines
3.8 KiB
Go

package core
import (
"os"
"path/filepath"
"testing"
"github.com/gkampitakis/go-snaps/snaps"
"github.com/railwayapp/railpack/core/app"
"github.com/railwayapp/railpack/core/logger"
"github.com/stretchr/testify/require"
)
func TestMain(m *testing.M) {
v := m.Run()
snaps.Clean(m, snaps.CleanOpts{Sort: true})
os.Exit(v)
}
// generate snapshot plan JSON for each build example and assert against it
func TestGenerateBuildPlanForExamples(t *testing.T) {
wd, err := os.Getwd()
require.NoError(t, err)
// Get all the examples
examplesDir := filepath.Join(filepath.Dir(wd), "examples")
entries, err := os.ReadDir(examplesDir)
require.NoError(t, err)
for _, entry := range entries {
if !entry.IsDir() {
continue
}
// For each example, generate a build plan that we can snapshot test
t.Run(entry.Name(), func(t *testing.T) {
examplePath := filepath.Join(examplesDir, entry.Name())
userApp, err := app.NewApp(examplePath)
require.NoError(t, err)
env := app.NewEnvironment(nil)
buildResult := GenerateBuildPlan(userApp, env, &GenerateBuildPlanOptions{})
if !buildResult.Success {
t.Fatalf("failed to generate build plan for %s: %s", entry.Name(), buildResult.Logs)
}
plan := buildResult.Plan
// Remove the generated-mise-toml asset since the versions may change between runs
for _, step := range plan.Steps {
for name := range step.Assets {
if name == "generated-mise-toml" {
step.Assets[name] = "[generated-mise-toml]"
}
}
}
snaps.MatchStandaloneJSON(t, plan)
})
}
}
func TestGenerateConfigFromFile_NotFound(t *testing.T) {
// Use an existing example app directory so relative paths resolve
appPath := "../examples/config-file"
userApp, err := app.NewApp(appPath)
require.NoError(t, err)
env := app.NewEnvironment(nil)
l := logger.NewLogger()
options := &GenerateBuildPlanOptions{ConfigFilePath: "does-not-exist.railpack.json"}
cfg, genErr := GenerateConfigFromFile(userApp, env, options, l)
require.Error(t, genErr, "expected an error when explicit config file does not exist")
require.Nil(t, cfg, "config should be nil on error")
}
func TestGenerateConfigFromFile_Malformed(t *testing.T) {
appPath := "../examples/config-file"
userApp, err := app.NewApp(appPath)
require.NoError(t, err)
env := app.NewEnvironment(nil)
l := logger.NewLogger()
options := &GenerateBuildPlanOptions{ConfigFilePath: "railpack.malformed.json"}
cfg, genErr := GenerateConfigFromFile(userApp, env, options, l)
require.Error(t, genErr, "expected an error for malformed JSON config file")
require.Nil(t, cfg, "config should be nil on error")
}
func TestGetConfig_MergesEnvironmentAndFileSecrets(t *testing.T) {
tempDir := t.TempDir()
configPath := filepath.Join(tempDir, defaultConfigFileName)
err := os.WriteFile(configPath, []byte(`{"secrets":["VITE_APP_TITLE","FILE_ONLY_SECRET"]}`), 0644)
require.NoError(t, err)
userApp, err := app.NewApp(tempDir)
require.NoError(t, err)
envVars := map[string]string{
"DATABASE_URL": "postgres://localhost/mydb",
"SENTRY_AUTH_TOKEN": "sntrx_abc",
"VITE_APP_TITLE": "MyApp",
"MY_SECRET": "s3cret",
}
env := app.NewEnvironment(&envVars)
config, err := GetConfig(userApp, env, &GenerateBuildPlanOptions{}, logger.NewLogger())
require.NoError(t, err)
require.ElementsMatch(t, []string{
"DATABASE_URL",
"SENTRY_AUTH_TOKEN",
"VITE_APP_TITLE",
"MY_SECRET",
"FILE_ONLY_SECRET",
}, config.Secrets)
}
func TestGenerateBuildPlan_DockerignoreMetadata(t *testing.T) {
appPath := "../examples/dockerignore"
userApp, err := app.NewApp(appPath)
require.NoError(t, err)
env := app.NewEnvironment(nil)
buildResult := GenerateBuildPlan(userApp, env, &GenerateBuildPlanOptions{})
require.True(t, buildResult.Success)
require.NotNil(t, buildResult.Metadata)
require.Equal(t, "true", buildResult.Metadata["dockerIgnore"])
}