Skip to content

Commit 6ce45e3

Browse files
wildsheepzkuanyong-wong-partiorChristopherHX
authored
feature: Add support for github action variables (#1833)
* feature: Add support for github action variables * add --var flag for github variables * unitests: Updated unittests to cover vars context. * Remove syntax extension for vars and correct unit tests * Update pkg/runner/expression.go Co-authored-by: ChristopherHX <[email protected]> --------- Co-authored-by: kuanyong-wong-partior <[email protected]> Co-authored-by: ChristopherHX <[email protected]>
1 parent 3ac2b72 commit 6ce45e3

File tree

7 files changed

+38
-0
lines changed

7 files changed

+38
-0
lines changed

cmd/input.go

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type Input struct {
1616
reuseContainers bool
1717
bindWorkdir bool
1818
secrets []string
19+
vars []string
1920
envs []string
2021
inputs []string
2122
platforms []string
@@ -26,6 +27,7 @@ type Input struct {
2627
envfile string
2728
inputfile string
2829
secretfile string
30+
varfile string
2931
insecureSecrets bool
3032
defaultBranch string
3133
privileged bool
@@ -78,6 +80,10 @@ func (i *Input) Secretfile() string {
7880
return i.resolve(i.secretfile)
7981
}
8082

83+
func (i *Input) Varfile() string {
84+
return i.resolve(i.varfile)
85+
}
86+
8187
// Workdir returns path to workdir
8288
func (i *Input) Workdir() string {
8389
return i.resolve(".")

cmd/root.go

+7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ func Execute(ctx context.Context, version string) {
4949

5050
rootCmd.Flags().StringVar(&input.remoteName, "remote-name", "origin", "git remote name that will be used to retrieve url of git repo")
5151
rootCmd.Flags().StringArrayVarP(&input.secrets, "secret", "s", []string{}, "secret to make available to actions with optional value (e.g. -s mysecret=foo or -s mysecret)")
52+
rootCmd.Flags().StringArrayVar(&input.vars, "var", []string{}, "variable to make available to actions with optional value (e.g. --var myvar=foo or --var myvar)")
5253
rootCmd.Flags().StringArrayVarP(&input.envs, "env", "", []string{}, "env to make available to actions with optional value (e.g. --env myenv=foo or --env myenv)")
5354
rootCmd.Flags().StringArrayVarP(&input.inputs, "input", "", []string{}, "action input to make available to actions (e.g. --input myinput=foo)")
5455
rootCmd.Flags().StringArrayVarP(&input.platforms, "platform", "P", []string{}, "custom image to use per platform (e.g. -P ubuntu-18.04=nektos/act-environments-ubuntu:18.04)")
@@ -77,6 +78,7 @@ func Execute(ctx context.Context, version string) {
7778
rootCmd.PersistentFlags().BoolVarP(&input.noOutput, "quiet", "q", false, "disable logging of output from steps")
7879
rootCmd.PersistentFlags().BoolVarP(&input.dryrun, "dryrun", "n", false, "dryrun mode")
7980
rootCmd.PersistentFlags().StringVarP(&input.secretfile, "secret-file", "", ".secrets", "file with list of secrets to read from (e.g. --secret-file .secrets)")
81+
rootCmd.PersistentFlags().StringVarP(&input.varfile, "var-file", "", ".vars", "file with list of vars to read from (e.g. --var-file .vars)")
8082
rootCmd.PersistentFlags().BoolVarP(&input.insecureSecrets, "insecure-secrets", "", false, "NOT RECOMMENDED! Doesn't hide secrets while printing logs.")
8183
rootCmd.PersistentFlags().StringVarP(&input.envfile, "env-file", "", ".env", "environment file to read and use as env in the containers")
8284
rootCmd.PersistentFlags().StringVarP(&input.inputfile, "input-file", "", ".input", "input file to read and use as action input")
@@ -418,6 +420,10 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
418420
secrets := newSecrets(input.secrets)
419421
_ = readEnvs(input.Secretfile(), secrets)
420422

423+
log.Debugf("Loading vars from %s", input.Varfile())
424+
vars := newSecrets(input.vars)
425+
_ = readEnvs(input.Varfile(), vars)
426+
421427
matrixes := parseMatrix(input.matrix)
422428
log.Debugf("Evaluated matrix inclusions: %v", matrixes)
423429

@@ -579,6 +585,7 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
579585
JSONLogger: input.jsonLogger,
580586
Env: envs,
581587
Secrets: secrets,
588+
Vars: vars,
582589
Inputs: inputs,
583590
Token: secrets["GITHUB_TOKEN"],
584591
InsecureSecrets: input.insecureSecrets,

pkg/exprparser/interpreter.go

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type EvaluationEnvironment struct {
1919
Steps map[string]*model.StepResult
2020
Runner map[string]interface{}
2121
Secrets map[string]string
22+
Vars map[string]string
2223
Strategy map[string]interface{}
2324
Matrix map[string]interface{}
2425
Needs map[string]Needs
@@ -148,6 +149,7 @@ func (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode) (interfa
148149
}
149150
}
150151

152+
// nolint:gocyclo
151153
func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableNode) (interface{}, error) {
152154
switch strings.ToLower(variableNode.Name) {
153155
case "github":
@@ -167,6 +169,8 @@ func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableN
167169
return impl.env.Runner, nil
168170
case "secrets":
169171
return impl.env.Secrets, nil
172+
case "vars":
173+
return impl.env.Vars, nil
170174
case "strategy":
171175
return impl.env.Strategy, nil
172176
case "matrix":

pkg/exprparser/interpreter_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ func TestContexts(t *testing.T) {
557557
// {"contains(steps.*.outputs.name, 'value')", true, "steps-context-array-outputs"},
558558
{"runner.os", "Linux", "runner-context"},
559559
{"secrets.name", "value", "secrets-context"},
560+
{"vars.name", "value", "vars-context"},
560561
{"strategy.fail-fast", true, "strategy-context"},
561562
{"matrix.os", "Linux", "matrix-context"},
562563
{"needs.job-id.outputs.output-name", "value", "needs-context"},
@@ -593,6 +594,9 @@ func TestContexts(t *testing.T) {
593594
Secrets: map[string]string{
594595
"name": "value",
595596
},
597+
Vars: map[string]string{
598+
"name": "value",
599+
},
596600
Strategy: map[string]interface{}{
597601
"fail-fast": true,
598602
},

pkg/runner/expression.go

+6
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ func (rc *RunContext) NewExpressionEvaluatorWithEnv(ctx context.Context, env map
7777
// but required to interpolate/evaluate the step outputs on the job
7878
Steps: rc.getStepsContext(),
7979
Secrets: getWorkflowSecrets(ctx, rc),
80+
Vars: getWorkflowVars(ctx, rc),
8081
Strategy: strategy,
8182
Matrix: rc.Matrix,
8283
Needs: using,
@@ -124,6 +125,7 @@ func (rc *RunContext) NewStepExpressionEvaluator(ctx context.Context, step step)
124125
Job: rc.getJobContext(),
125126
Steps: rc.getStepsContext(),
126127
Secrets: getWorkflowSecrets(ctx, rc),
128+
Vars: getWorkflowVars(ctx, rc),
127129
Strategy: strategy,
128130
Matrix: rc.Matrix,
129131
Needs: using,
@@ -483,3 +485,7 @@ func getWorkflowSecrets(ctx context.Context, rc *RunContext) map[string]string {
483485

484486
return rc.Config.Secrets
485487
}
488+
489+
func getWorkflowVars(ctx context.Context, rc *RunContext) map[string]string {
490+
return rc.Config.Vars
491+
}

pkg/runner/expression_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ func createRunContext(t *testing.T) *RunContext {
2828
Secrets: map[string]string{
2929
"CASE_INSENSITIVE_SECRET": "value",
3030
},
31+
Vars: map[string]string{
32+
"CASE_INSENSITIVE_VAR": "value",
33+
},
3134
},
3235
Env: map[string]string{
3336
"key": "value",
@@ -122,6 +125,8 @@ func TestEvaluateRunContext(t *testing.T) {
122125
{"env.key", "value", ""},
123126
{"secrets.CASE_INSENSITIVE_SECRET", "value", ""},
124127
{"secrets.case_insensitive_secret", "value", ""},
128+
{"vars.CASE_INSENSITIVE_VAR", "value", ""},
129+
{"vars.case_insensitive_var", "value", ""},
125130
{"format('{{0}}', 'test')", "{0}", ""},
126131
{"format('{{{0}}}', 'test')", "{test}", ""},
127132
{"format('}}')", "}", ""},
@@ -195,6 +200,9 @@ func TestInterpolate(t *testing.T) {
195200
Secrets: map[string]string{
196201
"CASE_INSENSITIVE_SECRET": "value",
197202
},
203+
Vars: map[string]string{
204+
"CASE_INSENSITIVE_VAR": "value",
205+
},
198206
},
199207
Env: map[string]string{
200208
"KEYWITHNOTHING": "valuewithnothing",
@@ -229,6 +237,8 @@ func TestInterpolate(t *testing.T) {
229237
{" ${{ env.KEY_WITH_UNDERSCORES }} ", " value_with_underscores "},
230238
{"${{ secrets.CASE_INSENSITIVE_SECRET }}", "value"},
231239
{"${{ secrets.case_insensitive_secret }}", "value"},
240+
{"${{ vars.CASE_INSENSITIVE_VAR }}", "value"},
241+
{"${{ vars.case_insensitive_var }}", "value"},
232242
{"${{ env.UNKNOWN }}", ""},
233243
{"${{ env.SOMETHING_TRUE }}", "true"},
234244
{"${{ env.SOMETHING_FALSE }}", "false"},

pkg/runner/runner.go

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type Config struct {
3434
Env map[string]string // env for containers
3535
Inputs map[string]string // manually passed action inputs
3636
Secrets map[string]string // list of secrets
37+
Vars map[string]string // list of vars
3738
Token string // GitHub token
3839
InsecureSecrets bool // switch hiding output when printing to terminal
3940
Platforms map[string]string // list of platforms

0 commit comments

Comments
 (0)