diff --git a/node/dagger.json b/node/dagger.json index d810f51..c395bfa 100644 --- a/node/dagger.json +++ b/node/dagger.json @@ -8,6 +8,10 @@ { "name": "autodetection", "source": "../autodetection" + }, + { + "name": "utils", + "source": "../utils" } ], "source": "dagger", diff --git a/node/dagger/main.go b/node/dagger/main.go index 184e615..b9ef884 100644 --- a/node/dagger/main.go +++ b/node/dagger/main.go @@ -79,6 +79,35 @@ func (n *Node) SetupSystem( return n } +// Add a new environment variable for the container +func (n *Node) WithEnvVar( + name string, + // Indicate the value of the env var + // +optional + value string, + // Indicate the env var is a secret with this value + // +optional + secret *dagger.Secret, +) *Node { + if value != "" { + n.Ctr = n.Ctr.WithEnvVariable(name, value) + } else { + n.Ctr = n.Ctr.WithSecretVariable(name, secret) + } + + return n +} + +// Add a new environment variable for the container +func (n *Node) WithDotEnv( + // Dotenv format data to inject as environment variables as secret + data *dagger.Secret, +) *Node { + n.Ctr = dag.Utils().WithDotEnvSecret(n.Ctr, data) + + return n +} + // Execute all commands func (n *Node) Do(ctx context.Context) (string, error) { return n.Ctr.Stdout(ctx) diff --git a/node/dagger/node.go b/node/dagger/node.go index 7573db5..969d257 100644 --- a/node/dagger/node.go +++ b/node/dagger/node.go @@ -2,11 +2,13 @@ package main import ( "context" + "fmt" "github.com/google/uuid" "golang.org/x/sync/errgroup" "main/internal/dagger" "path/filepath" "strconv" + "strings" ) // Return the Node container with the right base image @@ -26,7 +28,7 @@ func (n *Node) WithVersion( if isAlpine { baseImage += "-alpine" } - n.Ctr = dag.Container().From(baseImage) + n.Ctr = dag.Container().From(baseImage).WithExec([]string{"mkdir", "/outputs"}) n.BaseImageRef = baseImage @@ -284,6 +286,8 @@ func (n *Node) prepareWorkspaceYarnOption() []string { func (n *Node) Run( // Command from the package.json to run command []string, + // Indicate if we want to capture in /outputs the stdout + exit code in order to extract the folder + captureOutput bool, ) *Node { baseCommand := []string{n.PkgMgr} @@ -298,10 +302,22 @@ func (n *Node) Run( } } - baseCommand = append(baseCommand, "run") + baseCommand = append(append(baseCommand, "run"), command...) + + if captureOutput { + baseCommand = []string{ + "sh", + "-c", + fmt.Sprintf( + "{ %s 2>&1; echo -n $? > /outputs/exit_code; } | tee /outputs/output.txt", + strings.Join(baseCommand, " "), + ), + } + } + n.Ctr = n. Ctr. - WithExec(append(baseCommand, command...)) + WithExec(baseCommand) return n } @@ -312,25 +328,39 @@ func (n *Node) Install() *Node { } // Execute lint command -func (n *Node) Lint() *Node { - return n.Run([]string{"lint"}) +func (n *Node) Lint( + // Indicate if we want to capture in /outputs the stdout + exit code in order to extract the folder + // +optional + // +default=false + captureOutput bool, +) *Node { + return n.Run([]string{"lint"}, captureOutput) } // Execute test command -func (n *Node) Test() *Node { - return n.Run([]string{"test"}) +func (n *Node) Test( + // Indicate if we want to capture in /outputs the stdout + exit code in order to extract the folder + // +optional + // +default=false + captureOutput bool, +) *Node { + return n.Run([]string{"test"}, captureOutput) } // Execute test commands in parallel func (n *Node) ParallelTest( ctx context.Context, cmds [][]string, + // Indicate if we want to capture in /outputs the stdout + exit code in order to extract the folder + // +optional + // +default=false + captureOutput bool, ) error { var eg errgroup.Group for _, cmd := range cmds { eg.Go(func() error { - _, err := n.Run(cmd).Do(ctx) + _, err := n.Run(cmd, captureOutput).Do(ctx) return err }) } @@ -339,13 +369,23 @@ func (n *Node) ParallelTest( } // Execute clean command -func (n *Node) Clean() *Node { - return n.Run([]string{"clean"}) +func (n *Node) Clean( + // Indicate if we want to capture in /outputs the stdout + exit code in order to extract the folder + // +optional + // +default=false + captureOutput bool, +) *Node { + return n.Run([]string{"clean"}, captureOutput) } // Execute the build command -func (n *Node) Build() *Node { - return n.Run([]string{"build"}) +func (n *Node) Build( + // Indicate if we want to capture in /outputs the stdout + exit code in order to extract the folder + // +optional + // +default=false + captureOutput bool, +) *Node { + return n.Run([]string{"build"}, captureOutput) } // Execute the publish which push a package to a registry diff --git a/node/dagger/pipeline.go b/node/dagger/pipeline.go index 5ec9d10..373d4e7 100644 --- a/node/dagger/pipeline.go +++ b/node/dagger/pipeline.go @@ -48,24 +48,26 @@ func (n *Node) Pipeline( ) (string, error) { pipeline := n.Install() + // TODO(how we handle capture output later define if we keep this function or change the return type for Node then user decide what to do) + for _, hook := range preHooks { - pipeline = pipeline.Run(hook) + pipeline = pipeline.Run(hook, false) } if n.DetectLint { - pipeline = pipeline.Lint() + pipeline = pipeline.Lint(false) } if n.DetectTest { - pipeline = pipeline.Test() + pipeline = pipeline.Test(false) } // TODO(Move it at the end) for _, hook := range postHooks { - pipeline = pipeline.Run(hook) + pipeline = pipeline.Run(hook, false) } - pipeline = pipeline.Build() + pipeline = pipeline.Build(false) if n.DetectPackage { return pipeline. diff --git a/node/dagger/utils.go b/node/dagger/utils.go index fb94bcf..f204670 100644 --- a/node/dagger/utils.go +++ b/node/dagger/utils.go @@ -7,9 +7,17 @@ func (n *Node) Container() *dagger.Container { return n.Ctr } -// Return the current working directory -func (n *Node) Directory() *dagger.Directory { - return n.Ctr.Directory(workdir) +// Return a directory by default the current working directory +func (n *Node) Directory( + // Define permission on the package in the registry + // +optional + path string, +) *dagger.Directory { + if path == "" { + return n.Ctr.Directory(workdir) + } + + return n.Ctr.Directory(path) } // Open a shell in the current container or execute a command inside it, like node