@@ -68,6 +68,82 @@ func TestReadMultiLineEmpty(t *testing.T) {
6868 assert .Equal (t , "" , result )
6969}
7070
71+ func TestBootstrapStepEnvLiteral (t * testing.T ) {
72+ dir := t .TempDir ()
73+ marker := filepath .Join (dir , "result" )
74+ steps := []config.BootstrapStep {
75+ {Name : "Env test" , Check : "false" , Run : "echo $MY_VAR > " + marker , Env : map [string ]string {"MY_VAR" : "hello" }},
76+ }
77+ err := RunBootstrap (context .Background (), "." , steps , nil )
78+ require .NoError (t , err )
79+ data , err := os .ReadFile (marker )
80+ require .NoError (t , err )
81+ assert .Contains (t , string (data ), "hello" )
82+ }
83+
84+ func TestBootstrapStepEnvInterpolation (t * testing.T ) {
85+ dir := t .TempDir ()
86+ marker := filepath .Join (dir , "result" )
87+ steps := []config.BootstrapStep {
88+ {Name : "Interpolate" , Check : "false" , Run : "echo $GREETING > " + marker , Env : map [string ]string {"GREETING" : "$(echo world)" }},
89+ }
90+ err := RunBootstrap (context .Background (), "." , steps , nil )
91+ require .NoError (t , err )
92+ data , err := os .ReadFile (marker )
93+ require .NoError (t , err )
94+ assert .Contains (t , string (data ), "world" )
95+ }
96+
97+ func TestBootstrapStepEnvAvailableInCheck (t * testing.T ) {
98+ steps := []config.BootstrapStep {
99+ {Name : "Check sees env" , Check : "test $MY_FLAG = yes" , Run : "false" , Env : map [string ]string {"MY_FLAG" : "yes" }},
100+ }
101+ // Check should pass thanks to env, so run (which would fail) is never called.
102+ err := RunBootstrap (context .Background (), "." , steps , nil )
103+ require .NoError (t , err )
104+ }
105+
106+ func TestBootstrapStepEnvOverridesGlobal (t * testing.T ) {
107+ dir := t .TempDir ()
108+ marker := filepath .Join (dir , "result" )
109+ globalEnv := []string {"MY_VAR=global" }
110+ steps := []config.BootstrapStep {
111+ {Name : "Override" , Check : "false" , Run : "echo $MY_VAR > " + marker , Env : map [string ]string {"MY_VAR" : "step" }},
112+ }
113+ err := RunBootstrap (context .Background (), "." , steps , globalEnv )
114+ require .NoError (t , err )
115+ data , err := os .ReadFile (marker )
116+ require .NoError (t , err )
117+ assert .Contains (t , string (data ), "step" )
118+ }
119+
120+ func TestBootstrapStepEnvFailedInterpolation (t * testing.T ) {
121+ dir := t .TempDir ()
122+ marker := filepath .Join (dir , "result" )
123+ steps := []config.BootstrapStep {
124+ {Name : "Bad cmd" , Check : "false" , Run : "echo [$MISSING] > " + marker , Env : map [string ]string {"MISSING" : "$(cat /nonexistent/xxx)" }},
125+ }
126+ err := RunBootstrap (context .Background (), "." , steps , nil )
127+ require .NoError (t , err )
128+ data , err := os .ReadFile (marker )
129+ require .NoError (t , err )
130+ assert .Contains (t , string (data ), "[]" )
131+ }
132+
133+ func TestBootstrapStepEnvNotVisibleToNextStep (t * testing.T ) {
134+ dir := t .TempDir ()
135+ marker := filepath .Join (dir , "result" )
136+ steps := []config.BootstrapStep {
137+ {Name : "Step 1" , Check : "false" , Run : "true" , Env : map [string ]string {"STEP1_VAR" : "secret" }},
138+ {Name : "Step 2" , Check : "false" , Run : "echo [$STEP1_VAR] > " + marker },
139+ }
140+ err := RunBootstrap (context .Background (), "." , steps , nil )
141+ require .NoError (t , err )
142+ data , err := os .ReadFile (marker )
143+ require .NoError (t , err )
144+ assert .Contains (t , string (data ), "[]" )
145+ }
146+
71147func TestBootstrapPromptSkipsInNonTTY (t * testing.T ) {
72148 steps := []config.BootstrapStep {
73149 {Name : "Needs input" , Check : "false" , Prompt : "Paste key:" , Run : "true" },
0 commit comments