diff --git a/README.md b/README.md index 7b36732..506346e 100644 --- a/README.md +++ b/README.md @@ -80,16 +80,29 @@ _(As a convention in the list below, all task parameters are specified with a * `$BUILD_ARG_*`: params prefixed with `BUILD_ARG_` will be provided as build args. For example `BUILD_ARG_foo=bar`, will set the `foo` build arg as `bar`. -* `$BUILD_ARGS_FILE` (default empty): path to a file containing build args in - the form `foo=bar`, one per line. Empty lines are skipped. +* `$BUILD_ARGS_FILE` (default empty): path to a file containing build args. By + default the task will assume each line is in the form `foo=bar`, one per + line. Empty lines are skipped. If the file ends in `yml` or `yaml` it will + be parsed as a YAML file. The YAML file can only contain string keys and + values. - Example file contents: + Example simple file contents: ``` - EMAIL=me@yopmail.com + EMAIL=me@example.com HOW_MANY_THINGS=1 DO_THING=false ``` + Example YAML file contents: + + ```yaml + EMAIL: me@example.com + HOW_MANY_THINGS: "1" + DO_THING: "false" + MULTI_LINE_ARG: | + thing1 + thing2 + ``` * `$BUILDKIT_SECRET_*`: files with extra secrets which are made available via `--mount=type=secret,id=...`. See [New Docker Build secret information](https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information) for more information on build secrets. diff --git a/go.mod b/go.mod index 1d5f2e1..295b270 100644 --- a/go.mod +++ b/go.mod @@ -38,5 +38,5 @@ require ( golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/term v0.25.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/yaml.v3 v3.0.1 ) diff --git a/task.go b/task.go index 9de7e2a..15e8d9d 100644 --- a/task.go +++ b/task.go @@ -3,6 +3,7 @@ package task import ( "encoding/json" "fmt" + "gopkg.in/yaml.v3" "io" "os" "os/exec" @@ -373,13 +374,24 @@ func sanitize(cfg *Config) error { return errors.Wrap(err, "read build args file") } - for _, arg := range strings.Split(string(buildArgs), "\n") { - if len(arg) == 0 { - // skip blank lines - continue + if strings.HasSuffix(cfg.BuildArgsFile, ".yml") || strings.HasSuffix(cfg.BuildArgsFile, ".yaml") { + var buildArgsData map[string]string + err = yaml.Unmarshal(buildArgs, &buildArgsData) + if err != nil { + return errors.Wrap(err, "read build args yaml file") } + for key, arg := range buildArgsData { + cfg.BuildArgs = append(cfg.BuildArgs, key + "=" + arg) + } + } else { + for _, arg := range strings.Split(string(buildArgs), "\n") { + if len(arg) == 0 { + // skip blank lines + continue + } - cfg.BuildArgs = append(cfg.BuildArgs, arg) + cfg.BuildArgs = append(cfg.BuildArgs, arg) + } } } diff --git a/task_test.go b/task_test.go index 2681bda..999c184 100644 --- a/task_test.go +++ b/task_test.go @@ -152,6 +152,15 @@ func (s *TaskSuite) TestBuildArgsFile() { s.NoError(err) } +func (s *TaskSuite) TestBuildArgsYamlFile() { + s.req.Config.ContextDir = "testdata/build-args" + s.req.Config.BuildArgsFile = "testdata/build-args/build_args_file.yaml" + + // the Dockerfile itself asserts that the arg has been received + _, err := s.build() + s.NoError(err) +} + func (s *TaskSuite) TestBuildArgsStaticAndFile() { s.req.Config.ContextDir = "testdata/build-args" s.req.Config.BuildArgs = []string{"some_arg=some_value"} diff --git a/testdata/build-args/build_args_file.yaml b/testdata/build-args/build_args_file.yaml new file mode 100644 index 0000000..d1fb8ac --- /dev/null +++ b/testdata/build-args/build_args_file.yaml @@ -0,0 +1,2 @@ +some_arg: some_value +some_other_arg: some_other_value