docker / docker/buildx

Bake: Add a built-in function for running shell commands and scripts.

Open
#2,776 3 comments 19 reactions 2 assignees View on GitHub

@crazy-max is already working on this.

Since Nov 13, 2024.

kind/enhancement status/triage
Dominant language
Go
Stars
4.5k
Forks
682
Avg merge
2d 14h
Merged PRs (30d)
29

Description

Description

Issue

Bake quickly becomes a preferred solution for running CI/CD and local tasks. However, sometimes, we need to run a pre-task, like fetching the current Git commit reference or setting up custom environment variables. Currently, Bake doesn’t offer a built-in way to handle these tasks, making it difficult to gather this information on the fly. As a result, users have to rely on external tools or scripts to complete setup tasks.

Proposal

The goal of this proposal is to add a built-in function to run shell commands and scripts. This feature would let users handle tasks like setting up variables/gathering info without needing extra tools like Makefile and keeping workflows in one place.

To address this, I propose adding a new built-in function to the hclparser stdlib. This function would be similar to other built-ins in stdlib.go and would leverage "github.com/mvdan/sh" to execute shell commands.

func shellFunc() function.Function {
	return function.New(&function.Spec{
		Params: []function.Parameter{
			{
				Name: "script",
				Type: cty.String,
			},
		},
		Type: function.StaticReturnType(cty.String),
		Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
			script := args[0].AsString()

			var buf bytes.Buffer

                        	r, err := interp.New(
                          		interp.Env(expand.ListEnviron(os.Environ()...)),
                          		interp.ExecHandlers(func(next interp.ExecHandlerFunc) interp.ExecHandlerFunc {
                          			return interp.DefaultExecHandler(10 * time.Second)
                          		}),
                          		interp.StdIO(nil, &buf, &buf),
                          		interp.Dir(s.Dir),
                	)
                
                	if err != nil {
                		return err
                	}
                
                	parser := syntax.NewParser()
                       p, err := parser.Parse(strings.NewReader(script), "")
                	if err != nil {
                		return err
                	}

			if err := r.Run(ctx, p); err != nil {
				return cty.NilVal, fmt.Errorf("%w:%s", err, buf.String())
			}

			return cty.StringVal(buf.String()), nil
		},
	})
}
target "default" {
  output = ["type=image,name=foo"]
  annotations = [shell("git log --pretty=format:'%h' -n 1")]
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.