From 49386366707baba8a34061c465f3626d79453b35 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 5 Apr 2023 12:30:32 +0200 Subject: [PATCH 01/34] chore: reset repo --- .github/workflows/release.yaml | 41 ---------------------------------- 1 file changed, 41 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 92834da..260ceaa 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,18 +17,11 @@ jobs: - name: Install Cosign uses: sigstore/cosign-installer@v2.5.0 - - name: Install Chainloop - run: | - curl -sfL https://docs.chainloop.dev/install.sh | bash -s -- --version v${{ env.CHAINLOOP_VERSION }} - - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Initialize Attestation - run: chainloop attestation init # --contract-revision 2 - - name: Set up Go uses: actions/setup-go@v3 with: @@ -61,37 +54,3 @@ jobs: output-file: /tmp/sbom.cyclonedx.json env: IMAGE: ghcr.io/chainloop-dev/integration-demo:${{ github.ref_name }} - - - name: Add Container Image Artifact - run: chainloop attestation add --name image --value ghcr.io/chainloop-dev/integration-demo:${{ github.ref_name }} - - - name: Add SBOM Artifact - run: chainloop attestation add --name sbom --value /tmp/sbom.cyclonedx.json - - - name: Add Binary Artifact - run: | - BINARY_PATH="$(echo -n '${{ steps.release.outputs.metadata }}' | jq -r '"dist/" + .project_name + "_" + .version + "_" + .runtime.goos + "_" + .runtime.goarch + ".tar.gz"')" - - chainloop attestation add --name binary --value ${BINARY_PATH} - - - name: Finish and Record Attestation - if: ${{ success() }} - run: | - chainloop attestation status --full - chainloop attestation push --key env://CHAINLOOP_SIGNING_KEY - env: - CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} - CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} - - - name: Mark attestation as failed - if: ${{ failure() }} - run: | - chainloop attestation reset - - - name: Mark attestation as cancelled - if: ${{ cancelled() }} - run: | - chainloop attestation reset --trigger cancellation - env: - CHAINLOOP_VERSION: 0.8.95 - CHAINLOOP_ROBOT_ACCOUNT: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} From 14f3c5585ebc559a96821969fc7d5788c9200fe5 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 5 Apr 2023 12:35:39 +0200 Subject: [PATCH 02/34] chore(ci): integrate chainloop --- .github/workflows/release.yaml | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 260ceaa..a0923b3 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,11 +17,18 @@ jobs: - name: Install Cosign uses: sigstore/cosign-installer@v2.5.0 + - name: Install Chainloop + run: | + curl -sfL https://docs.chainloop.dev/install.sh | bash -s -- --version v${{ env.CHAINLOOP_VERSION }} + - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 0 + - name: Initialize Attestation + run: chainloop attestation init # --contract-revision 2 + - name: Set up Go uses: actions/setup-go@v3 with: @@ -54,3 +61,37 @@ jobs: output-file: /tmp/sbom.cyclonedx.json env: IMAGE: ghcr.io/chainloop-dev/integration-demo:${{ github.ref_name }} + + - name: Add Container Image Artifact + run: chainloop attestation add --name image --value ghcr.io/chainloop-dev/integration-demo:${{ github.ref_name }} + + - name: Add SBOM Artifact + run: chainloop attestation add --name sbom --value /tmp/sbom.cyclonedx.json + + - name: Add Binary Artifact + run: | + BINARY_PATH="$(echo -n '${{ steps.release.outputs.metadata }}' | jq -r '"dist/" + .project_name + "_" + .version + "_" + .runtime.goos + "_" + .runtime.goarch + ".tar.gz"')" + + chainloop attestation add --name binary --value ${BINARY_PATH} + + - name: Finish and Record Attestation + if: ${{ success() }} + run: | + chainloop attestation status --full + chainloop attestation push --key env://CHAINLOOP_SIGNING_KEY + env: + CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} + CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + + - name: Mark attestation as failed + if: ${{ failure() }} + run: | + chainloop attestation reset + + - name: Mark attestation as cancelled + if: ${{ cancelled() }} + run: | + chainloop attestation reset --trigger cancellation + env: + CHAINLOOP_VERSION: 0.8.92 + CHAINLOOP_ROBOT_ACCOUNT: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} From 0c10ea44fd54d2126d1400258c72c264529c8be9 Mon Sep 17 00:00:00 2001 From: Daniel Liszka Date: Fri, 19 May 2023 18:04:11 +0200 Subject: [PATCH 03/34] fix(ci): bump to cosign 2.0 (#117) Signed-off-by: Daniel Liszka --- .github/workflows/release.yaml | 6 ++++-- .goreleaser.yml | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a0923b3..1a91c6d 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -15,7 +15,9 @@ jobs: contents: write # required for goreleaser steps: - name: Install Cosign - uses: sigstore/cosign-installer@v2.5.0 + uses: sigstore/cosign-installer@main + with: + cosign-release: 'v2.0.2' - name: Install Chainloop run: | @@ -93,5 +95,5 @@ jobs: run: | chainloop attestation reset --trigger cancellation env: - CHAINLOOP_VERSION: 0.8.92 + CHAINLOOP_VERSION: 0.9.1 CHAINLOOP_ROBOT_ACCOUNT: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} diff --git a/.goreleaser.yml b/.goreleaser.yml index bba9d0e..6127515 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -16,13 +16,14 @@ signs: "sign-blob", "--key=env://COSIGN_PRIVATE_KEY", "--output-signature=${signature}", + "--yes", "${artifact}", ] artifacts: all docker_signs: - cmd: cosign - args: ["sign", "--key=env://COSIGN_PRIVATE_KEY", "${artifact}"] + args: ["sign", "--yes", "--key=env://COSIGN_PRIVATE_KEY", "${artifact}"] artifacts: all dockers: From bffc3c4bf7510167ffc64b430f6f54844b483200 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Fri, 30 Jun 2023 12:25:54 +0200 Subject: [PATCH 04/34] bump chainloop Signed-off-by: Miguel Martinez Trivino --- .github/workflows/release.yaml | 2 +- chainloop-demo/github-workflow/release.v1.yaml | 2 +- chainloop-demo/github-workflow/release.v2.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 1a91c6d..c92d6a7 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -95,5 +95,5 @@ jobs: run: | chainloop attestation reset --trigger cancellation env: - CHAINLOOP_VERSION: 0.9.1 + CHAINLOOP_VERSION: 0.12.0 CHAINLOOP_ROBOT_ACCOUNT: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} diff --git a/chainloop-demo/github-workflow/release.v1.yaml b/chainloop-demo/github-workflow/release.v1.yaml index 36fac53..b813927 100644 --- a/chainloop-demo/github-workflow/release.v1.yaml +++ b/chainloop-demo/github-workflow/release.v1.yaml @@ -81,5 +81,5 @@ jobs: run: | chainloop attestation reset --trigger cancellation env: - CHAINLOOP_VERSION: 0.8.92 + CHAINLOOP_VERSION: 0.12.0 CHAINLOOP_ROBOT_ACCOUNT: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} diff --git a/chainloop-demo/github-workflow/release.v2.yaml b/chainloop-demo/github-workflow/release.v2.yaml index a0923b3..8e154ff 100644 --- a/chainloop-demo/github-workflow/release.v2.yaml +++ b/chainloop-demo/github-workflow/release.v2.yaml @@ -93,5 +93,5 @@ jobs: run: | chainloop attestation reset --trigger cancellation env: - CHAINLOOP_VERSION: 0.8.92 + CHAINLOOP_VERSION: 0.12.0 CHAINLOOP_ROBOT_ACCOUNT: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} From 14a154c83ea0f8d9520c4756d571016c058f97c3 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Fri, 30 Jun 2023 12:30:07 +0200 Subject: [PATCH 05/34] add spdx demo Signed-off-by: Miguel Martinez Trivino --- .github/workflows/release.yaml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c92d6a7..aac747f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -64,12 +64,24 @@ jobs: env: IMAGE: ghcr.io/chainloop-dev/integration-demo:${{ github.ref_name }} + - uses: anchore/sbom-action@v0 + with: + image: ${{ env.IMAGE }} + format: spdx-json + artifact-name: sbom.spdx.json + output-file: /tmp/sbom.spdx.json + env: + IMAGE: ghcr.io/chainloop-dev/integration-demo:${{ github.ref_name }} + - name: Add Container Image Artifact run: chainloop attestation add --name image --value ghcr.io/chainloop-dev/integration-demo:${{ github.ref_name }} - - name: Add SBOM Artifact + - name: Add CycloneDX SBOM Artifact run: chainloop attestation add --name sbom --value /tmp/sbom.cyclonedx.json + - name: Add SPDX SBOM Artifact + run: chainloop attestation add --name sbom --value /tmp/sbom.spdx.json + - name: Add Binary Artifact run: | BINARY_PATH="$(echo -n '${{ steps.release.outputs.metadata }}' | jq -r '"dist/" + .project_name + "_" + .version + "_" + .runtime.goos + "_" + .runtime.goarch + ".tar.gz"')" From ff6700b543418c36fb7d1e957a78c972282de318 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Fri, 30 Jun 2023 12:33:09 +0200 Subject: [PATCH 06/34] add spdx demo Signed-off-by: Miguel Martinez Trivino --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index aac747f..0661961 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -80,7 +80,7 @@ jobs: run: chainloop attestation add --name sbom --value /tmp/sbom.cyclonedx.json - name: Add SPDX SBOM Artifact - run: chainloop attestation add --name sbom --value /tmp/sbom.spdx.json + run: chainloop attestation add --name sbom-spdx --value /tmp/sbom.spdx.json - name: Add Binary Artifact run: | From 94b7442e3f11fc6f584d540ea0d439b02088305a Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 18:01:36 +0100 Subject: [PATCH 07/34] add integration demo Signed-off-by: Miguel Martinez Trivino --- chainloop-demo/dagger/.gitattributes | 2 + .../dagger/build-and-release/dagger.gen.go | 7044 +++++++++++++++++ .../dagger/build-and-release/main.go | 11 + .../build-and-release/querybuilder/marshal.go | 162 + .../querybuilder/querybuilder.go | 183 + chainloop-demo/dagger/dagger.json | 12 + go.mod | 10 + go.sum | 20 + 8 files changed, 7444 insertions(+) create mode 100644 chainloop-demo/dagger/.gitattributes create mode 100644 chainloop-demo/dagger/build-and-release/dagger.gen.go create mode 100644 chainloop-demo/dagger/build-and-release/main.go create mode 100644 chainloop-demo/dagger/build-and-release/querybuilder/marshal.go create mode 100644 chainloop-demo/dagger/build-and-release/querybuilder/querybuilder.go create mode 100644 chainloop-demo/dagger/dagger.json diff --git a/chainloop-demo/dagger/.gitattributes b/chainloop-demo/dagger/.gitattributes new file mode 100644 index 0000000..bd21599 --- /dev/null +++ b/chainloop-demo/dagger/.gitattributes @@ -0,0 +1,2 @@ +/dagger.gen.go linguist-generated +/querybuilder/** linguist-generated diff --git a/chainloop-demo/dagger/build-and-release/dagger.gen.go b/chainloop-demo/dagger/build-and-release/dagger.gen.go new file mode 100644 index 0000000..91768c2 --- /dev/null +++ b/chainloop-demo/dagger/build-and-release/dagger.gen.go @@ -0,0 +1,7044 @@ +// Code generated by dagger. DO NOT EDIT. + +package main + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net" + "net/http" + "os" + "reflect" + "strconv" + "strings" + + "github.com/Khan/genqlient/graphql" + "github.com/vektah/gqlparser/v2/gqlerror" + + "github.com/chainloop-dev/integration-demo/chainloop-demo/dagger/build-and-release/querybuilder" +) + +// assertNotNil panic if the given value is nil. +// This function is used to validate that input with pointer type are not nil. +// See https://github.com/dagger/dagger/issues/5696 for more context. +func assertNotNil(argName string, value any) { + // We use reflect because just comparing value to nil is not working since + // the value is wrapped into a type when passed as parameter. + // E.g., nil become (*dagger.File)(nil). + if reflect.ValueOf(value).IsNil() { + panic(fmt.Sprintf("unexpected nil pointer for argument %q", argName)) + } +} + +// ptr returns a pointer to the given value. +func ptr[T any](v T) *T { + return &v +} + +type DaggerObject querybuilder.GraphQLMarshaller + +func convertSlice[I any, O any](in []I, f func(I) O) []O { + out := make([]O, len(in)) + for i, v := range in { + out[i] = f(v) + } + return out +} + +// getCustomError parses a GraphQL error into a more specific error type. +func getCustomError(err error) error { + var gqlErr *gqlerror.Error + + if !errors.As(err, &gqlErr) { + return nil + } + + ext := gqlErr.Extensions + + typ, ok := ext["_type"].(string) + if !ok { + return nil + } + + if typ == "EXEC_ERROR" { + e := &ExecError{ + original: err, + } + if code, ok := ext["exitCode"].(float64); ok { + e.ExitCode = int(code) + } + if args, ok := ext["cmd"].([]interface{}); ok { + cmd := make([]string, len(args)) + for i, v := range args { + cmd[i] = v.(string) + } + e.Cmd = cmd + } + if stdout, ok := ext["stdout"].(string); ok { + e.Stdout = stdout + } + if stderr, ok := ext["stderr"].(string); ok { + e.Stderr = stderr + } + return e + } + + return nil +} + +// ExecError is an API error from an exec operation. +type ExecError struct { + original error + Cmd []string + ExitCode int + Stdout string + Stderr string +} + +func (e *ExecError) Error() string { + // As a default when just printing the error, include the stdout + // and stderr for visibility + msg := e.Message() + if strings.TrimSpace(e.Stdout) != "" { + msg += "\nStdout:\n" + e.Stdout + } + if strings.TrimSpace(e.Stderr) != "" { + msg += "\nStderr:\n" + e.Stderr + } + return msg +} + +func (e *ExecError) Message() string { + return e.original.Error() +} + +func (e *ExecError) Unwrap() error { + return e.original +} + +// The `CacheVolumeID` scalar type represents an identifier for an object of type CacheVolume. +type CacheVolumeID string + +// The `ContainerID` scalar type represents an identifier for an object of type Container. +type ContainerID string + +// The `CurrentModuleID` scalar type represents an identifier for an object of type CurrentModule. +type CurrentModuleID string + +// The `DirectoryID` scalar type represents an identifier for an object of type Directory. +type DirectoryID string + +// The `EnvVariableID` scalar type represents an identifier for an object of type EnvVariable. +type EnvVariableID string + +// The `FieldTypeDefID` scalar type represents an identifier for an object of type FieldTypeDef. +type FieldTypeDefID string + +// The `FileID` scalar type represents an identifier for an object of type File. +type FileID string + +// The `FunctionArgID` scalar type represents an identifier for an object of type FunctionArg. +type FunctionArgID string + +// The `FunctionCallArgValueID` scalar type represents an identifier for an object of type FunctionCallArgValue. +type FunctionCallArgValueID string + +// The `FunctionCallID` scalar type represents an identifier for an object of type FunctionCall. +type FunctionCallID string + +// The `FunctionID` scalar type represents an identifier for an object of type Function. +type FunctionID string + +// The `GeneratedCodeID` scalar type represents an identifier for an object of type GeneratedCode. +type GeneratedCodeID string + +// The `GitModuleSourceID` scalar type represents an identifier for an object of type GitModuleSource. +type GitModuleSourceID string + +// The `GitRefID` scalar type represents an identifier for an object of type GitRef. +type GitRefID string + +// The `GitRepositoryID` scalar type represents an identifier for an object of type GitRepository. +type GitRepositoryID string + +// The `GolangID` scalar type represents an identifier for an object of type Golang. +type GolangID string + +// The `InputTypeDefID` scalar type represents an identifier for an object of type InputTypeDef. +type InputTypeDefID string + +// The `InterfaceTypeDefID` scalar type represents an identifier for an object of type InterfaceTypeDef. +type InterfaceTypeDefID string + +// An arbitrary JSON-encoded value. +type JSON string + +// The `LabelID` scalar type represents an identifier for an object of type Label. +type LabelID string + +// The `ListTypeDefID` scalar type represents an identifier for an object of type ListTypeDef. +type ListTypeDefID string + +// The `LocalModuleSourceID` scalar type represents an identifier for an object of type LocalModuleSource. +type LocalModuleSourceID string + +// The `ModuleDependencyID` scalar type represents an identifier for an object of type ModuleDependency. +type ModuleDependencyID string + +// The `ModuleID` scalar type represents an identifier for an object of type Module. +type ModuleID string + +// The `ModuleSourceID` scalar type represents an identifier for an object of type ModuleSource. +type ModuleSourceID string + +// The `ObjectTypeDefID` scalar type represents an identifier for an object of type ObjectTypeDef. +type ObjectTypeDefID string + +// The platform config OS and architecture in a Container. +// +// The format is [os]/[platform]/[version] (e.g., "darwin/arm64/v7", "windows/amd64", "linux/arm64"). +type Platform string + +// The `PortID` scalar type represents an identifier for an object of type Port. +type PortID string + +// The `SecretID` scalar type represents an identifier for an object of type Secret. +type SecretID string + +// The `ServiceID` scalar type represents an identifier for an object of type Service. +type ServiceID string + +// The `SocketID` scalar type represents an identifier for an object of type Socket. +type SocketID string + +// The `TerminalID` scalar type represents an identifier for an object of type Terminal. +type TerminalID string + +// The `TypeDefID` scalar type represents an identifier for an object of type TypeDef. +type TypeDefID string + +// The absence of a value. +// +// A Null Void is used as a placeholder for resolvers that do not return anything. +type Void string + +// Key value object that represents a build argument. +type BuildArg struct { + // The build argument name. + Name string `json:"name"` + + // The build argument value. + Value string `json:"value"` +} + +// Key value object that represents a pipeline label. +type PipelineLabel struct { + // Label name. + Name string `json:"name"` + + // Label value. + Value string `json:"value"` +} + +// Port forwarding rules for tunneling network traffic. +type PortForward struct { + // Destination port for traffic. + Backend int `json:"backend"` + + // Port to expose to clients. If unspecified, a default will be chosen. + Frontend int `json:"frontend"` + + // Transport layer protocol to use for traffic. + Protocol NetworkProtocol `json:"protocol,omitempty"` +} + +// A directory whose contents persist across runs. +type CacheVolume struct { + q *querybuilder.Selection + c graphql.Client + + id *CacheVolumeID +} + +// A unique identifier for this CacheVolume. +func (r *CacheVolume) ID(ctx context.Context) (CacheVolumeID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response CacheVolumeID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *CacheVolume) XXX_GraphQLType() string { + return "CacheVolume" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *CacheVolume) XXX_GraphQLIDType() string { + return "CacheVolumeID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *CacheVolume) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *CacheVolume) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *CacheVolume) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadCacheVolumeFromID(CacheVolumeID(id)) + return nil +} + +// An OCI-compatible container, also known as a Docker container. +type Container struct { + q *querybuilder.Selection + c graphql.Client + + envVariable *string + export *bool + id *ContainerID + imageRef *string + label *string + platform *Platform + publish *string + stderr *string + stdout *string + sync *ContainerID + user *string + workdir *string +} +type WithContainerFunc func(r *Container) *Container + +// With calls the provided function with current Container. +// +// This is useful for reusability and readability by not breaking the calling chain. +func (r *Container) With(f WithContainerFunc) *Container { + return f(r) +} + +// Turn the container into a Service. +// +// Be sure to set any exposed ports before this conversion. +func (r *Container) AsService() *Service { + q := r.q.Select("asService") + + return &Service{ + q: q, + c: r.c, + } +} + +// ContainerAsTarballOpts contains options for Container.AsTarball +type ContainerAsTarballOpts struct { + // Identifiers for other platform specific containers. + // + // Used for multi-platform images. + PlatformVariants []*Container + // Force each layer of the image to use the specified compression algorithm. + // + // If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + ForcedCompression ImageLayerCompression + // Use the specified media types for the image's layers. + // + // Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. + MediaTypes ImageMediaTypes +} + +// Returns a File representing the container serialized to a tarball. +func (r *Container) AsTarball(opts ...ContainerAsTarballOpts) *File { + q := r.q.Select("asTarball") + for i := len(opts) - 1; i >= 0; i-- { + // `platformVariants` optional argument + if !querybuilder.IsZeroValue(opts[i].PlatformVariants) { + q = q.Arg("platformVariants", opts[i].PlatformVariants) + } + // `forcedCompression` optional argument + if !querybuilder.IsZeroValue(opts[i].ForcedCompression) { + q = q.Arg("forcedCompression", opts[i].ForcedCompression) + } + // `mediaTypes` optional argument + if !querybuilder.IsZeroValue(opts[i].MediaTypes) { + q = q.Arg("mediaTypes", opts[i].MediaTypes) + } + } + + return &File{ + q: q, + c: r.c, + } +} + +// ContainerBuildOpts contains options for Container.Build +type ContainerBuildOpts struct { + // Path to the Dockerfile to use. + Dockerfile string + // Target build stage to build. + Target string + // Additional build arguments. + BuildArgs []BuildArg + // Secrets to pass to the build. + // + // They will be mounted at /run/secrets/[secret-name] in the build container + // + // They can be accessed in the Dockerfile using the "secret" mount type and mount path /run/secrets/[secret-name], e.g. RUN --mount=type=secret,id=my-secret curl http://example.com?token=$(cat /run/secrets/my-secret) + Secrets []*Secret +} + +// Initializes this container from a Dockerfile build. +func (r *Container) Build(context *Directory, opts ...ContainerBuildOpts) *Container { + assertNotNil("context", context) + q := r.q.Select("build") + for i := len(opts) - 1; i >= 0; i-- { + // `dockerfile` optional argument + if !querybuilder.IsZeroValue(opts[i].Dockerfile) { + q = q.Arg("dockerfile", opts[i].Dockerfile) + } + // `target` optional argument + if !querybuilder.IsZeroValue(opts[i].Target) { + q = q.Arg("target", opts[i].Target) + } + // `buildArgs` optional argument + if !querybuilder.IsZeroValue(opts[i].BuildArgs) { + q = q.Arg("buildArgs", opts[i].BuildArgs) + } + // `secrets` optional argument + if !querybuilder.IsZeroValue(opts[i].Secrets) { + q = q.Arg("secrets", opts[i].Secrets) + } + } + q = q.Arg("context", context) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves default arguments for future commands. +func (r *Container) DefaultArgs(ctx context.Context) ([]string, error) { + q := r.q.Select("defaultArgs") + + var response []string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Retrieves a directory at the given path. +// +// Mounts are included. +func (r *Container) Directory(path string) *Directory { + q := r.q.Select("directory") + q = q.Arg("path", path) + + return &Directory{ + q: q, + c: r.c, + } +} + +// Retrieves entrypoint to be prepended to the arguments of all commands. +func (r *Container) Entrypoint(ctx context.Context) ([]string, error) { + q := r.q.Select("entrypoint") + + var response []string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Retrieves the value of the specified environment variable. +func (r *Container) EnvVariable(ctx context.Context, name string) (string, error) { + if r.envVariable != nil { + return *r.envVariable, nil + } + q := r.q.Select("envVariable") + q = q.Arg("name", name) + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Retrieves the list of environment variables passed to commands. +func (r *Container) EnvVariables(ctx context.Context) ([]EnvVariable, error) { + q := r.q.Select("envVariables") + + q = q.Select("id") + + type envVariables struct { + Id EnvVariableID + } + + convert := func(fields []envVariables) []EnvVariable { + out := []EnvVariable{} + + for i := range fields { + val := EnvVariable{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadEnvVariableFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []envVariables + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// EXPERIMENTAL API! Subject to change/removal at any time. +// +// Configures all available GPUs on the host to be accessible to this container. +// +// This currently works for Nvidia devices only. +func (r *Container) ExperimentalWithAllGPUs() *Container { + q := r.q.Select("experimentalWithAllGPUs") + + return &Container{ + q: q, + c: r.c, + } +} + +// EXPERIMENTAL API! Subject to change/removal at any time. +// +// Configures the provided list of devices to be accesible to this container. +// +// This currently works for Nvidia devices only. +func (r *Container) ExperimentalWithGPU(devices []string) *Container { + q := r.q.Select("experimentalWithGPU") + q = q.Arg("devices", devices) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerExportOpts contains options for Container.Export +type ContainerExportOpts struct { + // Identifiers for other platform specific containers. + // + // Used for multi-platform image. + PlatformVariants []*Container + // Force each layer of the exported image to use the specified compression algorithm. + // + // If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + ForcedCompression ImageLayerCompression + // Use the specified media types for the exported image's layers. + // + // Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. + MediaTypes ImageMediaTypes +} + +// Writes the container as an OCI tarball to the destination file path on the host. +// +// Return true on success. +// +// It can also export platform variants. +func (r *Container) Export(ctx context.Context, path string, opts ...ContainerExportOpts) (bool, error) { + if r.export != nil { + return *r.export, nil + } + q := r.q.Select("export") + for i := len(opts) - 1; i >= 0; i-- { + // `platformVariants` optional argument + if !querybuilder.IsZeroValue(opts[i].PlatformVariants) { + q = q.Arg("platformVariants", opts[i].PlatformVariants) + } + // `forcedCompression` optional argument + if !querybuilder.IsZeroValue(opts[i].ForcedCompression) { + q = q.Arg("forcedCompression", opts[i].ForcedCompression) + } + // `mediaTypes` optional argument + if !querybuilder.IsZeroValue(opts[i].MediaTypes) { + q = q.Arg("mediaTypes", opts[i].MediaTypes) + } + } + q = q.Arg("path", path) + + var response bool + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Retrieves the list of exposed ports. +// +// This includes ports already exposed by the image, even if not explicitly added with dagger. +func (r *Container) ExposedPorts(ctx context.Context) ([]Port, error) { + q := r.q.Select("exposedPorts") + + q = q.Select("id") + + type exposedPorts struct { + Id PortID + } + + convert := func(fields []exposedPorts) []Port { + out := []Port{} + + for i := range fields { + val := Port{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadPortFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []exposedPorts + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// Retrieves a file at the given path. +// +// Mounts are included. +func (r *Container) File(path string) *File { + q := r.q.Select("file") + q = q.Arg("path", path) + + return &File{ + q: q, + c: r.c, + } +} + +// Initializes this container from a pulled base image. +func (r *Container) From(address string) *Container { + q := r.q.Select("from") + q = q.Arg("address", address) + + return &Container{ + q: q, + c: r.c, + } +} + +// A unique identifier for this Container. +func (r *Container) ID(ctx context.Context) (ContainerID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response ContainerID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Container) XXX_GraphQLType() string { + return "Container" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Container) XXX_GraphQLIDType() string { + return "ContainerID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Container) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Container) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Container) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadContainerFromID(ContainerID(id)) + return nil +} + +// The unique image reference which can only be retrieved immediately after the 'Container.From' call. +func (r *Container) ImageRef(ctx context.Context) (string, error) { + if r.imageRef != nil { + return *r.imageRef, nil + } + q := r.q.Select("imageRef") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// ContainerImportOpts contains options for Container.Import +type ContainerImportOpts struct { + // Identifies the tag to import from the archive, if the archive bundles multiple tags. + Tag string +} + +// Reads the container from an OCI tarball. +func (r *Container) Import(source *File, opts ...ContainerImportOpts) *Container { + assertNotNil("source", source) + q := r.q.Select("import") + for i := len(opts) - 1; i >= 0; i-- { + // `tag` optional argument + if !querybuilder.IsZeroValue(opts[i].Tag) { + q = q.Arg("tag", opts[i].Tag) + } + } + q = q.Arg("source", source) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves the value of the specified label. +func (r *Container) Label(ctx context.Context, name string) (string, error) { + if r.label != nil { + return *r.label, nil + } + q := r.q.Select("label") + q = q.Arg("name", name) + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Retrieves the list of labels passed to container. +func (r *Container) Labels(ctx context.Context) ([]Label, error) { + q := r.q.Select("labels") + + q = q.Select("id") + + type labels struct { + Id LabelID + } + + convert := func(fields []labels) []Label { + out := []Label{} + + for i := range fields { + val := Label{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadLabelFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []labels + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// Retrieves the list of paths where a directory is mounted. +func (r *Container) Mounts(ctx context.Context) ([]string, error) { + q := r.q.Select("mounts") + + var response []string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// ContainerPipelineOpts contains options for Container.Pipeline +type ContainerPipelineOpts struct { + // Description of the sub-pipeline. + Description string + // Labels to apply to the sub-pipeline. + Labels []PipelineLabel +} + +// Creates a named sub-pipeline. +func (r *Container) Pipeline(name string, opts ...ContainerPipelineOpts) *Container { + q := r.q.Select("pipeline") + for i := len(opts) - 1; i >= 0; i-- { + // `description` optional argument + if !querybuilder.IsZeroValue(opts[i].Description) { + q = q.Arg("description", opts[i].Description) + } + // `labels` optional argument + if !querybuilder.IsZeroValue(opts[i].Labels) { + q = q.Arg("labels", opts[i].Labels) + } + } + q = q.Arg("name", name) + + return &Container{ + q: q, + c: r.c, + } +} + +// The platform this container executes and publishes as. +func (r *Container) Platform(ctx context.Context) (Platform, error) { + if r.platform != nil { + return *r.platform, nil + } + q := r.q.Select("platform") + + var response Platform + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// ContainerPublishOpts contains options for Container.Publish +type ContainerPublishOpts struct { + // Identifiers for other platform specific containers. + // + // Used for multi-platform image. + PlatformVariants []*Container + // Force each layer of the published image to use the specified compression algorithm. + // + // If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. + ForcedCompression ImageLayerCompression + // Use the specified media types for the published image's layers. + // + // Defaults to OCI, which is largely compatible with most recent registries, but Docker may be needed for older registries without OCI support. + MediaTypes ImageMediaTypes +} + +// Publishes this container as a new image to the specified address. +// +// Publish returns a fully qualified ref. +// +// It can also publish platform variants. +func (r *Container) Publish(ctx context.Context, address string, opts ...ContainerPublishOpts) (string, error) { + if r.publish != nil { + return *r.publish, nil + } + q := r.q.Select("publish") + for i := len(opts) - 1; i >= 0; i-- { + // `platformVariants` optional argument + if !querybuilder.IsZeroValue(opts[i].PlatformVariants) { + q = q.Arg("platformVariants", opts[i].PlatformVariants) + } + // `forcedCompression` optional argument + if !querybuilder.IsZeroValue(opts[i].ForcedCompression) { + q = q.Arg("forcedCompression", opts[i].ForcedCompression) + } + // `mediaTypes` optional argument + if !querybuilder.IsZeroValue(opts[i].MediaTypes) { + q = q.Arg("mediaTypes", opts[i].MediaTypes) + } + } + q = q.Arg("address", address) + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Retrieves this container's root filesystem. Mounts are not included. +func (r *Container) Rootfs() *Directory { + q := r.q.Select("rootfs") + + return &Directory{ + q: q, + c: r.c, + } +} + +// The error stream of the last executed command. +// +// Will execute default command if none is set, or error if there's no default. +func (r *Container) Stderr(ctx context.Context) (string, error) { + if r.stderr != nil { + return *r.stderr, nil + } + q := r.q.Select("stderr") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The output stream of the last executed command. +// +// Will execute default command if none is set, or error if there's no default. +func (r *Container) Stdout(ctx context.Context) (string, error) { + if r.stdout != nil { + return *r.stdout, nil + } + q := r.q.Select("stdout") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Forces evaluation of the pipeline in the engine. +// +// It doesn't run the default command if no exec has been set. +func (r *Container) Sync(ctx context.Context) (*Container, error) { + q := r.q.Select("sync") + + return r, q.Execute(ctx, r.c) +} + +// ContainerTerminalOpts contains options for Container.Terminal +type ContainerTerminalOpts struct { + // If set, override the container's default terminal command and invoke these command arguments instead. + Cmd []string +} + +// Return an interactive terminal for this container using its configured default terminal command if not overridden by args (or sh as a fallback default). +func (r *Container) Terminal(opts ...ContainerTerminalOpts) *Terminal { + q := r.q.Select("terminal") + for i := len(opts) - 1; i >= 0; i-- { + // `cmd` optional argument + if !querybuilder.IsZeroValue(opts[i].Cmd) { + q = q.Arg("cmd", opts[i].Cmd) + } + } + + return &Terminal{ + q: q, + c: r.c, + } +} + +// Retrieves the user to be set for all commands. +func (r *Container) User(ctx context.Context) (string, error) { + if r.user != nil { + return *r.user, nil + } + q := r.q.Select("user") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Configures default arguments for future commands. +func (r *Container) WithDefaultArgs(args []string) *Container { + q := r.q.Select("withDefaultArgs") + q = q.Arg("args", args) + + return &Container{ + q: q, + c: r.c, + } +} + +// Set the default command to invoke for the container's terminal API. +func (r *Container) WithDefaultTerminalCmd(args []string) *Container { + q := r.q.Select("withDefaultTerminalCmd") + q = q.Arg("args", args) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithDirectoryOpts contains options for Container.WithDirectory +type ContainerWithDirectoryOpts struct { + // Patterns to exclude in the written directory (e.g. ["node_modules/**", ".gitignore", ".git/"]). + Exclude []string + // Patterns to include in the written directory (e.g. ["*.go", "go.mod", "go.sum"]). + Include []string + // A user:group to set for the directory and its contents. + // + // The user and group can either be an ID (1000:1000) or a name (foo:bar). + // + // If the group is omitted, it defaults to the same as the user. + Owner string +} + +// Retrieves this container plus a directory written at the given path. +func (r *Container) WithDirectory(path string, directory *Directory, opts ...ContainerWithDirectoryOpts) *Container { + assertNotNil("directory", directory) + q := r.q.Select("withDirectory") + for i := len(opts) - 1; i >= 0; i-- { + // `exclude` optional argument + if !querybuilder.IsZeroValue(opts[i].Exclude) { + q = q.Arg("exclude", opts[i].Exclude) + } + // `include` optional argument + if !querybuilder.IsZeroValue(opts[i].Include) { + q = q.Arg("include", opts[i].Include) + } + // `owner` optional argument + if !querybuilder.IsZeroValue(opts[i].Owner) { + q = q.Arg("owner", opts[i].Owner) + } + } + q = q.Arg("path", path) + q = q.Arg("directory", directory) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithEntrypointOpts contains options for Container.WithEntrypoint +type ContainerWithEntrypointOpts struct { + // Don't remove the default arguments when setting the entrypoint. + KeepDefaultArgs bool +} + +// Retrieves this container but with a different command entrypoint. +func (r *Container) WithEntrypoint(args []string, opts ...ContainerWithEntrypointOpts) *Container { + q := r.q.Select("withEntrypoint") + for i := len(opts) - 1; i >= 0; i-- { + // `keepDefaultArgs` optional argument + if !querybuilder.IsZeroValue(opts[i].KeepDefaultArgs) { + q = q.Arg("keepDefaultArgs", opts[i].KeepDefaultArgs) + } + } + q = q.Arg("args", args) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithEnvVariableOpts contains options for Container.WithEnvVariable +type ContainerWithEnvVariableOpts struct { + // Replace `${VAR}` or `$VAR` in the value according to the current environment variables defined in the container (e.g., "/opt/bin:$PATH"). + Expand bool +} + +// Retrieves this container plus the given environment variable. +func (r *Container) WithEnvVariable(name string, value string, opts ...ContainerWithEnvVariableOpts) *Container { + q := r.q.Select("withEnvVariable") + for i := len(opts) - 1; i >= 0; i-- { + // `expand` optional argument + if !querybuilder.IsZeroValue(opts[i].Expand) { + q = q.Arg("expand", opts[i].Expand) + } + } + q = q.Arg("name", name) + q = q.Arg("value", value) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithExecOpts contains options for Container.WithExec +type ContainerWithExecOpts struct { + // If the container has an entrypoint, ignore it for args rather than using it to wrap them. + SkipEntrypoint bool + // Content to write to the command's standard input before closing (e.g., "Hello world"). + Stdin string + // Redirect the command's standard output to a file in the container (e.g., "/tmp/stdout"). + RedirectStdout string + // Redirect the command's standard error to a file in the container (e.g., "/tmp/stderr"). + RedirectStderr string + // Provides dagger access to the executed command. + // + // Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. + ExperimentalPrivilegedNesting bool + // Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + InsecureRootCapabilities bool +} + +// Retrieves this container after executing the specified command inside it. +func (r *Container) WithExec(args []string, opts ...ContainerWithExecOpts) *Container { + q := r.q.Select("withExec") + for i := len(opts) - 1; i >= 0; i-- { + // `skipEntrypoint` optional argument + if !querybuilder.IsZeroValue(opts[i].SkipEntrypoint) { + q = q.Arg("skipEntrypoint", opts[i].SkipEntrypoint) + } + // `stdin` optional argument + if !querybuilder.IsZeroValue(opts[i].Stdin) { + q = q.Arg("stdin", opts[i].Stdin) + } + // `redirectStdout` optional argument + if !querybuilder.IsZeroValue(opts[i].RedirectStdout) { + q = q.Arg("redirectStdout", opts[i].RedirectStdout) + } + // `redirectStderr` optional argument + if !querybuilder.IsZeroValue(opts[i].RedirectStderr) { + q = q.Arg("redirectStderr", opts[i].RedirectStderr) + } + // `experimentalPrivilegedNesting` optional argument + if !querybuilder.IsZeroValue(opts[i].ExperimentalPrivilegedNesting) { + q = q.Arg("experimentalPrivilegedNesting", opts[i].ExperimentalPrivilegedNesting) + } + // `insecureRootCapabilities` optional argument + if !querybuilder.IsZeroValue(opts[i].InsecureRootCapabilities) { + q = q.Arg("insecureRootCapabilities", opts[i].InsecureRootCapabilities) + } + } + q = q.Arg("args", args) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithExposedPortOpts contains options for Container.WithExposedPort +type ContainerWithExposedPortOpts struct { + // Transport layer network protocol + Protocol NetworkProtocol + // Optional port description + Description string + // Skip the health check when run as a service. + ExperimentalSkipHealthcheck bool +} + +// Expose a network port. +// +// Exposed ports serve two purposes: +// +// - For health checks and introspection, when running services +// +// - For setting the EXPOSE OCI field when publishing the container +func (r *Container) WithExposedPort(port int, opts ...ContainerWithExposedPortOpts) *Container { + q := r.q.Select("withExposedPort") + for i := len(opts) - 1; i >= 0; i-- { + // `protocol` optional argument + if !querybuilder.IsZeroValue(opts[i].Protocol) { + q = q.Arg("protocol", opts[i].Protocol) + } + // `description` optional argument + if !querybuilder.IsZeroValue(opts[i].Description) { + q = q.Arg("description", opts[i].Description) + } + // `experimentalSkipHealthcheck` optional argument + if !querybuilder.IsZeroValue(opts[i].ExperimentalSkipHealthcheck) { + q = q.Arg("experimentalSkipHealthcheck", opts[i].ExperimentalSkipHealthcheck) + } + } + q = q.Arg("port", port) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithFileOpts contains options for Container.WithFile +type ContainerWithFileOpts struct { + // Permission given to the copied file (e.g., 0600). + Permissions int + // A user:group to set for the file. + // + // The user and group can either be an ID (1000:1000) or a name (foo:bar). + // + // If the group is omitted, it defaults to the same as the user. + Owner string +} + +// Retrieves this container plus the contents of the given file copied to the given path. +func (r *Container) WithFile(path string, source *File, opts ...ContainerWithFileOpts) *Container { + assertNotNil("source", source) + q := r.q.Select("withFile") + for i := len(opts) - 1; i >= 0; i-- { + // `permissions` optional argument + if !querybuilder.IsZeroValue(opts[i].Permissions) { + q = q.Arg("permissions", opts[i].Permissions) + } + // `owner` optional argument + if !querybuilder.IsZeroValue(opts[i].Owner) { + q = q.Arg("owner", opts[i].Owner) + } + } + q = q.Arg("path", path) + q = q.Arg("source", source) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithFilesOpts contains options for Container.WithFiles +type ContainerWithFilesOpts struct { + // Permission given to the copied files (e.g., 0600). + Permissions int + // A user:group to set for the files. + // + // The user and group can either be an ID (1000:1000) or a name (foo:bar). + // + // If the group is omitted, it defaults to the same as the user. + Owner string +} + +// Retrieves this container plus the contents of the given files copied to the given path. +func (r *Container) WithFiles(path string, sources []*File, opts ...ContainerWithFilesOpts) *Container { + q := r.q.Select("withFiles") + for i := len(opts) - 1; i >= 0; i-- { + // `permissions` optional argument + if !querybuilder.IsZeroValue(opts[i].Permissions) { + q = q.Arg("permissions", opts[i].Permissions) + } + // `owner` optional argument + if !querybuilder.IsZeroValue(opts[i].Owner) { + q = q.Arg("owner", opts[i].Owner) + } + } + q = q.Arg("path", path) + q = q.Arg("sources", sources) + + return &Container{ + q: q, + c: r.c, + } +} + +// Indicate that subsequent operations should be featured more prominently in the UI. +func (r *Container) WithFocus() *Container { + q := r.q.Select("withFocus") + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container plus the given label. +func (r *Container) WithLabel(name string, value string) *Container { + q := r.q.Select("withLabel") + q = q.Arg("name", name) + q = q.Arg("value", value) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithMountedCacheOpts contains options for Container.WithMountedCache +type ContainerWithMountedCacheOpts struct { + // Identifier of the directory to use as the cache volume's root. + Source *Directory + // Sharing mode of the cache volume. + Sharing CacheSharingMode + // A user:group to set for the mounted cache directory. + // + // Note that this changes the ownership of the specified mount along with the initial filesystem provided by source (if any). It does not have any effect if/when the cache has already been created. + // + // The user and group can either be an ID (1000:1000) or a name (foo:bar). + // + // If the group is omitted, it defaults to the same as the user. + Owner string +} + +// Retrieves this container plus a cache volume mounted at the given path. +func (r *Container) WithMountedCache(path string, cache *CacheVolume, opts ...ContainerWithMountedCacheOpts) *Container { + assertNotNil("cache", cache) + q := r.q.Select("withMountedCache") + for i := len(opts) - 1; i >= 0; i-- { + // `source` optional argument + if !querybuilder.IsZeroValue(opts[i].Source) { + q = q.Arg("source", opts[i].Source) + } + // `sharing` optional argument + if !querybuilder.IsZeroValue(opts[i].Sharing) { + q = q.Arg("sharing", opts[i].Sharing) + } + // `owner` optional argument + if !querybuilder.IsZeroValue(opts[i].Owner) { + q = q.Arg("owner", opts[i].Owner) + } + } + q = q.Arg("path", path) + q = q.Arg("cache", cache) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithMountedDirectoryOpts contains options for Container.WithMountedDirectory +type ContainerWithMountedDirectoryOpts struct { + // A user:group to set for the mounted directory and its contents. + // + // The user and group can either be an ID (1000:1000) or a name (foo:bar). + // + // If the group is omitted, it defaults to the same as the user. + Owner string +} + +// Retrieves this container plus a directory mounted at the given path. +func (r *Container) WithMountedDirectory(path string, source *Directory, opts ...ContainerWithMountedDirectoryOpts) *Container { + assertNotNil("source", source) + q := r.q.Select("withMountedDirectory") + for i := len(opts) - 1; i >= 0; i-- { + // `owner` optional argument + if !querybuilder.IsZeroValue(opts[i].Owner) { + q = q.Arg("owner", opts[i].Owner) + } + } + q = q.Arg("path", path) + q = q.Arg("source", source) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithMountedFileOpts contains options for Container.WithMountedFile +type ContainerWithMountedFileOpts struct { + // A user or user:group to set for the mounted file. + // + // The user and group can either be an ID (1000:1000) or a name (foo:bar). + // + // If the group is omitted, it defaults to the same as the user. + Owner string +} + +// Retrieves this container plus a file mounted at the given path. +func (r *Container) WithMountedFile(path string, source *File, opts ...ContainerWithMountedFileOpts) *Container { + assertNotNil("source", source) + q := r.q.Select("withMountedFile") + for i := len(opts) - 1; i >= 0; i-- { + // `owner` optional argument + if !querybuilder.IsZeroValue(opts[i].Owner) { + q = q.Arg("owner", opts[i].Owner) + } + } + q = q.Arg("path", path) + q = q.Arg("source", source) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithMountedSecretOpts contains options for Container.WithMountedSecret +type ContainerWithMountedSecretOpts struct { + // A user:group to set for the mounted secret. + // + // The user and group can either be an ID (1000:1000) or a name (foo:bar). + // + // If the group is omitted, it defaults to the same as the user. + Owner string + // Permission given to the mounted secret (e.g., 0600). + // + // This option requires an owner to be set to be active. + Mode int +} + +// Retrieves this container plus a secret mounted into a file at the given path. +func (r *Container) WithMountedSecret(path string, source *Secret, opts ...ContainerWithMountedSecretOpts) *Container { + assertNotNil("source", source) + q := r.q.Select("withMountedSecret") + for i := len(opts) - 1; i >= 0; i-- { + // `owner` optional argument + if !querybuilder.IsZeroValue(opts[i].Owner) { + q = q.Arg("owner", opts[i].Owner) + } + // `mode` optional argument + if !querybuilder.IsZeroValue(opts[i].Mode) { + q = q.Arg("mode", opts[i].Mode) + } + } + q = q.Arg("path", path) + q = q.Arg("source", source) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container plus a temporary directory mounted at the given path. +func (r *Container) WithMountedTemp(path string) *Container { + q := r.q.Select("withMountedTemp") + q = q.Arg("path", path) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithNewFileOpts contains options for Container.WithNewFile +type ContainerWithNewFileOpts struct { + // Content of the file to write (e.g., "Hello world!"). + Contents string + // Permission given to the written file (e.g., 0600). + Permissions int + // A user:group to set for the file. + // + // The user and group can either be an ID (1000:1000) or a name (foo:bar). + // + // If the group is omitted, it defaults to the same as the user. + Owner string +} + +// Retrieves this container plus a new file written at the given path. +func (r *Container) WithNewFile(path string, opts ...ContainerWithNewFileOpts) *Container { + q := r.q.Select("withNewFile") + for i := len(opts) - 1; i >= 0; i-- { + // `contents` optional argument + if !querybuilder.IsZeroValue(opts[i].Contents) { + q = q.Arg("contents", opts[i].Contents) + } + // `permissions` optional argument + if !querybuilder.IsZeroValue(opts[i].Permissions) { + q = q.Arg("permissions", opts[i].Permissions) + } + // `owner` optional argument + if !querybuilder.IsZeroValue(opts[i].Owner) { + q = q.Arg("owner", opts[i].Owner) + } + } + q = q.Arg("path", path) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container with a registry authentication for a given address. +func (r *Container) WithRegistryAuth(address string, username string, secret *Secret) *Container { + assertNotNil("secret", secret) + q := r.q.Select("withRegistryAuth") + q = q.Arg("address", address) + q = q.Arg("username", username) + q = q.Arg("secret", secret) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves the container with the given directory mounted to /. +func (r *Container) WithRootfs(directory *Directory) *Container { + assertNotNil("directory", directory) + q := r.q.Select("withRootfs") + q = q.Arg("directory", directory) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container plus an env variable containing the given secret. +func (r *Container) WithSecretVariable(name string, secret *Secret) *Container { + assertNotNil("secret", secret) + q := r.q.Select("withSecretVariable") + q = q.Arg("name", name) + q = q.Arg("secret", secret) + + return &Container{ + q: q, + c: r.c, + } +} + +// Establish a runtime dependency on a service. +// +// The service will be started automatically when needed and detached when it is no longer needed, executing the default command if none is set. +// +// The service will be reachable from the container via the provided hostname alias. +// +// The service dependency will also convey to any files or directories produced by the container. +func (r *Container) WithServiceBinding(alias string, service *Service) *Container { + assertNotNil("service", service) + q := r.q.Select("withServiceBinding") + q = q.Arg("alias", alias) + q = q.Arg("service", service) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithUnixSocketOpts contains options for Container.WithUnixSocket +type ContainerWithUnixSocketOpts struct { + // A user:group to set for the mounted socket. + // + // The user and group can either be an ID (1000:1000) or a name (foo:bar). + // + // If the group is omitted, it defaults to the same as the user. + Owner string +} + +// Retrieves this container plus a socket forwarded to the given Unix socket path. +func (r *Container) WithUnixSocket(path string, source *Socket, opts ...ContainerWithUnixSocketOpts) *Container { + assertNotNil("source", source) + q := r.q.Select("withUnixSocket") + for i := len(opts) - 1; i >= 0; i-- { + // `owner` optional argument + if !querybuilder.IsZeroValue(opts[i].Owner) { + q = q.Arg("owner", opts[i].Owner) + } + } + q = q.Arg("path", path) + q = q.Arg("source", source) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container with a different command user. +func (r *Container) WithUser(name string) *Container { + q := r.q.Select("withUser") + q = q.Arg("name", name) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container with a different working directory. +func (r *Container) WithWorkdir(path string) *Container { + q := r.q.Select("withWorkdir") + q = q.Arg("path", path) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container with unset default arguments for future commands. +func (r *Container) WithoutDefaultArgs() *Container { + q := r.q.Select("withoutDefaultArgs") + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithoutEntrypointOpts contains options for Container.WithoutEntrypoint +type ContainerWithoutEntrypointOpts struct { + // Don't remove the default arguments when unsetting the entrypoint. + KeepDefaultArgs bool +} + +// Retrieves this container with an unset command entrypoint. +func (r *Container) WithoutEntrypoint(opts ...ContainerWithoutEntrypointOpts) *Container { + q := r.q.Select("withoutEntrypoint") + for i := len(opts) - 1; i >= 0; i-- { + // `keepDefaultArgs` optional argument + if !querybuilder.IsZeroValue(opts[i].KeepDefaultArgs) { + q = q.Arg("keepDefaultArgs", opts[i].KeepDefaultArgs) + } + } + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container minus the given environment variable. +func (r *Container) WithoutEnvVariable(name string) *Container { + q := r.q.Select("withoutEnvVariable") + q = q.Arg("name", name) + + return &Container{ + q: q, + c: r.c, + } +} + +// ContainerWithoutExposedPortOpts contains options for Container.WithoutExposedPort +type ContainerWithoutExposedPortOpts struct { + // Port protocol to unexpose + Protocol NetworkProtocol +} + +// Unexpose a previously exposed port. +func (r *Container) WithoutExposedPort(port int, opts ...ContainerWithoutExposedPortOpts) *Container { + q := r.q.Select("withoutExposedPort") + for i := len(opts) - 1; i >= 0; i-- { + // `protocol` optional argument + if !querybuilder.IsZeroValue(opts[i].Protocol) { + q = q.Arg("protocol", opts[i].Protocol) + } + } + q = q.Arg("port", port) + + return &Container{ + q: q, + c: r.c, + } +} + +// Indicate that subsequent operations should not be featured more prominently in the UI. +// +// This is the initial state of all containers. +func (r *Container) WithoutFocus() *Container { + q := r.q.Select("withoutFocus") + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container minus the given environment label. +func (r *Container) WithoutLabel(name string) *Container { + q := r.q.Select("withoutLabel") + q = q.Arg("name", name) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container after unmounting everything at the given path. +func (r *Container) WithoutMount(path string) *Container { + q := r.q.Select("withoutMount") + q = q.Arg("path", path) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container without the registry authentication of a given address. +func (r *Container) WithoutRegistryAuth(address string) *Container { + q := r.q.Select("withoutRegistryAuth") + q = q.Arg("address", address) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container with a previously added Unix socket removed. +func (r *Container) WithoutUnixSocket(path string) *Container { + q := r.q.Select("withoutUnixSocket") + q = q.Arg("path", path) + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container with an unset command user. +// +// Should default to root. +func (r *Container) WithoutUser() *Container { + q := r.q.Select("withoutUser") + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves this container with an unset working directory. +// +// Should default to "/". +func (r *Container) WithoutWorkdir() *Container { + q := r.q.Select("withoutWorkdir") + + return &Container{ + q: q, + c: r.c, + } +} + +// Retrieves the working directory for all commands. +func (r *Container) Workdir(ctx context.Context) (string, error) { + if r.workdir != nil { + return *r.workdir, nil + } + q := r.q.Select("workdir") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Reflective module API provided to functions at runtime. +type CurrentModule struct { + q *querybuilder.Selection + c graphql.Client + + id *CurrentModuleID + name *string +} + +// A unique identifier for this CurrentModule. +func (r *CurrentModule) ID(ctx context.Context) (CurrentModuleID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response CurrentModuleID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *CurrentModule) XXX_GraphQLType() string { + return "CurrentModule" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *CurrentModule) XXX_GraphQLIDType() string { + return "CurrentModuleID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *CurrentModule) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *CurrentModule) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *CurrentModule) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadCurrentModuleFromID(CurrentModuleID(id)) + return nil +} + +// The name of the module being executed in +func (r *CurrentModule) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The directory containing the module's source code loaded into the engine (plus any generated code that may have been created). +func (r *CurrentModule) Source() *Directory { + q := r.q.Select("source") + + return &Directory{ + q: q, + c: r.c, + } +} + +// CurrentModuleWorkdirOpts contains options for CurrentModule.Workdir +type CurrentModuleWorkdirOpts struct { + // Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). + Exclude []string + // Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). + Include []string +} + +// Load a directory from the module's scratch working directory, including any changes that may have been made to it during module function execution. +func (r *CurrentModule) Workdir(path string, opts ...CurrentModuleWorkdirOpts) *Directory { + q := r.q.Select("workdir") + for i := len(opts) - 1; i >= 0; i-- { + // `exclude` optional argument + if !querybuilder.IsZeroValue(opts[i].Exclude) { + q = q.Arg("exclude", opts[i].Exclude) + } + // `include` optional argument + if !querybuilder.IsZeroValue(opts[i].Include) { + q = q.Arg("include", opts[i].Include) + } + } + q = q.Arg("path", path) + + return &Directory{ + q: q, + c: r.c, + } +} + +// Load a file from the module's scratch working directory, including any changes that may have been made to it during module function execution.Load a file from the module's scratch working directory, including any changes that may have been made to it during module function execution. +func (r *CurrentModule) WorkdirFile(path string) *File { + q := r.q.Select("workdirFile") + q = q.Arg("path", path) + + return &File{ + q: q, + c: r.c, + } +} + +// A directory. +type Directory struct { + q *querybuilder.Selection + c graphql.Client + + export *bool + id *DirectoryID + sync *DirectoryID +} +type WithDirectoryFunc func(r *Directory) *Directory + +// With calls the provided function with current Directory. +// +// This is useful for reusability and readability by not breaking the calling chain. +func (r *Directory) With(f WithDirectoryFunc) *Directory { + return f(r) +} + +// DirectoryAsModuleOpts contains options for Directory.AsModule +type DirectoryAsModuleOpts struct { + // An optional subpath of the directory which contains the module's configuration file. + // + // This is needed when the module code is in a subdirectory but requires parent directories to be loaded in order to execute. For example, the module source code may need a go.mod, project.toml, package.json, etc. file from a parent directory. + // + // If not set, the module source code is loaded from the root of the directory. + SourceRootPath string +} + +// Load the directory as a Dagger module +func (r *Directory) AsModule(opts ...DirectoryAsModuleOpts) *Module { + q := r.q.Select("asModule") + for i := len(opts) - 1; i >= 0; i-- { + // `sourceRootPath` optional argument + if !querybuilder.IsZeroValue(opts[i].SourceRootPath) { + q = q.Arg("sourceRootPath", opts[i].SourceRootPath) + } + } + + return &Module{ + q: q, + c: r.c, + } +} + +// Gets the difference between this directory and an another directory. +func (r *Directory) Diff(other *Directory) *Directory { + assertNotNil("other", other) + q := r.q.Select("diff") + q = q.Arg("other", other) + + return &Directory{ + q: q, + c: r.c, + } +} + +// Retrieves a directory at the given path. +func (r *Directory) Directory(path string) *Directory { + q := r.q.Select("directory") + q = q.Arg("path", path) + + return &Directory{ + q: q, + c: r.c, + } +} + +// DirectoryDockerBuildOpts contains options for Directory.DockerBuild +type DirectoryDockerBuildOpts struct { + // The platform to build. + Platform Platform + // Path to the Dockerfile to use (e.g., "frontend.Dockerfile"). + Dockerfile string + // Target build stage to build. + Target string + // Build arguments to use in the build. + BuildArgs []BuildArg + // Secrets to pass to the build. + // + // They will be mounted at /run/secrets/[secret-name]. + Secrets []*Secret +} + +// Builds a new Docker container from this directory. +func (r *Directory) DockerBuild(opts ...DirectoryDockerBuildOpts) *Container { + q := r.q.Select("dockerBuild") + for i := len(opts) - 1; i >= 0; i-- { + // `platform` optional argument + if !querybuilder.IsZeroValue(opts[i].Platform) { + q = q.Arg("platform", opts[i].Platform) + } + // `dockerfile` optional argument + if !querybuilder.IsZeroValue(opts[i].Dockerfile) { + q = q.Arg("dockerfile", opts[i].Dockerfile) + } + // `target` optional argument + if !querybuilder.IsZeroValue(opts[i].Target) { + q = q.Arg("target", opts[i].Target) + } + // `buildArgs` optional argument + if !querybuilder.IsZeroValue(opts[i].BuildArgs) { + q = q.Arg("buildArgs", opts[i].BuildArgs) + } + // `secrets` optional argument + if !querybuilder.IsZeroValue(opts[i].Secrets) { + q = q.Arg("secrets", opts[i].Secrets) + } + } + + return &Container{ + q: q, + c: r.c, + } +} + +// DirectoryEntriesOpts contains options for Directory.Entries +type DirectoryEntriesOpts struct { + // Location of the directory to look at (e.g., "/src"). + Path string +} + +// Returns a list of files and directories at the given path. +func (r *Directory) Entries(ctx context.Context, opts ...DirectoryEntriesOpts) ([]string, error) { + q := r.q.Select("entries") + for i := len(opts) - 1; i >= 0; i-- { + // `path` optional argument + if !querybuilder.IsZeroValue(opts[i].Path) { + q = q.Arg("path", opts[i].Path) + } + } + + var response []string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Writes the contents of the directory to a path on the host. +func (r *Directory) Export(ctx context.Context, path string) (bool, error) { + if r.export != nil { + return *r.export, nil + } + q := r.q.Select("export") + q = q.Arg("path", path) + + var response bool + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Retrieves a file at the given path. +func (r *Directory) File(path string) *File { + q := r.q.Select("file") + q = q.Arg("path", path) + + return &File{ + q: q, + c: r.c, + } +} + +// Returns a list of files and directories that matche the given pattern. +func (r *Directory) Glob(ctx context.Context, pattern string) ([]string, error) { + q := r.q.Select("glob") + q = q.Arg("pattern", pattern) + + var response []string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this Directory. +func (r *Directory) ID(ctx context.Context) (DirectoryID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response DirectoryID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Directory) XXX_GraphQLType() string { + return "Directory" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Directory) XXX_GraphQLIDType() string { + return "DirectoryID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Directory) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Directory) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Directory) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadDirectoryFromID(DirectoryID(id)) + return nil +} + +// DirectoryPipelineOpts contains options for Directory.Pipeline +type DirectoryPipelineOpts struct { + // Description of the sub-pipeline. + Description string + // Labels to apply to the sub-pipeline. + Labels []PipelineLabel +} + +// Creates a named sub-pipeline. +func (r *Directory) Pipeline(name string, opts ...DirectoryPipelineOpts) *Directory { + q := r.q.Select("pipeline") + for i := len(opts) - 1; i >= 0; i-- { + // `description` optional argument + if !querybuilder.IsZeroValue(opts[i].Description) { + q = q.Arg("description", opts[i].Description) + } + // `labels` optional argument + if !querybuilder.IsZeroValue(opts[i].Labels) { + q = q.Arg("labels", opts[i].Labels) + } + } + q = q.Arg("name", name) + + return &Directory{ + q: q, + c: r.c, + } +} + +// Force evaluation in the engine. +func (r *Directory) Sync(ctx context.Context) (*Directory, error) { + q := r.q.Select("sync") + + return r, q.Execute(ctx, r.c) +} + +// DirectoryWithDirectoryOpts contains options for Directory.WithDirectory +type DirectoryWithDirectoryOpts struct { + // Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). + Exclude []string + // Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). + Include []string +} + +// Retrieves this directory plus a directory written at the given path. +func (r *Directory) WithDirectory(path string, directory *Directory, opts ...DirectoryWithDirectoryOpts) *Directory { + assertNotNil("directory", directory) + q := r.q.Select("withDirectory") + for i := len(opts) - 1; i >= 0; i-- { + // `exclude` optional argument + if !querybuilder.IsZeroValue(opts[i].Exclude) { + q = q.Arg("exclude", opts[i].Exclude) + } + // `include` optional argument + if !querybuilder.IsZeroValue(opts[i].Include) { + q = q.Arg("include", opts[i].Include) + } + } + q = q.Arg("path", path) + q = q.Arg("directory", directory) + + return &Directory{ + q: q, + c: r.c, + } +} + +// DirectoryWithFileOpts contains options for Directory.WithFile +type DirectoryWithFileOpts struct { + // Permission given to the copied file (e.g., 0600). + Permissions int +} + +// Retrieves this directory plus the contents of the given file copied to the given path. +func (r *Directory) WithFile(path string, source *File, opts ...DirectoryWithFileOpts) *Directory { + assertNotNil("source", source) + q := r.q.Select("withFile") + for i := len(opts) - 1; i >= 0; i-- { + // `permissions` optional argument + if !querybuilder.IsZeroValue(opts[i].Permissions) { + q = q.Arg("permissions", opts[i].Permissions) + } + } + q = q.Arg("path", path) + q = q.Arg("source", source) + + return &Directory{ + q: q, + c: r.c, + } +} + +// DirectoryWithFilesOpts contains options for Directory.WithFiles +type DirectoryWithFilesOpts struct { + // Permission given to the copied files (e.g., 0600). + Permissions int +} + +// Retrieves this directory plus the contents of the given files copied to the given path. +func (r *Directory) WithFiles(path string, sources []*File, opts ...DirectoryWithFilesOpts) *Directory { + q := r.q.Select("withFiles") + for i := len(opts) - 1; i >= 0; i-- { + // `permissions` optional argument + if !querybuilder.IsZeroValue(opts[i].Permissions) { + q = q.Arg("permissions", opts[i].Permissions) + } + } + q = q.Arg("path", path) + q = q.Arg("sources", sources) + + return &Directory{ + q: q, + c: r.c, + } +} + +// DirectoryWithNewDirectoryOpts contains options for Directory.WithNewDirectory +type DirectoryWithNewDirectoryOpts struct { + // Permission granted to the created directory (e.g., 0777). + Permissions int +} + +// Retrieves this directory plus a new directory created at the given path. +func (r *Directory) WithNewDirectory(path string, opts ...DirectoryWithNewDirectoryOpts) *Directory { + q := r.q.Select("withNewDirectory") + for i := len(opts) - 1; i >= 0; i-- { + // `permissions` optional argument + if !querybuilder.IsZeroValue(opts[i].Permissions) { + q = q.Arg("permissions", opts[i].Permissions) + } + } + q = q.Arg("path", path) + + return &Directory{ + q: q, + c: r.c, + } +} + +// DirectoryWithNewFileOpts contains options for Directory.WithNewFile +type DirectoryWithNewFileOpts struct { + // Permission given to the copied file (e.g., 0600). + Permissions int +} + +// Retrieves this directory plus a new file written at the given path. +func (r *Directory) WithNewFile(path string, contents string, opts ...DirectoryWithNewFileOpts) *Directory { + q := r.q.Select("withNewFile") + for i := len(opts) - 1; i >= 0; i-- { + // `permissions` optional argument + if !querybuilder.IsZeroValue(opts[i].Permissions) { + q = q.Arg("permissions", opts[i].Permissions) + } + } + q = q.Arg("path", path) + q = q.Arg("contents", contents) + + return &Directory{ + q: q, + c: r.c, + } +} + +// Retrieves this directory with all file/dir timestamps set to the given time. +func (r *Directory) WithTimestamps(timestamp int) *Directory { + q := r.q.Select("withTimestamps") + q = q.Arg("timestamp", timestamp) + + return &Directory{ + q: q, + c: r.c, + } +} + +// Retrieves this directory with the directory at the given path removed. +func (r *Directory) WithoutDirectory(path string) *Directory { + q := r.q.Select("withoutDirectory") + q = q.Arg("path", path) + + return &Directory{ + q: q, + c: r.c, + } +} + +// Retrieves this directory with the file at the given path removed. +func (r *Directory) WithoutFile(path string) *Directory { + q := r.q.Select("withoutFile") + q = q.Arg("path", path) + + return &Directory{ + q: q, + c: r.c, + } +} + +// An environment variable name and value. +type EnvVariable struct { + q *querybuilder.Selection + c graphql.Client + + id *EnvVariableID + name *string + value *string +} + +// A unique identifier for this EnvVariable. +func (r *EnvVariable) ID(ctx context.Context) (EnvVariableID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response EnvVariableID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *EnvVariable) XXX_GraphQLType() string { + return "EnvVariable" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *EnvVariable) XXX_GraphQLIDType() string { + return "EnvVariableID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *EnvVariable) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *EnvVariable) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *EnvVariable) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadEnvVariableFromID(EnvVariableID(id)) + return nil +} + +// The environment variable name. +func (r *EnvVariable) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The environment variable value. +func (r *EnvVariable) Value(ctx context.Context) (string, error) { + if r.value != nil { + return *r.value, nil + } + q := r.q.Select("value") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A definition of a field on a custom object defined in a Module. +// +// A field on an object has a static value, as opposed to a function on an object whose value is computed by invoking code (and can accept arguments). +type FieldTypeDef struct { + q *querybuilder.Selection + c graphql.Client + + description *string + id *FieldTypeDefID + name *string +} + +// A doc string for the field, if any. +func (r *FieldTypeDef) Description(ctx context.Context) (string, error) { + if r.description != nil { + return *r.description, nil + } + q := r.q.Select("description") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this FieldTypeDef. +func (r *FieldTypeDef) ID(ctx context.Context) (FieldTypeDefID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response FieldTypeDefID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *FieldTypeDef) XXX_GraphQLType() string { + return "FieldTypeDef" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *FieldTypeDef) XXX_GraphQLIDType() string { + return "FieldTypeDefID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *FieldTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *FieldTypeDef) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *FieldTypeDef) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadFieldTypeDefFromID(FieldTypeDefID(id)) + return nil +} + +// The name of the field in lowerCamelCase format. +func (r *FieldTypeDef) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The type of the field. +func (r *FieldTypeDef) TypeDef() *TypeDef { + q := r.q.Select("typeDef") + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// A file. +type File struct { + q *querybuilder.Selection + c graphql.Client + + contents *string + export *bool + id *FileID + name *string + size *int + sync *FileID +} +type WithFileFunc func(r *File) *File + +// With calls the provided function with current File. +// +// This is useful for reusability and readability by not breaking the calling chain. +func (r *File) With(f WithFileFunc) *File { + return f(r) +} + +// Retrieves the contents of the file. +func (r *File) Contents(ctx context.Context) (string, error) { + if r.contents != nil { + return *r.contents, nil + } + q := r.q.Select("contents") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// FileExportOpts contains options for File.Export +type FileExportOpts struct { + // If allowParentDirPath is true, the path argument can be a directory path, in which case the file will be created in that directory. + AllowParentDirPath bool +} + +// Writes the file to a file path on the host. +func (r *File) Export(ctx context.Context, path string, opts ...FileExportOpts) (bool, error) { + if r.export != nil { + return *r.export, nil + } + q := r.q.Select("export") + for i := len(opts) - 1; i >= 0; i-- { + // `allowParentDirPath` optional argument + if !querybuilder.IsZeroValue(opts[i].AllowParentDirPath) { + q = q.Arg("allowParentDirPath", opts[i].AllowParentDirPath) + } + } + q = q.Arg("path", path) + + var response bool + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this File. +func (r *File) ID(ctx context.Context) (FileID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response FileID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *File) XXX_GraphQLType() string { + return "File" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *File) XXX_GraphQLIDType() string { + return "FileID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *File) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *File) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *File) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadFileFromID(FileID(id)) + return nil +} + +// Retrieves the name of the file. +func (r *File) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Retrieves the size of the file, in bytes. +func (r *File) Size(ctx context.Context) (int, error) { + if r.size != nil { + return *r.size, nil + } + q := r.q.Select("size") + + var response int + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Force evaluation in the engine. +func (r *File) Sync(ctx context.Context) (*File, error) { + q := r.q.Select("sync") + + return r, q.Execute(ctx, r.c) +} + +// Retrieves this file with its created/modified timestamps set to the given time. +func (r *File) WithTimestamps(timestamp int) *File { + q := r.q.Select("withTimestamps") + q = q.Arg("timestamp", timestamp) + + return &File{ + q: q, + c: r.c, + } +} + +// Function represents a resolver provided by a Module. +// +// A function always evaluates against a parent object and is given a set of named arguments. +type Function struct { + q *querybuilder.Selection + c graphql.Client + + description *string + id *FunctionID + name *string +} +type WithFunctionFunc func(r *Function) *Function + +// With calls the provided function with current Function. +// +// This is useful for reusability and readability by not breaking the calling chain. +func (r *Function) With(f WithFunctionFunc) *Function { + return f(r) +} + +// Arguments accepted by the function, if any. +func (r *Function) Args(ctx context.Context) ([]FunctionArg, error) { + q := r.q.Select("args") + + q = q.Select("id") + + type args struct { + Id FunctionArgID + } + + convert := func(fields []args) []FunctionArg { + out := []FunctionArg{} + + for i := range fields { + val := FunctionArg{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadFunctionArgFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []args + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// A doc string for the function, if any. +func (r *Function) Description(ctx context.Context) (string, error) { + if r.description != nil { + return *r.description, nil + } + q := r.q.Select("description") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this Function. +func (r *Function) ID(ctx context.Context) (FunctionID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response FunctionID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Function) XXX_GraphQLType() string { + return "Function" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Function) XXX_GraphQLIDType() string { + return "FunctionID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Function) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Function) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Function) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadFunctionFromID(FunctionID(id)) + return nil +} + +// The name of the function. +func (r *Function) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The type returned by the function. +func (r *Function) ReturnType() *TypeDef { + q := r.q.Select("returnType") + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// FunctionWithArgOpts contains options for Function.WithArg +type FunctionWithArgOpts struct { + // A doc string for the argument, if any + Description string + // A default value to use for this argument if not explicitly set by the caller, if any + DefaultValue JSON +} + +// Returns the function with the provided argument +func (r *Function) WithArg(name string, typeDef *TypeDef, opts ...FunctionWithArgOpts) *Function { + assertNotNil("typeDef", typeDef) + q := r.q.Select("withArg") + for i := len(opts) - 1; i >= 0; i-- { + // `description` optional argument + if !querybuilder.IsZeroValue(opts[i].Description) { + q = q.Arg("description", opts[i].Description) + } + // `defaultValue` optional argument + if !querybuilder.IsZeroValue(opts[i].DefaultValue) { + q = q.Arg("defaultValue", opts[i].DefaultValue) + } + } + q = q.Arg("name", name) + q = q.Arg("typeDef", typeDef) + + return &Function{ + q: q, + c: r.c, + } +} + +// Returns the function with the given doc string. +func (r *Function) WithDescription(description string) *Function { + q := r.q.Select("withDescription") + q = q.Arg("description", description) + + return &Function{ + q: q, + c: r.c, + } +} + +// An argument accepted by a function. +// +// This is a specification for an argument at function definition time, not an argument passed at function call time. +type FunctionArg struct { + q *querybuilder.Selection + c graphql.Client + + defaultValue *JSON + description *string + id *FunctionArgID + name *string +} + +// A default value to use for this argument when not explicitly set by the caller, if any. +func (r *FunctionArg) DefaultValue(ctx context.Context) (JSON, error) { + if r.defaultValue != nil { + return *r.defaultValue, nil + } + q := r.q.Select("defaultValue") + + var response JSON + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A doc string for the argument, if any. +func (r *FunctionArg) Description(ctx context.Context) (string, error) { + if r.description != nil { + return *r.description, nil + } + q := r.q.Select("description") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this FunctionArg. +func (r *FunctionArg) ID(ctx context.Context) (FunctionArgID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response FunctionArgID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *FunctionArg) XXX_GraphQLType() string { + return "FunctionArg" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *FunctionArg) XXX_GraphQLIDType() string { + return "FunctionArgID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *FunctionArg) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *FunctionArg) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *FunctionArg) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadFunctionArgFromID(FunctionArgID(id)) + return nil +} + +// The name of the argument in lowerCamelCase format. +func (r *FunctionArg) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The type of the argument. +func (r *FunctionArg) TypeDef() *TypeDef { + q := r.q.Select("typeDef") + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// An active function call. +type FunctionCall struct { + q *querybuilder.Selection + c graphql.Client + + id *FunctionCallID + name *string + parent *JSON + parentName *string + returnValue *Void +} + +// A unique identifier for this FunctionCall. +func (r *FunctionCall) ID(ctx context.Context) (FunctionCallID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response FunctionCallID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *FunctionCall) XXX_GraphQLType() string { + return "FunctionCall" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *FunctionCall) XXX_GraphQLIDType() string { + return "FunctionCallID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *FunctionCall) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *FunctionCall) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *FunctionCall) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadFunctionCallFromID(FunctionCallID(id)) + return nil +} + +// The argument values the function is being invoked with. +func (r *FunctionCall) InputArgs(ctx context.Context) ([]FunctionCallArgValue, error) { + q := r.q.Select("inputArgs") + + q = q.Select("id") + + type inputArgs struct { + Id FunctionCallArgValueID + } + + convert := func(fields []inputArgs) []FunctionCallArgValue { + out := []FunctionCallArgValue{} + + for i := range fields { + val := FunctionCallArgValue{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadFunctionCallArgValueFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []inputArgs + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// The name of the function being called. +func (r *FunctionCall) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The value of the parent object of the function being called. If the function is top-level to the module, this is always an empty object. +func (r *FunctionCall) Parent(ctx context.Context) (JSON, error) { + if r.parent != nil { + return *r.parent, nil + } + q := r.q.Select("parent") + + var response JSON + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The name of the parent object of the function being called. If the function is top-level to the module, this is the name of the module. +func (r *FunctionCall) ParentName(ctx context.Context) (string, error) { + if r.parentName != nil { + return *r.parentName, nil + } + q := r.q.Select("parentName") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Set the return value of the function call to the provided value. +func (r *FunctionCall) ReturnValue(ctx context.Context, value JSON) (Void, error) { + if r.returnValue != nil { + return *r.returnValue, nil + } + q := r.q.Select("returnValue") + q = q.Arg("value", value) + + var response Void + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A value passed as a named argument to a function call. +type FunctionCallArgValue struct { + q *querybuilder.Selection + c graphql.Client + + id *FunctionCallArgValueID + name *string + value *JSON +} + +// A unique identifier for this FunctionCallArgValue. +func (r *FunctionCallArgValue) ID(ctx context.Context) (FunctionCallArgValueID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response FunctionCallArgValueID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *FunctionCallArgValue) XXX_GraphQLType() string { + return "FunctionCallArgValue" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *FunctionCallArgValue) XXX_GraphQLIDType() string { + return "FunctionCallArgValueID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *FunctionCallArgValue) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *FunctionCallArgValue) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *FunctionCallArgValue) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadFunctionCallArgValueFromID(FunctionCallArgValueID(id)) + return nil +} + +// The name of the argument. +func (r *FunctionCallArgValue) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The value of the argument represented as a JSON serialized string. +func (r *FunctionCallArgValue) Value(ctx context.Context) (JSON, error) { + if r.value != nil { + return *r.value, nil + } + q := r.q.Select("value") + + var response JSON + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The result of running an SDK's codegen. +type GeneratedCode struct { + q *querybuilder.Selection + c graphql.Client + + id *GeneratedCodeID +} +type WithGeneratedCodeFunc func(r *GeneratedCode) *GeneratedCode + +// With calls the provided function with current GeneratedCode. +// +// This is useful for reusability and readability by not breaking the calling chain. +func (r *GeneratedCode) With(f WithGeneratedCodeFunc) *GeneratedCode { + return f(r) +} + +// The directory containing the generated code. +func (r *GeneratedCode) Code() *Directory { + q := r.q.Select("code") + + return &Directory{ + q: q, + c: r.c, + } +} + +// A unique identifier for this GeneratedCode. +func (r *GeneratedCode) ID(ctx context.Context) (GeneratedCodeID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response GeneratedCodeID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *GeneratedCode) XXX_GraphQLType() string { + return "GeneratedCode" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *GeneratedCode) XXX_GraphQLIDType() string { + return "GeneratedCodeID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *GeneratedCode) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *GeneratedCode) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *GeneratedCode) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadGeneratedCodeFromID(GeneratedCodeID(id)) + return nil +} + +// List of paths to mark generated in version control (i.e. .gitattributes). +func (r *GeneratedCode) VcsGeneratedPaths(ctx context.Context) ([]string, error) { + q := r.q.Select("vcsGeneratedPaths") + + var response []string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// List of paths to ignore in version control (i.e. .gitignore). +func (r *GeneratedCode) VcsIgnoredPaths(ctx context.Context) ([]string, error) { + q := r.q.Select("vcsIgnoredPaths") + + var response []string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Set the list of paths to mark generated in version control. +func (r *GeneratedCode) WithVCSGeneratedPaths(paths []string) *GeneratedCode { + q := r.q.Select("withVCSGeneratedPaths") + q = q.Arg("paths", paths) + + return &GeneratedCode{ + q: q, + c: r.c, + } +} + +// Set the list of paths to ignore in version control. +func (r *GeneratedCode) WithVCSIgnoredPaths(paths []string) *GeneratedCode { + q := r.q.Select("withVCSIgnoredPaths") + q = q.Arg("paths", paths) + + return &GeneratedCode{ + q: q, + c: r.c, + } +} + +// Module source originating from a git repo. +type GitModuleSource struct { + q *querybuilder.Selection + c graphql.Client + + cloneURL *string + commit *string + htmlURL *string + id *GitModuleSourceID + rootSubpath *string + version *string +} + +// The URL from which the source's git repo can be cloned. +func (r *GitModuleSource) CloneURL(ctx context.Context) (string, error) { + if r.cloneURL != nil { + return *r.cloneURL, nil + } + q := r.q.Select("cloneURL") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The resolved commit of the git repo this source points to. +func (r *GitModuleSource) Commit(ctx context.Context) (string, error) { + if r.commit != nil { + return *r.commit, nil + } + q := r.q.Select("commit") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The directory containing everything needed to load load and use the module. +func (r *GitModuleSource) ContextDirectory() *Directory { + q := r.q.Select("contextDirectory") + + return &Directory{ + q: q, + c: r.c, + } +} + +// The URL to the source's git repo in a web browser +func (r *GitModuleSource) HTMLURL(ctx context.Context) (string, error) { + if r.htmlURL != nil { + return *r.htmlURL, nil + } + q := r.q.Select("htmlURL") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this GitModuleSource. +func (r *GitModuleSource) ID(ctx context.Context) (GitModuleSourceID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response GitModuleSourceID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *GitModuleSource) XXX_GraphQLType() string { + return "GitModuleSource" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *GitModuleSource) XXX_GraphQLIDType() string { + return "GitModuleSourceID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *GitModuleSource) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *GitModuleSource) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *GitModuleSource) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadGitModuleSourceFromID(GitModuleSourceID(id)) + return nil +} + +// The path to the root of the module source under the context directory. This directory contains its configuration file. It also contains its source code (possibly as a subdirectory). +func (r *GitModuleSource) RootSubpath(ctx context.Context) (string, error) { + if r.rootSubpath != nil { + return *r.rootSubpath, nil + } + q := r.q.Select("rootSubpath") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The specified version of the git repo this source points to. +func (r *GitModuleSource) Version(ctx context.Context) (string, error) { + if r.version != nil { + return *r.version, nil + } + q := r.q.Select("version") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A git ref (tag, branch, or commit). +type GitRef struct { + q *querybuilder.Selection + c graphql.Client + + commit *string + id *GitRefID +} + +// The resolved commit id at this ref. +func (r *GitRef) Commit(ctx context.Context) (string, error) { + if r.commit != nil { + return *r.commit, nil + } + q := r.q.Select("commit") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this GitRef. +func (r *GitRef) ID(ctx context.Context) (GitRefID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response GitRefID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *GitRef) XXX_GraphQLType() string { + return "GitRef" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *GitRef) XXX_GraphQLIDType() string { + return "GitRefID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *GitRef) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *GitRef) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *GitRef) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadGitRefFromID(GitRefID(id)) + return nil +} + +// GitRefTreeOpts contains options for GitRef.Tree +type GitRefTreeOpts struct { + // DEPRECATED: This option should be passed to `git` instead. + SSHKnownHosts string + // DEPRECATED: This option should be passed to `git` instead. + SSHAuthSocket *Socket +} + +// The filesystem tree at this ref. +func (r *GitRef) Tree(opts ...GitRefTreeOpts) *Directory { + q := r.q.Select("tree") + for i := len(opts) - 1; i >= 0; i-- { + // `sshKnownHosts` optional argument + if !querybuilder.IsZeroValue(opts[i].SSHKnownHosts) { + q = q.Arg("sshKnownHosts", opts[i].SSHKnownHosts) + } + // `sshAuthSocket` optional argument + if !querybuilder.IsZeroValue(opts[i].SSHAuthSocket) { + q = q.Arg("sshAuthSocket", opts[i].SSHAuthSocket) + } + } + + return &Directory{ + q: q, + c: r.c, + } +} + +// A git repository. +type GitRepository struct { + q *querybuilder.Selection + c graphql.Client + + id *GitRepositoryID +} + +// Returns details of a branch. +func (r *GitRepository) Branch(name string) *GitRef { + q := r.q.Select("branch") + q = q.Arg("name", name) + + return &GitRef{ + q: q, + c: r.c, + } +} + +// Returns details of a commit. +func (r *GitRepository) Commit(id string) *GitRef { + q := r.q.Select("commit") + q = q.Arg("id", id) + + return &GitRef{ + q: q, + c: r.c, + } +} + +// A unique identifier for this GitRepository. +func (r *GitRepository) ID(ctx context.Context) (GitRepositoryID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response GitRepositoryID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *GitRepository) XXX_GraphQLType() string { + return "GitRepository" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *GitRepository) XXX_GraphQLIDType() string { + return "GitRepositoryID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *GitRepository) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *GitRepository) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *GitRepository) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadGitRepositoryFromID(GitRepositoryID(id)) + return nil +} + +// Returns details of a ref. +func (r *GitRepository) Ref(name string) *GitRef { + q := r.q.Select("ref") + q = q.Arg("name", name) + + return &GitRef{ + q: q, + c: r.c, + } +} + +// Returns details of a tag. +func (r *GitRepository) Tag(name string) *GitRef { + q := r.q.Select("tag") + q = q.Arg("name", name) + + return &GitRef{ + q: q, + c: r.c, + } +} + +type Golang struct { + q *querybuilder.Selection + c graphql.Client + + golangciLint *string + id *GolangID + test *string +} +type WithGolangFunc func(r *Golang) *Golang + +// With calls the provided function with current Golang. +// +// This is useful for reusability and readability by not breaking the calling chain. +func (r *Golang) With(f WithGolangFunc) *Golang { + return f(r) +} + +// Sets up the Container with a golang image and cache volumes +func (r *Golang) Base(version string) *Golang { + q := r.q.Select("base") + q = q.Arg("version", version) + + return &Golang{ + q: q, + c: r.c, + } +} + +// GolangBuildOpts contains options for Golang.Build +type GolangBuildOpts struct { + Arch string + + Os string +} + +// Build the Go project +func (r *Golang) Build(args []string, opts ...GolangBuildOpts) *Directory { + q := r.q.Select("build") + for i := len(opts) - 1; i >= 0; i-- { + // `arch` optional argument + if !querybuilder.IsZeroValue(opts[i].Arch) { + q = q.Arg("arch", opts[i].Arch) + } + // `os` optional argument + if !querybuilder.IsZeroValue(opts[i].Os) { + q = q.Arg("os", opts[i].Os) + } + } + q = q.Arg("args", args) + + return &Directory{ + q: q, + c: r.c, + } +} + +// GolangBuildRemoteOpts contains options for Golang.BuildRemote +type GolangBuildRemoteOpts struct { + Arch string + + Platform string +} + +// Build a remote git repo +func (r *Golang) BuildRemote(remote string, ref string, module string, opts ...GolangBuildRemoteOpts) *Directory { + q := r.q.Select("buildRemote") + for i := len(opts) - 1; i >= 0; i-- { + // `arch` optional argument + if !querybuilder.IsZeroValue(opts[i].Arch) { + q = q.Arg("arch", opts[i].Arch) + } + // `platform` optional argument + if !querybuilder.IsZeroValue(opts[i].Platform) { + q = q.Arg("platform", opts[i].Platform) + } + } + q = q.Arg("remote", remote) + q = q.Arg("ref", ref) + q = q.Arg("module", module) + + return &Directory{ + q: q, + c: r.c, + } +} + +// Accessor for the Container +func (r *Golang) Container() *Container { + q := r.q.Select("container") + + return &Container{ + q: q, + c: r.c, + } +} + +func (r *Golang) Ctr() *Container { + q := r.q.Select("ctr") + + return &Container{ + q: q, + c: r.c, + } +} + +// Lint the Go project +func (r *Golang) GolangciLint(ctx context.Context) (string, error) { + if r.golangciLint != nil { + return *r.golangciLint, nil + } + q := r.q.Select("golangciLint") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this Golang. +func (r *Golang) ID(ctx context.Context) (GolangID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response GolangID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Golang) XXX_GraphQLType() string { + return "Golang" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Golang) XXX_GraphQLIDType() string { + return "GolangID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Golang) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Golang) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Golang) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadGolangFromID(GolangID(id)) + return nil +} + +func (r *Golang) Proj() *Directory { + q := r.q.Select("proj") + + return &Directory{ + q: q, + c: r.c, + } +} + +// Accessor for the Project +func (r *Golang) Project() *Directory { + q := r.q.Select("project") + + return &Directory{ + q: q, + c: r.c, + } +} + +// Test the Go project +func (r *Golang) Test(ctx context.Context, args []string) (string, error) { + if r.test != nil { + return *r.test, nil + } + q := r.q.Select("test") + q = q.Arg("args", args) + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Bring your own container +func (r *Golang) WithContainer(ctr *Container) *Golang { + assertNotNil("ctr", ctr) + q := r.q.Select("withContainer") + q = q.Arg("ctr", ctr) + + return &Golang{ + q: q, + c: r.c, + } +} + +// Specify the Project to use in the module +func (r *Golang) WithProject(dir *Directory) *Golang { + assertNotNil("dir", dir) + q := r.q.Select("withProject") + q = q.Arg("dir", dir) + + return &Golang{ + q: q, + c: r.c, + } +} + +// A graphql input type, which is essentially just a group of named args. +// This is currently only used to represent pre-existing usage of graphql input types +// in the core API. It is not used by user modules and shouldn't ever be as user +// module accept input objects via their id rather than graphql input types. +type InputTypeDef struct { + q *querybuilder.Selection + c graphql.Client + + id *InputTypeDefID + name *string +} + +// Static fields defined on this input object, if any. +func (r *InputTypeDef) Fields(ctx context.Context) ([]FieldTypeDef, error) { + q := r.q.Select("fields") + + q = q.Select("id") + + type fields struct { + Id FieldTypeDefID + } + + convert := func(fields []fields) []FieldTypeDef { + out := []FieldTypeDef{} + + for i := range fields { + val := FieldTypeDef{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadFieldTypeDefFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []fields + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// A unique identifier for this InputTypeDef. +func (r *InputTypeDef) ID(ctx context.Context) (InputTypeDefID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response InputTypeDefID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *InputTypeDef) XXX_GraphQLType() string { + return "InputTypeDef" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *InputTypeDef) XXX_GraphQLIDType() string { + return "InputTypeDefID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *InputTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *InputTypeDef) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *InputTypeDef) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadInputTypeDefFromID(InputTypeDefID(id)) + return nil +} + +// The name of the input object. +func (r *InputTypeDef) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A definition of a custom interface defined in a Module. +type InterfaceTypeDef struct { + q *querybuilder.Selection + c graphql.Client + + description *string + id *InterfaceTypeDefID + name *string + sourceModuleName *string +} + +// The doc string for the interface, if any. +func (r *InterfaceTypeDef) Description(ctx context.Context) (string, error) { + if r.description != nil { + return *r.description, nil + } + q := r.q.Select("description") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Functions defined on this interface, if any. +func (r *InterfaceTypeDef) Functions(ctx context.Context) ([]Function, error) { + q := r.q.Select("functions") + + q = q.Select("id") + + type functions struct { + Id FunctionID + } + + convert := func(fields []functions) []Function { + out := []Function{} + + for i := range fields { + val := Function{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadFunctionFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []functions + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// A unique identifier for this InterfaceTypeDef. +func (r *InterfaceTypeDef) ID(ctx context.Context) (InterfaceTypeDefID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response InterfaceTypeDefID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *InterfaceTypeDef) XXX_GraphQLType() string { + return "InterfaceTypeDef" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *InterfaceTypeDef) XXX_GraphQLIDType() string { + return "InterfaceTypeDefID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *InterfaceTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *InterfaceTypeDef) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *InterfaceTypeDef) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadInterfaceTypeDefFromID(InterfaceTypeDefID(id)) + return nil +} + +// The name of the interface. +func (r *InterfaceTypeDef) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// If this InterfaceTypeDef is associated with a Module, the name of the module. Unset otherwise. +func (r *InterfaceTypeDef) SourceModuleName(ctx context.Context) (string, error) { + if r.sourceModuleName != nil { + return *r.sourceModuleName, nil + } + q := r.q.Select("sourceModuleName") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A simple key value object that represents a label. +type Label struct { + q *querybuilder.Selection + c graphql.Client + + id *LabelID + name *string + value *string +} + +// A unique identifier for this Label. +func (r *Label) ID(ctx context.Context) (LabelID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response LabelID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Label) XXX_GraphQLType() string { + return "Label" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Label) XXX_GraphQLIDType() string { + return "LabelID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Label) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Label) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Label) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadLabelFromID(LabelID(id)) + return nil +} + +// The label name. +func (r *Label) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The label value. +func (r *Label) Value(ctx context.Context) (string, error) { + if r.value != nil { + return *r.value, nil + } + q := r.q.Select("value") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A definition of a list type in a Module. +type ListTypeDef struct { + q *querybuilder.Selection + c graphql.Client + + id *ListTypeDefID +} + +// The type of the elements in the list. +func (r *ListTypeDef) ElementTypeDef() *TypeDef { + q := r.q.Select("elementTypeDef") + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// A unique identifier for this ListTypeDef. +func (r *ListTypeDef) ID(ctx context.Context) (ListTypeDefID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response ListTypeDefID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *ListTypeDef) XXX_GraphQLType() string { + return "ListTypeDef" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *ListTypeDef) XXX_GraphQLIDType() string { + return "ListTypeDefID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *ListTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *ListTypeDef) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *ListTypeDef) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadListTypeDefFromID(ListTypeDefID(id)) + return nil +} + +// Module source that that originates from a path locally relative to an arbitrary directory. +type LocalModuleSource struct { + q *querybuilder.Selection + c graphql.Client + + id *LocalModuleSourceID + rootSubpath *string +} + +// The directory containing everything needed to load load and use the module. +func (r *LocalModuleSource) ContextDirectory() *Directory { + q := r.q.Select("contextDirectory") + + return &Directory{ + q: q, + c: r.c, + } +} + +// A unique identifier for this LocalModuleSource. +func (r *LocalModuleSource) ID(ctx context.Context) (LocalModuleSourceID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response LocalModuleSourceID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *LocalModuleSource) XXX_GraphQLType() string { + return "LocalModuleSource" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *LocalModuleSource) XXX_GraphQLIDType() string { + return "LocalModuleSourceID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *LocalModuleSource) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *LocalModuleSource) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *LocalModuleSource) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadLocalModuleSourceFromID(LocalModuleSourceID(id)) + return nil +} + +// The path to the root of the module source under the context directory. This directory contains its configuration file. It also contains its source code (possibly as a subdirectory). +func (r *LocalModuleSource) RootSubpath(ctx context.Context) (string, error) { + if r.rootSubpath != nil { + return *r.rootSubpath, nil + } + q := r.q.Select("rootSubpath") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A Dagger module. +type Module struct { + q *querybuilder.Selection + c graphql.Client + + description *string + id *ModuleID + name *string + sdk *string + serve *Void +} +type WithModuleFunc func(r *Module) *Module + +// With calls the provided function with current Module. +// +// This is useful for reusability and readability by not breaking the calling chain. +func (r *Module) With(f WithModuleFunc) *Module { + return f(r) +} + +// Modules used by this module. +func (r *Module) Dependencies(ctx context.Context) ([]Module, error) { + q := r.q.Select("dependencies") + + q = q.Select("id") + + type dependencies struct { + Id ModuleID + } + + convert := func(fields []dependencies) []Module { + out := []Module{} + + for i := range fields { + val := Module{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadModuleFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []dependencies + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// The dependencies as configured by the module. +func (r *Module) DependencyConfig(ctx context.Context) ([]ModuleDependency, error) { + q := r.q.Select("dependencyConfig") + + q = q.Select("id") + + type dependencyConfig struct { + Id ModuleDependencyID + } + + convert := func(fields []dependencyConfig) []ModuleDependency { + out := []ModuleDependency{} + + for i := range fields { + val := ModuleDependency{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadModuleDependencyFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []dependencyConfig + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// The doc string of the module, if any +func (r *Module) Description(ctx context.Context) (string, error) { + if r.description != nil { + return *r.description, nil + } + q := r.q.Select("description") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The generated files and directories made on top of the module source's context directory. +func (r *Module) GeneratedContextDiff() *Directory { + q := r.q.Select("generatedContextDiff") + + return &Directory{ + q: q, + c: r.c, + } +} + +// The module source's context plus any configuration and source files created by codegen. +func (r *Module) GeneratedContextDirectory() *Directory { + q := r.q.Select("generatedContextDirectory") + + return &Directory{ + q: q, + c: r.c, + } +} + +// A unique identifier for this Module. +func (r *Module) ID(ctx context.Context) (ModuleID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response ModuleID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Module) XXX_GraphQLType() string { + return "Module" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Module) XXX_GraphQLIDType() string { + return "ModuleID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Module) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Module) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Module) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadModuleFromID(ModuleID(id)) + return nil +} + +// Retrieves the module with the objects loaded via its SDK. +func (r *Module) Initialize() *Module { + q := r.q.Select("initialize") + + return &Module{ + q: q, + c: r.c, + } +} + +// Interfaces served by this module. +func (r *Module) Interfaces(ctx context.Context) ([]TypeDef, error) { + q := r.q.Select("interfaces") + + q = q.Select("id") + + type interfaces struct { + Id TypeDefID + } + + convert := func(fields []interfaces) []TypeDef { + out := []TypeDef{} + + for i := range fields { + val := TypeDef{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadTypeDefFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []interfaces + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// The name of the module +func (r *Module) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Objects served by this module. +func (r *Module) Objects(ctx context.Context) ([]TypeDef, error) { + q := r.q.Select("objects") + + q = q.Select("id") + + type objects struct { + Id TypeDefID + } + + convert := func(fields []objects) []TypeDef { + out := []TypeDef{} + + for i := range fields { + val := TypeDef{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadTypeDefFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []objects + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// The container that runs the module's entrypoint. It will fail to execute if the module doesn't compile. +func (r *Module) Runtime() *Container { + q := r.q.Select("runtime") + + return &Container{ + q: q, + c: r.c, + } +} + +// The SDK used by this module. Either a name of a builtin SDK or a module source ref string pointing to the SDK's implementation. +func (r *Module) SDK(ctx context.Context) (string, error) { + if r.sdk != nil { + return *r.sdk, nil + } + q := r.q.Select("sdk") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Serve a module's API in the current session. +// +// Note: this can only be called once per session. In the future, it could return a stream or service to remove the side effect. +func (r *Module) Serve(ctx context.Context) (Void, error) { + if r.serve != nil { + return *r.serve, nil + } + q := r.q.Select("serve") + + var response Void + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The source for the module. +func (r *Module) Source() *ModuleSource { + q := r.q.Select("source") + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// Retrieves the module with the given description +func (r *Module) WithDescription(description string) *Module { + q := r.q.Select("withDescription") + q = q.Arg("description", description) + + return &Module{ + q: q, + c: r.c, + } +} + +// This module plus the given Interface type and associated functions +func (r *Module) WithInterface(iface *TypeDef) *Module { + assertNotNil("iface", iface) + q := r.q.Select("withInterface") + q = q.Arg("iface", iface) + + return &Module{ + q: q, + c: r.c, + } +} + +// This module plus the given Object type and associated functions. +func (r *Module) WithObject(object *TypeDef) *Module { + assertNotNil("object", object) + q := r.q.Select("withObject") + q = q.Arg("object", object) + + return &Module{ + q: q, + c: r.c, + } +} + +// Retrieves the module with basic configuration loaded if present. +func (r *Module) WithSource(source *ModuleSource) *Module { + assertNotNil("source", source) + q := r.q.Select("withSource") + q = q.Arg("source", source) + + return &Module{ + q: q, + c: r.c, + } +} + +// The configuration of dependency of a module. +type ModuleDependency struct { + q *querybuilder.Selection + c graphql.Client + + id *ModuleDependencyID + name *string +} + +// A unique identifier for this ModuleDependency. +func (r *ModuleDependency) ID(ctx context.Context) (ModuleDependencyID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response ModuleDependencyID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *ModuleDependency) XXX_GraphQLType() string { + return "ModuleDependency" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *ModuleDependency) XXX_GraphQLIDType() string { + return "ModuleDependencyID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *ModuleDependency) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *ModuleDependency) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *ModuleDependency) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadModuleDependencyFromID(ModuleDependencyID(id)) + return nil +} + +// The name of the dependency module. +func (r *ModuleDependency) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The source for the dependency module. +func (r *ModuleDependency) Source() *ModuleSource { + q := r.q.Select("source") + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// The source needed to load and run a module, along with any metadata about the source such as versions/urls/etc. +type ModuleSource struct { + q *querybuilder.Selection + c graphql.Client + + asString *string + configExists *bool + id *ModuleSourceID + kind *ModuleSourceKind + moduleName *string + moduleOriginalName *string + resolveContextPathFromCaller *string + sourceRootSubpath *string + sourceSubpath *string +} +type WithModuleSourceFunc func(r *ModuleSource) *ModuleSource + +// With calls the provided function with current ModuleSource. +// +// This is useful for reusability and readability by not breaking the calling chain. +func (r *ModuleSource) With(f WithModuleSourceFunc) *ModuleSource { + return f(r) +} + +// If the source is a of kind git, the git source representation of it. +func (r *ModuleSource) AsGitSource() *GitModuleSource { + q := r.q.Select("asGitSource") + + return &GitModuleSource{ + q: q, + c: r.c, + } +} + +// If the source is of kind local, the local source representation of it. +func (r *ModuleSource) AsLocalSource() *LocalModuleSource { + q := r.q.Select("asLocalSource") + + return &LocalModuleSource{ + q: q, + c: r.c, + } +} + +// Load the source as a module. If this is a local source, the parent directory must have been provided during module source creation +func (r *ModuleSource) AsModule() *Module { + q := r.q.Select("asModule") + + return &Module{ + q: q, + c: r.c, + } +} + +// A human readable ref string representation of this module source. +func (r *ModuleSource) AsString(ctx context.Context) (string, error) { + if r.asString != nil { + return *r.asString, nil + } + q := r.q.Select("asString") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Returns whether the module source has a configuration file. +func (r *ModuleSource) ConfigExists(ctx context.Context) (bool, error) { + if r.configExists != nil { + return *r.configExists, nil + } + q := r.q.Select("configExists") + + var response bool + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The directory containing everything needed to load load and use the module. +func (r *ModuleSource) ContextDirectory() *Directory { + q := r.q.Select("contextDirectory") + + return &Directory{ + q: q, + c: r.c, + } +} + +// The dependencies of the module source. Includes dependencies from the configuration and any extras from withDependencies calls. +func (r *ModuleSource) Dependencies(ctx context.Context) ([]ModuleDependency, error) { + q := r.q.Select("dependencies") + + q = q.Select("id") + + type dependencies struct { + Id ModuleDependencyID + } + + convert := func(fields []dependencies) []ModuleDependency { + out := []ModuleDependency{} + + for i := range fields { + val := ModuleDependency{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadModuleDependencyFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []dependencies + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// The directory containing the module configuration and source code (source code may be in a subdir). +func (r *ModuleSource) Directory(path string) *Directory { + q := r.q.Select("directory") + q = q.Arg("path", path) + + return &Directory{ + q: q, + c: r.c, + } +} + +// A unique identifier for this ModuleSource. +func (r *ModuleSource) ID(ctx context.Context) (ModuleSourceID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response ModuleSourceID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *ModuleSource) XXX_GraphQLType() string { + return "ModuleSource" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *ModuleSource) XXX_GraphQLIDType() string { + return "ModuleSourceID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *ModuleSource) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *ModuleSource) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *ModuleSource) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadModuleSourceFromID(ModuleSourceID(id)) + return nil +} + +// The kind of source (e.g. local, git, etc.) +func (r *ModuleSource) Kind(ctx context.Context) (ModuleSourceKind, error) { + if r.kind != nil { + return *r.kind, nil + } + q := r.q.Select("kind") + + var response ModuleSourceKind + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// If set, the name of the module this source references, including any overrides at runtime by callers. +func (r *ModuleSource) ModuleName(ctx context.Context) (string, error) { + if r.moduleName != nil { + return *r.moduleName, nil + } + q := r.q.Select("moduleName") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The original name of the module this source references, as defined in the module configuration. +func (r *ModuleSource) ModuleOriginalName(ctx context.Context) (string, error) { + if r.moduleOriginalName != nil { + return *r.moduleOriginalName, nil + } + q := r.q.Select("moduleOriginalName") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The path to the module source's context directory on the caller's filesystem. Only valid for local sources. +func (r *ModuleSource) ResolveContextPathFromCaller(ctx context.Context) (string, error) { + if r.resolveContextPathFromCaller != nil { + return *r.resolveContextPathFromCaller, nil + } + q := r.q.Select("resolveContextPathFromCaller") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Resolve the provided module source arg as a dependency relative to this module source. +func (r *ModuleSource) ResolveDependency(dep *ModuleSource) *ModuleSource { + assertNotNil("dep", dep) + q := r.q.Select("resolveDependency") + q = q.Arg("dep", dep) + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// Load the source from its path on the caller's filesystem, including only needed+configured files and directories. Only valid for local sources. +func (r *ModuleSource) ResolveFromCaller() *ModuleSource { + q := r.q.Select("resolveFromCaller") + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// The path relative to context of the root of the module source, which contains dagger.json. It also contains the module implementation source code, but that may or may not being a subdir of this root. +func (r *ModuleSource) SourceRootSubpath(ctx context.Context) (string, error) { + if r.sourceRootSubpath != nil { + return *r.sourceRootSubpath, nil + } + q := r.q.Select("sourceRootSubpath") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The path relative to context of the module implementation source code. +func (r *ModuleSource) SourceSubpath(ctx context.Context) (string, error) { + if r.sourceSubpath != nil { + return *r.sourceSubpath, nil + } + q := r.q.Select("sourceSubpath") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Update the module source with a new context directory. Only valid for local sources. +func (r *ModuleSource) WithContextDirectory(dir *Directory) *ModuleSource { + assertNotNil("dir", dir) + q := r.q.Select("withContextDirectory") + q = q.Arg("dir", dir) + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// Append the provided dependencies to the module source's dependency list. +func (r *ModuleSource) WithDependencies(dependencies []*ModuleDependency) *ModuleSource { + q := r.q.Select("withDependencies") + q = q.Arg("dependencies", dependencies) + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// Update the module source with a new name. +func (r *ModuleSource) WithName(name string) *ModuleSource { + q := r.q.Select("withName") + q = q.Arg("name", name) + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// Update the module source with a new SDK. +func (r *ModuleSource) WithSDK(sdk string) *ModuleSource { + q := r.q.Select("withSDK") + q = q.Arg("sdk", sdk) + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// Update the module source with a new source subpath. +func (r *ModuleSource) WithSourceSubpath(path string) *ModuleSource { + q := r.q.Select("withSourceSubpath") + q = q.Arg("path", path) + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// A definition of a custom object defined in a Module. +type ObjectTypeDef struct { + q *querybuilder.Selection + c graphql.Client + + description *string + id *ObjectTypeDefID + name *string + sourceModuleName *string +} + +// The function used to construct new instances of this object, if any +func (r *ObjectTypeDef) Constructor() *Function { + q := r.q.Select("constructor") + + return &Function{ + q: q, + c: r.c, + } +} + +// The doc string for the object, if any. +func (r *ObjectTypeDef) Description(ctx context.Context) (string, error) { + if r.description != nil { + return *r.description, nil + } + q := r.q.Select("description") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Static fields defined on this object, if any. +func (r *ObjectTypeDef) Fields(ctx context.Context) ([]FieldTypeDef, error) { + q := r.q.Select("fields") + + q = q.Select("id") + + type fields struct { + Id FieldTypeDefID + } + + convert := func(fields []fields) []FieldTypeDef { + out := []FieldTypeDef{} + + for i := range fields { + val := FieldTypeDef{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadFieldTypeDefFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []fields + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// Functions defined on this object, if any. +func (r *ObjectTypeDef) Functions(ctx context.Context) ([]Function, error) { + q := r.q.Select("functions") + + q = q.Select("id") + + type functions struct { + Id FunctionID + } + + convert := func(fields []functions) []Function { + out := []Function{} + + for i := range fields { + val := Function{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadFunctionFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []functions + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// A unique identifier for this ObjectTypeDef. +func (r *ObjectTypeDef) ID(ctx context.Context) (ObjectTypeDefID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response ObjectTypeDefID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *ObjectTypeDef) XXX_GraphQLType() string { + return "ObjectTypeDef" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *ObjectTypeDef) XXX_GraphQLIDType() string { + return "ObjectTypeDefID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *ObjectTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *ObjectTypeDef) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *ObjectTypeDef) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadObjectTypeDefFromID(ObjectTypeDefID(id)) + return nil +} + +// The name of the object. +func (r *ObjectTypeDef) Name(ctx context.Context) (string, error) { + if r.name != nil { + return *r.name, nil + } + q := r.q.Select("name") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// If this ObjectTypeDef is associated with a Module, the name of the module. Unset otherwise. +func (r *ObjectTypeDef) SourceModuleName(ctx context.Context) (string, error) { + if r.sourceModuleName != nil { + return *r.sourceModuleName, nil + } + q := r.q.Select("sourceModuleName") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A port exposed by a container. +type Port struct { + q *querybuilder.Selection + c graphql.Client + + description *string + experimentalSkipHealthcheck *bool + id *PortID + port *int + protocol *NetworkProtocol +} + +// The port description. +func (r *Port) Description(ctx context.Context) (string, error) { + if r.description != nil { + return *r.description, nil + } + q := r.q.Select("description") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Skip the health check when run as a service. +func (r *Port) ExperimentalSkipHealthcheck(ctx context.Context) (bool, error) { + if r.experimentalSkipHealthcheck != nil { + return *r.experimentalSkipHealthcheck, nil + } + q := r.q.Select("experimentalSkipHealthcheck") + + var response bool + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this Port. +func (r *Port) ID(ctx context.Context) (PortID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response PortID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Port) XXX_GraphQLType() string { + return "Port" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Port) XXX_GraphQLIDType() string { + return "PortID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Port) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Port) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Port) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadPortFromID(PortID(id)) + return nil +} + +// The port number. +func (r *Port) Port(ctx context.Context) (int, error) { + if r.port != nil { + return *r.port, nil + } + q := r.q.Select("port") + + var response int + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// The transport layer protocol. +func (r *Port) Protocol(ctx context.Context) (NetworkProtocol, error) { + if r.protocol != nil { + return *r.protocol, nil + } + q := r.q.Select("protocol") + + var response NetworkProtocol + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +type WithClientFunc func(r *Client) *Client + +// With calls the provided function with current Client. +// +// This is useful for reusability and readability by not breaking the calling chain. +func (r *Client) With(f WithClientFunc) *Client { + return f(r) +} + +// Retrieves a content-addressed blob. +func (r *Client) Blob(digest string, size int, mediaType string, uncompressed string) *Directory { + q := r.q.Select("blob") + q = q.Arg("digest", digest) + q = q.Arg("size", size) + q = q.Arg("mediaType", mediaType) + q = q.Arg("uncompressed", uncompressed) + + return &Directory{ + q: q, + c: r.c, + } +} + +// Constructs a cache volume for a given cache key. +func (r *Client) CacheVolume(key string) *CacheVolume { + q := r.q.Select("cacheVolume") + q = q.Arg("key", key) + + return &CacheVolume{ + q: q, + c: r.c, + } +} + +// Checks if the current Dagger Engine is compatible with an SDK's required version. +func (r *Client) CheckVersionCompatibility(ctx context.Context, version string) (bool, error) { + q := r.q.Select("checkVersionCompatibility") + q = q.Arg("version", version) + + var response bool + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// ContainerOpts contains options for Client.Container +type ContainerOpts struct { + // DEPRECATED: Use `loadContainerFromID` instead. + ID ContainerID + // Platform to initialize the container with. + Platform Platform +} + +// Creates a scratch container. +// +// Optional platform argument initializes new containers to execute and publish as that platform. Platform defaults to that of the builder's host. +func (r *Client) Container(opts ...ContainerOpts) *Container { + q := r.q.Select("container") + for i := len(opts) - 1; i >= 0; i-- { + // `id` optional argument + if !querybuilder.IsZeroValue(opts[i].ID) { + q = q.Arg("id", opts[i].ID) + } + // `platform` optional argument + if !querybuilder.IsZeroValue(opts[i].Platform) { + q = q.Arg("platform", opts[i].Platform) + } + } + + return &Container{ + q: q, + c: r.c, + } +} + +// The FunctionCall context that the SDK caller is currently executing in. +// +// If the caller is not currently executing in a function, this will return an error. +func (r *Client) CurrentFunctionCall() *FunctionCall { + q := r.q.Select("currentFunctionCall") + + return &FunctionCall{ + q: q, + c: r.c, + } +} + +// The module currently being served in the session, if any. +func (r *Client) CurrentModule() *CurrentModule { + q := r.q.Select("currentModule") + + return &CurrentModule{ + q: q, + c: r.c, + } +} + +// The TypeDef representations of the objects currently being served in the session. +func (r *Client) CurrentTypeDefs(ctx context.Context) ([]TypeDef, error) { + q := r.q.Select("currentTypeDefs") + + q = q.Select("id") + + type currentTypeDefs struct { + Id TypeDefID + } + + convert := func(fields []currentTypeDefs) []TypeDef { + out := []TypeDef{} + + for i := range fields { + val := TypeDef{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadTypeDefFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []currentTypeDefs + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// The default platform of the engine. +func (r *Client) DefaultPlatform(ctx context.Context) (Platform, error) { + q := r.q.Select("defaultPlatform") + + var response Platform + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// DirectoryOpts contains options for Client.Directory +type DirectoryOpts struct { + // DEPRECATED: Use `loadDirectoryFromID` isntead. + ID DirectoryID +} + +// Creates an empty directory. +func (r *Client) Directory(opts ...DirectoryOpts) *Directory { + q := r.q.Select("directory") + for i := len(opts) - 1; i >= 0; i-- { + // `id` optional argument + if !querybuilder.IsZeroValue(opts[i].ID) { + q = q.Arg("id", opts[i].ID) + } + } + + return &Directory{ + q: q, + c: r.c, + } +} + +// Deprecated: Use LoadFileFromID instead. +func (r *Client) File(id FileID) *File { + q := r.q.Select("file") + q = q.Arg("id", id) + + return &File{ + q: q, + c: r.c, + } +} + +// Creates a function. +func (r *Client) Function(name string, returnType *TypeDef) *Function { + assertNotNil("returnType", returnType) + q := r.q.Select("function") + q = q.Arg("name", name) + q = q.Arg("returnType", returnType) + + return &Function{ + q: q, + c: r.c, + } +} + +// Create a code generation result, given a directory containing the generated code. +func (r *Client) GeneratedCode(code *Directory) *GeneratedCode { + assertNotNil("code", code) + q := r.q.Select("generatedCode") + q = q.Arg("code", code) + + return &GeneratedCode{ + q: q, + c: r.c, + } +} + +// GitOpts contains options for Client.Git +type GitOpts struct { + // Set to true to keep .git directory. + KeepGitDir bool + // A service which must be started before the repo is fetched. + ExperimentalServiceHost *Service + // Set SSH known hosts + SSHKnownHosts string + // Set SSH auth socket + SSHAuthSocket *Socket +} + +// Queries a Git repository. +func (r *Client) Git(url string, opts ...GitOpts) *GitRepository { + q := r.q.Select("git") + for i := len(opts) - 1; i >= 0; i-- { + // `keepGitDir` optional argument + if !querybuilder.IsZeroValue(opts[i].KeepGitDir) { + q = q.Arg("keepGitDir", opts[i].KeepGitDir) + } + // `experimentalServiceHost` optional argument + if !querybuilder.IsZeroValue(opts[i].ExperimentalServiceHost) { + q = q.Arg("experimentalServiceHost", opts[i].ExperimentalServiceHost) + } + // `sshKnownHosts` optional argument + if !querybuilder.IsZeroValue(opts[i].SSHKnownHosts) { + q = q.Arg("sshKnownHosts", opts[i].SSHKnownHosts) + } + // `sshAuthSocket` optional argument + if !querybuilder.IsZeroValue(opts[i].SSHAuthSocket) { + q = q.Arg("sshAuthSocket", opts[i].SSHAuthSocket) + } + } + q = q.Arg("url", url) + + return &GitRepository{ + q: q, + c: r.c, + } +} + +// GolangOpts contains options for Client.Golang +type GolangOpts struct { + Ctr *Container + + Proj *Directory +} + +func (r *Client) Golang(opts ...GolangOpts) *Golang { + q := r.q.Select("golang") + for i := len(opts) - 1; i >= 0; i-- { + // `ctr` optional argument + if !querybuilder.IsZeroValue(opts[i].Ctr) { + q = q.Arg("ctr", opts[i].Ctr) + } + // `proj` optional argument + if !querybuilder.IsZeroValue(opts[i].Proj) { + q = q.Arg("proj", opts[i].Proj) + } + } + + return &Golang{ + q: q, + c: r.c, + } +} + +// HTTPOpts contains options for Client.HTTP +type HTTPOpts struct { + // A service which must be started before the URL is fetched. + ExperimentalServiceHost *Service +} + +// Returns a file containing an http remote url content. +func (r *Client) HTTP(url string, opts ...HTTPOpts) *File { + q := r.q.Select("http") + for i := len(opts) - 1; i >= 0; i-- { + // `experimentalServiceHost` optional argument + if !querybuilder.IsZeroValue(opts[i].ExperimentalServiceHost) { + q = q.Arg("experimentalServiceHost", opts[i].ExperimentalServiceHost) + } + } + q = q.Arg("url", url) + + return &File{ + q: q, + c: r.c, + } +} + +// Load a CacheVolume from its ID. +func (r *Client) LoadCacheVolumeFromID(id CacheVolumeID) *CacheVolume { + q := r.q.Select("loadCacheVolumeFromID") + q = q.Arg("id", id) + + return &CacheVolume{ + q: q, + c: r.c, + } +} + +// Load a Container from its ID. +func (r *Client) LoadContainerFromID(id ContainerID) *Container { + q := r.q.Select("loadContainerFromID") + q = q.Arg("id", id) + + return &Container{ + q: q, + c: r.c, + } +} + +// Load a CurrentModule from its ID. +func (r *Client) LoadCurrentModuleFromID(id CurrentModuleID) *CurrentModule { + q := r.q.Select("loadCurrentModuleFromID") + q = q.Arg("id", id) + + return &CurrentModule{ + q: q, + c: r.c, + } +} + +// Load a Directory from its ID. +func (r *Client) LoadDirectoryFromID(id DirectoryID) *Directory { + q := r.q.Select("loadDirectoryFromID") + q = q.Arg("id", id) + + return &Directory{ + q: q, + c: r.c, + } +} + +// Load a EnvVariable from its ID. +func (r *Client) LoadEnvVariableFromID(id EnvVariableID) *EnvVariable { + q := r.q.Select("loadEnvVariableFromID") + q = q.Arg("id", id) + + return &EnvVariable{ + q: q, + c: r.c, + } +} + +// Load a FieldTypeDef from its ID. +func (r *Client) LoadFieldTypeDefFromID(id FieldTypeDefID) *FieldTypeDef { + q := r.q.Select("loadFieldTypeDefFromID") + q = q.Arg("id", id) + + return &FieldTypeDef{ + q: q, + c: r.c, + } +} + +// Load a File from its ID. +func (r *Client) LoadFileFromID(id FileID) *File { + q := r.q.Select("loadFileFromID") + q = q.Arg("id", id) + + return &File{ + q: q, + c: r.c, + } +} + +// Load a FunctionArg from its ID. +func (r *Client) LoadFunctionArgFromID(id FunctionArgID) *FunctionArg { + q := r.q.Select("loadFunctionArgFromID") + q = q.Arg("id", id) + + return &FunctionArg{ + q: q, + c: r.c, + } +} + +// Load a FunctionCallArgValue from its ID. +func (r *Client) LoadFunctionCallArgValueFromID(id FunctionCallArgValueID) *FunctionCallArgValue { + q := r.q.Select("loadFunctionCallArgValueFromID") + q = q.Arg("id", id) + + return &FunctionCallArgValue{ + q: q, + c: r.c, + } +} + +// Load a FunctionCall from its ID. +func (r *Client) LoadFunctionCallFromID(id FunctionCallID) *FunctionCall { + q := r.q.Select("loadFunctionCallFromID") + q = q.Arg("id", id) + + return &FunctionCall{ + q: q, + c: r.c, + } +} + +// Load a Function from its ID. +func (r *Client) LoadFunctionFromID(id FunctionID) *Function { + q := r.q.Select("loadFunctionFromID") + q = q.Arg("id", id) + + return &Function{ + q: q, + c: r.c, + } +} + +// Load a GeneratedCode from its ID. +func (r *Client) LoadGeneratedCodeFromID(id GeneratedCodeID) *GeneratedCode { + q := r.q.Select("loadGeneratedCodeFromID") + q = q.Arg("id", id) + + return &GeneratedCode{ + q: q, + c: r.c, + } +} + +// Load a GitModuleSource from its ID. +func (r *Client) LoadGitModuleSourceFromID(id GitModuleSourceID) *GitModuleSource { + q := r.q.Select("loadGitModuleSourceFromID") + q = q.Arg("id", id) + + return &GitModuleSource{ + q: q, + c: r.c, + } +} + +// Load a GitRef from its ID. +func (r *Client) LoadGitRefFromID(id GitRefID) *GitRef { + q := r.q.Select("loadGitRefFromID") + q = q.Arg("id", id) + + return &GitRef{ + q: q, + c: r.c, + } +} + +// Load a GitRepository from its ID. +func (r *Client) LoadGitRepositoryFromID(id GitRepositoryID) *GitRepository { + q := r.q.Select("loadGitRepositoryFromID") + q = q.Arg("id", id) + + return &GitRepository{ + q: q, + c: r.c, + } +} + +// Load a Golang from its ID. +func (r *Client) LoadGolangFromID(id GolangID) *Golang { + q := r.q.Select("loadGolangFromID") + q = q.Arg("id", id) + + return &Golang{ + q: q, + c: r.c, + } +} + +// Load a InputTypeDef from its ID. +func (r *Client) LoadInputTypeDefFromID(id InputTypeDefID) *InputTypeDef { + q := r.q.Select("loadInputTypeDefFromID") + q = q.Arg("id", id) + + return &InputTypeDef{ + q: q, + c: r.c, + } +} + +// Load a InterfaceTypeDef from its ID. +func (r *Client) LoadInterfaceTypeDefFromID(id InterfaceTypeDefID) *InterfaceTypeDef { + q := r.q.Select("loadInterfaceTypeDefFromID") + q = q.Arg("id", id) + + return &InterfaceTypeDef{ + q: q, + c: r.c, + } +} + +// Load a Label from its ID. +func (r *Client) LoadLabelFromID(id LabelID) *Label { + q := r.q.Select("loadLabelFromID") + q = q.Arg("id", id) + + return &Label{ + q: q, + c: r.c, + } +} + +// Load a ListTypeDef from its ID. +func (r *Client) LoadListTypeDefFromID(id ListTypeDefID) *ListTypeDef { + q := r.q.Select("loadListTypeDefFromID") + q = q.Arg("id", id) + + return &ListTypeDef{ + q: q, + c: r.c, + } +} + +// Load a LocalModuleSource from its ID. +func (r *Client) LoadLocalModuleSourceFromID(id LocalModuleSourceID) *LocalModuleSource { + q := r.q.Select("loadLocalModuleSourceFromID") + q = q.Arg("id", id) + + return &LocalModuleSource{ + q: q, + c: r.c, + } +} + +// Load a ModuleDependency from its ID. +func (r *Client) LoadModuleDependencyFromID(id ModuleDependencyID) *ModuleDependency { + q := r.q.Select("loadModuleDependencyFromID") + q = q.Arg("id", id) + + return &ModuleDependency{ + q: q, + c: r.c, + } +} + +// Load a Module from its ID. +func (r *Client) LoadModuleFromID(id ModuleID) *Module { + q := r.q.Select("loadModuleFromID") + q = q.Arg("id", id) + + return &Module{ + q: q, + c: r.c, + } +} + +// Load a ModuleSource from its ID. +func (r *Client) LoadModuleSourceFromID(id ModuleSourceID) *ModuleSource { + q := r.q.Select("loadModuleSourceFromID") + q = q.Arg("id", id) + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// Load a ObjectTypeDef from its ID. +func (r *Client) LoadObjectTypeDefFromID(id ObjectTypeDefID) *ObjectTypeDef { + q := r.q.Select("loadObjectTypeDefFromID") + q = q.Arg("id", id) + + return &ObjectTypeDef{ + q: q, + c: r.c, + } +} + +// Load a Port from its ID. +func (r *Client) LoadPortFromID(id PortID) *Port { + q := r.q.Select("loadPortFromID") + q = q.Arg("id", id) + + return &Port{ + q: q, + c: r.c, + } +} + +// Load a Secret from its ID. +func (r *Client) LoadSecretFromID(id SecretID) *Secret { + q := r.q.Select("loadSecretFromID") + q = q.Arg("id", id) + + return &Secret{ + q: q, + c: r.c, + } +} + +// Load a Service from its ID. +func (r *Client) LoadServiceFromID(id ServiceID) *Service { + q := r.q.Select("loadServiceFromID") + q = q.Arg("id", id) + + return &Service{ + q: q, + c: r.c, + } +} + +// Load a Socket from its ID. +func (r *Client) LoadSocketFromID(id SocketID) *Socket { + q := r.q.Select("loadSocketFromID") + q = q.Arg("id", id) + + return &Socket{ + q: q, + c: r.c, + } +} + +// Load a Terminal from its ID. +func (r *Client) LoadTerminalFromID(id TerminalID) *Terminal { + q := r.q.Select("loadTerminalFromID") + q = q.Arg("id", id) + + return &Terminal{ + q: q, + c: r.c, + } +} + +// Load a TypeDef from its ID. +func (r *Client) LoadTypeDefFromID(id TypeDefID) *TypeDef { + q := r.q.Select("loadTypeDefFromID") + q = q.Arg("id", id) + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// Create a new module. +func (r *Client) Module() *Module { + q := r.q.Select("module") + + return &Module{ + q: q, + c: r.c, + } +} + +// ModuleDependencyOpts contains options for Client.ModuleDependency +type ModuleDependencyOpts struct { + // If set, the name to use for the dependency. Otherwise, once installed to a parent module, the name of the dependency module will be used by default. + Name string +} + +// Create a new module dependency configuration from a module source and name +func (r *Client) ModuleDependency(source *ModuleSource, opts ...ModuleDependencyOpts) *ModuleDependency { + assertNotNil("source", source) + q := r.q.Select("moduleDependency") + for i := len(opts) - 1; i >= 0; i-- { + // `name` optional argument + if !querybuilder.IsZeroValue(opts[i].Name) { + q = q.Arg("name", opts[i].Name) + } + } + q = q.Arg("source", source) + + return &ModuleDependency{ + q: q, + c: r.c, + } +} + +// ModuleSourceOpts contains options for Client.ModuleSource +type ModuleSourceOpts struct { + // If true, enforce that the source is a stable version for source kinds that support versioning. + Stable bool +} + +// Create a new module source instance from a source ref string. +func (r *Client) ModuleSource(refString string, opts ...ModuleSourceOpts) *ModuleSource { + q := r.q.Select("moduleSource") + for i := len(opts) - 1; i >= 0; i-- { + // `stable` optional argument + if !querybuilder.IsZeroValue(opts[i].Stable) { + q = q.Arg("stable", opts[i].Stable) + } + } + q = q.Arg("refString", refString) + + return &ModuleSource{ + q: q, + c: r.c, + } +} + +// PipelineOpts contains options for Client.Pipeline +type PipelineOpts struct { + // Description of the sub-pipeline. + Description string + // Labels to apply to the sub-pipeline. + Labels []PipelineLabel +} + +// Creates a named sub-pipeline. +func (r *Client) Pipeline(name string, opts ...PipelineOpts) *Client { + q := r.q.Select("pipeline") + for i := len(opts) - 1; i >= 0; i-- { + // `description` optional argument + if !querybuilder.IsZeroValue(opts[i].Description) { + q = q.Arg("description", opts[i].Description) + } + // `labels` optional argument + if !querybuilder.IsZeroValue(opts[i].Labels) { + q = q.Arg("labels", opts[i].Labels) + } + } + q = q.Arg("name", name) + + return &Client{ + q: q, + c: r.c, + } +} + +// Reference a secret by name. +func (r *Client) Secret(name string) *Secret { + q := r.q.Select("secret") + q = q.Arg("name", name) + + return &Secret{ + q: q, + c: r.c, + } +} + +// Sets a secret given a user defined name to its plaintext and returns the secret. +// +// The plaintext value is limited to a size of 128000 bytes. +func (r *Client) SetSecret(name string, plaintext string) *Secret { + q := r.q.Select("setSecret") + q = q.Arg("name", name) + q = q.Arg("plaintext", plaintext) + + return &Secret{ + q: q, + c: r.c, + } +} + +// Loads a socket by its ID. +// +// Deprecated: Use LoadSocketFromID instead. +func (r *Client) Socket(id SocketID) *Socket { + q := r.q.Select("socket") + q = q.Arg("id", id) + + return &Socket{ + q: q, + c: r.c, + } +} + +// Create a new TypeDef. +func (r *Client) TypeDef() *TypeDef { + q := r.q.Select("typeDef") + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// A reference to a secret value, which can be handled more safely than the value itself. +type Secret struct { + q *querybuilder.Selection + c graphql.Client + + id *SecretID + plaintext *string +} + +// A unique identifier for this Secret. +func (r *Secret) ID(ctx context.Context) (SecretID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response SecretID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Secret) XXX_GraphQLType() string { + return "Secret" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Secret) XXX_GraphQLIDType() string { + return "SecretID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Secret) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Secret) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Secret) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadSecretFromID(SecretID(id)) + return nil +} + +// The value of this secret. +func (r *Secret) Plaintext(ctx context.Context) (string, error) { + if r.plaintext != nil { + return *r.plaintext, nil + } + q := r.q.Select("plaintext") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A content-addressed service providing TCP connectivity. +type Service struct { + q *querybuilder.Selection + c graphql.Client + + endpoint *string + hostname *string + id *ServiceID + start *ServiceID + stop *ServiceID + up *Void +} + +// ServiceEndpointOpts contains options for Service.Endpoint +type ServiceEndpointOpts struct { + // The exposed port number for the endpoint + Port int + // Return a URL with the given scheme, eg. http for http:// + Scheme string +} + +// Retrieves an endpoint that clients can use to reach this container. +// +// If no port is specified, the first exposed port is used. If none exist an error is returned. +// +// If a scheme is specified, a URL is returned. Otherwise, a host:port pair is returned. +func (r *Service) Endpoint(ctx context.Context, opts ...ServiceEndpointOpts) (string, error) { + if r.endpoint != nil { + return *r.endpoint, nil + } + q := r.q.Select("endpoint") + for i := len(opts) - 1; i >= 0; i-- { + // `port` optional argument + if !querybuilder.IsZeroValue(opts[i].Port) { + q = q.Arg("port", opts[i].Port) + } + // `scheme` optional argument + if !querybuilder.IsZeroValue(opts[i].Scheme) { + q = q.Arg("scheme", opts[i].Scheme) + } + } + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Retrieves a hostname which can be used by clients to reach this container. +func (r *Service) Hostname(ctx context.Context) (string, error) { + if r.hostname != nil { + return *r.hostname, nil + } + q := r.q.Select("hostname") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this Service. +func (r *Service) ID(ctx context.Context) (ServiceID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response ServiceID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Service) XXX_GraphQLType() string { + return "Service" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Service) XXX_GraphQLIDType() string { + return "ServiceID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Service) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Service) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Service) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadServiceFromID(ServiceID(id)) + return nil +} + +// Retrieves the list of ports provided by the service. +func (r *Service) Ports(ctx context.Context) ([]Port, error) { + q := r.q.Select("ports") + + q = q.Select("id") + + type ports struct { + Id PortID + } + + convert := func(fields []ports) []Port { + out := []Port{} + + for i := range fields { + val := Port{id: &fields[i].Id} + val.q = querybuilder.Query().Select("loadPortFromID").Arg("id", fields[i].Id) + val.c = r.c + out = append(out, val) + } + + return out + } + var response []ports + + q = q.Bind(&response) + + err := q.Execute(ctx, r.c) + if err != nil { + return nil, err + } + + return convert(response), nil +} + +// Start the service and wait for its health checks to succeed. +// +// Services bound to a Container do not need to be manually started. +func (r *Service) Start(ctx context.Context) (*Service, error) { + q := r.q.Select("start") + + return r, q.Execute(ctx, r.c) +} + +// ServiceStopOpts contains options for Service.Stop +type ServiceStopOpts struct { + // Immediately kill the service without waiting for a graceful exit + Kill bool +} + +// Stop the service. +func (r *Service) Stop(ctx context.Context, opts ...ServiceStopOpts) (*Service, error) { + q := r.q.Select("stop") + for i := len(opts) - 1; i >= 0; i-- { + // `kill` optional argument + if !querybuilder.IsZeroValue(opts[i].Kill) { + q = q.Arg("kill", opts[i].Kill) + } + } + + return r, q.Execute(ctx, r.c) +} + +// ServiceUpOpts contains options for Service.Up +type ServiceUpOpts struct { + // List of frontend/backend port mappings to forward. + // + // Frontend is the port accepting traffic on the host, backend is the service port. + Ports []PortForward + // Bind each tunnel port to a random port on the host. + Random bool +} + +// Creates a tunnel that forwards traffic from the caller's network to this service. +func (r *Service) Up(ctx context.Context, opts ...ServiceUpOpts) (Void, error) { + if r.up != nil { + return *r.up, nil + } + q := r.q.Select("up") + for i := len(opts) - 1; i >= 0; i-- { + // `ports` optional argument + if !querybuilder.IsZeroValue(opts[i].Ports) { + q = q.Arg("ports", opts[i].Ports) + } + // `random` optional argument + if !querybuilder.IsZeroValue(opts[i].Random) { + q = q.Arg("random", opts[i].Random) + } + } + + var response Void + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A Unix or TCP/IP socket that can be mounted into a container. +type Socket struct { + q *querybuilder.Selection + c graphql.Client + + id *SocketID +} + +// A unique identifier for this Socket. +func (r *Socket) ID(ctx context.Context) (SocketID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response SocketID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Socket) XXX_GraphQLType() string { + return "Socket" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Socket) XXX_GraphQLIDType() string { + return "SocketID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Socket) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Socket) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Socket) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadSocketFromID(SocketID(id)) + return nil +} + +// An interactive terminal that clients can connect to. +type Terminal struct { + q *querybuilder.Selection + c graphql.Client + + id *TerminalID + websocketEndpoint *string +} + +// A unique identifier for this Terminal. +func (r *Terminal) ID(ctx context.Context) (TerminalID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response TerminalID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Terminal) XXX_GraphQLType() string { + return "Terminal" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Terminal) XXX_GraphQLIDType() string { + return "TerminalID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Terminal) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Terminal) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Terminal) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadTerminalFromID(TerminalID(id)) + return nil +} + +// An http endpoint at which this terminal can be connected to over a websocket. +func (r *Terminal) WebsocketEndpoint(ctx context.Context) (string, error) { + if r.websocketEndpoint != nil { + return *r.websocketEndpoint, nil + } + q := r.q.Select("websocketEndpoint") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A definition of a parameter or return type in a Module. +type TypeDef struct { + q *querybuilder.Selection + c graphql.Client + + id *TypeDefID + kind *TypeDefKind + optional *bool +} +type WithTypeDefFunc func(r *TypeDef) *TypeDef + +// With calls the provided function with current TypeDef. +// +// This is useful for reusability and readability by not breaking the calling chain. +func (r *TypeDef) With(f WithTypeDefFunc) *TypeDef { + return f(r) +} + +// If kind is INPUT, the input-specific type definition. If kind is not INPUT, this will be null. +func (r *TypeDef) AsInput() *InputTypeDef { + q := r.q.Select("asInput") + + return &InputTypeDef{ + q: q, + c: r.c, + } +} + +// If kind is INTERFACE, the interface-specific type definition. If kind is not INTERFACE, this will be null. +func (r *TypeDef) AsInterface() *InterfaceTypeDef { + q := r.q.Select("asInterface") + + return &InterfaceTypeDef{ + q: q, + c: r.c, + } +} + +// If kind is LIST, the list-specific type definition. If kind is not LIST, this will be null. +func (r *TypeDef) AsList() *ListTypeDef { + q := r.q.Select("asList") + + return &ListTypeDef{ + q: q, + c: r.c, + } +} + +// If kind is OBJECT, the object-specific type definition. If kind is not OBJECT, this will be null. +func (r *TypeDef) AsObject() *ObjectTypeDef { + q := r.q.Select("asObject") + + return &ObjectTypeDef{ + q: q, + c: r.c, + } +} + +// A unique identifier for this TypeDef. +func (r *TypeDef) ID(ctx context.Context) (TypeDefID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response TypeDefID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *TypeDef) XXX_GraphQLType() string { + return "TypeDef" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *TypeDef) XXX_GraphQLIDType() string { + return "TypeDefID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *TypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *TypeDef) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *TypeDef) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadTypeDefFromID(TypeDefID(id)) + return nil +} + +// The kind of type this is (e.g. primitive, list, object). +func (r *TypeDef) Kind(ctx context.Context) (TypeDefKind, error) { + if r.kind != nil { + return *r.kind, nil + } + q := r.q.Select("kind") + + var response TypeDefKind + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Whether this type can be set to null. Defaults to false. +func (r *TypeDef) Optional(ctx context.Context) (bool, error) { + if r.optional != nil { + return *r.optional, nil + } + q := r.q.Select("optional") + + var response bool + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Adds a function for constructing a new instance of an Object TypeDef, failing if the type is not an object. +func (r *TypeDef) WithConstructor(function *Function) *TypeDef { + assertNotNil("function", function) + q := r.q.Select("withConstructor") + q = q.Arg("function", function) + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// TypeDefWithFieldOpts contains options for TypeDef.WithField +type TypeDefWithFieldOpts struct { + // A doc string for the field, if any + Description string +} + +// Adds a static field for an Object TypeDef, failing if the type is not an object. +func (r *TypeDef) WithField(name string, typeDef *TypeDef, opts ...TypeDefWithFieldOpts) *TypeDef { + assertNotNil("typeDef", typeDef) + q := r.q.Select("withField") + for i := len(opts) - 1; i >= 0; i-- { + // `description` optional argument + if !querybuilder.IsZeroValue(opts[i].Description) { + q = q.Arg("description", opts[i].Description) + } + } + q = q.Arg("name", name) + q = q.Arg("typeDef", typeDef) + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// Adds a function for an Object or Interface TypeDef, failing if the type is not one of those kinds. +func (r *TypeDef) WithFunction(function *Function) *TypeDef { + assertNotNil("function", function) + q := r.q.Select("withFunction") + q = q.Arg("function", function) + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// TypeDefWithInterfaceOpts contains options for TypeDef.WithInterface +type TypeDefWithInterfaceOpts struct { + Description string +} + +// Returns a TypeDef of kind Interface with the provided name. +func (r *TypeDef) WithInterface(name string, opts ...TypeDefWithInterfaceOpts) *TypeDef { + q := r.q.Select("withInterface") + for i := len(opts) - 1; i >= 0; i-- { + // `description` optional argument + if !querybuilder.IsZeroValue(opts[i].Description) { + q = q.Arg("description", opts[i].Description) + } + } + q = q.Arg("name", name) + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// Sets the kind of the type. +func (r *TypeDef) WithKind(kind TypeDefKind) *TypeDef { + q := r.q.Select("withKind") + q = q.Arg("kind", kind) + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// Returns a TypeDef of kind List with the provided type for its elements. +func (r *TypeDef) WithListOf(elementType *TypeDef) *TypeDef { + assertNotNil("elementType", elementType) + q := r.q.Select("withListOf") + q = q.Arg("elementType", elementType) + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// TypeDefWithObjectOpts contains options for TypeDef.WithObject +type TypeDefWithObjectOpts struct { + Description string +} + +// Returns a TypeDef of kind Object with the provided name. +// +// Note that an object's fields and functions may be omitted if the intent is only to refer to an object. This is how functions are able to return their own object, or any other circular reference. +func (r *TypeDef) WithObject(name string, opts ...TypeDefWithObjectOpts) *TypeDef { + q := r.q.Select("withObject") + for i := len(opts) - 1; i >= 0; i-- { + // `description` optional argument + if !querybuilder.IsZeroValue(opts[i].Description) { + q = q.Arg("description", opts[i].Description) + } + } + q = q.Arg("name", name) + + return &TypeDef{ + q: q, + c: r.c, + } +} + +// Sets whether this type can be set to null. +func (r *TypeDef) WithOptional(optional bool) *TypeDef { + q := r.q.Select("withOptional") + q = q.Arg("optional", optional) + + return &TypeDef{ + q: q, + c: r.c, + } +} + +type CacheSharingMode string + +func (CacheSharingMode) IsEnum() {} + +const ( + // Shares the cache volume amongst many build pipelines, but will serialize the writes + Locked CacheSharingMode = "LOCKED" + + // Keeps a cache volume for a single build pipeline + Private CacheSharingMode = "PRIVATE" + + // Shares the cache volume amongst many build pipelines + Shared CacheSharingMode = "SHARED" +) + +type ImageLayerCompression string + +func (ImageLayerCompression) IsEnum() {} + +const ( + Estargz ImageLayerCompression = "EStarGZ" + + Gzip ImageLayerCompression = "Gzip" + + Uncompressed ImageLayerCompression = "Uncompressed" + + Zstd ImageLayerCompression = "Zstd" +) + +type ImageMediaTypes string + +func (ImageMediaTypes) IsEnum() {} + +const ( + Dockermediatypes ImageMediaTypes = "DockerMediaTypes" + + Ocimediatypes ImageMediaTypes = "OCIMediaTypes" +) + +type ModuleSourceKind string + +func (ModuleSourceKind) IsEnum() {} + +const ( + GitSource ModuleSourceKind = "GIT_SOURCE" + + LocalSource ModuleSourceKind = "LOCAL_SOURCE" +) + +type NetworkProtocol string + +func (NetworkProtocol) IsEnum() {} + +const ( + Tcp NetworkProtocol = "TCP" + + Udp NetworkProtocol = "UDP" +) + +type TypeDefKind string + +func (TypeDefKind) IsEnum() {} + +const ( + // A boolean value. + BooleanKind TypeDefKind = "BOOLEAN_KIND" + + // A graphql input type, used only when representing the core API via TypeDefs. + InputKind TypeDefKind = "INPUT_KIND" + + // An integer value. + IntegerKind TypeDefKind = "INTEGER_KIND" + + // A named type of functions that can be matched+implemented by other objects+interfaces. + // + // Always paired with an InterfaceTypeDef. + InterfaceKind TypeDefKind = "INTERFACE_KIND" + + // A list of values all having the same type. + // + // Always paired with a ListTypeDef. + ListKind TypeDefKind = "LIST_KIND" + + // A named type defined in the GraphQL schema, with fields and functions. + // + // Always paired with an ObjectTypeDef. + ObjectKind TypeDefKind = "OBJECT_KIND" + + // A string value. + StringKind TypeDefKind = "STRING_KIND" + + // A special kind used to signify that no value is returned. + // + // This is used for functions that have no return value. The outer TypeDef specifying this Kind is always Optional, as the Void is never actually represented. + VoidKind TypeDefKind = "VOID_KIND" +) + +type Client struct { + c graphql.Client + q *querybuilder.Selection +} + +var dag = initDag() + +// initializing the var dag directly rather than using +// an init func so that users can successfully use dag +// in any global var initialization of their own code +func initDag() *Client { + gqlClient, q := getClientParams() + return &Client{ + c: gqlClient, + q: q, + } +} + +func getClientParams() (graphql.Client, *querybuilder.Selection) { + portStr, ok := os.LookupEnv("DAGGER_SESSION_PORT") + if !ok { + panic("DAGGER_SESSION_PORT is not set") + } + port, err := strconv.Atoi(portStr) + if err != nil { + panic(fmt.Errorf("DAGGER_SESSION_PORT %q is invalid: %w", portStr, err)) + } + + sessionToken := os.Getenv("DAGGER_SESSION_TOKEN") + if sessionToken == "" { + panic("DAGGER_SESSION_TOKEN is not set") + } + + host := fmt.Sprintf("127.0.0.1:%d", port) + + dialTransport := &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("tcp", host) + }, + } + httpClient := &http.Client{ + Transport: roundTripperFunc(func(r *http.Request) (*http.Response, error) { + r.SetBasicAuth(sessionToken, "") + return dialTransport.RoundTrip(r) + }), + } + gqlClient := errorWrappedClient{graphql.NewClient(fmt.Sprintf("http://%s/query", host), httpClient)} + + return gqlClient, querybuilder.Query() +} + +// TODO: pollutes namespace, move to non internal package in dagger.io/dagger +type roundTripperFunc func(*http.Request) (*http.Response, error) + +func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) { + return fn(req) +} + +type errorWrappedClient struct { + graphql.Client +} + +func (c errorWrappedClient) MakeRequest(ctx context.Context, req *graphql.Request, resp *graphql.Response) error { + err := c.Client.MakeRequest(ctx, req, resp) + if err != nil { + if e := getCustomError(err); e != nil { + return e + } + return err + } + return nil +} + +func (r *BuildAndRelease) UnmarshalJSON(bs []byte) error { + var concrete struct{} + err := json.Unmarshal(bs, &concrete) + if err != nil { + return err + } + return nil +} + +func main() { + ctx := context.Background() + + fnCall := dag.CurrentFunctionCall() + parentName, err := fnCall.ParentName(ctx) + if err != nil { + fmt.Println(err.Error()) + os.Exit(2) + } + fnName, err := fnCall.Name(ctx) + if err != nil { + fmt.Println(err.Error()) + os.Exit(2) + } + parentJson, err := fnCall.Parent(ctx) + if err != nil { + fmt.Println(err.Error()) + os.Exit(2) + } + fnArgs, err := fnCall.InputArgs(ctx) + if err != nil { + fmt.Println(err.Error()) + os.Exit(2) + } + + inputArgs := map[string][]byte{} + for _, fnArg := range fnArgs { + argName, err := fnArg.Name(ctx) + if err != nil { + fmt.Println(err.Error()) + os.Exit(2) + } + argValue, err := fnArg.Value(ctx) + if err != nil { + fmt.Println(err.Error()) + os.Exit(2) + } + inputArgs[argName] = []byte(argValue) + } + + result, err := invoke(ctx, []byte(parentJson), parentName, fnName, inputArgs) + if err != nil { + fmt.Println(err.Error()) + os.Exit(2) + } + resultBytes, err := json.Marshal(result) + if err != nil { + fmt.Println(err.Error()) + os.Exit(2) + } + _, err = fnCall.ReturnValue(ctx, JSON(resultBytes)) + if err != nil { + fmt.Println(err.Error()) + os.Exit(2) + } +} + +func invoke(ctx context.Context, parentJSON []byte, parentName string, fnName string, inputArgs map[string][]byte) (_ any, err error) { + switch parentName { + case "BuildAndRelease": + switch fnName { + case "Build": + var parent BuildAndRelease + err = json.Unmarshal(parentJSON, &parent) + if err != nil { + panic(fmt.Errorf("%s: %w", "failed to unmarshal parent object", err)) + } + var proj *Directory + if inputArgs["proj"] != nil { + err = json.Unmarshal([]byte(inputArgs["proj"]), &proj) + if err != nil { + panic(fmt.Errorf("%s: %w", "failed to unmarshal input arg proj", err)) + } + } + return (*BuildAndRelease).Build(&parent, proj) + default: + return nil, fmt.Errorf("unknown function %s", fnName) + } + case "": + return dag.Module(). + WithObject( + dag.TypeDef().WithObject("BuildAndRelease"). + WithFunction( + dag.Function("Build", + dag.TypeDef().WithObject("Directory")). + WithArg("proj", dag.TypeDef().WithObject("Directory")))), nil + default: + return nil, fmt.Errorf("unknown object %s", parentName) + } +} diff --git a/chainloop-demo/dagger/build-and-release/main.go b/chainloop-demo/dagger/build-and-release/main.go new file mode 100644 index 0000000..67b3f7e --- /dev/null +++ b/chainloop-demo/dagger/build-and-release/main.go @@ -0,0 +1,11 @@ +package main + +import "context" + +type BuildAndRelease struct{} + +func (m *BuildAndRelease) Build(ctx context.Context, proj *Directory) (*File, error) { + // Build the go binary + binary := dag.Golang().WithProject(proj).Build([]string{"-o", "server"}).File("server") + return binary, nil +} diff --git a/chainloop-demo/dagger/build-and-release/querybuilder/marshal.go b/chainloop-demo/dagger/build-and-release/querybuilder/marshal.go new file mode 100644 index 0000000..1f5468a --- /dev/null +++ b/chainloop-demo/dagger/build-and-release/querybuilder/marshal.go @@ -0,0 +1,162 @@ +package querybuilder + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "reflect" + "strings" + + gqlgen "github.com/99designs/gqlgen/graphql" + "golang.org/x/exp/slices" + "golang.org/x/sync/errgroup" +) + +// GraphQLMarshaller is an internal interface for marshalling an object into GraphQL. +type GraphQLMarshaller interface { + // XXX_GraphQLType is an internal function. It returns the native GraphQL type name + XXX_GraphQLType() string + // XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object + XXX_GraphQLIDType() string + // XXX_GraphqlID is an internal function. It returns the underlying type ID + XXX_GraphQLID(ctx context.Context) (string, error) + json.Marshaler +} + +const ( + GraphQLMarshallerType = "XXX_GraphQLType" + GraphQLMarshallerIDType = "XXX_GraphQLIDType" + GraphQLMarshallerID = "XXX_GraphQLID" +) + +type enum interface { + IsEnum() +} + +var ( + gqlMarshaller = reflect.TypeOf((*GraphQLMarshaller)(nil)).Elem() + enumT = reflect.TypeOf((*enum)(nil)).Elem() +) + +func MarshalGQL(ctx context.Context, v any) (string, error) { + return marshalValue(ctx, reflect.ValueOf(v)) +} + +func marshalValue(ctx context.Context, v reflect.Value) (string, error) { + t := v.Type() + + if t.Implements(gqlMarshaller) { + return marshalCustom(ctx, v) + } + + switch t.Kind() { + case reflect.Bool: + return fmt.Sprintf("%t", v.Bool()), nil + case reflect.Int: + return fmt.Sprintf("%d", v.Int()), nil + case reflect.String: + if t.Implements(enumT) { + // enums render as their literal value + return v.String(), nil + } + + // escape strings following graphQL spec + // https://github.com/graphql/graphql-spec/blob/main/spec/Section%202%20--%20Language.md#string-value + var buf bytes.Buffer + gqlgen.MarshalString(v.String()).MarshalGQL(&buf) + return buf.String(), nil + case reflect.Pointer, reflect.Interface: + if v.IsNil() { + return "null", nil + } + return marshalValue(ctx, v.Elem()) + case reflect.Slice: + n := v.Len() + elems := make([]string, n) + eg, gctx := errgroup.WithContext(ctx) + for i := 0; i < n; i++ { + i := i + eg.Go(func() error { + m, err := marshalValue(gctx, v.Index(i)) + if err != nil { + return err + } + elems[i] = m + return nil + }) + } + if err := eg.Wait(); err != nil { + return "", err + } + return fmt.Sprintf("[%s]", strings.Join(elems, ",")), nil + case reflect.Struct: + n := v.NumField() + elems := make([]string, n) + eg, gctx := errgroup.WithContext(ctx) + for i := 0; i < n; i++ { + i := i + eg.Go(func() error { + f := t.Field(i) + fv := v.Field(i) + name := f.Name + jsonTag := strings.Split(f.Tag.Get("json"), ",") + if jsonTag[0] != "" { + name = jsonTag[0] + } + isOptional := slices.Contains(jsonTag[1:], "omitempty") + if isOptional && IsZeroValue(fv.Interface()) { + return nil + } + m, err := marshalValue(gctx, fv) + if err != nil { + return err + } + if m != `""` && m != "null" { + elems[i] = fmt.Sprintf("%s:%s", name, m) + } + return nil + }) + } + if err := eg.Wait(); err != nil { + return "", err + } + nonNullElems := make([]string, 0, n) + for _, elem := range elems { + if elem != "" { + nonNullElems = append(nonNullElems, elem) + } + } + return fmt.Sprintf("{%s}", strings.Join(nonNullElems, ",")), nil + default: + panic(fmt.Errorf("unsupported argument of kind %s", t.Kind())) + } +} + +func marshalCustom(ctx context.Context, v reflect.Value) (string, error) { + result := v.MethodByName(GraphQLMarshallerID).Call([]reflect.Value{ + reflect.ValueOf(ctx), + }) + if len(result) != 2 { + panic(result) + } + err := result[1].Interface() + if err != nil { + return "", err.(error) + } + + return fmt.Sprintf("%q", result[0].String()), nil +} + +func IsZeroValue(value any) bool { + v := reflect.ValueOf(value) + kind := v.Type().Kind() + switch kind { + case reflect.Pointer: + return v.IsNil() + case reflect.Slice, reflect.Array: + return v.Len() == 0 + default: + return v.IsZero() + } +} diff --git a/chainloop-demo/dagger/build-and-release/querybuilder/querybuilder.go b/chainloop-demo/dagger/build-and-release/querybuilder/querybuilder.go new file mode 100644 index 0000000..c2841e5 --- /dev/null +++ b/chainloop-demo/dagger/build-and-release/querybuilder/querybuilder.go @@ -0,0 +1,183 @@ +package querybuilder + +import ( + "context" + "encoding/json" + "fmt" + "strings" + "sync" + + "github.com/Khan/genqlient/graphql" + "golang.org/x/sync/errgroup" +) + +func Query() *Selection { + return &Selection{} +} + +type Selection struct { + name string + alias string + args map[string]*argument + bind interface{} + + prev *Selection +} + +func (s *Selection) path() []*Selection { + selections := []*Selection{} + for sel := s; sel.prev != nil; sel = sel.prev { + selections = append([]*Selection{sel}, selections...) + } + + return selections +} + +func (s *Selection) SelectWithAlias(alias, name string) *Selection { + sel := &Selection{ + name: name, + prev: s, + alias: alias, + } + return sel +} + +func (s *Selection) Select(name string) *Selection { + return s.SelectWithAlias("", name) +} + +func (s *Selection) Arg(name string, value any) *Selection { + sel := *s + if sel.args == nil { + sel.args = map[string]*argument{} + } + + sel.args[name] = &argument{ + value: value, + } + return &sel +} + +func (s *Selection) Bind(v interface{}) *Selection { + sel := *s + sel.bind = v + return &sel +} + +func (s *Selection) marshalArguments(ctx context.Context) error { + eg, gctx := errgroup.WithContext(ctx) + for _, sel := range s.path() { + for _, arg := range sel.args { + arg := arg + eg.Go(func() error { + return arg.marshal(gctx) + }) + } + } + + return eg.Wait() +} + +func (s *Selection) Build(ctx context.Context) (string, error) { + if err := s.marshalArguments(ctx); err != nil { + return "", err + } + + var b strings.Builder + b.WriteString("query") + + path := s.path() + + for _, sel := range path { + b.WriteRune('{') + + if sel.alias != "" { + b.WriteString(sel.alias) + b.WriteRune(':') + } + + b.WriteString(sel.name) + + if len(sel.args) > 0 { + b.WriteRune('(') + i := 0 + for name, arg := range sel.args { + if i > 0 { + b.WriteString(", ") + } + b.WriteString(name) + b.WriteRune(':') + b.WriteString(arg.marshalled) + i++ + } + b.WriteRune(')') + } + } + + b.WriteString(strings.Repeat("}", len(path))) + return b.String(), nil +} + +func (s *Selection) unpack(data interface{}) error { + for _, i := range s.path() { + k := i.name + if i.alias != "" { + k = i.alias + } + + // Try to assert type of the value + switch f := data.(type) { + case map[string]interface{}: + data = f[k] + case []interface{}: + data = f + default: + fmt.Printf("type not found %s\n", f) + } + + if i.bind != nil { + marshalled, err := json.Marshal(data) + if err != nil { + return err + } + json.Unmarshal(marshalled, s.bind) + } + } + + return nil +} + +func (s *Selection) Execute(ctx context.Context, c graphql.Client) error { + query, err := s.Build(ctx) + if err != nil { + return err + } + + var response any + err = c.MakeRequest(ctx, + &graphql.Request{ + Query: query, + }, + &graphql.Response{Data: &response}, + ) + if err != nil { + return err + } + + return s.unpack(response) +} + +type argument struct { + value any + + marshalled string + marshalledErr error + once sync.Once +} + +func (a *argument) marshal(ctx context.Context) error { + a.once.Do(func() { + a.marshalled, a.marshalledErr = MarshalGQL(ctx, a.value) + }) + return a.marshalledErr +} diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json new file mode 100644 index 0000000..084d747 --- /dev/null +++ b/chainloop-demo/dagger/dagger.json @@ -0,0 +1,12 @@ +{ + "name": "build-and-release", + "sdk": "go", + "dependencies": [ + { + "name": "golang", + "source": "github.com/kpenfound/dagger-modules/golang@5cb802660efb1242e5d7beb382f772f0a3f34616" + } + ], + "source": "build-and-release", + "engineVersion": "v0.9.10" +} diff --git a/go.mod b/go.mod index 365172f..7b9c5de 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,16 @@ module github.com/chainloop-dev/integration-demo go 1.19 require ( + github.com/99designs/gqlgen v0.17.44 + github.com/Khan/genqlient v0.6.0 github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f github.com/mattn/go-sqlite3 v1.14.16 + github.com/vektah/gqlparser/v2 v2.5.11 + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a + golang.org/x/sync v0.6.0 +) + +require ( + github.com/google/uuid v1.6.0 // indirect + github.com/sosodev/duration v1.2.0 // indirect ) diff --git a/go.sum b/go.sum index 4f2ade7..a4d2f72 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,24 @@ +github.com/99designs/gqlgen v0.17.44 h1:OS2wLk/67Y+vXM75XHbwRnNYJcbuJd4OBL76RX3NQQA= +github.com/99designs/gqlgen v0.17.44/go.mod h1:UTCu3xpK2mLI5qcMNw+HKDiEL77it/1XtAjisC4sLwM= +github.com/Khan/genqlient v0.6.0 h1:Bwb1170ekuNIVIwTJEqvO8y7RxBxXu639VJOkKSrwAk= +github.com/Khan/genqlient v0.6.0/go.mod h1:rvChwWVTqXhiapdhLDV4bp9tz/Xvtewwkon4DpWWCRM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f h1:gOO/tNZMjjvTKZWpY7YnXC72ULNLErRtp94LountVE8= github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sosodev/duration v1.2.0 h1:pqK/FLSjsAADWY74SyWDCjOcd5l7H8GSnnOGEB9A1Us= +github.com/sosodev/duration v1.2.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= +github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From c77910a207544b281ddcf9dddcd57d57fa41ad6c Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 18:20:32 +0100 Subject: [PATCH 08/34] initial build and publish Signed-off-by: Miguel Martinez Trivino --- .../dagger/build-and-release/dagger.gen.go | 232 +++++++++++++++++- .../dagger/build-and-release/main.go | 23 +- chainloop-demo/dagger/dagger.json | 8 + 3 files changed, 258 insertions(+), 5 deletions(-) diff --git a/chainloop-demo/dagger/build-and-release/dagger.gen.go b/chainloop-demo/dagger/build-and-release/dagger.gen.go index 91768c2..1c0f5bc 100644 --- a/chainloop-demo/dagger/build-and-release/dagger.gen.go +++ b/chainloop-demo/dagger/build-and-release/dagger.gen.go @@ -213,6 +213,9 @@ type ServiceID string // The `SocketID` scalar type represents an identifier for an object of type Socket. type SocketID string +// The `SyftID` scalar type represents an identifier for an object of type Syft. +type SyftID string + // The `TerminalID` scalar type represents an identifier for an object of type Terminal. type TerminalID string @@ -224,6 +227,9 @@ type TypeDefID string // A Null Void is used as a placeholder for resolvers that do not return anything. type Void string +// The `WolfiID` scalar type represents an identifier for an object of type Wolfi. +type WolfiID string + // Key value object that represents a build argument. type BuildArg struct { // The build argument name. @@ -5951,6 +5957,17 @@ func (r *Client) LoadSocketFromID(id SocketID) *Socket { } } +// Load a Syft from its ID. +func (r *Client) LoadSyftFromID(id SyftID) *Syft { + q := r.q.Select("loadSyftFromID") + q = q.Arg("id", id) + + return &Syft{ + q: q, + c: r.c, + } +} + // Load a Terminal from its ID. func (r *Client) LoadTerminalFromID(id TerminalID) *Terminal { q := r.q.Select("loadTerminalFromID") @@ -5973,6 +5990,17 @@ func (r *Client) LoadTypeDefFromID(id TypeDefID) *TypeDef { } } +// Load a Wolfi from its ID. +func (r *Client) LoadWolfiFromID(id WolfiID) *Wolfi { + q := r.q.Select("loadWolfiFromID") + q = q.Arg("id", id) + + return &Wolfi{ + q: q, + c: r.c, + } +} + // Create a new module. func (r *Client) Module() *Module { q := r.q.Select("module") @@ -6097,6 +6125,15 @@ func (r *Client) Socket(id SocketID) *Socket { } } +func (r *Client) Syft() *Syft { + q := r.q.Select("syft") + + return &Syft{ + q: q, + c: r.c, + } +} + // Create a new TypeDef. func (r *Client) TypeDef() *TypeDef { q := r.q.Select("typeDef") @@ -6107,6 +6144,15 @@ func (r *Client) TypeDef() *TypeDef { } } +func (r *Client) Wolfi() *Wolfi { + q := r.q.Select("wolfi") + + return &Wolfi{ + q: q, + c: r.c, + } +} + // A reference to a secret value, which can be handled more safely than the value itself. type Secret struct { q *querybuilder.Selection @@ -6440,6 +6486,97 @@ func (r *Socket) UnmarshalJSON(bs []byte) error { return nil } +type Syft struct { + q *querybuilder.Selection + c graphql.Client + + id *SyftID +} + +// A unique identifier for this Syft. +func (r *Syft) ID(ctx context.Context) (SyftID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response SyftID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Syft) XXX_GraphQLType() string { + return "Syft" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Syft) XXX_GraphQLIDType() string { + return "SyftID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Syft) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Syft) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Syft) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadSyftFromID(SyftID(id)) + return nil +} + +// SyftSbomOpts contains options for Syft.Sbom +type SyftSbomOpts struct { + // + // The image to run the job in + // + Image string + // + // The output format + // + Output string +} + +// Generate a software bill of materials +func (r *Syft) Sbom(src *Directory, outputFile string, opts ...SyftSbomOpts) *File { + assertNotNil("src", src) + q := r.q.Select("sbom") + for i := len(opts) - 1; i >= 0; i-- { + // `image` optional argument + if !querybuilder.IsZeroValue(opts[i].Image) { + q = q.Arg("image", opts[i].Image) + } + // `output` optional argument + if !querybuilder.IsZeroValue(opts[i].Output) { + q = q.Arg("output", opts[i].Output) + } + } + q = q.Arg("src", src) + q = q.Arg("outputFile", outputFile) + + return &File{ + q: q, + c: r.c, + } +} + // An interactive terminal that clients can connect to. type Terminal struct { q *querybuilder.Selection @@ -6773,6 +6910,97 @@ func (r *TypeDef) WithOptional(optional bool) *TypeDef { } } +// A Dagger Module to integrate with Wolfi Linux +// https://wolfi.dev +type Wolfi struct { + q *querybuilder.Selection + c graphql.Client + + id *WolfiID +} + +// WolfiContainerOpts contains options for Wolfi.Container +type WolfiContainerOpts struct { + // + // APK packages to install + // + Packages []string + // + // Overlay images to merge on top of the base. + // See https://twitter.com/ibuildthecloud/status/1721306361999597884 + // + Overlays []*Container +} + +// Build a Wolfi Linux container +func (r *Wolfi) Container(opts ...WolfiContainerOpts) *Container { + q := r.q.Select("container") + for i := len(opts) - 1; i >= 0; i-- { + // `packages` optional argument + if !querybuilder.IsZeroValue(opts[i].Packages) { + q = q.Arg("packages", opts[i].Packages) + } + // `overlays` optional argument + if !querybuilder.IsZeroValue(opts[i].Overlays) { + q = q.Arg("overlays", opts[i].Overlays) + } + } + + return &Container{ + q: q, + c: r.c, + } +} + +// A unique identifier for this Wolfi. +func (r *Wolfi) ID(ctx context.Context) (WolfiID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response WolfiID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Wolfi) XXX_GraphQLType() string { + return "Wolfi" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Wolfi) XXX_GraphQLIDType() string { + return "WolfiID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Wolfi) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Wolfi) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Wolfi) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadWolfiFromID(WolfiID(id)) + return nil +} + type CacheSharingMode string func (CacheSharingMode) IsEnum() {} @@ -7026,7 +7254,7 @@ func invoke(ctx context.Context, parentJSON []byte, parentName string, fnName st panic(fmt.Errorf("%s: %w", "failed to unmarshal input arg proj", err)) } } - return (*BuildAndRelease).Build(&parent, proj) + return (*BuildAndRelease).Build(&parent, ctx, proj) default: return nil, fmt.Errorf("unknown function %s", fnName) } @@ -7036,7 +7264,7 @@ func invoke(ctx context.Context, parentJSON []byte, parentName string, fnName st dag.TypeDef().WithObject("BuildAndRelease"). WithFunction( dag.Function("Build", - dag.TypeDef().WithObject("Directory")). + dag.TypeDef().WithObject("File")). WithArg("proj", dag.TypeDef().WithObject("Directory")))), nil default: return nil, fmt.Errorf("unknown object %s", parentName) diff --git a/chainloop-demo/dagger/build-and-release/main.go b/chainloop-demo/dagger/build-and-release/main.go index 67b3f7e..8120334 100644 --- a/chainloop-demo/dagger/build-and-release/main.go +++ b/chainloop-demo/dagger/build-and-release/main.go @@ -1,11 +1,28 @@ package main -import "context" +import ( + "context" + "fmt" + "math" + "math/rand" +) type BuildAndRelease struct{} -func (m *BuildAndRelease) Build(ctx context.Context, proj *Directory) (*File, error) { +func (m *BuildAndRelease) Build(ctx context.Context, proj *Directory) (string, error) { + // Generate SBOM from the code + _ = dag.Syft().Sbom(proj, "sbom.json", SyftSbomOpts{Output: "cyclonedx-json"}) + // Build the go binary binary := dag.Golang().WithProject(proj).Build([]string{"-o", "server"}).File("server") - return binary, nil + + imagePath, err := dag.Wolfi().Container(). + WithFile("/server", binary). + WithEntrypoint([]string{"/server"}). + Publish(ctx, fmt.Sprintf("ttl.sh/chainloop-demo-%.0f", math.Floor(rand.Float64()*10000000))) //#nosec + if err != nil { + return "", err + } + + return imagePath, nil } diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index 084d747..72b770f 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -2,9 +2,17 @@ "name": "build-and-release", "sdk": "go", "dependencies": [ + { + "name": "wolfi", + "source": "github.com/shykes/daggerverse/wolfi@f678bfe29024559abec0ac77fbbd558bc8402cdf" + }, { "name": "golang", "source": "github.com/kpenfound/dagger-modules/golang@5cb802660efb1242e5d7beb382f772f0a3f34616" + }, + { + "name": "syft", + "source": "github.com/fluent-ci-templates/syft-pipeline@5cfd62b6070ff68731875fe7aacdbfd7910e5a95" } ], "source": "build-and-release", From 3fc0ddaf7619db1c6130b6361bfacd9107d0e2e4 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 18:22:22 +0100 Subject: [PATCH 09/34] initial build and publish Signed-off-by: Miguel Martinez Trivino --- chainloop-demo/dagger/build-and-release/dagger.gen.go | 6 +++--- chainloop-demo/dagger/build-and-release/main.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/chainloop-demo/dagger/build-and-release/dagger.gen.go b/chainloop-demo/dagger/build-and-release/dagger.gen.go index 1c0f5bc..efa15a1 100644 --- a/chainloop-demo/dagger/build-and-release/dagger.gen.go +++ b/chainloop-demo/dagger/build-and-release/dagger.gen.go @@ -7171,7 +7171,7 @@ func (c errorWrappedClient) MakeRequest(ctx context.Context, req *graphql.Reques return nil } -func (r *BuildAndRelease) UnmarshalJSON(bs []byte) error { +func (r *Demo) UnmarshalJSON(bs []byte) error { var concrete struct{} err := json.Unmarshal(bs, &concrete) if err != nil { @@ -7242,7 +7242,7 @@ func invoke(ctx context.Context, parentJSON []byte, parentName string, fnName st case "BuildAndRelease": switch fnName { case "Build": - var parent BuildAndRelease + var parent Demo err = json.Unmarshal(parentJSON, &parent) if err != nil { panic(fmt.Errorf("%s: %w", "failed to unmarshal parent object", err)) @@ -7254,7 +7254,7 @@ func invoke(ctx context.Context, parentJSON []byte, parentName string, fnName st panic(fmt.Errorf("%s: %w", "failed to unmarshal input arg proj", err)) } } - return (*BuildAndRelease).Build(&parent, ctx, proj) + return (*Demo).Build(&parent, ctx, proj) default: return nil, fmt.Errorf("unknown function %s", fnName) } diff --git a/chainloop-demo/dagger/build-and-release/main.go b/chainloop-demo/dagger/build-and-release/main.go index 8120334..d7d0fc8 100644 --- a/chainloop-demo/dagger/build-and-release/main.go +++ b/chainloop-demo/dagger/build-and-release/main.go @@ -9,7 +9,7 @@ import ( type BuildAndRelease struct{} -func (m *BuildAndRelease) Build(ctx context.Context, proj *Directory) (string, error) { +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) (string, error) { // Generate SBOM from the code _ = dag.Syft().Sbom(proj, "sbom.json", SyftSbomOpts{Output: "cyclonedx-json"}) From dca46b9baffe95fe5c6aa473efb8b397f7ee2990 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 22:37:10 +0100 Subject: [PATCH 10/34] initial build and publish Signed-off-by: Miguel Martinez Trivino --- .../dagger/build-and-release/dagger.gen.go | 265 +++++++++++++++++- .../dagger/build-and-release/main.go | 49 +++- chainloop-demo/dagger/dagger.json | 8 +- 3 files changed, 309 insertions(+), 13 deletions(-) diff --git a/chainloop-demo/dagger/build-and-release/dagger.gen.go b/chainloop-demo/dagger/build-and-release/dagger.gen.go index efa15a1..093954c 100644 --- a/chainloop-demo/dagger/build-and-release/dagger.gen.go +++ b/chainloop-demo/dagger/build-and-release/dagger.gen.go @@ -121,6 +121,9 @@ func (e *ExecError) Unwrap() error { // The `CacheVolumeID` scalar type represents an identifier for an object of type CacheVolume. type CacheVolumeID string +// The `ChainloopID` scalar type represents an identifier for an object of type Chainloop. +type ChainloopID string + // The `ContainerID` scalar type represents an identifier for an object of type Container. type ContainerID string @@ -317,6 +320,234 @@ func (r *CacheVolume) UnmarshalJSON(bs []byte) error { return nil } +type Chainloop struct { + q *querybuilder.Selection + c graphql.Client + + attestationAdd *string + attestationInit *string + attestationPush *string + attestationReset *string + attestationStatus *string + id *ChainloopID +} + +// ChainloopAttestationAddOpts contains options for Chainloop.AttestationAdd +type ChainloopAttestationAddOpts struct { + // + // path to the file to be added + // + Path *File + // + // raw value to be added + // + Value string + // + // Container Registry Credentials for Container image-based materials + // i.e docker.io, ghcr.io, etc + // + Registry string + + RegistryUsername string + + RegistryPassword *Secret +} + +// Add a piece of evidence/material to the current attestation +// The material value can be provided either in the form of a file or as a raw string +// The file type is required for materials of kind ARTIFACT that are uploaded to the CAS +func (r *Chainloop) AttestationAdd(ctx context.Context, attestationId string, name string, opts ...ChainloopAttestationAddOpts) (string, error) { + if r.attestationAdd != nil { + return *r.attestationAdd, nil + } + q := r.q.Select("attestationAdd") + for i := len(opts) - 1; i >= 0; i-- { + // `path` optional argument + if !querybuilder.IsZeroValue(opts[i].Path) { + q = q.Arg("path", opts[i].Path) + } + // `value` optional argument + if !querybuilder.IsZeroValue(opts[i].Value) { + q = q.Arg("value", opts[i].Value) + } + // `registry` optional argument + if !querybuilder.IsZeroValue(opts[i].Registry) { + q = q.Arg("registry", opts[i].Registry) + } + // `registryUsername` optional argument + if !querybuilder.IsZeroValue(opts[i].RegistryUsername) { + q = q.Arg("registryUsername", opts[i].RegistryUsername) + } + // `registryPassword` optional argument + if !querybuilder.IsZeroValue(opts[i].RegistryPassword) { + q = q.Arg("registryPassword", opts[i].RegistryPassword) + } + } + q = q.Arg("attestationId", attestationId) + q = q.Arg("name", name) + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// ChainloopAttestationInitOpts contains options for Chainloop.AttestationInit +type ChainloopAttestationInitOpts struct { + // + // Workflow Contract revision, default is the latest + // + ContractRevision string + // + // Path to the git repository to be attested + // + Repository *Directory +} + +// Start the attestation crafting process +func (r *Chainloop) AttestationInit(ctx context.Context, opts ...ChainloopAttestationInitOpts) (string, error) { + if r.attestationInit != nil { + return *r.attestationInit, nil + } + q := r.q.Select("attestationInit") + for i := len(opts) - 1; i >= 0; i-- { + // `contractRevision` optional argument + if !querybuilder.IsZeroValue(opts[i].ContractRevision) { + q = q.Arg("contractRevision", opts[i].ContractRevision) + } + // `repository` optional argument + if !querybuilder.IsZeroValue(opts[i].Repository) { + q = q.Arg("repository", opts[i].Repository) + } + } + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Generate, sign and push the attestation to the control plane +func (r *Chainloop) AttestationPush(ctx context.Context, attestationId string, signingKey *Secret, passphrase *Secret) (string, error) { + assertNotNil("signingKey", signingKey) + assertNotNil("passphrase", passphrase) + if r.attestationPush != nil { + return *r.attestationPush, nil + } + q := r.q.Select("attestationPush") + q = q.Arg("attestationId", attestationId) + q = q.Arg("signingKey", signingKey) + q = q.Arg("passphrase", passphrase) + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// ChainloopAttestationResetOpts contains options for Chainloop.AttestationReset +type ChainloopAttestationResetOpts struct { + Trigger string + + Reason string +} + +// Mark current attestation process as canceled or failed. --trigger "failure" | "cancellation" (default: "failure") +func (r *Chainloop) AttestationReset(ctx context.Context, attestationId string, opts ...ChainloopAttestationResetOpts) (string, error) { + if r.attestationReset != nil { + return *r.attestationReset, nil + } + q := r.q.Select("attestationReset") + for i := len(opts) - 1; i >= 0; i-- { + // `trigger` optional argument + if !querybuilder.IsZeroValue(opts[i].Trigger) { + q = q.Arg("trigger", opts[i].Trigger) + } + // `reason` optional argument + if !querybuilder.IsZeroValue(opts[i].Reason) { + q = q.Arg("reason", opts[i].Reason) + } + } + q = q.Arg("attestationId", attestationId) + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// Check the status of the current attestation +func (r *Chainloop) AttestationStatus(ctx context.Context, attestationId string) (string, error) { + if r.attestationStatus != nil { + return *r.attestationStatus, nil + } + q := r.q.Select("attestationStatus") + q = q.Arg("attestationId", attestationId) + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// A unique identifier for this Chainloop. +func (r *Chainloop) ID(ctx context.Context) (ChainloopID, error) { + if r.id != nil { + return *r.id, nil + } + q := r.q.Select("id") + + var response ChainloopID + + q = q.Bind(&response) + return response, q.Execute(ctx, r.c) +} + +// XXX_GraphQLType is an internal function. It returns the native GraphQL type name +func (r *Chainloop) XXX_GraphQLType() string { + return "Chainloop" +} + +// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object +func (r *Chainloop) XXX_GraphQLIDType() string { + return "ChainloopID" +} + +// XXX_GraphQLID is an internal function. It returns the underlying type ID +func (r *Chainloop) XXX_GraphQLID(ctx context.Context) (string, error) { + id, err := r.ID(ctx) + if err != nil { + return "", err + } + return string(id), nil +} + +func (r *Chainloop) MarshalJSON() ([]byte, error) { + id, err := r.ID(context.Background()) + if err != nil { + return nil, err + } + return json.Marshal(id) +} +func (r *Chainloop) UnmarshalJSON(bs []byte) error { + var id string + err := json.Unmarshal(bs, &id) + if err != nil { + return err + } + *r = *dag.LoadChainloopFromID(ChainloopID(id)) + return nil +} + +func (r *Chainloop) Token() *Secret { + q := r.q.Select("token") + + return &Secret{ + q: q, + c: r.c, + } +} + // An OCI-compatible container, also known as a Docker container. type Container struct { q *querybuilder.Selection @@ -5383,6 +5614,17 @@ func (r *Client) CacheVolume(key string) *CacheVolume { } } +func (r *Client) Chainloop(token *Secret) *Chainloop { + assertNotNil("token", token) + q := r.q.Select("chainloop") + q = q.Arg("token", token) + + return &Chainloop{ + q: q, + c: r.c, + } +} + // Checks if the current Dagger Engine is compatible with an SDK's required version. func (r *Client) CheckVersionCompatibility(ctx context.Context, version string) (bool, error) { q := r.q.Select("checkVersionCompatibility") @@ -5649,6 +5891,17 @@ func (r *Client) LoadCacheVolumeFromID(id CacheVolumeID) *CacheVolume { } } +// Load a Chainloop from its ID. +func (r *Client) LoadChainloopFromID(id ChainloopID) *Chainloop { + q := r.q.Select("loadChainloopFromID") + q = q.Arg("id", id) + + return &Chainloop{ + q: q, + c: r.c, + } +} + // Load a Container from its ID. func (r *Client) LoadContainerFromID(id ContainerID) *Container { q := r.q.Select("loadContainerFromID") @@ -7171,7 +7424,7 @@ func (c errorWrappedClient) MakeRequest(ctx context.Context, req *graphql.Reques return nil } -func (r *Demo) UnmarshalJSON(bs []byte) error { +func (r *BuildAndRelease) UnmarshalJSON(bs []byte) error { var concrete struct{} err := json.Unmarshal(bs, &concrete) if err != nil { @@ -7241,8 +7494,8 @@ func invoke(ctx context.Context, parentJSON []byte, parentName string, fnName st switch parentName { case "BuildAndRelease": switch fnName { - case "Build": - var parent Demo + case "BuildAndPublish": + var parent BuildAndRelease err = json.Unmarshal(parentJSON, &parent) if err != nil { panic(fmt.Errorf("%s: %w", "failed to unmarshal parent object", err)) @@ -7254,7 +7507,7 @@ func invoke(ctx context.Context, parentJSON []byte, parentName string, fnName st panic(fmt.Errorf("%s: %w", "failed to unmarshal input arg proj", err)) } } - return (*Demo).Build(&parent, ctx, proj) + return (*BuildAndRelease).BuildAndPublish(&parent, ctx, proj) default: return nil, fmt.Errorf("unknown function %s", fnName) } @@ -7263,8 +7516,8 @@ func invoke(ctx context.Context, parentJSON []byte, parentName string, fnName st WithObject( dag.TypeDef().WithObject("BuildAndRelease"). WithFunction( - dag.Function("Build", - dag.TypeDef().WithObject("File")). + dag.Function("BuildAndPublish", + dag.TypeDef().WithKind(StringKind)). WithArg("proj", dag.TypeDef().WithObject("Directory")))), nil default: return nil, fmt.Errorf("unknown object %s", parentName) diff --git a/chainloop-demo/dagger/build-and-release/main.go b/chainloop-demo/dagger/build-and-release/main.go index d7d0fc8..e463b93 100644 --- a/chainloop-demo/dagger/build-and-release/main.go +++ b/chainloop-demo/dagger/build-and-release/main.go @@ -9,14 +9,34 @@ import ( type BuildAndRelease struct{} -func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) (string, error) { - // Generate SBOM from the code - _ = dag.Syft().Sbom(proj, "sbom.json", SyftSbomOpts{Output: "cyclonedx-json"}) +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { + var err error + + // Initialize the attestation + attestationID, err := dag.Chainloop(chainloopToken).AttestationInit(ctx, ChainloopAttestationInitOpts{Repository: proj}) + if err != nil { + return "", fmt.Errorf("failed to initialize attestation: %w", err) + } + + // Finish the attestation once we are done + defer func() { + // If there was an error in the process, mark the attestation as failed in Chainloop + if err != nil { + dag.Chainloop(chainloopToken).AttestationReset(ctx, attestationID, ChainloopAttestationResetOpts{Reason: err.Error()}) + } else { + // Push the attestation to Chainloop + _, err = dag.Chainloop(chainloopToken).AttestationPush(ctx, attestationID, chainloopSigningKey, chainloopPassphrase) + } + }() // Build the go binary binary := dag.Golang().WithProject(proj).Build([]string{"-o", "server"}).File("server") - imagePath, err := dag.Wolfi().Container(). + // Generate SBOM from the code + sbom := dag.Syft().Sbom(proj, "sbom.json", SyftSbomOpts{Output: "cyclonedx-json"}) + + // Build and publish a container image + imageRepo, err := dag.Wolfi().Container(). WithFile("/server", binary). WithEntrypoint([]string{"/server"}). Publish(ctx, fmt.Sprintf("ttl.sh/chainloop-demo-%.0f", math.Floor(rand.Float64()*10000000))) //#nosec @@ -24,5 +44,24 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) return "", err } - return imagePath, nil + // Attest the pieces of evidence + // Container image + _, err = dag.Chainloop(chainloopToken).AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: imageRepo}) + if err != nil { + return "", fmt.Errorf("failed to add image piece of evidence: %w", err) + } + + // Binary + _, err = dag.Chainloop(chainloopToken).AttestationAdd(ctx, attestationID, "binary", ChainloopAttestationAddOpts{Path: binary}) + if err != nil { + return "", fmt.Errorf("failed to add binary piece of evidence: %w", err) + } + + // SBOM + _, err = dag.Chainloop(chainloopToken).AttestationAdd(ctx, attestationID, "sbom", ChainloopAttestationAddOpts{Path: sbom}) + if err != nil { + return "", fmt.Errorf("failed to add SBOM piece of evidence: %w", err) + } + + return imageRepo, nil } diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index 72b770f..465fe64 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -3,8 +3,8 @@ "sdk": "go", "dependencies": [ { - "name": "wolfi", - "source": "github.com/shykes/daggerverse/wolfi@f678bfe29024559abec0ac77fbbd558bc8402cdf" + "name": "chainloop", + "source": "github.com/chainloop-dev/chainloop/extras/dagger@ae2e814ef5f33b2098371349235a2f387217af2f" }, { "name": "golang", @@ -13,6 +13,10 @@ { "name": "syft", "source": "github.com/fluent-ci-templates/syft-pipeline@5cfd62b6070ff68731875fe7aacdbfd7910e5a95" + }, + { + "name": "wolfi", + "source": "github.com/shykes/daggerverse/wolfi@f678bfe29024559abec0ac77fbbd558bc8402cdf" } ], "source": "build-and-release", From 41b5f789cdea0f8b4cffe0d1a84975ab53c3271d Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 22:57:49 +0100 Subject: [PATCH 11/34] initial build and publish Signed-off-by: Miguel Martinez Trivino --- .../dagger/build-and-release/main.go | 61 +++++++++++++------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/chainloop-demo/dagger/build-and-release/main.go b/chainloop-demo/dagger/build-and-release/main.go index e463b93..9d81d89 100644 --- a/chainloop-demo/dagger/build-and-release/main.go +++ b/chainloop-demo/dagger/build-and-release/main.go @@ -9,11 +9,14 @@ import ( type BuildAndRelease struct{} +// Build and Publish a go-application as a container image +// Attest the pieces of evidence to Chainloop func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { var err error + chainloopClient := dag.Chainloop(chainloopToken) // Initialize the attestation - attestationID, err := dag.Chainloop(chainloopToken).AttestationInit(ctx, ChainloopAttestationInitOpts{Repository: proj}) + attestationID, err := chainloopClient.AttestationInit(ctx, ChainloopAttestationInitOpts{Repository: proj}) if err != nil { return "", fmt.Errorf("failed to initialize attestation: %w", err) } @@ -22,46 +25,66 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, defer func() { // If there was an error in the process, mark the attestation as failed in Chainloop if err != nil { - dag.Chainloop(chainloopToken).AttestationReset(ctx, attestationID, ChainloopAttestationResetOpts{Reason: err.Error()}) + chainloopClient.AttestationReset(ctx, attestationID, ChainloopAttestationResetOpts{Reason: err.Error()}) } else { // Push the attestation to Chainloop - _, err = dag.Chainloop(chainloopToken).AttestationPush(ctx, attestationID, chainloopSigningKey, chainloopPassphrase) + _, err = chainloopClient.AttestationPush(ctx, attestationID, chainloopSigningKey, chainloopPassphrase) } }() - // Build the go binary - binary := dag.Golang().WithProject(proj).Build([]string{"-o", "server"}).File("server") - - // Generate SBOM from the code - sbom := dag.Syft().Sbom(proj, "sbom.json", SyftSbomOpts{Output: "cyclonedx-json"}) - - // Build and publish a container image - imageRepo, err := dag.Wolfi().Container(). - WithFile("/server", binary). - WithEntrypoint([]string{"/server"}). - Publish(ctx, fmt.Sprintf("ttl.sh/chainloop-demo-%.0f", math.Floor(rand.Float64()*10000000))) //#nosec + // build artifacts + res, err := m.doBuildAndPublish(ctx, proj) if err != nil { - return "", err + return "", fmt.Errorf("failed to build and publish: %w", err) } // Attest the pieces of evidence // Container image - _, err = dag.Chainloop(chainloopToken).AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: imageRepo}) + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: res.imageRepo}) if err != nil { return "", fmt.Errorf("failed to add image piece of evidence: %w", err) } // Binary - _, err = dag.Chainloop(chainloopToken).AttestationAdd(ctx, attestationID, "binary", ChainloopAttestationAddOpts{Path: binary}) + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "binary", ChainloopAttestationAddOpts{Path: res.binary}) if err != nil { return "", fmt.Errorf("failed to add binary piece of evidence: %w", err) } // SBOM - _, err = dag.Chainloop(chainloopToken).AttestationAdd(ctx, attestationID, "sbom", ChainloopAttestationAddOpts{Path: sbom}) + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "sbom", ChainloopAttestationAddOpts{Path: res.sbom}) if err != nil { return "", fmt.Errorf("failed to add SBOM piece of evidence: %w", err) } - return imageRepo, nil + // Return information about the attestation + return chainloopClient.AttestationStatus(ctx, attestationID) +} + +type buildResult struct { + // Go binary + binary *File + // Path to the container image repository + imageRepo string + // SBOM file + sbom *File +} + +func (m *BuildAndRelease) doBuildAndPublish(ctx context.Context, proj *Directory) (*buildResult, error) { + // Build the go binary + binary := dag.Golang().WithProject(proj).Build([]string{"-o", "server"}).File("server") + + // Generate a CycloneDX SBOM from the source code + sbom := dag.Syft().Sbom(proj, "sbom.json", SyftSbomOpts{Output: "cyclonedx-json"}) + + // Build and publish a container image + imageRepo, err := dag.Wolfi().Container(). + WithFile("/server", binary). + WithEntrypoint([]string{"/server"}). + Publish(ctx, fmt.Sprintf("ttl.sh/chainloop-demo-%.0f", math.Floor(rand.Float64()*10000000))) //#nosec + if err != nil { + return nil, err + } + + return &buildResult{imageRepo: imageRepo, sbom: sbom, binary: binary}, nil } From 7d403457c09de5c0e1954b0f6a1147ce3a802e06 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 23:01:54 +0100 Subject: [PATCH 12/34] update toolchain Signed-off-by: Miguel Martinez Trivino --- go.mod | 2 +- go.sum | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 7b9c5de..f12562b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/chainloop-dev/integration-demo -go 1.19 +go 1.21 require ( github.com/99designs/gqlgen v0.17.44 diff --git a/go.sum b/go.sum index a4d2f72..f0d2d48 100644 --- a/go.sum +++ b/go.sum @@ -3,18 +3,23 @@ github.com/99designs/gqlgen v0.17.44/go.mod h1:UTCu3xpK2mLI5qcMNw+HKDiEL77it/1Xt github.com/Khan/genqlient v0.6.0 h1:Bwb1170ekuNIVIwTJEqvO8y7RxBxXu639VJOkKSrwAk= github.com/Khan/genqlient v0.6.0/go.mod h1:rvChwWVTqXhiapdhLDV4bp9tz/Xvtewwkon4DpWWCRM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f h1:gOO/tNZMjjvTKZWpY7YnXC72ULNLErRtp94LountVE8= github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.2.0 h1:pqK/FLSjsAADWY74SyWDCjOcd5l7H8GSnnOGEB9A1Us= github.com/sosodev/duration v1.2.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= @@ -22,3 +27,4 @@ golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From e59aa91e75dde0b82be6dac4bc01980d4deeed53 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 23:10:09 +0100 Subject: [PATCH 13/34] update module Signed-off-by: Miguel Martinez Trivino --- .../dagger/build-and-release/dagger.gen.go | 7525 ----------------- .../build-and-release/querybuilder/marshal.go | 162 - .../querybuilder/querybuilder.go | 183 - chainloop-demo/dagger/dagger.json | 1 - .../dagger/{build-and-release => }/main.go | 2 +- 5 files changed, 1 insertion(+), 7872 deletions(-) delete mode 100644 chainloop-demo/dagger/build-and-release/dagger.gen.go delete mode 100644 chainloop-demo/dagger/build-and-release/querybuilder/marshal.go delete mode 100644 chainloop-demo/dagger/build-and-release/querybuilder/querybuilder.go rename chainloop-demo/dagger/{build-and-release => }/main.go (97%) diff --git a/chainloop-demo/dagger/build-and-release/dagger.gen.go b/chainloop-demo/dagger/build-and-release/dagger.gen.go deleted file mode 100644 index 093954c..0000000 --- a/chainloop-demo/dagger/build-and-release/dagger.gen.go +++ /dev/null @@ -1,7525 +0,0 @@ -// Code generated by dagger. DO NOT EDIT. - -package main - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net" - "net/http" - "os" - "reflect" - "strconv" - "strings" - - "github.com/Khan/genqlient/graphql" - "github.com/vektah/gqlparser/v2/gqlerror" - - "github.com/chainloop-dev/integration-demo/chainloop-demo/dagger/build-and-release/querybuilder" -) - -// assertNotNil panic if the given value is nil. -// This function is used to validate that input with pointer type are not nil. -// See https://github.com/dagger/dagger/issues/5696 for more context. -func assertNotNil(argName string, value any) { - // We use reflect because just comparing value to nil is not working since - // the value is wrapped into a type when passed as parameter. - // E.g., nil become (*dagger.File)(nil). - if reflect.ValueOf(value).IsNil() { - panic(fmt.Sprintf("unexpected nil pointer for argument %q", argName)) - } -} - -// ptr returns a pointer to the given value. -func ptr[T any](v T) *T { - return &v -} - -type DaggerObject querybuilder.GraphQLMarshaller - -func convertSlice[I any, O any](in []I, f func(I) O) []O { - out := make([]O, len(in)) - for i, v := range in { - out[i] = f(v) - } - return out -} - -// getCustomError parses a GraphQL error into a more specific error type. -func getCustomError(err error) error { - var gqlErr *gqlerror.Error - - if !errors.As(err, &gqlErr) { - return nil - } - - ext := gqlErr.Extensions - - typ, ok := ext["_type"].(string) - if !ok { - return nil - } - - if typ == "EXEC_ERROR" { - e := &ExecError{ - original: err, - } - if code, ok := ext["exitCode"].(float64); ok { - e.ExitCode = int(code) - } - if args, ok := ext["cmd"].([]interface{}); ok { - cmd := make([]string, len(args)) - for i, v := range args { - cmd[i] = v.(string) - } - e.Cmd = cmd - } - if stdout, ok := ext["stdout"].(string); ok { - e.Stdout = stdout - } - if stderr, ok := ext["stderr"].(string); ok { - e.Stderr = stderr - } - return e - } - - return nil -} - -// ExecError is an API error from an exec operation. -type ExecError struct { - original error - Cmd []string - ExitCode int - Stdout string - Stderr string -} - -func (e *ExecError) Error() string { - // As a default when just printing the error, include the stdout - // and stderr for visibility - msg := e.Message() - if strings.TrimSpace(e.Stdout) != "" { - msg += "\nStdout:\n" + e.Stdout - } - if strings.TrimSpace(e.Stderr) != "" { - msg += "\nStderr:\n" + e.Stderr - } - return msg -} - -func (e *ExecError) Message() string { - return e.original.Error() -} - -func (e *ExecError) Unwrap() error { - return e.original -} - -// The `CacheVolumeID` scalar type represents an identifier for an object of type CacheVolume. -type CacheVolumeID string - -// The `ChainloopID` scalar type represents an identifier for an object of type Chainloop. -type ChainloopID string - -// The `ContainerID` scalar type represents an identifier for an object of type Container. -type ContainerID string - -// The `CurrentModuleID` scalar type represents an identifier for an object of type CurrentModule. -type CurrentModuleID string - -// The `DirectoryID` scalar type represents an identifier for an object of type Directory. -type DirectoryID string - -// The `EnvVariableID` scalar type represents an identifier for an object of type EnvVariable. -type EnvVariableID string - -// The `FieldTypeDefID` scalar type represents an identifier for an object of type FieldTypeDef. -type FieldTypeDefID string - -// The `FileID` scalar type represents an identifier for an object of type File. -type FileID string - -// The `FunctionArgID` scalar type represents an identifier for an object of type FunctionArg. -type FunctionArgID string - -// The `FunctionCallArgValueID` scalar type represents an identifier for an object of type FunctionCallArgValue. -type FunctionCallArgValueID string - -// The `FunctionCallID` scalar type represents an identifier for an object of type FunctionCall. -type FunctionCallID string - -// The `FunctionID` scalar type represents an identifier for an object of type Function. -type FunctionID string - -// The `GeneratedCodeID` scalar type represents an identifier for an object of type GeneratedCode. -type GeneratedCodeID string - -// The `GitModuleSourceID` scalar type represents an identifier for an object of type GitModuleSource. -type GitModuleSourceID string - -// The `GitRefID` scalar type represents an identifier for an object of type GitRef. -type GitRefID string - -// The `GitRepositoryID` scalar type represents an identifier for an object of type GitRepository. -type GitRepositoryID string - -// The `GolangID` scalar type represents an identifier for an object of type Golang. -type GolangID string - -// The `InputTypeDefID` scalar type represents an identifier for an object of type InputTypeDef. -type InputTypeDefID string - -// The `InterfaceTypeDefID` scalar type represents an identifier for an object of type InterfaceTypeDef. -type InterfaceTypeDefID string - -// An arbitrary JSON-encoded value. -type JSON string - -// The `LabelID` scalar type represents an identifier for an object of type Label. -type LabelID string - -// The `ListTypeDefID` scalar type represents an identifier for an object of type ListTypeDef. -type ListTypeDefID string - -// The `LocalModuleSourceID` scalar type represents an identifier for an object of type LocalModuleSource. -type LocalModuleSourceID string - -// The `ModuleDependencyID` scalar type represents an identifier for an object of type ModuleDependency. -type ModuleDependencyID string - -// The `ModuleID` scalar type represents an identifier for an object of type Module. -type ModuleID string - -// The `ModuleSourceID` scalar type represents an identifier for an object of type ModuleSource. -type ModuleSourceID string - -// The `ObjectTypeDefID` scalar type represents an identifier for an object of type ObjectTypeDef. -type ObjectTypeDefID string - -// The platform config OS and architecture in a Container. -// -// The format is [os]/[platform]/[version] (e.g., "darwin/arm64/v7", "windows/amd64", "linux/arm64"). -type Platform string - -// The `PortID` scalar type represents an identifier for an object of type Port. -type PortID string - -// The `SecretID` scalar type represents an identifier for an object of type Secret. -type SecretID string - -// The `ServiceID` scalar type represents an identifier for an object of type Service. -type ServiceID string - -// The `SocketID` scalar type represents an identifier for an object of type Socket. -type SocketID string - -// The `SyftID` scalar type represents an identifier for an object of type Syft. -type SyftID string - -// The `TerminalID` scalar type represents an identifier for an object of type Terminal. -type TerminalID string - -// The `TypeDefID` scalar type represents an identifier for an object of type TypeDef. -type TypeDefID string - -// The absence of a value. -// -// A Null Void is used as a placeholder for resolvers that do not return anything. -type Void string - -// The `WolfiID` scalar type represents an identifier for an object of type Wolfi. -type WolfiID string - -// Key value object that represents a build argument. -type BuildArg struct { - // The build argument name. - Name string `json:"name"` - - // The build argument value. - Value string `json:"value"` -} - -// Key value object that represents a pipeline label. -type PipelineLabel struct { - // Label name. - Name string `json:"name"` - - // Label value. - Value string `json:"value"` -} - -// Port forwarding rules for tunneling network traffic. -type PortForward struct { - // Destination port for traffic. - Backend int `json:"backend"` - - // Port to expose to clients. If unspecified, a default will be chosen. - Frontend int `json:"frontend"` - - // Transport layer protocol to use for traffic. - Protocol NetworkProtocol `json:"protocol,omitempty"` -} - -// A directory whose contents persist across runs. -type CacheVolume struct { - q *querybuilder.Selection - c graphql.Client - - id *CacheVolumeID -} - -// A unique identifier for this CacheVolume. -func (r *CacheVolume) ID(ctx context.Context) (CacheVolumeID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response CacheVolumeID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *CacheVolume) XXX_GraphQLType() string { - return "CacheVolume" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *CacheVolume) XXX_GraphQLIDType() string { - return "CacheVolumeID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *CacheVolume) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *CacheVolume) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *CacheVolume) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadCacheVolumeFromID(CacheVolumeID(id)) - return nil -} - -type Chainloop struct { - q *querybuilder.Selection - c graphql.Client - - attestationAdd *string - attestationInit *string - attestationPush *string - attestationReset *string - attestationStatus *string - id *ChainloopID -} - -// ChainloopAttestationAddOpts contains options for Chainloop.AttestationAdd -type ChainloopAttestationAddOpts struct { - // - // path to the file to be added - // - Path *File - // - // raw value to be added - // - Value string - // - // Container Registry Credentials for Container image-based materials - // i.e docker.io, ghcr.io, etc - // - Registry string - - RegistryUsername string - - RegistryPassword *Secret -} - -// Add a piece of evidence/material to the current attestation -// The material value can be provided either in the form of a file or as a raw string -// The file type is required for materials of kind ARTIFACT that are uploaded to the CAS -func (r *Chainloop) AttestationAdd(ctx context.Context, attestationId string, name string, opts ...ChainloopAttestationAddOpts) (string, error) { - if r.attestationAdd != nil { - return *r.attestationAdd, nil - } - q := r.q.Select("attestationAdd") - for i := len(opts) - 1; i >= 0; i-- { - // `path` optional argument - if !querybuilder.IsZeroValue(opts[i].Path) { - q = q.Arg("path", opts[i].Path) - } - // `value` optional argument - if !querybuilder.IsZeroValue(opts[i].Value) { - q = q.Arg("value", opts[i].Value) - } - // `registry` optional argument - if !querybuilder.IsZeroValue(opts[i].Registry) { - q = q.Arg("registry", opts[i].Registry) - } - // `registryUsername` optional argument - if !querybuilder.IsZeroValue(opts[i].RegistryUsername) { - q = q.Arg("registryUsername", opts[i].RegistryUsername) - } - // `registryPassword` optional argument - if !querybuilder.IsZeroValue(opts[i].RegistryPassword) { - q = q.Arg("registryPassword", opts[i].RegistryPassword) - } - } - q = q.Arg("attestationId", attestationId) - q = q.Arg("name", name) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// ChainloopAttestationInitOpts contains options for Chainloop.AttestationInit -type ChainloopAttestationInitOpts struct { - // - // Workflow Contract revision, default is the latest - // - ContractRevision string - // - // Path to the git repository to be attested - // - Repository *Directory -} - -// Start the attestation crafting process -func (r *Chainloop) AttestationInit(ctx context.Context, opts ...ChainloopAttestationInitOpts) (string, error) { - if r.attestationInit != nil { - return *r.attestationInit, nil - } - q := r.q.Select("attestationInit") - for i := len(opts) - 1; i >= 0; i-- { - // `contractRevision` optional argument - if !querybuilder.IsZeroValue(opts[i].ContractRevision) { - q = q.Arg("contractRevision", opts[i].ContractRevision) - } - // `repository` optional argument - if !querybuilder.IsZeroValue(opts[i].Repository) { - q = q.Arg("repository", opts[i].Repository) - } - } - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Generate, sign and push the attestation to the control plane -func (r *Chainloop) AttestationPush(ctx context.Context, attestationId string, signingKey *Secret, passphrase *Secret) (string, error) { - assertNotNil("signingKey", signingKey) - assertNotNil("passphrase", passphrase) - if r.attestationPush != nil { - return *r.attestationPush, nil - } - q := r.q.Select("attestationPush") - q = q.Arg("attestationId", attestationId) - q = q.Arg("signingKey", signingKey) - q = q.Arg("passphrase", passphrase) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// ChainloopAttestationResetOpts contains options for Chainloop.AttestationReset -type ChainloopAttestationResetOpts struct { - Trigger string - - Reason string -} - -// Mark current attestation process as canceled or failed. --trigger "failure" | "cancellation" (default: "failure") -func (r *Chainloop) AttestationReset(ctx context.Context, attestationId string, opts ...ChainloopAttestationResetOpts) (string, error) { - if r.attestationReset != nil { - return *r.attestationReset, nil - } - q := r.q.Select("attestationReset") - for i := len(opts) - 1; i >= 0; i-- { - // `trigger` optional argument - if !querybuilder.IsZeroValue(opts[i].Trigger) { - q = q.Arg("trigger", opts[i].Trigger) - } - // `reason` optional argument - if !querybuilder.IsZeroValue(opts[i].Reason) { - q = q.Arg("reason", opts[i].Reason) - } - } - q = q.Arg("attestationId", attestationId) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Check the status of the current attestation -func (r *Chainloop) AttestationStatus(ctx context.Context, attestationId string) (string, error) { - if r.attestationStatus != nil { - return *r.attestationStatus, nil - } - q := r.q.Select("attestationStatus") - q = q.Arg("attestationId", attestationId) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this Chainloop. -func (r *Chainloop) ID(ctx context.Context) (ChainloopID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response ChainloopID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Chainloop) XXX_GraphQLType() string { - return "Chainloop" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Chainloop) XXX_GraphQLIDType() string { - return "ChainloopID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Chainloop) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Chainloop) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Chainloop) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadChainloopFromID(ChainloopID(id)) - return nil -} - -func (r *Chainloop) Token() *Secret { - q := r.q.Select("token") - - return &Secret{ - q: q, - c: r.c, - } -} - -// An OCI-compatible container, also known as a Docker container. -type Container struct { - q *querybuilder.Selection - c graphql.Client - - envVariable *string - export *bool - id *ContainerID - imageRef *string - label *string - platform *Platform - publish *string - stderr *string - stdout *string - sync *ContainerID - user *string - workdir *string -} -type WithContainerFunc func(r *Container) *Container - -// With calls the provided function with current Container. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *Container) With(f WithContainerFunc) *Container { - return f(r) -} - -// Turn the container into a Service. -// -// Be sure to set any exposed ports before this conversion. -func (r *Container) AsService() *Service { - q := r.q.Select("asService") - - return &Service{ - q: q, - c: r.c, - } -} - -// ContainerAsTarballOpts contains options for Container.AsTarball -type ContainerAsTarballOpts struct { - // Identifiers for other platform specific containers. - // - // Used for multi-platform images. - PlatformVariants []*Container - // Force each layer of the image to use the specified compression algorithm. - // - // If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. - ForcedCompression ImageLayerCompression - // Use the specified media types for the image's layers. - // - // Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. - MediaTypes ImageMediaTypes -} - -// Returns a File representing the container serialized to a tarball. -func (r *Container) AsTarball(opts ...ContainerAsTarballOpts) *File { - q := r.q.Select("asTarball") - for i := len(opts) - 1; i >= 0; i-- { - // `platformVariants` optional argument - if !querybuilder.IsZeroValue(opts[i].PlatformVariants) { - q = q.Arg("platformVariants", opts[i].PlatformVariants) - } - // `forcedCompression` optional argument - if !querybuilder.IsZeroValue(opts[i].ForcedCompression) { - q = q.Arg("forcedCompression", opts[i].ForcedCompression) - } - // `mediaTypes` optional argument - if !querybuilder.IsZeroValue(opts[i].MediaTypes) { - q = q.Arg("mediaTypes", opts[i].MediaTypes) - } - } - - return &File{ - q: q, - c: r.c, - } -} - -// ContainerBuildOpts contains options for Container.Build -type ContainerBuildOpts struct { - // Path to the Dockerfile to use. - Dockerfile string - // Target build stage to build. - Target string - // Additional build arguments. - BuildArgs []BuildArg - // Secrets to pass to the build. - // - // They will be mounted at /run/secrets/[secret-name] in the build container - // - // They can be accessed in the Dockerfile using the "secret" mount type and mount path /run/secrets/[secret-name], e.g. RUN --mount=type=secret,id=my-secret curl http://example.com?token=$(cat /run/secrets/my-secret) - Secrets []*Secret -} - -// Initializes this container from a Dockerfile build. -func (r *Container) Build(context *Directory, opts ...ContainerBuildOpts) *Container { - assertNotNil("context", context) - q := r.q.Select("build") - for i := len(opts) - 1; i >= 0; i-- { - // `dockerfile` optional argument - if !querybuilder.IsZeroValue(opts[i].Dockerfile) { - q = q.Arg("dockerfile", opts[i].Dockerfile) - } - // `target` optional argument - if !querybuilder.IsZeroValue(opts[i].Target) { - q = q.Arg("target", opts[i].Target) - } - // `buildArgs` optional argument - if !querybuilder.IsZeroValue(opts[i].BuildArgs) { - q = q.Arg("buildArgs", opts[i].BuildArgs) - } - // `secrets` optional argument - if !querybuilder.IsZeroValue(opts[i].Secrets) { - q = q.Arg("secrets", opts[i].Secrets) - } - } - q = q.Arg("context", context) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves default arguments for future commands. -func (r *Container) DefaultArgs(ctx context.Context) ([]string, error) { - q := r.q.Select("defaultArgs") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Retrieves a directory at the given path. -// -// Mounts are included. -func (r *Container) Directory(path string) *Directory { - q := r.q.Select("directory") - q = q.Arg("path", path) - - return &Directory{ - q: q, - c: r.c, - } -} - -// Retrieves entrypoint to be prepended to the arguments of all commands. -func (r *Container) Entrypoint(ctx context.Context) ([]string, error) { - q := r.q.Select("entrypoint") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Retrieves the value of the specified environment variable. -func (r *Container) EnvVariable(ctx context.Context, name string) (string, error) { - if r.envVariable != nil { - return *r.envVariable, nil - } - q := r.q.Select("envVariable") - q = q.Arg("name", name) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Retrieves the list of environment variables passed to commands. -func (r *Container) EnvVariables(ctx context.Context) ([]EnvVariable, error) { - q := r.q.Select("envVariables") - - q = q.Select("id") - - type envVariables struct { - Id EnvVariableID - } - - convert := func(fields []envVariables) []EnvVariable { - out := []EnvVariable{} - - for i := range fields { - val := EnvVariable{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadEnvVariableFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []envVariables - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// EXPERIMENTAL API! Subject to change/removal at any time. -// -// Configures all available GPUs on the host to be accessible to this container. -// -// This currently works for Nvidia devices only. -func (r *Container) ExperimentalWithAllGPUs() *Container { - q := r.q.Select("experimentalWithAllGPUs") - - return &Container{ - q: q, - c: r.c, - } -} - -// EXPERIMENTAL API! Subject to change/removal at any time. -// -// Configures the provided list of devices to be accesible to this container. -// -// This currently works for Nvidia devices only. -func (r *Container) ExperimentalWithGPU(devices []string) *Container { - q := r.q.Select("experimentalWithGPU") - q = q.Arg("devices", devices) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerExportOpts contains options for Container.Export -type ContainerExportOpts struct { - // Identifiers for other platform specific containers. - // - // Used for multi-platform image. - PlatformVariants []*Container - // Force each layer of the exported image to use the specified compression algorithm. - // - // If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. - ForcedCompression ImageLayerCompression - // Use the specified media types for the exported image's layers. - // - // Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. - MediaTypes ImageMediaTypes -} - -// Writes the container as an OCI tarball to the destination file path on the host. -// -// Return true on success. -// -// It can also export platform variants. -func (r *Container) Export(ctx context.Context, path string, opts ...ContainerExportOpts) (bool, error) { - if r.export != nil { - return *r.export, nil - } - q := r.q.Select("export") - for i := len(opts) - 1; i >= 0; i-- { - // `platformVariants` optional argument - if !querybuilder.IsZeroValue(opts[i].PlatformVariants) { - q = q.Arg("platformVariants", opts[i].PlatformVariants) - } - // `forcedCompression` optional argument - if !querybuilder.IsZeroValue(opts[i].ForcedCompression) { - q = q.Arg("forcedCompression", opts[i].ForcedCompression) - } - // `mediaTypes` optional argument - if !querybuilder.IsZeroValue(opts[i].MediaTypes) { - q = q.Arg("mediaTypes", opts[i].MediaTypes) - } - } - q = q.Arg("path", path) - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Retrieves the list of exposed ports. -// -// This includes ports already exposed by the image, even if not explicitly added with dagger. -func (r *Container) ExposedPorts(ctx context.Context) ([]Port, error) { - q := r.q.Select("exposedPorts") - - q = q.Select("id") - - type exposedPorts struct { - Id PortID - } - - convert := func(fields []exposedPorts) []Port { - out := []Port{} - - for i := range fields { - val := Port{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadPortFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []exposedPorts - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// Retrieves a file at the given path. -// -// Mounts are included. -func (r *Container) File(path string) *File { - q := r.q.Select("file") - q = q.Arg("path", path) - - return &File{ - q: q, - c: r.c, - } -} - -// Initializes this container from a pulled base image. -func (r *Container) From(address string) *Container { - q := r.q.Select("from") - q = q.Arg("address", address) - - return &Container{ - q: q, - c: r.c, - } -} - -// A unique identifier for this Container. -func (r *Container) ID(ctx context.Context) (ContainerID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response ContainerID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Container) XXX_GraphQLType() string { - return "Container" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Container) XXX_GraphQLIDType() string { - return "ContainerID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Container) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Container) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Container) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadContainerFromID(ContainerID(id)) - return nil -} - -// The unique image reference which can only be retrieved immediately after the 'Container.From' call. -func (r *Container) ImageRef(ctx context.Context) (string, error) { - if r.imageRef != nil { - return *r.imageRef, nil - } - q := r.q.Select("imageRef") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// ContainerImportOpts contains options for Container.Import -type ContainerImportOpts struct { - // Identifies the tag to import from the archive, if the archive bundles multiple tags. - Tag string -} - -// Reads the container from an OCI tarball. -func (r *Container) Import(source *File, opts ...ContainerImportOpts) *Container { - assertNotNil("source", source) - q := r.q.Select("import") - for i := len(opts) - 1; i >= 0; i-- { - // `tag` optional argument - if !querybuilder.IsZeroValue(opts[i].Tag) { - q = q.Arg("tag", opts[i].Tag) - } - } - q = q.Arg("source", source) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves the value of the specified label. -func (r *Container) Label(ctx context.Context, name string) (string, error) { - if r.label != nil { - return *r.label, nil - } - q := r.q.Select("label") - q = q.Arg("name", name) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Retrieves the list of labels passed to container. -func (r *Container) Labels(ctx context.Context) ([]Label, error) { - q := r.q.Select("labels") - - q = q.Select("id") - - type labels struct { - Id LabelID - } - - convert := func(fields []labels) []Label { - out := []Label{} - - for i := range fields { - val := Label{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadLabelFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []labels - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// Retrieves the list of paths where a directory is mounted. -func (r *Container) Mounts(ctx context.Context) ([]string, error) { - q := r.q.Select("mounts") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// ContainerPipelineOpts contains options for Container.Pipeline -type ContainerPipelineOpts struct { - // Description of the sub-pipeline. - Description string - // Labels to apply to the sub-pipeline. - Labels []PipelineLabel -} - -// Creates a named sub-pipeline. -func (r *Container) Pipeline(name string, opts ...ContainerPipelineOpts) *Container { - q := r.q.Select("pipeline") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - // `labels` optional argument - if !querybuilder.IsZeroValue(opts[i].Labels) { - q = q.Arg("labels", opts[i].Labels) - } - } - q = q.Arg("name", name) - - return &Container{ - q: q, - c: r.c, - } -} - -// The platform this container executes and publishes as. -func (r *Container) Platform(ctx context.Context) (Platform, error) { - if r.platform != nil { - return *r.platform, nil - } - q := r.q.Select("platform") - - var response Platform - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// ContainerPublishOpts contains options for Container.Publish -type ContainerPublishOpts struct { - // Identifiers for other platform specific containers. - // - // Used for multi-platform image. - PlatformVariants []*Container - // Force each layer of the published image to use the specified compression algorithm. - // - // If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. - ForcedCompression ImageLayerCompression - // Use the specified media types for the published image's layers. - // - // Defaults to OCI, which is largely compatible with most recent registries, but Docker may be needed for older registries without OCI support. - MediaTypes ImageMediaTypes -} - -// Publishes this container as a new image to the specified address. -// -// Publish returns a fully qualified ref. -// -// It can also publish platform variants. -func (r *Container) Publish(ctx context.Context, address string, opts ...ContainerPublishOpts) (string, error) { - if r.publish != nil { - return *r.publish, nil - } - q := r.q.Select("publish") - for i := len(opts) - 1; i >= 0; i-- { - // `platformVariants` optional argument - if !querybuilder.IsZeroValue(opts[i].PlatformVariants) { - q = q.Arg("platformVariants", opts[i].PlatformVariants) - } - // `forcedCompression` optional argument - if !querybuilder.IsZeroValue(opts[i].ForcedCompression) { - q = q.Arg("forcedCompression", opts[i].ForcedCompression) - } - // `mediaTypes` optional argument - if !querybuilder.IsZeroValue(opts[i].MediaTypes) { - q = q.Arg("mediaTypes", opts[i].MediaTypes) - } - } - q = q.Arg("address", address) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Retrieves this container's root filesystem. Mounts are not included. -func (r *Container) Rootfs() *Directory { - q := r.q.Select("rootfs") - - return &Directory{ - q: q, - c: r.c, - } -} - -// The error stream of the last executed command. -// -// Will execute default command if none is set, or error if there's no default. -func (r *Container) Stderr(ctx context.Context) (string, error) { - if r.stderr != nil { - return *r.stderr, nil - } - q := r.q.Select("stderr") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The output stream of the last executed command. -// -// Will execute default command if none is set, or error if there's no default. -func (r *Container) Stdout(ctx context.Context) (string, error) { - if r.stdout != nil { - return *r.stdout, nil - } - q := r.q.Select("stdout") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Forces evaluation of the pipeline in the engine. -// -// It doesn't run the default command if no exec has been set. -func (r *Container) Sync(ctx context.Context) (*Container, error) { - q := r.q.Select("sync") - - return r, q.Execute(ctx, r.c) -} - -// ContainerTerminalOpts contains options for Container.Terminal -type ContainerTerminalOpts struct { - // If set, override the container's default terminal command and invoke these command arguments instead. - Cmd []string -} - -// Return an interactive terminal for this container using its configured default terminal command if not overridden by args (or sh as a fallback default). -func (r *Container) Terminal(opts ...ContainerTerminalOpts) *Terminal { - q := r.q.Select("terminal") - for i := len(opts) - 1; i >= 0; i-- { - // `cmd` optional argument - if !querybuilder.IsZeroValue(opts[i].Cmd) { - q = q.Arg("cmd", opts[i].Cmd) - } - } - - return &Terminal{ - q: q, - c: r.c, - } -} - -// Retrieves the user to be set for all commands. -func (r *Container) User(ctx context.Context) (string, error) { - if r.user != nil { - return *r.user, nil - } - q := r.q.Select("user") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Configures default arguments for future commands. -func (r *Container) WithDefaultArgs(args []string) *Container { - q := r.q.Select("withDefaultArgs") - q = q.Arg("args", args) - - return &Container{ - q: q, - c: r.c, - } -} - -// Set the default command to invoke for the container's terminal API. -func (r *Container) WithDefaultTerminalCmd(args []string) *Container { - q := r.q.Select("withDefaultTerminalCmd") - q = q.Arg("args", args) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithDirectoryOpts contains options for Container.WithDirectory -type ContainerWithDirectoryOpts struct { - // Patterns to exclude in the written directory (e.g. ["node_modules/**", ".gitignore", ".git/"]). - Exclude []string - // Patterns to include in the written directory (e.g. ["*.go", "go.mod", "go.sum"]). - Include []string - // A user:group to set for the directory and its contents. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a directory written at the given path. -func (r *Container) WithDirectory(path string, directory *Directory, opts ...ContainerWithDirectoryOpts) *Container { - assertNotNil("directory", directory) - q := r.q.Select("withDirectory") - for i := len(opts) - 1; i >= 0; i-- { - // `exclude` optional argument - if !querybuilder.IsZeroValue(opts[i].Exclude) { - q = q.Arg("exclude", opts[i].Exclude) - } - // `include` optional argument - if !querybuilder.IsZeroValue(opts[i].Include) { - q = q.Arg("include", opts[i].Include) - } - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("directory", directory) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithEntrypointOpts contains options for Container.WithEntrypoint -type ContainerWithEntrypointOpts struct { - // Don't remove the default arguments when setting the entrypoint. - KeepDefaultArgs bool -} - -// Retrieves this container but with a different command entrypoint. -func (r *Container) WithEntrypoint(args []string, opts ...ContainerWithEntrypointOpts) *Container { - q := r.q.Select("withEntrypoint") - for i := len(opts) - 1; i >= 0; i-- { - // `keepDefaultArgs` optional argument - if !querybuilder.IsZeroValue(opts[i].KeepDefaultArgs) { - q = q.Arg("keepDefaultArgs", opts[i].KeepDefaultArgs) - } - } - q = q.Arg("args", args) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithEnvVariableOpts contains options for Container.WithEnvVariable -type ContainerWithEnvVariableOpts struct { - // Replace `${VAR}` or `$VAR` in the value according to the current environment variables defined in the container (e.g., "/opt/bin:$PATH"). - Expand bool -} - -// Retrieves this container plus the given environment variable. -func (r *Container) WithEnvVariable(name string, value string, opts ...ContainerWithEnvVariableOpts) *Container { - q := r.q.Select("withEnvVariable") - for i := len(opts) - 1; i >= 0; i-- { - // `expand` optional argument - if !querybuilder.IsZeroValue(opts[i].Expand) { - q = q.Arg("expand", opts[i].Expand) - } - } - q = q.Arg("name", name) - q = q.Arg("value", value) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithExecOpts contains options for Container.WithExec -type ContainerWithExecOpts struct { - // If the container has an entrypoint, ignore it for args rather than using it to wrap them. - SkipEntrypoint bool - // Content to write to the command's standard input before closing (e.g., "Hello world"). - Stdin string - // Redirect the command's standard output to a file in the container (e.g., "/tmp/stdout"). - RedirectStdout string - // Redirect the command's standard error to a file in the container (e.g., "/tmp/stderr"). - RedirectStderr string - // Provides dagger access to the executed command. - // - // Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. - ExperimentalPrivilegedNesting bool - // Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. - InsecureRootCapabilities bool -} - -// Retrieves this container after executing the specified command inside it. -func (r *Container) WithExec(args []string, opts ...ContainerWithExecOpts) *Container { - q := r.q.Select("withExec") - for i := len(opts) - 1; i >= 0; i-- { - // `skipEntrypoint` optional argument - if !querybuilder.IsZeroValue(opts[i].SkipEntrypoint) { - q = q.Arg("skipEntrypoint", opts[i].SkipEntrypoint) - } - // `stdin` optional argument - if !querybuilder.IsZeroValue(opts[i].Stdin) { - q = q.Arg("stdin", opts[i].Stdin) - } - // `redirectStdout` optional argument - if !querybuilder.IsZeroValue(opts[i].RedirectStdout) { - q = q.Arg("redirectStdout", opts[i].RedirectStdout) - } - // `redirectStderr` optional argument - if !querybuilder.IsZeroValue(opts[i].RedirectStderr) { - q = q.Arg("redirectStderr", opts[i].RedirectStderr) - } - // `experimentalPrivilegedNesting` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalPrivilegedNesting) { - q = q.Arg("experimentalPrivilegedNesting", opts[i].ExperimentalPrivilegedNesting) - } - // `insecureRootCapabilities` optional argument - if !querybuilder.IsZeroValue(opts[i].InsecureRootCapabilities) { - q = q.Arg("insecureRootCapabilities", opts[i].InsecureRootCapabilities) - } - } - q = q.Arg("args", args) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithExposedPortOpts contains options for Container.WithExposedPort -type ContainerWithExposedPortOpts struct { - // Transport layer network protocol - Protocol NetworkProtocol - // Optional port description - Description string - // Skip the health check when run as a service. - ExperimentalSkipHealthcheck bool -} - -// Expose a network port. -// -// Exposed ports serve two purposes: -// -// - For health checks and introspection, when running services -// -// - For setting the EXPOSE OCI field when publishing the container -func (r *Container) WithExposedPort(port int, opts ...ContainerWithExposedPortOpts) *Container { - q := r.q.Select("withExposedPort") - for i := len(opts) - 1; i >= 0; i-- { - // `protocol` optional argument - if !querybuilder.IsZeroValue(opts[i].Protocol) { - q = q.Arg("protocol", opts[i].Protocol) - } - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - // `experimentalSkipHealthcheck` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalSkipHealthcheck) { - q = q.Arg("experimentalSkipHealthcheck", opts[i].ExperimentalSkipHealthcheck) - } - } - q = q.Arg("port", port) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithFileOpts contains options for Container.WithFile -type ContainerWithFileOpts struct { - // Permission given to the copied file (e.g., 0600). - Permissions int - // A user:group to set for the file. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus the contents of the given file copied to the given path. -func (r *Container) WithFile(path string, source *File, opts ...ContainerWithFileOpts) *Container { - assertNotNil("source", source) - q := r.q.Select("withFile") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithFilesOpts contains options for Container.WithFiles -type ContainerWithFilesOpts struct { - // Permission given to the copied files (e.g., 0600). - Permissions int - // A user:group to set for the files. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus the contents of the given files copied to the given path. -func (r *Container) WithFiles(path string, sources []*File, opts ...ContainerWithFilesOpts) *Container { - q := r.q.Select("withFiles") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("sources", sources) - - return &Container{ - q: q, - c: r.c, - } -} - -// Indicate that subsequent operations should be featured more prominently in the UI. -func (r *Container) WithFocus() *Container { - q := r.q.Select("withFocus") - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container plus the given label. -func (r *Container) WithLabel(name string, value string) *Container { - q := r.q.Select("withLabel") - q = q.Arg("name", name) - q = q.Arg("value", value) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithMountedCacheOpts contains options for Container.WithMountedCache -type ContainerWithMountedCacheOpts struct { - // Identifier of the directory to use as the cache volume's root. - Source *Directory - // Sharing mode of the cache volume. - Sharing CacheSharingMode - // A user:group to set for the mounted cache directory. - // - // Note that this changes the ownership of the specified mount along with the initial filesystem provided by source (if any). It does not have any effect if/when the cache has already been created. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a cache volume mounted at the given path. -func (r *Container) WithMountedCache(path string, cache *CacheVolume, opts ...ContainerWithMountedCacheOpts) *Container { - assertNotNil("cache", cache) - q := r.q.Select("withMountedCache") - for i := len(opts) - 1; i >= 0; i-- { - // `source` optional argument - if !querybuilder.IsZeroValue(opts[i].Source) { - q = q.Arg("source", opts[i].Source) - } - // `sharing` optional argument - if !querybuilder.IsZeroValue(opts[i].Sharing) { - q = q.Arg("sharing", opts[i].Sharing) - } - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("cache", cache) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithMountedDirectoryOpts contains options for Container.WithMountedDirectory -type ContainerWithMountedDirectoryOpts struct { - // A user:group to set for the mounted directory and its contents. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a directory mounted at the given path. -func (r *Container) WithMountedDirectory(path string, source *Directory, opts ...ContainerWithMountedDirectoryOpts) *Container { - assertNotNil("source", source) - q := r.q.Select("withMountedDirectory") - for i := len(opts) - 1; i >= 0; i-- { - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithMountedFileOpts contains options for Container.WithMountedFile -type ContainerWithMountedFileOpts struct { - // A user or user:group to set for the mounted file. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a file mounted at the given path. -func (r *Container) WithMountedFile(path string, source *File, opts ...ContainerWithMountedFileOpts) *Container { - assertNotNil("source", source) - q := r.q.Select("withMountedFile") - for i := len(opts) - 1; i >= 0; i-- { - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithMountedSecretOpts contains options for Container.WithMountedSecret -type ContainerWithMountedSecretOpts struct { - // A user:group to set for the mounted secret. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string - // Permission given to the mounted secret (e.g., 0600). - // - // This option requires an owner to be set to be active. - Mode int -} - -// Retrieves this container plus a secret mounted into a file at the given path. -func (r *Container) WithMountedSecret(path string, source *Secret, opts ...ContainerWithMountedSecretOpts) *Container { - assertNotNil("source", source) - q := r.q.Select("withMountedSecret") - for i := len(opts) - 1; i >= 0; i-- { - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - // `mode` optional argument - if !querybuilder.IsZeroValue(opts[i].Mode) { - q = q.Arg("mode", opts[i].Mode) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container plus a temporary directory mounted at the given path. -func (r *Container) WithMountedTemp(path string) *Container { - q := r.q.Select("withMountedTemp") - q = q.Arg("path", path) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithNewFileOpts contains options for Container.WithNewFile -type ContainerWithNewFileOpts struct { - // Content of the file to write (e.g., "Hello world!"). - Contents string - // Permission given to the written file (e.g., 0600). - Permissions int - // A user:group to set for the file. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a new file written at the given path. -func (r *Container) WithNewFile(path string, opts ...ContainerWithNewFileOpts) *Container { - q := r.q.Select("withNewFile") - for i := len(opts) - 1; i >= 0; i-- { - // `contents` optional argument - if !querybuilder.IsZeroValue(opts[i].Contents) { - q = q.Arg("contents", opts[i].Contents) - } - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container with a registry authentication for a given address. -func (r *Container) WithRegistryAuth(address string, username string, secret *Secret) *Container { - assertNotNil("secret", secret) - q := r.q.Select("withRegistryAuth") - q = q.Arg("address", address) - q = q.Arg("username", username) - q = q.Arg("secret", secret) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves the container with the given directory mounted to /. -func (r *Container) WithRootfs(directory *Directory) *Container { - assertNotNil("directory", directory) - q := r.q.Select("withRootfs") - q = q.Arg("directory", directory) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container plus an env variable containing the given secret. -func (r *Container) WithSecretVariable(name string, secret *Secret) *Container { - assertNotNil("secret", secret) - q := r.q.Select("withSecretVariable") - q = q.Arg("name", name) - q = q.Arg("secret", secret) - - return &Container{ - q: q, - c: r.c, - } -} - -// Establish a runtime dependency on a service. -// -// The service will be started automatically when needed and detached when it is no longer needed, executing the default command if none is set. -// -// The service will be reachable from the container via the provided hostname alias. -// -// The service dependency will also convey to any files or directories produced by the container. -func (r *Container) WithServiceBinding(alias string, service *Service) *Container { - assertNotNil("service", service) - q := r.q.Select("withServiceBinding") - q = q.Arg("alias", alias) - q = q.Arg("service", service) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithUnixSocketOpts contains options for Container.WithUnixSocket -type ContainerWithUnixSocketOpts struct { - // A user:group to set for the mounted socket. - // - // The user and group can either be an ID (1000:1000) or a name (foo:bar). - // - // If the group is omitted, it defaults to the same as the user. - Owner string -} - -// Retrieves this container plus a socket forwarded to the given Unix socket path. -func (r *Container) WithUnixSocket(path string, source *Socket, opts ...ContainerWithUnixSocketOpts) *Container { - assertNotNil("source", source) - q := r.q.Select("withUnixSocket") - for i := len(opts) - 1; i >= 0; i-- { - // `owner` optional argument - if !querybuilder.IsZeroValue(opts[i].Owner) { - q = q.Arg("owner", opts[i].Owner) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container with a different command user. -func (r *Container) WithUser(name string) *Container { - q := r.q.Select("withUser") - q = q.Arg("name", name) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container with a different working directory. -func (r *Container) WithWorkdir(path string) *Container { - q := r.q.Select("withWorkdir") - q = q.Arg("path", path) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container with unset default arguments for future commands. -func (r *Container) WithoutDefaultArgs() *Container { - q := r.q.Select("withoutDefaultArgs") - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithoutEntrypointOpts contains options for Container.WithoutEntrypoint -type ContainerWithoutEntrypointOpts struct { - // Don't remove the default arguments when unsetting the entrypoint. - KeepDefaultArgs bool -} - -// Retrieves this container with an unset command entrypoint. -func (r *Container) WithoutEntrypoint(opts ...ContainerWithoutEntrypointOpts) *Container { - q := r.q.Select("withoutEntrypoint") - for i := len(opts) - 1; i >= 0; i-- { - // `keepDefaultArgs` optional argument - if !querybuilder.IsZeroValue(opts[i].KeepDefaultArgs) { - q = q.Arg("keepDefaultArgs", opts[i].KeepDefaultArgs) - } - } - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container minus the given environment variable. -func (r *Container) WithoutEnvVariable(name string) *Container { - q := r.q.Select("withoutEnvVariable") - q = q.Arg("name", name) - - return &Container{ - q: q, - c: r.c, - } -} - -// ContainerWithoutExposedPortOpts contains options for Container.WithoutExposedPort -type ContainerWithoutExposedPortOpts struct { - // Port protocol to unexpose - Protocol NetworkProtocol -} - -// Unexpose a previously exposed port. -func (r *Container) WithoutExposedPort(port int, opts ...ContainerWithoutExposedPortOpts) *Container { - q := r.q.Select("withoutExposedPort") - for i := len(opts) - 1; i >= 0; i-- { - // `protocol` optional argument - if !querybuilder.IsZeroValue(opts[i].Protocol) { - q = q.Arg("protocol", opts[i].Protocol) - } - } - q = q.Arg("port", port) - - return &Container{ - q: q, - c: r.c, - } -} - -// Indicate that subsequent operations should not be featured more prominently in the UI. -// -// This is the initial state of all containers. -func (r *Container) WithoutFocus() *Container { - q := r.q.Select("withoutFocus") - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container minus the given environment label. -func (r *Container) WithoutLabel(name string) *Container { - q := r.q.Select("withoutLabel") - q = q.Arg("name", name) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container after unmounting everything at the given path. -func (r *Container) WithoutMount(path string) *Container { - q := r.q.Select("withoutMount") - q = q.Arg("path", path) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container without the registry authentication of a given address. -func (r *Container) WithoutRegistryAuth(address string) *Container { - q := r.q.Select("withoutRegistryAuth") - q = q.Arg("address", address) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container with a previously added Unix socket removed. -func (r *Container) WithoutUnixSocket(path string) *Container { - q := r.q.Select("withoutUnixSocket") - q = q.Arg("path", path) - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container with an unset command user. -// -// Should default to root. -func (r *Container) WithoutUser() *Container { - q := r.q.Select("withoutUser") - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves this container with an unset working directory. -// -// Should default to "/". -func (r *Container) WithoutWorkdir() *Container { - q := r.q.Select("withoutWorkdir") - - return &Container{ - q: q, - c: r.c, - } -} - -// Retrieves the working directory for all commands. -func (r *Container) Workdir(ctx context.Context) (string, error) { - if r.workdir != nil { - return *r.workdir, nil - } - q := r.q.Select("workdir") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Reflective module API provided to functions at runtime. -type CurrentModule struct { - q *querybuilder.Selection - c graphql.Client - - id *CurrentModuleID - name *string -} - -// A unique identifier for this CurrentModule. -func (r *CurrentModule) ID(ctx context.Context) (CurrentModuleID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response CurrentModuleID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *CurrentModule) XXX_GraphQLType() string { - return "CurrentModule" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *CurrentModule) XXX_GraphQLIDType() string { - return "CurrentModuleID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *CurrentModule) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *CurrentModule) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *CurrentModule) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadCurrentModuleFromID(CurrentModuleID(id)) - return nil -} - -// The name of the module being executed in -func (r *CurrentModule) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The directory containing the module's source code loaded into the engine (plus any generated code that may have been created). -func (r *CurrentModule) Source() *Directory { - q := r.q.Select("source") - - return &Directory{ - q: q, - c: r.c, - } -} - -// CurrentModuleWorkdirOpts contains options for CurrentModule.Workdir -type CurrentModuleWorkdirOpts struct { - // Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). - Exclude []string - // Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). - Include []string -} - -// Load a directory from the module's scratch working directory, including any changes that may have been made to it during module function execution. -func (r *CurrentModule) Workdir(path string, opts ...CurrentModuleWorkdirOpts) *Directory { - q := r.q.Select("workdir") - for i := len(opts) - 1; i >= 0; i-- { - // `exclude` optional argument - if !querybuilder.IsZeroValue(opts[i].Exclude) { - q = q.Arg("exclude", opts[i].Exclude) - } - // `include` optional argument - if !querybuilder.IsZeroValue(opts[i].Include) { - q = q.Arg("include", opts[i].Include) - } - } - q = q.Arg("path", path) - - return &Directory{ - q: q, - c: r.c, - } -} - -// Load a file from the module's scratch working directory, including any changes that may have been made to it during module function execution.Load a file from the module's scratch working directory, including any changes that may have been made to it during module function execution. -func (r *CurrentModule) WorkdirFile(path string) *File { - q := r.q.Select("workdirFile") - q = q.Arg("path", path) - - return &File{ - q: q, - c: r.c, - } -} - -// A directory. -type Directory struct { - q *querybuilder.Selection - c graphql.Client - - export *bool - id *DirectoryID - sync *DirectoryID -} -type WithDirectoryFunc func(r *Directory) *Directory - -// With calls the provided function with current Directory. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *Directory) With(f WithDirectoryFunc) *Directory { - return f(r) -} - -// DirectoryAsModuleOpts contains options for Directory.AsModule -type DirectoryAsModuleOpts struct { - // An optional subpath of the directory which contains the module's configuration file. - // - // This is needed when the module code is in a subdirectory but requires parent directories to be loaded in order to execute. For example, the module source code may need a go.mod, project.toml, package.json, etc. file from a parent directory. - // - // If not set, the module source code is loaded from the root of the directory. - SourceRootPath string -} - -// Load the directory as a Dagger module -func (r *Directory) AsModule(opts ...DirectoryAsModuleOpts) *Module { - q := r.q.Select("asModule") - for i := len(opts) - 1; i >= 0; i-- { - // `sourceRootPath` optional argument - if !querybuilder.IsZeroValue(opts[i].SourceRootPath) { - q = q.Arg("sourceRootPath", opts[i].SourceRootPath) - } - } - - return &Module{ - q: q, - c: r.c, - } -} - -// Gets the difference between this directory and an another directory. -func (r *Directory) Diff(other *Directory) *Directory { - assertNotNil("other", other) - q := r.q.Select("diff") - q = q.Arg("other", other) - - return &Directory{ - q: q, - c: r.c, - } -} - -// Retrieves a directory at the given path. -func (r *Directory) Directory(path string) *Directory { - q := r.q.Select("directory") - q = q.Arg("path", path) - - return &Directory{ - q: q, - c: r.c, - } -} - -// DirectoryDockerBuildOpts contains options for Directory.DockerBuild -type DirectoryDockerBuildOpts struct { - // The platform to build. - Platform Platform - // Path to the Dockerfile to use (e.g., "frontend.Dockerfile"). - Dockerfile string - // Target build stage to build. - Target string - // Build arguments to use in the build. - BuildArgs []BuildArg - // Secrets to pass to the build. - // - // They will be mounted at /run/secrets/[secret-name]. - Secrets []*Secret -} - -// Builds a new Docker container from this directory. -func (r *Directory) DockerBuild(opts ...DirectoryDockerBuildOpts) *Container { - q := r.q.Select("dockerBuild") - for i := len(opts) - 1; i >= 0; i-- { - // `platform` optional argument - if !querybuilder.IsZeroValue(opts[i].Platform) { - q = q.Arg("platform", opts[i].Platform) - } - // `dockerfile` optional argument - if !querybuilder.IsZeroValue(opts[i].Dockerfile) { - q = q.Arg("dockerfile", opts[i].Dockerfile) - } - // `target` optional argument - if !querybuilder.IsZeroValue(opts[i].Target) { - q = q.Arg("target", opts[i].Target) - } - // `buildArgs` optional argument - if !querybuilder.IsZeroValue(opts[i].BuildArgs) { - q = q.Arg("buildArgs", opts[i].BuildArgs) - } - // `secrets` optional argument - if !querybuilder.IsZeroValue(opts[i].Secrets) { - q = q.Arg("secrets", opts[i].Secrets) - } - } - - return &Container{ - q: q, - c: r.c, - } -} - -// DirectoryEntriesOpts contains options for Directory.Entries -type DirectoryEntriesOpts struct { - // Location of the directory to look at (e.g., "/src"). - Path string -} - -// Returns a list of files and directories at the given path. -func (r *Directory) Entries(ctx context.Context, opts ...DirectoryEntriesOpts) ([]string, error) { - q := r.q.Select("entries") - for i := len(opts) - 1; i >= 0; i-- { - // `path` optional argument - if !querybuilder.IsZeroValue(opts[i].Path) { - q = q.Arg("path", opts[i].Path) - } - } - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Writes the contents of the directory to a path on the host. -func (r *Directory) Export(ctx context.Context, path string) (bool, error) { - if r.export != nil { - return *r.export, nil - } - q := r.q.Select("export") - q = q.Arg("path", path) - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Retrieves a file at the given path. -func (r *Directory) File(path string) *File { - q := r.q.Select("file") - q = q.Arg("path", path) - - return &File{ - q: q, - c: r.c, - } -} - -// Returns a list of files and directories that matche the given pattern. -func (r *Directory) Glob(ctx context.Context, pattern string) ([]string, error) { - q := r.q.Select("glob") - q = q.Arg("pattern", pattern) - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this Directory. -func (r *Directory) ID(ctx context.Context) (DirectoryID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response DirectoryID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Directory) XXX_GraphQLType() string { - return "Directory" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Directory) XXX_GraphQLIDType() string { - return "DirectoryID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Directory) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Directory) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Directory) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadDirectoryFromID(DirectoryID(id)) - return nil -} - -// DirectoryPipelineOpts contains options for Directory.Pipeline -type DirectoryPipelineOpts struct { - // Description of the sub-pipeline. - Description string - // Labels to apply to the sub-pipeline. - Labels []PipelineLabel -} - -// Creates a named sub-pipeline. -func (r *Directory) Pipeline(name string, opts ...DirectoryPipelineOpts) *Directory { - q := r.q.Select("pipeline") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - // `labels` optional argument - if !querybuilder.IsZeroValue(opts[i].Labels) { - q = q.Arg("labels", opts[i].Labels) - } - } - q = q.Arg("name", name) - - return &Directory{ - q: q, - c: r.c, - } -} - -// Force evaluation in the engine. -func (r *Directory) Sync(ctx context.Context) (*Directory, error) { - q := r.q.Select("sync") - - return r, q.Execute(ctx, r.c) -} - -// DirectoryWithDirectoryOpts contains options for Directory.WithDirectory -type DirectoryWithDirectoryOpts struct { - // Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). - Exclude []string - // Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). - Include []string -} - -// Retrieves this directory plus a directory written at the given path. -func (r *Directory) WithDirectory(path string, directory *Directory, opts ...DirectoryWithDirectoryOpts) *Directory { - assertNotNil("directory", directory) - q := r.q.Select("withDirectory") - for i := len(opts) - 1; i >= 0; i-- { - // `exclude` optional argument - if !querybuilder.IsZeroValue(opts[i].Exclude) { - q = q.Arg("exclude", opts[i].Exclude) - } - // `include` optional argument - if !querybuilder.IsZeroValue(opts[i].Include) { - q = q.Arg("include", opts[i].Include) - } - } - q = q.Arg("path", path) - q = q.Arg("directory", directory) - - return &Directory{ - q: q, - c: r.c, - } -} - -// DirectoryWithFileOpts contains options for Directory.WithFile -type DirectoryWithFileOpts struct { - // Permission given to the copied file (e.g., 0600). - Permissions int -} - -// Retrieves this directory plus the contents of the given file copied to the given path. -func (r *Directory) WithFile(path string, source *File, opts ...DirectoryWithFileOpts) *Directory { - assertNotNil("source", source) - q := r.q.Select("withFile") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - } - q = q.Arg("path", path) - q = q.Arg("source", source) - - return &Directory{ - q: q, - c: r.c, - } -} - -// DirectoryWithFilesOpts contains options for Directory.WithFiles -type DirectoryWithFilesOpts struct { - // Permission given to the copied files (e.g., 0600). - Permissions int -} - -// Retrieves this directory plus the contents of the given files copied to the given path. -func (r *Directory) WithFiles(path string, sources []*File, opts ...DirectoryWithFilesOpts) *Directory { - q := r.q.Select("withFiles") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - } - q = q.Arg("path", path) - q = q.Arg("sources", sources) - - return &Directory{ - q: q, - c: r.c, - } -} - -// DirectoryWithNewDirectoryOpts contains options for Directory.WithNewDirectory -type DirectoryWithNewDirectoryOpts struct { - // Permission granted to the created directory (e.g., 0777). - Permissions int -} - -// Retrieves this directory plus a new directory created at the given path. -func (r *Directory) WithNewDirectory(path string, opts ...DirectoryWithNewDirectoryOpts) *Directory { - q := r.q.Select("withNewDirectory") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - } - q = q.Arg("path", path) - - return &Directory{ - q: q, - c: r.c, - } -} - -// DirectoryWithNewFileOpts contains options for Directory.WithNewFile -type DirectoryWithNewFileOpts struct { - // Permission given to the copied file (e.g., 0600). - Permissions int -} - -// Retrieves this directory plus a new file written at the given path. -func (r *Directory) WithNewFile(path string, contents string, opts ...DirectoryWithNewFileOpts) *Directory { - q := r.q.Select("withNewFile") - for i := len(opts) - 1; i >= 0; i-- { - // `permissions` optional argument - if !querybuilder.IsZeroValue(opts[i].Permissions) { - q = q.Arg("permissions", opts[i].Permissions) - } - } - q = q.Arg("path", path) - q = q.Arg("contents", contents) - - return &Directory{ - q: q, - c: r.c, - } -} - -// Retrieves this directory with all file/dir timestamps set to the given time. -func (r *Directory) WithTimestamps(timestamp int) *Directory { - q := r.q.Select("withTimestamps") - q = q.Arg("timestamp", timestamp) - - return &Directory{ - q: q, - c: r.c, - } -} - -// Retrieves this directory with the directory at the given path removed. -func (r *Directory) WithoutDirectory(path string) *Directory { - q := r.q.Select("withoutDirectory") - q = q.Arg("path", path) - - return &Directory{ - q: q, - c: r.c, - } -} - -// Retrieves this directory with the file at the given path removed. -func (r *Directory) WithoutFile(path string) *Directory { - q := r.q.Select("withoutFile") - q = q.Arg("path", path) - - return &Directory{ - q: q, - c: r.c, - } -} - -// An environment variable name and value. -type EnvVariable struct { - q *querybuilder.Selection - c graphql.Client - - id *EnvVariableID - name *string - value *string -} - -// A unique identifier for this EnvVariable. -func (r *EnvVariable) ID(ctx context.Context) (EnvVariableID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response EnvVariableID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *EnvVariable) XXX_GraphQLType() string { - return "EnvVariable" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *EnvVariable) XXX_GraphQLIDType() string { - return "EnvVariableID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *EnvVariable) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *EnvVariable) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *EnvVariable) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadEnvVariableFromID(EnvVariableID(id)) - return nil -} - -// The environment variable name. -func (r *EnvVariable) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The environment variable value. -func (r *EnvVariable) Value(ctx context.Context) (string, error) { - if r.value != nil { - return *r.value, nil - } - q := r.q.Select("value") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A definition of a field on a custom object defined in a Module. -// -// A field on an object has a static value, as opposed to a function on an object whose value is computed by invoking code (and can accept arguments). -type FieldTypeDef struct { - q *querybuilder.Selection - c graphql.Client - - description *string - id *FieldTypeDefID - name *string -} - -// A doc string for the field, if any. -func (r *FieldTypeDef) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.q.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this FieldTypeDef. -func (r *FieldTypeDef) ID(ctx context.Context) (FieldTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response FieldTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *FieldTypeDef) XXX_GraphQLType() string { - return "FieldTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *FieldTypeDef) XXX_GraphQLIDType() string { - return "FieldTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *FieldTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *FieldTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *FieldTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFieldTypeDefFromID(FieldTypeDefID(id)) - return nil -} - -// The name of the field in lowerCamelCase format. -func (r *FieldTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The type of the field. -func (r *FieldTypeDef) TypeDef() *TypeDef { - q := r.q.Select("typeDef") - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// A file. -type File struct { - q *querybuilder.Selection - c graphql.Client - - contents *string - export *bool - id *FileID - name *string - size *int - sync *FileID -} -type WithFileFunc func(r *File) *File - -// With calls the provided function with current File. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *File) With(f WithFileFunc) *File { - return f(r) -} - -// Retrieves the contents of the file. -func (r *File) Contents(ctx context.Context) (string, error) { - if r.contents != nil { - return *r.contents, nil - } - q := r.q.Select("contents") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// FileExportOpts contains options for File.Export -type FileExportOpts struct { - // If allowParentDirPath is true, the path argument can be a directory path, in which case the file will be created in that directory. - AllowParentDirPath bool -} - -// Writes the file to a file path on the host. -func (r *File) Export(ctx context.Context, path string, opts ...FileExportOpts) (bool, error) { - if r.export != nil { - return *r.export, nil - } - q := r.q.Select("export") - for i := len(opts) - 1; i >= 0; i-- { - // `allowParentDirPath` optional argument - if !querybuilder.IsZeroValue(opts[i].AllowParentDirPath) { - q = q.Arg("allowParentDirPath", opts[i].AllowParentDirPath) - } - } - q = q.Arg("path", path) - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this File. -func (r *File) ID(ctx context.Context) (FileID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response FileID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *File) XXX_GraphQLType() string { - return "File" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *File) XXX_GraphQLIDType() string { - return "FileID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *File) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *File) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *File) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFileFromID(FileID(id)) - return nil -} - -// Retrieves the name of the file. -func (r *File) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Retrieves the size of the file, in bytes. -func (r *File) Size(ctx context.Context) (int, error) { - if r.size != nil { - return *r.size, nil - } - q := r.q.Select("size") - - var response int - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Force evaluation in the engine. -func (r *File) Sync(ctx context.Context) (*File, error) { - q := r.q.Select("sync") - - return r, q.Execute(ctx, r.c) -} - -// Retrieves this file with its created/modified timestamps set to the given time. -func (r *File) WithTimestamps(timestamp int) *File { - q := r.q.Select("withTimestamps") - q = q.Arg("timestamp", timestamp) - - return &File{ - q: q, - c: r.c, - } -} - -// Function represents a resolver provided by a Module. -// -// A function always evaluates against a parent object and is given a set of named arguments. -type Function struct { - q *querybuilder.Selection - c graphql.Client - - description *string - id *FunctionID - name *string -} -type WithFunctionFunc func(r *Function) *Function - -// With calls the provided function with current Function. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *Function) With(f WithFunctionFunc) *Function { - return f(r) -} - -// Arguments accepted by the function, if any. -func (r *Function) Args(ctx context.Context) ([]FunctionArg, error) { - q := r.q.Select("args") - - q = q.Select("id") - - type args struct { - Id FunctionArgID - } - - convert := func(fields []args) []FunctionArg { - out := []FunctionArg{} - - for i := range fields { - val := FunctionArg{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadFunctionArgFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []args - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// A doc string for the function, if any. -func (r *Function) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.q.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this Function. -func (r *Function) ID(ctx context.Context) (FunctionID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response FunctionID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Function) XXX_GraphQLType() string { - return "Function" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Function) XXX_GraphQLIDType() string { - return "FunctionID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Function) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Function) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Function) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFunctionFromID(FunctionID(id)) - return nil -} - -// The name of the function. -func (r *Function) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The type returned by the function. -func (r *Function) ReturnType() *TypeDef { - q := r.q.Select("returnType") - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// FunctionWithArgOpts contains options for Function.WithArg -type FunctionWithArgOpts struct { - // A doc string for the argument, if any - Description string - // A default value to use for this argument if not explicitly set by the caller, if any - DefaultValue JSON -} - -// Returns the function with the provided argument -func (r *Function) WithArg(name string, typeDef *TypeDef, opts ...FunctionWithArgOpts) *Function { - assertNotNil("typeDef", typeDef) - q := r.q.Select("withArg") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - // `defaultValue` optional argument - if !querybuilder.IsZeroValue(opts[i].DefaultValue) { - q = q.Arg("defaultValue", opts[i].DefaultValue) - } - } - q = q.Arg("name", name) - q = q.Arg("typeDef", typeDef) - - return &Function{ - q: q, - c: r.c, - } -} - -// Returns the function with the given doc string. -func (r *Function) WithDescription(description string) *Function { - q := r.q.Select("withDescription") - q = q.Arg("description", description) - - return &Function{ - q: q, - c: r.c, - } -} - -// An argument accepted by a function. -// -// This is a specification for an argument at function definition time, not an argument passed at function call time. -type FunctionArg struct { - q *querybuilder.Selection - c graphql.Client - - defaultValue *JSON - description *string - id *FunctionArgID - name *string -} - -// A default value to use for this argument when not explicitly set by the caller, if any. -func (r *FunctionArg) DefaultValue(ctx context.Context) (JSON, error) { - if r.defaultValue != nil { - return *r.defaultValue, nil - } - q := r.q.Select("defaultValue") - - var response JSON - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A doc string for the argument, if any. -func (r *FunctionArg) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.q.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this FunctionArg. -func (r *FunctionArg) ID(ctx context.Context) (FunctionArgID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response FunctionArgID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *FunctionArg) XXX_GraphQLType() string { - return "FunctionArg" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *FunctionArg) XXX_GraphQLIDType() string { - return "FunctionArgID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *FunctionArg) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *FunctionArg) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *FunctionArg) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFunctionArgFromID(FunctionArgID(id)) - return nil -} - -// The name of the argument in lowerCamelCase format. -func (r *FunctionArg) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The type of the argument. -func (r *FunctionArg) TypeDef() *TypeDef { - q := r.q.Select("typeDef") - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// An active function call. -type FunctionCall struct { - q *querybuilder.Selection - c graphql.Client - - id *FunctionCallID - name *string - parent *JSON - parentName *string - returnValue *Void -} - -// A unique identifier for this FunctionCall. -func (r *FunctionCall) ID(ctx context.Context) (FunctionCallID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response FunctionCallID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *FunctionCall) XXX_GraphQLType() string { - return "FunctionCall" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *FunctionCall) XXX_GraphQLIDType() string { - return "FunctionCallID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *FunctionCall) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *FunctionCall) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *FunctionCall) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFunctionCallFromID(FunctionCallID(id)) - return nil -} - -// The argument values the function is being invoked with. -func (r *FunctionCall) InputArgs(ctx context.Context) ([]FunctionCallArgValue, error) { - q := r.q.Select("inputArgs") - - q = q.Select("id") - - type inputArgs struct { - Id FunctionCallArgValueID - } - - convert := func(fields []inputArgs) []FunctionCallArgValue { - out := []FunctionCallArgValue{} - - for i := range fields { - val := FunctionCallArgValue{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadFunctionCallArgValueFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []inputArgs - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The name of the function being called. -func (r *FunctionCall) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The value of the parent object of the function being called. If the function is top-level to the module, this is always an empty object. -func (r *FunctionCall) Parent(ctx context.Context) (JSON, error) { - if r.parent != nil { - return *r.parent, nil - } - q := r.q.Select("parent") - - var response JSON - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The name of the parent object of the function being called. If the function is top-level to the module, this is the name of the module. -func (r *FunctionCall) ParentName(ctx context.Context) (string, error) { - if r.parentName != nil { - return *r.parentName, nil - } - q := r.q.Select("parentName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Set the return value of the function call to the provided value. -func (r *FunctionCall) ReturnValue(ctx context.Context, value JSON) (Void, error) { - if r.returnValue != nil { - return *r.returnValue, nil - } - q := r.q.Select("returnValue") - q = q.Arg("value", value) - - var response Void - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A value passed as a named argument to a function call. -type FunctionCallArgValue struct { - q *querybuilder.Selection - c graphql.Client - - id *FunctionCallArgValueID - name *string - value *JSON -} - -// A unique identifier for this FunctionCallArgValue. -func (r *FunctionCallArgValue) ID(ctx context.Context) (FunctionCallArgValueID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response FunctionCallArgValueID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *FunctionCallArgValue) XXX_GraphQLType() string { - return "FunctionCallArgValue" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *FunctionCallArgValue) XXX_GraphQLIDType() string { - return "FunctionCallArgValueID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *FunctionCallArgValue) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *FunctionCallArgValue) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *FunctionCallArgValue) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadFunctionCallArgValueFromID(FunctionCallArgValueID(id)) - return nil -} - -// The name of the argument. -func (r *FunctionCallArgValue) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The value of the argument represented as a JSON serialized string. -func (r *FunctionCallArgValue) Value(ctx context.Context) (JSON, error) { - if r.value != nil { - return *r.value, nil - } - q := r.q.Select("value") - - var response JSON - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The result of running an SDK's codegen. -type GeneratedCode struct { - q *querybuilder.Selection - c graphql.Client - - id *GeneratedCodeID -} -type WithGeneratedCodeFunc func(r *GeneratedCode) *GeneratedCode - -// With calls the provided function with current GeneratedCode. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *GeneratedCode) With(f WithGeneratedCodeFunc) *GeneratedCode { - return f(r) -} - -// The directory containing the generated code. -func (r *GeneratedCode) Code() *Directory { - q := r.q.Select("code") - - return &Directory{ - q: q, - c: r.c, - } -} - -// A unique identifier for this GeneratedCode. -func (r *GeneratedCode) ID(ctx context.Context) (GeneratedCodeID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response GeneratedCodeID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *GeneratedCode) XXX_GraphQLType() string { - return "GeneratedCode" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *GeneratedCode) XXX_GraphQLIDType() string { - return "GeneratedCodeID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *GeneratedCode) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *GeneratedCode) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *GeneratedCode) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadGeneratedCodeFromID(GeneratedCodeID(id)) - return nil -} - -// List of paths to mark generated in version control (i.e. .gitattributes). -func (r *GeneratedCode) VcsGeneratedPaths(ctx context.Context) ([]string, error) { - q := r.q.Select("vcsGeneratedPaths") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// List of paths to ignore in version control (i.e. .gitignore). -func (r *GeneratedCode) VcsIgnoredPaths(ctx context.Context) ([]string, error) { - q := r.q.Select("vcsIgnoredPaths") - - var response []string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Set the list of paths to mark generated in version control. -func (r *GeneratedCode) WithVCSGeneratedPaths(paths []string) *GeneratedCode { - q := r.q.Select("withVCSGeneratedPaths") - q = q.Arg("paths", paths) - - return &GeneratedCode{ - q: q, - c: r.c, - } -} - -// Set the list of paths to ignore in version control. -func (r *GeneratedCode) WithVCSIgnoredPaths(paths []string) *GeneratedCode { - q := r.q.Select("withVCSIgnoredPaths") - q = q.Arg("paths", paths) - - return &GeneratedCode{ - q: q, - c: r.c, - } -} - -// Module source originating from a git repo. -type GitModuleSource struct { - q *querybuilder.Selection - c graphql.Client - - cloneURL *string - commit *string - htmlURL *string - id *GitModuleSourceID - rootSubpath *string - version *string -} - -// The URL from which the source's git repo can be cloned. -func (r *GitModuleSource) CloneURL(ctx context.Context) (string, error) { - if r.cloneURL != nil { - return *r.cloneURL, nil - } - q := r.q.Select("cloneURL") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The resolved commit of the git repo this source points to. -func (r *GitModuleSource) Commit(ctx context.Context) (string, error) { - if r.commit != nil { - return *r.commit, nil - } - q := r.q.Select("commit") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The directory containing everything needed to load load and use the module. -func (r *GitModuleSource) ContextDirectory() *Directory { - q := r.q.Select("contextDirectory") - - return &Directory{ - q: q, - c: r.c, - } -} - -// The URL to the source's git repo in a web browser -func (r *GitModuleSource) HTMLURL(ctx context.Context) (string, error) { - if r.htmlURL != nil { - return *r.htmlURL, nil - } - q := r.q.Select("htmlURL") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this GitModuleSource. -func (r *GitModuleSource) ID(ctx context.Context) (GitModuleSourceID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response GitModuleSourceID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *GitModuleSource) XXX_GraphQLType() string { - return "GitModuleSource" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *GitModuleSource) XXX_GraphQLIDType() string { - return "GitModuleSourceID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *GitModuleSource) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *GitModuleSource) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *GitModuleSource) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadGitModuleSourceFromID(GitModuleSourceID(id)) - return nil -} - -// The path to the root of the module source under the context directory. This directory contains its configuration file. It also contains its source code (possibly as a subdirectory). -func (r *GitModuleSource) RootSubpath(ctx context.Context) (string, error) { - if r.rootSubpath != nil { - return *r.rootSubpath, nil - } - q := r.q.Select("rootSubpath") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The specified version of the git repo this source points to. -func (r *GitModuleSource) Version(ctx context.Context) (string, error) { - if r.version != nil { - return *r.version, nil - } - q := r.q.Select("version") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A git ref (tag, branch, or commit). -type GitRef struct { - q *querybuilder.Selection - c graphql.Client - - commit *string - id *GitRefID -} - -// The resolved commit id at this ref. -func (r *GitRef) Commit(ctx context.Context) (string, error) { - if r.commit != nil { - return *r.commit, nil - } - q := r.q.Select("commit") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this GitRef. -func (r *GitRef) ID(ctx context.Context) (GitRefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response GitRefID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *GitRef) XXX_GraphQLType() string { - return "GitRef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *GitRef) XXX_GraphQLIDType() string { - return "GitRefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *GitRef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *GitRef) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *GitRef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadGitRefFromID(GitRefID(id)) - return nil -} - -// GitRefTreeOpts contains options for GitRef.Tree -type GitRefTreeOpts struct { - // DEPRECATED: This option should be passed to `git` instead. - SSHKnownHosts string - // DEPRECATED: This option should be passed to `git` instead. - SSHAuthSocket *Socket -} - -// The filesystem tree at this ref. -func (r *GitRef) Tree(opts ...GitRefTreeOpts) *Directory { - q := r.q.Select("tree") - for i := len(opts) - 1; i >= 0; i-- { - // `sshKnownHosts` optional argument - if !querybuilder.IsZeroValue(opts[i].SSHKnownHosts) { - q = q.Arg("sshKnownHosts", opts[i].SSHKnownHosts) - } - // `sshAuthSocket` optional argument - if !querybuilder.IsZeroValue(opts[i].SSHAuthSocket) { - q = q.Arg("sshAuthSocket", opts[i].SSHAuthSocket) - } - } - - return &Directory{ - q: q, - c: r.c, - } -} - -// A git repository. -type GitRepository struct { - q *querybuilder.Selection - c graphql.Client - - id *GitRepositoryID -} - -// Returns details of a branch. -func (r *GitRepository) Branch(name string) *GitRef { - q := r.q.Select("branch") - q = q.Arg("name", name) - - return &GitRef{ - q: q, - c: r.c, - } -} - -// Returns details of a commit. -func (r *GitRepository) Commit(id string) *GitRef { - q := r.q.Select("commit") - q = q.Arg("id", id) - - return &GitRef{ - q: q, - c: r.c, - } -} - -// A unique identifier for this GitRepository. -func (r *GitRepository) ID(ctx context.Context) (GitRepositoryID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response GitRepositoryID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *GitRepository) XXX_GraphQLType() string { - return "GitRepository" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *GitRepository) XXX_GraphQLIDType() string { - return "GitRepositoryID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *GitRepository) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *GitRepository) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *GitRepository) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadGitRepositoryFromID(GitRepositoryID(id)) - return nil -} - -// Returns details of a ref. -func (r *GitRepository) Ref(name string) *GitRef { - q := r.q.Select("ref") - q = q.Arg("name", name) - - return &GitRef{ - q: q, - c: r.c, - } -} - -// Returns details of a tag. -func (r *GitRepository) Tag(name string) *GitRef { - q := r.q.Select("tag") - q = q.Arg("name", name) - - return &GitRef{ - q: q, - c: r.c, - } -} - -type Golang struct { - q *querybuilder.Selection - c graphql.Client - - golangciLint *string - id *GolangID - test *string -} -type WithGolangFunc func(r *Golang) *Golang - -// With calls the provided function with current Golang. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *Golang) With(f WithGolangFunc) *Golang { - return f(r) -} - -// Sets up the Container with a golang image and cache volumes -func (r *Golang) Base(version string) *Golang { - q := r.q.Select("base") - q = q.Arg("version", version) - - return &Golang{ - q: q, - c: r.c, - } -} - -// GolangBuildOpts contains options for Golang.Build -type GolangBuildOpts struct { - Arch string - - Os string -} - -// Build the Go project -func (r *Golang) Build(args []string, opts ...GolangBuildOpts) *Directory { - q := r.q.Select("build") - for i := len(opts) - 1; i >= 0; i-- { - // `arch` optional argument - if !querybuilder.IsZeroValue(opts[i].Arch) { - q = q.Arg("arch", opts[i].Arch) - } - // `os` optional argument - if !querybuilder.IsZeroValue(opts[i].Os) { - q = q.Arg("os", opts[i].Os) - } - } - q = q.Arg("args", args) - - return &Directory{ - q: q, - c: r.c, - } -} - -// GolangBuildRemoteOpts contains options for Golang.BuildRemote -type GolangBuildRemoteOpts struct { - Arch string - - Platform string -} - -// Build a remote git repo -func (r *Golang) BuildRemote(remote string, ref string, module string, opts ...GolangBuildRemoteOpts) *Directory { - q := r.q.Select("buildRemote") - for i := len(opts) - 1; i >= 0; i-- { - // `arch` optional argument - if !querybuilder.IsZeroValue(opts[i].Arch) { - q = q.Arg("arch", opts[i].Arch) - } - // `platform` optional argument - if !querybuilder.IsZeroValue(opts[i].Platform) { - q = q.Arg("platform", opts[i].Platform) - } - } - q = q.Arg("remote", remote) - q = q.Arg("ref", ref) - q = q.Arg("module", module) - - return &Directory{ - q: q, - c: r.c, - } -} - -// Accessor for the Container -func (r *Golang) Container() *Container { - q := r.q.Select("container") - - return &Container{ - q: q, - c: r.c, - } -} - -func (r *Golang) Ctr() *Container { - q := r.q.Select("ctr") - - return &Container{ - q: q, - c: r.c, - } -} - -// Lint the Go project -func (r *Golang) GolangciLint(ctx context.Context) (string, error) { - if r.golangciLint != nil { - return *r.golangciLint, nil - } - q := r.q.Select("golangciLint") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this Golang. -func (r *Golang) ID(ctx context.Context) (GolangID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response GolangID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Golang) XXX_GraphQLType() string { - return "Golang" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Golang) XXX_GraphQLIDType() string { - return "GolangID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Golang) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Golang) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Golang) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadGolangFromID(GolangID(id)) - return nil -} - -func (r *Golang) Proj() *Directory { - q := r.q.Select("proj") - - return &Directory{ - q: q, - c: r.c, - } -} - -// Accessor for the Project -func (r *Golang) Project() *Directory { - q := r.q.Select("project") - - return &Directory{ - q: q, - c: r.c, - } -} - -// Test the Go project -func (r *Golang) Test(ctx context.Context, args []string) (string, error) { - if r.test != nil { - return *r.test, nil - } - q := r.q.Select("test") - q = q.Arg("args", args) - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Bring your own container -func (r *Golang) WithContainer(ctr *Container) *Golang { - assertNotNil("ctr", ctr) - q := r.q.Select("withContainer") - q = q.Arg("ctr", ctr) - - return &Golang{ - q: q, - c: r.c, - } -} - -// Specify the Project to use in the module -func (r *Golang) WithProject(dir *Directory) *Golang { - assertNotNil("dir", dir) - q := r.q.Select("withProject") - q = q.Arg("dir", dir) - - return &Golang{ - q: q, - c: r.c, - } -} - -// A graphql input type, which is essentially just a group of named args. -// This is currently only used to represent pre-existing usage of graphql input types -// in the core API. It is not used by user modules and shouldn't ever be as user -// module accept input objects via their id rather than graphql input types. -type InputTypeDef struct { - q *querybuilder.Selection - c graphql.Client - - id *InputTypeDefID - name *string -} - -// Static fields defined on this input object, if any. -func (r *InputTypeDef) Fields(ctx context.Context) ([]FieldTypeDef, error) { - q := r.q.Select("fields") - - q = q.Select("id") - - type fields struct { - Id FieldTypeDefID - } - - convert := func(fields []fields) []FieldTypeDef { - out := []FieldTypeDef{} - - for i := range fields { - val := FieldTypeDef{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadFieldTypeDefFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []fields - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// A unique identifier for this InputTypeDef. -func (r *InputTypeDef) ID(ctx context.Context) (InputTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response InputTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *InputTypeDef) XXX_GraphQLType() string { - return "InputTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *InputTypeDef) XXX_GraphQLIDType() string { - return "InputTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *InputTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *InputTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *InputTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadInputTypeDefFromID(InputTypeDefID(id)) - return nil -} - -// The name of the input object. -func (r *InputTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A definition of a custom interface defined in a Module. -type InterfaceTypeDef struct { - q *querybuilder.Selection - c graphql.Client - - description *string - id *InterfaceTypeDefID - name *string - sourceModuleName *string -} - -// The doc string for the interface, if any. -func (r *InterfaceTypeDef) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.q.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Functions defined on this interface, if any. -func (r *InterfaceTypeDef) Functions(ctx context.Context) ([]Function, error) { - q := r.q.Select("functions") - - q = q.Select("id") - - type functions struct { - Id FunctionID - } - - convert := func(fields []functions) []Function { - out := []Function{} - - for i := range fields { - val := Function{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadFunctionFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []functions - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// A unique identifier for this InterfaceTypeDef. -func (r *InterfaceTypeDef) ID(ctx context.Context) (InterfaceTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response InterfaceTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *InterfaceTypeDef) XXX_GraphQLType() string { - return "InterfaceTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *InterfaceTypeDef) XXX_GraphQLIDType() string { - return "InterfaceTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *InterfaceTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *InterfaceTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *InterfaceTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadInterfaceTypeDefFromID(InterfaceTypeDefID(id)) - return nil -} - -// The name of the interface. -func (r *InterfaceTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// If this InterfaceTypeDef is associated with a Module, the name of the module. Unset otherwise. -func (r *InterfaceTypeDef) SourceModuleName(ctx context.Context) (string, error) { - if r.sourceModuleName != nil { - return *r.sourceModuleName, nil - } - q := r.q.Select("sourceModuleName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A simple key value object that represents a label. -type Label struct { - q *querybuilder.Selection - c graphql.Client - - id *LabelID - name *string - value *string -} - -// A unique identifier for this Label. -func (r *Label) ID(ctx context.Context) (LabelID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response LabelID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Label) XXX_GraphQLType() string { - return "Label" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Label) XXX_GraphQLIDType() string { - return "LabelID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Label) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Label) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Label) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadLabelFromID(LabelID(id)) - return nil -} - -// The label name. -func (r *Label) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The label value. -func (r *Label) Value(ctx context.Context) (string, error) { - if r.value != nil { - return *r.value, nil - } - q := r.q.Select("value") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A definition of a list type in a Module. -type ListTypeDef struct { - q *querybuilder.Selection - c graphql.Client - - id *ListTypeDefID -} - -// The type of the elements in the list. -func (r *ListTypeDef) ElementTypeDef() *TypeDef { - q := r.q.Select("elementTypeDef") - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// A unique identifier for this ListTypeDef. -func (r *ListTypeDef) ID(ctx context.Context) (ListTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response ListTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *ListTypeDef) XXX_GraphQLType() string { - return "ListTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *ListTypeDef) XXX_GraphQLIDType() string { - return "ListTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *ListTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *ListTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *ListTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadListTypeDefFromID(ListTypeDefID(id)) - return nil -} - -// Module source that that originates from a path locally relative to an arbitrary directory. -type LocalModuleSource struct { - q *querybuilder.Selection - c graphql.Client - - id *LocalModuleSourceID - rootSubpath *string -} - -// The directory containing everything needed to load load and use the module. -func (r *LocalModuleSource) ContextDirectory() *Directory { - q := r.q.Select("contextDirectory") - - return &Directory{ - q: q, - c: r.c, - } -} - -// A unique identifier for this LocalModuleSource. -func (r *LocalModuleSource) ID(ctx context.Context) (LocalModuleSourceID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response LocalModuleSourceID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *LocalModuleSource) XXX_GraphQLType() string { - return "LocalModuleSource" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *LocalModuleSource) XXX_GraphQLIDType() string { - return "LocalModuleSourceID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *LocalModuleSource) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *LocalModuleSource) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *LocalModuleSource) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadLocalModuleSourceFromID(LocalModuleSourceID(id)) - return nil -} - -// The path to the root of the module source under the context directory. This directory contains its configuration file. It also contains its source code (possibly as a subdirectory). -func (r *LocalModuleSource) RootSubpath(ctx context.Context) (string, error) { - if r.rootSubpath != nil { - return *r.rootSubpath, nil - } - q := r.q.Select("rootSubpath") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A Dagger module. -type Module struct { - q *querybuilder.Selection - c graphql.Client - - description *string - id *ModuleID - name *string - sdk *string - serve *Void -} -type WithModuleFunc func(r *Module) *Module - -// With calls the provided function with current Module. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *Module) With(f WithModuleFunc) *Module { - return f(r) -} - -// Modules used by this module. -func (r *Module) Dependencies(ctx context.Context) ([]Module, error) { - q := r.q.Select("dependencies") - - q = q.Select("id") - - type dependencies struct { - Id ModuleID - } - - convert := func(fields []dependencies) []Module { - out := []Module{} - - for i := range fields { - val := Module{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadModuleFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []dependencies - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The dependencies as configured by the module. -func (r *Module) DependencyConfig(ctx context.Context) ([]ModuleDependency, error) { - q := r.q.Select("dependencyConfig") - - q = q.Select("id") - - type dependencyConfig struct { - Id ModuleDependencyID - } - - convert := func(fields []dependencyConfig) []ModuleDependency { - out := []ModuleDependency{} - - for i := range fields { - val := ModuleDependency{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadModuleDependencyFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []dependencyConfig - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The doc string of the module, if any -func (r *Module) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.q.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The generated files and directories made on top of the module source's context directory. -func (r *Module) GeneratedContextDiff() *Directory { - q := r.q.Select("generatedContextDiff") - - return &Directory{ - q: q, - c: r.c, - } -} - -// The module source's context plus any configuration and source files created by codegen. -func (r *Module) GeneratedContextDirectory() *Directory { - q := r.q.Select("generatedContextDirectory") - - return &Directory{ - q: q, - c: r.c, - } -} - -// A unique identifier for this Module. -func (r *Module) ID(ctx context.Context) (ModuleID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response ModuleID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Module) XXX_GraphQLType() string { - return "Module" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Module) XXX_GraphQLIDType() string { - return "ModuleID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Module) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Module) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Module) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadModuleFromID(ModuleID(id)) - return nil -} - -// Retrieves the module with the objects loaded via its SDK. -func (r *Module) Initialize() *Module { - q := r.q.Select("initialize") - - return &Module{ - q: q, - c: r.c, - } -} - -// Interfaces served by this module. -func (r *Module) Interfaces(ctx context.Context) ([]TypeDef, error) { - q := r.q.Select("interfaces") - - q = q.Select("id") - - type interfaces struct { - Id TypeDefID - } - - convert := func(fields []interfaces) []TypeDef { - out := []TypeDef{} - - for i := range fields { - val := TypeDef{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadTypeDefFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []interfaces - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The name of the module -func (r *Module) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Objects served by this module. -func (r *Module) Objects(ctx context.Context) ([]TypeDef, error) { - q := r.q.Select("objects") - - q = q.Select("id") - - type objects struct { - Id TypeDefID - } - - convert := func(fields []objects) []TypeDef { - out := []TypeDef{} - - for i := range fields { - val := TypeDef{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadTypeDefFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []objects - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The container that runs the module's entrypoint. It will fail to execute if the module doesn't compile. -func (r *Module) Runtime() *Container { - q := r.q.Select("runtime") - - return &Container{ - q: q, - c: r.c, - } -} - -// The SDK used by this module. Either a name of a builtin SDK or a module source ref string pointing to the SDK's implementation. -func (r *Module) SDK(ctx context.Context) (string, error) { - if r.sdk != nil { - return *r.sdk, nil - } - q := r.q.Select("sdk") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Serve a module's API in the current session. -// -// Note: this can only be called once per session. In the future, it could return a stream or service to remove the side effect. -func (r *Module) Serve(ctx context.Context) (Void, error) { - if r.serve != nil { - return *r.serve, nil - } - q := r.q.Select("serve") - - var response Void - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The source for the module. -func (r *Module) Source() *ModuleSource { - q := r.q.Select("source") - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// Retrieves the module with the given description -func (r *Module) WithDescription(description string) *Module { - q := r.q.Select("withDescription") - q = q.Arg("description", description) - - return &Module{ - q: q, - c: r.c, - } -} - -// This module plus the given Interface type and associated functions -func (r *Module) WithInterface(iface *TypeDef) *Module { - assertNotNil("iface", iface) - q := r.q.Select("withInterface") - q = q.Arg("iface", iface) - - return &Module{ - q: q, - c: r.c, - } -} - -// This module plus the given Object type and associated functions. -func (r *Module) WithObject(object *TypeDef) *Module { - assertNotNil("object", object) - q := r.q.Select("withObject") - q = q.Arg("object", object) - - return &Module{ - q: q, - c: r.c, - } -} - -// Retrieves the module with basic configuration loaded if present. -func (r *Module) WithSource(source *ModuleSource) *Module { - assertNotNil("source", source) - q := r.q.Select("withSource") - q = q.Arg("source", source) - - return &Module{ - q: q, - c: r.c, - } -} - -// The configuration of dependency of a module. -type ModuleDependency struct { - q *querybuilder.Selection - c graphql.Client - - id *ModuleDependencyID - name *string -} - -// A unique identifier for this ModuleDependency. -func (r *ModuleDependency) ID(ctx context.Context) (ModuleDependencyID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response ModuleDependencyID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *ModuleDependency) XXX_GraphQLType() string { - return "ModuleDependency" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *ModuleDependency) XXX_GraphQLIDType() string { - return "ModuleDependencyID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *ModuleDependency) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *ModuleDependency) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *ModuleDependency) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadModuleDependencyFromID(ModuleDependencyID(id)) - return nil -} - -// The name of the dependency module. -func (r *ModuleDependency) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The source for the dependency module. -func (r *ModuleDependency) Source() *ModuleSource { - q := r.q.Select("source") - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// The source needed to load and run a module, along with any metadata about the source such as versions/urls/etc. -type ModuleSource struct { - q *querybuilder.Selection - c graphql.Client - - asString *string - configExists *bool - id *ModuleSourceID - kind *ModuleSourceKind - moduleName *string - moduleOriginalName *string - resolveContextPathFromCaller *string - sourceRootSubpath *string - sourceSubpath *string -} -type WithModuleSourceFunc func(r *ModuleSource) *ModuleSource - -// With calls the provided function with current ModuleSource. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *ModuleSource) With(f WithModuleSourceFunc) *ModuleSource { - return f(r) -} - -// If the source is a of kind git, the git source representation of it. -func (r *ModuleSource) AsGitSource() *GitModuleSource { - q := r.q.Select("asGitSource") - - return &GitModuleSource{ - q: q, - c: r.c, - } -} - -// If the source is of kind local, the local source representation of it. -func (r *ModuleSource) AsLocalSource() *LocalModuleSource { - q := r.q.Select("asLocalSource") - - return &LocalModuleSource{ - q: q, - c: r.c, - } -} - -// Load the source as a module. If this is a local source, the parent directory must have been provided during module source creation -func (r *ModuleSource) AsModule() *Module { - q := r.q.Select("asModule") - - return &Module{ - q: q, - c: r.c, - } -} - -// A human readable ref string representation of this module source. -func (r *ModuleSource) AsString(ctx context.Context) (string, error) { - if r.asString != nil { - return *r.asString, nil - } - q := r.q.Select("asString") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Returns whether the module source has a configuration file. -func (r *ModuleSource) ConfigExists(ctx context.Context) (bool, error) { - if r.configExists != nil { - return *r.configExists, nil - } - q := r.q.Select("configExists") - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The directory containing everything needed to load load and use the module. -func (r *ModuleSource) ContextDirectory() *Directory { - q := r.q.Select("contextDirectory") - - return &Directory{ - q: q, - c: r.c, - } -} - -// The dependencies of the module source. Includes dependencies from the configuration and any extras from withDependencies calls. -func (r *ModuleSource) Dependencies(ctx context.Context) ([]ModuleDependency, error) { - q := r.q.Select("dependencies") - - q = q.Select("id") - - type dependencies struct { - Id ModuleDependencyID - } - - convert := func(fields []dependencies) []ModuleDependency { - out := []ModuleDependency{} - - for i := range fields { - val := ModuleDependency{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadModuleDependencyFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []dependencies - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The directory containing the module configuration and source code (source code may be in a subdir). -func (r *ModuleSource) Directory(path string) *Directory { - q := r.q.Select("directory") - q = q.Arg("path", path) - - return &Directory{ - q: q, - c: r.c, - } -} - -// A unique identifier for this ModuleSource. -func (r *ModuleSource) ID(ctx context.Context) (ModuleSourceID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response ModuleSourceID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *ModuleSource) XXX_GraphQLType() string { - return "ModuleSource" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *ModuleSource) XXX_GraphQLIDType() string { - return "ModuleSourceID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *ModuleSource) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *ModuleSource) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *ModuleSource) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadModuleSourceFromID(ModuleSourceID(id)) - return nil -} - -// The kind of source (e.g. local, git, etc.) -func (r *ModuleSource) Kind(ctx context.Context) (ModuleSourceKind, error) { - if r.kind != nil { - return *r.kind, nil - } - q := r.q.Select("kind") - - var response ModuleSourceKind - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// If set, the name of the module this source references, including any overrides at runtime by callers. -func (r *ModuleSource) ModuleName(ctx context.Context) (string, error) { - if r.moduleName != nil { - return *r.moduleName, nil - } - q := r.q.Select("moduleName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The original name of the module this source references, as defined in the module configuration. -func (r *ModuleSource) ModuleOriginalName(ctx context.Context) (string, error) { - if r.moduleOriginalName != nil { - return *r.moduleOriginalName, nil - } - q := r.q.Select("moduleOriginalName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The path to the module source's context directory on the caller's filesystem. Only valid for local sources. -func (r *ModuleSource) ResolveContextPathFromCaller(ctx context.Context) (string, error) { - if r.resolveContextPathFromCaller != nil { - return *r.resolveContextPathFromCaller, nil - } - q := r.q.Select("resolveContextPathFromCaller") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Resolve the provided module source arg as a dependency relative to this module source. -func (r *ModuleSource) ResolveDependency(dep *ModuleSource) *ModuleSource { - assertNotNil("dep", dep) - q := r.q.Select("resolveDependency") - q = q.Arg("dep", dep) - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// Load the source from its path on the caller's filesystem, including only needed+configured files and directories. Only valid for local sources. -func (r *ModuleSource) ResolveFromCaller() *ModuleSource { - q := r.q.Select("resolveFromCaller") - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// The path relative to context of the root of the module source, which contains dagger.json. It also contains the module implementation source code, but that may or may not being a subdir of this root. -func (r *ModuleSource) SourceRootSubpath(ctx context.Context) (string, error) { - if r.sourceRootSubpath != nil { - return *r.sourceRootSubpath, nil - } - q := r.q.Select("sourceRootSubpath") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The path relative to context of the module implementation source code. -func (r *ModuleSource) SourceSubpath(ctx context.Context) (string, error) { - if r.sourceSubpath != nil { - return *r.sourceSubpath, nil - } - q := r.q.Select("sourceSubpath") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Update the module source with a new context directory. Only valid for local sources. -func (r *ModuleSource) WithContextDirectory(dir *Directory) *ModuleSource { - assertNotNil("dir", dir) - q := r.q.Select("withContextDirectory") - q = q.Arg("dir", dir) - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// Append the provided dependencies to the module source's dependency list. -func (r *ModuleSource) WithDependencies(dependencies []*ModuleDependency) *ModuleSource { - q := r.q.Select("withDependencies") - q = q.Arg("dependencies", dependencies) - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// Update the module source with a new name. -func (r *ModuleSource) WithName(name string) *ModuleSource { - q := r.q.Select("withName") - q = q.Arg("name", name) - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// Update the module source with a new SDK. -func (r *ModuleSource) WithSDK(sdk string) *ModuleSource { - q := r.q.Select("withSDK") - q = q.Arg("sdk", sdk) - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// Update the module source with a new source subpath. -func (r *ModuleSource) WithSourceSubpath(path string) *ModuleSource { - q := r.q.Select("withSourceSubpath") - q = q.Arg("path", path) - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// A definition of a custom object defined in a Module. -type ObjectTypeDef struct { - q *querybuilder.Selection - c graphql.Client - - description *string - id *ObjectTypeDefID - name *string - sourceModuleName *string -} - -// The function used to construct new instances of this object, if any -func (r *ObjectTypeDef) Constructor() *Function { - q := r.q.Select("constructor") - - return &Function{ - q: q, - c: r.c, - } -} - -// The doc string for the object, if any. -func (r *ObjectTypeDef) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.q.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Static fields defined on this object, if any. -func (r *ObjectTypeDef) Fields(ctx context.Context) ([]FieldTypeDef, error) { - q := r.q.Select("fields") - - q = q.Select("id") - - type fields struct { - Id FieldTypeDefID - } - - convert := func(fields []fields) []FieldTypeDef { - out := []FieldTypeDef{} - - for i := range fields { - val := FieldTypeDef{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadFieldTypeDefFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []fields - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// Functions defined on this object, if any. -func (r *ObjectTypeDef) Functions(ctx context.Context) ([]Function, error) { - q := r.q.Select("functions") - - q = q.Select("id") - - type functions struct { - Id FunctionID - } - - convert := func(fields []functions) []Function { - out := []Function{} - - for i := range fields { - val := Function{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadFunctionFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []functions - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// A unique identifier for this ObjectTypeDef. -func (r *ObjectTypeDef) ID(ctx context.Context) (ObjectTypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response ObjectTypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *ObjectTypeDef) XXX_GraphQLType() string { - return "ObjectTypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *ObjectTypeDef) XXX_GraphQLIDType() string { - return "ObjectTypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *ObjectTypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *ObjectTypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *ObjectTypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadObjectTypeDefFromID(ObjectTypeDefID(id)) - return nil -} - -// The name of the object. -func (r *ObjectTypeDef) Name(ctx context.Context) (string, error) { - if r.name != nil { - return *r.name, nil - } - q := r.q.Select("name") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// If this ObjectTypeDef is associated with a Module, the name of the module. Unset otherwise. -func (r *ObjectTypeDef) SourceModuleName(ctx context.Context) (string, error) { - if r.sourceModuleName != nil { - return *r.sourceModuleName, nil - } - q := r.q.Select("sourceModuleName") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A port exposed by a container. -type Port struct { - q *querybuilder.Selection - c graphql.Client - - description *string - experimentalSkipHealthcheck *bool - id *PortID - port *int - protocol *NetworkProtocol -} - -// The port description. -func (r *Port) Description(ctx context.Context) (string, error) { - if r.description != nil { - return *r.description, nil - } - q := r.q.Select("description") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Skip the health check when run as a service. -func (r *Port) ExperimentalSkipHealthcheck(ctx context.Context) (bool, error) { - if r.experimentalSkipHealthcheck != nil { - return *r.experimentalSkipHealthcheck, nil - } - q := r.q.Select("experimentalSkipHealthcheck") - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this Port. -func (r *Port) ID(ctx context.Context) (PortID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response PortID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Port) XXX_GraphQLType() string { - return "Port" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Port) XXX_GraphQLIDType() string { - return "PortID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Port) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Port) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Port) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadPortFromID(PortID(id)) - return nil -} - -// The port number. -func (r *Port) Port(ctx context.Context) (int, error) { - if r.port != nil { - return *r.port, nil - } - q := r.q.Select("port") - - var response int - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// The transport layer protocol. -func (r *Port) Protocol(ctx context.Context) (NetworkProtocol, error) { - if r.protocol != nil { - return *r.protocol, nil - } - q := r.q.Select("protocol") - - var response NetworkProtocol - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -type WithClientFunc func(r *Client) *Client - -// With calls the provided function with current Client. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *Client) With(f WithClientFunc) *Client { - return f(r) -} - -// Retrieves a content-addressed blob. -func (r *Client) Blob(digest string, size int, mediaType string, uncompressed string) *Directory { - q := r.q.Select("blob") - q = q.Arg("digest", digest) - q = q.Arg("size", size) - q = q.Arg("mediaType", mediaType) - q = q.Arg("uncompressed", uncompressed) - - return &Directory{ - q: q, - c: r.c, - } -} - -// Constructs a cache volume for a given cache key. -func (r *Client) CacheVolume(key string) *CacheVolume { - q := r.q.Select("cacheVolume") - q = q.Arg("key", key) - - return &CacheVolume{ - q: q, - c: r.c, - } -} - -func (r *Client) Chainloop(token *Secret) *Chainloop { - assertNotNil("token", token) - q := r.q.Select("chainloop") - q = q.Arg("token", token) - - return &Chainloop{ - q: q, - c: r.c, - } -} - -// Checks if the current Dagger Engine is compatible with an SDK's required version. -func (r *Client) CheckVersionCompatibility(ctx context.Context, version string) (bool, error) { - q := r.q.Select("checkVersionCompatibility") - q = q.Arg("version", version) - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// ContainerOpts contains options for Client.Container -type ContainerOpts struct { - // DEPRECATED: Use `loadContainerFromID` instead. - ID ContainerID - // Platform to initialize the container with. - Platform Platform -} - -// Creates a scratch container. -// -// Optional platform argument initializes new containers to execute and publish as that platform. Platform defaults to that of the builder's host. -func (r *Client) Container(opts ...ContainerOpts) *Container { - q := r.q.Select("container") - for i := len(opts) - 1; i >= 0; i-- { - // `id` optional argument - if !querybuilder.IsZeroValue(opts[i].ID) { - q = q.Arg("id", opts[i].ID) - } - // `platform` optional argument - if !querybuilder.IsZeroValue(opts[i].Platform) { - q = q.Arg("platform", opts[i].Platform) - } - } - - return &Container{ - q: q, - c: r.c, - } -} - -// The FunctionCall context that the SDK caller is currently executing in. -// -// If the caller is not currently executing in a function, this will return an error. -func (r *Client) CurrentFunctionCall() *FunctionCall { - q := r.q.Select("currentFunctionCall") - - return &FunctionCall{ - q: q, - c: r.c, - } -} - -// The module currently being served in the session, if any. -func (r *Client) CurrentModule() *CurrentModule { - q := r.q.Select("currentModule") - - return &CurrentModule{ - q: q, - c: r.c, - } -} - -// The TypeDef representations of the objects currently being served in the session. -func (r *Client) CurrentTypeDefs(ctx context.Context) ([]TypeDef, error) { - q := r.q.Select("currentTypeDefs") - - q = q.Select("id") - - type currentTypeDefs struct { - Id TypeDefID - } - - convert := func(fields []currentTypeDefs) []TypeDef { - out := []TypeDef{} - - for i := range fields { - val := TypeDef{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadTypeDefFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []currentTypeDefs - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// The default platform of the engine. -func (r *Client) DefaultPlatform(ctx context.Context) (Platform, error) { - q := r.q.Select("defaultPlatform") - - var response Platform - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// DirectoryOpts contains options for Client.Directory -type DirectoryOpts struct { - // DEPRECATED: Use `loadDirectoryFromID` isntead. - ID DirectoryID -} - -// Creates an empty directory. -func (r *Client) Directory(opts ...DirectoryOpts) *Directory { - q := r.q.Select("directory") - for i := len(opts) - 1; i >= 0; i-- { - // `id` optional argument - if !querybuilder.IsZeroValue(opts[i].ID) { - q = q.Arg("id", opts[i].ID) - } - } - - return &Directory{ - q: q, - c: r.c, - } -} - -// Deprecated: Use LoadFileFromID instead. -func (r *Client) File(id FileID) *File { - q := r.q.Select("file") - q = q.Arg("id", id) - - return &File{ - q: q, - c: r.c, - } -} - -// Creates a function. -func (r *Client) Function(name string, returnType *TypeDef) *Function { - assertNotNil("returnType", returnType) - q := r.q.Select("function") - q = q.Arg("name", name) - q = q.Arg("returnType", returnType) - - return &Function{ - q: q, - c: r.c, - } -} - -// Create a code generation result, given a directory containing the generated code. -func (r *Client) GeneratedCode(code *Directory) *GeneratedCode { - assertNotNil("code", code) - q := r.q.Select("generatedCode") - q = q.Arg("code", code) - - return &GeneratedCode{ - q: q, - c: r.c, - } -} - -// GitOpts contains options for Client.Git -type GitOpts struct { - // Set to true to keep .git directory. - KeepGitDir bool - // A service which must be started before the repo is fetched. - ExperimentalServiceHost *Service - // Set SSH known hosts - SSHKnownHosts string - // Set SSH auth socket - SSHAuthSocket *Socket -} - -// Queries a Git repository. -func (r *Client) Git(url string, opts ...GitOpts) *GitRepository { - q := r.q.Select("git") - for i := len(opts) - 1; i >= 0; i-- { - // `keepGitDir` optional argument - if !querybuilder.IsZeroValue(opts[i].KeepGitDir) { - q = q.Arg("keepGitDir", opts[i].KeepGitDir) - } - // `experimentalServiceHost` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalServiceHost) { - q = q.Arg("experimentalServiceHost", opts[i].ExperimentalServiceHost) - } - // `sshKnownHosts` optional argument - if !querybuilder.IsZeroValue(opts[i].SSHKnownHosts) { - q = q.Arg("sshKnownHosts", opts[i].SSHKnownHosts) - } - // `sshAuthSocket` optional argument - if !querybuilder.IsZeroValue(opts[i].SSHAuthSocket) { - q = q.Arg("sshAuthSocket", opts[i].SSHAuthSocket) - } - } - q = q.Arg("url", url) - - return &GitRepository{ - q: q, - c: r.c, - } -} - -// GolangOpts contains options for Client.Golang -type GolangOpts struct { - Ctr *Container - - Proj *Directory -} - -func (r *Client) Golang(opts ...GolangOpts) *Golang { - q := r.q.Select("golang") - for i := len(opts) - 1; i >= 0; i-- { - // `ctr` optional argument - if !querybuilder.IsZeroValue(opts[i].Ctr) { - q = q.Arg("ctr", opts[i].Ctr) - } - // `proj` optional argument - if !querybuilder.IsZeroValue(opts[i].Proj) { - q = q.Arg("proj", opts[i].Proj) - } - } - - return &Golang{ - q: q, - c: r.c, - } -} - -// HTTPOpts contains options for Client.HTTP -type HTTPOpts struct { - // A service which must be started before the URL is fetched. - ExperimentalServiceHost *Service -} - -// Returns a file containing an http remote url content. -func (r *Client) HTTP(url string, opts ...HTTPOpts) *File { - q := r.q.Select("http") - for i := len(opts) - 1; i >= 0; i-- { - // `experimentalServiceHost` optional argument - if !querybuilder.IsZeroValue(opts[i].ExperimentalServiceHost) { - q = q.Arg("experimentalServiceHost", opts[i].ExperimentalServiceHost) - } - } - q = q.Arg("url", url) - - return &File{ - q: q, - c: r.c, - } -} - -// Load a CacheVolume from its ID. -func (r *Client) LoadCacheVolumeFromID(id CacheVolumeID) *CacheVolume { - q := r.q.Select("loadCacheVolumeFromID") - q = q.Arg("id", id) - - return &CacheVolume{ - q: q, - c: r.c, - } -} - -// Load a Chainloop from its ID. -func (r *Client) LoadChainloopFromID(id ChainloopID) *Chainloop { - q := r.q.Select("loadChainloopFromID") - q = q.Arg("id", id) - - return &Chainloop{ - q: q, - c: r.c, - } -} - -// Load a Container from its ID. -func (r *Client) LoadContainerFromID(id ContainerID) *Container { - q := r.q.Select("loadContainerFromID") - q = q.Arg("id", id) - - return &Container{ - q: q, - c: r.c, - } -} - -// Load a CurrentModule from its ID. -func (r *Client) LoadCurrentModuleFromID(id CurrentModuleID) *CurrentModule { - q := r.q.Select("loadCurrentModuleFromID") - q = q.Arg("id", id) - - return &CurrentModule{ - q: q, - c: r.c, - } -} - -// Load a Directory from its ID. -func (r *Client) LoadDirectoryFromID(id DirectoryID) *Directory { - q := r.q.Select("loadDirectoryFromID") - q = q.Arg("id", id) - - return &Directory{ - q: q, - c: r.c, - } -} - -// Load a EnvVariable from its ID. -func (r *Client) LoadEnvVariableFromID(id EnvVariableID) *EnvVariable { - q := r.q.Select("loadEnvVariableFromID") - q = q.Arg("id", id) - - return &EnvVariable{ - q: q, - c: r.c, - } -} - -// Load a FieldTypeDef from its ID. -func (r *Client) LoadFieldTypeDefFromID(id FieldTypeDefID) *FieldTypeDef { - q := r.q.Select("loadFieldTypeDefFromID") - q = q.Arg("id", id) - - return &FieldTypeDef{ - q: q, - c: r.c, - } -} - -// Load a File from its ID. -func (r *Client) LoadFileFromID(id FileID) *File { - q := r.q.Select("loadFileFromID") - q = q.Arg("id", id) - - return &File{ - q: q, - c: r.c, - } -} - -// Load a FunctionArg from its ID. -func (r *Client) LoadFunctionArgFromID(id FunctionArgID) *FunctionArg { - q := r.q.Select("loadFunctionArgFromID") - q = q.Arg("id", id) - - return &FunctionArg{ - q: q, - c: r.c, - } -} - -// Load a FunctionCallArgValue from its ID. -func (r *Client) LoadFunctionCallArgValueFromID(id FunctionCallArgValueID) *FunctionCallArgValue { - q := r.q.Select("loadFunctionCallArgValueFromID") - q = q.Arg("id", id) - - return &FunctionCallArgValue{ - q: q, - c: r.c, - } -} - -// Load a FunctionCall from its ID. -func (r *Client) LoadFunctionCallFromID(id FunctionCallID) *FunctionCall { - q := r.q.Select("loadFunctionCallFromID") - q = q.Arg("id", id) - - return &FunctionCall{ - q: q, - c: r.c, - } -} - -// Load a Function from its ID. -func (r *Client) LoadFunctionFromID(id FunctionID) *Function { - q := r.q.Select("loadFunctionFromID") - q = q.Arg("id", id) - - return &Function{ - q: q, - c: r.c, - } -} - -// Load a GeneratedCode from its ID. -func (r *Client) LoadGeneratedCodeFromID(id GeneratedCodeID) *GeneratedCode { - q := r.q.Select("loadGeneratedCodeFromID") - q = q.Arg("id", id) - - return &GeneratedCode{ - q: q, - c: r.c, - } -} - -// Load a GitModuleSource from its ID. -func (r *Client) LoadGitModuleSourceFromID(id GitModuleSourceID) *GitModuleSource { - q := r.q.Select("loadGitModuleSourceFromID") - q = q.Arg("id", id) - - return &GitModuleSource{ - q: q, - c: r.c, - } -} - -// Load a GitRef from its ID. -func (r *Client) LoadGitRefFromID(id GitRefID) *GitRef { - q := r.q.Select("loadGitRefFromID") - q = q.Arg("id", id) - - return &GitRef{ - q: q, - c: r.c, - } -} - -// Load a GitRepository from its ID. -func (r *Client) LoadGitRepositoryFromID(id GitRepositoryID) *GitRepository { - q := r.q.Select("loadGitRepositoryFromID") - q = q.Arg("id", id) - - return &GitRepository{ - q: q, - c: r.c, - } -} - -// Load a Golang from its ID. -func (r *Client) LoadGolangFromID(id GolangID) *Golang { - q := r.q.Select("loadGolangFromID") - q = q.Arg("id", id) - - return &Golang{ - q: q, - c: r.c, - } -} - -// Load a InputTypeDef from its ID. -func (r *Client) LoadInputTypeDefFromID(id InputTypeDefID) *InputTypeDef { - q := r.q.Select("loadInputTypeDefFromID") - q = q.Arg("id", id) - - return &InputTypeDef{ - q: q, - c: r.c, - } -} - -// Load a InterfaceTypeDef from its ID. -func (r *Client) LoadInterfaceTypeDefFromID(id InterfaceTypeDefID) *InterfaceTypeDef { - q := r.q.Select("loadInterfaceTypeDefFromID") - q = q.Arg("id", id) - - return &InterfaceTypeDef{ - q: q, - c: r.c, - } -} - -// Load a Label from its ID. -func (r *Client) LoadLabelFromID(id LabelID) *Label { - q := r.q.Select("loadLabelFromID") - q = q.Arg("id", id) - - return &Label{ - q: q, - c: r.c, - } -} - -// Load a ListTypeDef from its ID. -func (r *Client) LoadListTypeDefFromID(id ListTypeDefID) *ListTypeDef { - q := r.q.Select("loadListTypeDefFromID") - q = q.Arg("id", id) - - return &ListTypeDef{ - q: q, - c: r.c, - } -} - -// Load a LocalModuleSource from its ID. -func (r *Client) LoadLocalModuleSourceFromID(id LocalModuleSourceID) *LocalModuleSource { - q := r.q.Select("loadLocalModuleSourceFromID") - q = q.Arg("id", id) - - return &LocalModuleSource{ - q: q, - c: r.c, - } -} - -// Load a ModuleDependency from its ID. -func (r *Client) LoadModuleDependencyFromID(id ModuleDependencyID) *ModuleDependency { - q := r.q.Select("loadModuleDependencyFromID") - q = q.Arg("id", id) - - return &ModuleDependency{ - q: q, - c: r.c, - } -} - -// Load a Module from its ID. -func (r *Client) LoadModuleFromID(id ModuleID) *Module { - q := r.q.Select("loadModuleFromID") - q = q.Arg("id", id) - - return &Module{ - q: q, - c: r.c, - } -} - -// Load a ModuleSource from its ID. -func (r *Client) LoadModuleSourceFromID(id ModuleSourceID) *ModuleSource { - q := r.q.Select("loadModuleSourceFromID") - q = q.Arg("id", id) - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// Load a ObjectTypeDef from its ID. -func (r *Client) LoadObjectTypeDefFromID(id ObjectTypeDefID) *ObjectTypeDef { - q := r.q.Select("loadObjectTypeDefFromID") - q = q.Arg("id", id) - - return &ObjectTypeDef{ - q: q, - c: r.c, - } -} - -// Load a Port from its ID. -func (r *Client) LoadPortFromID(id PortID) *Port { - q := r.q.Select("loadPortFromID") - q = q.Arg("id", id) - - return &Port{ - q: q, - c: r.c, - } -} - -// Load a Secret from its ID. -func (r *Client) LoadSecretFromID(id SecretID) *Secret { - q := r.q.Select("loadSecretFromID") - q = q.Arg("id", id) - - return &Secret{ - q: q, - c: r.c, - } -} - -// Load a Service from its ID. -func (r *Client) LoadServiceFromID(id ServiceID) *Service { - q := r.q.Select("loadServiceFromID") - q = q.Arg("id", id) - - return &Service{ - q: q, - c: r.c, - } -} - -// Load a Socket from its ID. -func (r *Client) LoadSocketFromID(id SocketID) *Socket { - q := r.q.Select("loadSocketFromID") - q = q.Arg("id", id) - - return &Socket{ - q: q, - c: r.c, - } -} - -// Load a Syft from its ID. -func (r *Client) LoadSyftFromID(id SyftID) *Syft { - q := r.q.Select("loadSyftFromID") - q = q.Arg("id", id) - - return &Syft{ - q: q, - c: r.c, - } -} - -// Load a Terminal from its ID. -func (r *Client) LoadTerminalFromID(id TerminalID) *Terminal { - q := r.q.Select("loadTerminalFromID") - q = q.Arg("id", id) - - return &Terminal{ - q: q, - c: r.c, - } -} - -// Load a TypeDef from its ID. -func (r *Client) LoadTypeDefFromID(id TypeDefID) *TypeDef { - q := r.q.Select("loadTypeDefFromID") - q = q.Arg("id", id) - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// Load a Wolfi from its ID. -func (r *Client) LoadWolfiFromID(id WolfiID) *Wolfi { - q := r.q.Select("loadWolfiFromID") - q = q.Arg("id", id) - - return &Wolfi{ - q: q, - c: r.c, - } -} - -// Create a new module. -func (r *Client) Module() *Module { - q := r.q.Select("module") - - return &Module{ - q: q, - c: r.c, - } -} - -// ModuleDependencyOpts contains options for Client.ModuleDependency -type ModuleDependencyOpts struct { - // If set, the name to use for the dependency. Otherwise, once installed to a parent module, the name of the dependency module will be used by default. - Name string -} - -// Create a new module dependency configuration from a module source and name -func (r *Client) ModuleDependency(source *ModuleSource, opts ...ModuleDependencyOpts) *ModuleDependency { - assertNotNil("source", source) - q := r.q.Select("moduleDependency") - for i := len(opts) - 1; i >= 0; i-- { - // `name` optional argument - if !querybuilder.IsZeroValue(opts[i].Name) { - q = q.Arg("name", opts[i].Name) - } - } - q = q.Arg("source", source) - - return &ModuleDependency{ - q: q, - c: r.c, - } -} - -// ModuleSourceOpts contains options for Client.ModuleSource -type ModuleSourceOpts struct { - // If true, enforce that the source is a stable version for source kinds that support versioning. - Stable bool -} - -// Create a new module source instance from a source ref string. -func (r *Client) ModuleSource(refString string, opts ...ModuleSourceOpts) *ModuleSource { - q := r.q.Select("moduleSource") - for i := len(opts) - 1; i >= 0; i-- { - // `stable` optional argument - if !querybuilder.IsZeroValue(opts[i].Stable) { - q = q.Arg("stable", opts[i].Stable) - } - } - q = q.Arg("refString", refString) - - return &ModuleSource{ - q: q, - c: r.c, - } -} - -// PipelineOpts contains options for Client.Pipeline -type PipelineOpts struct { - // Description of the sub-pipeline. - Description string - // Labels to apply to the sub-pipeline. - Labels []PipelineLabel -} - -// Creates a named sub-pipeline. -func (r *Client) Pipeline(name string, opts ...PipelineOpts) *Client { - q := r.q.Select("pipeline") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - // `labels` optional argument - if !querybuilder.IsZeroValue(opts[i].Labels) { - q = q.Arg("labels", opts[i].Labels) - } - } - q = q.Arg("name", name) - - return &Client{ - q: q, - c: r.c, - } -} - -// Reference a secret by name. -func (r *Client) Secret(name string) *Secret { - q := r.q.Select("secret") - q = q.Arg("name", name) - - return &Secret{ - q: q, - c: r.c, - } -} - -// Sets a secret given a user defined name to its plaintext and returns the secret. -// -// The plaintext value is limited to a size of 128000 bytes. -func (r *Client) SetSecret(name string, plaintext string) *Secret { - q := r.q.Select("setSecret") - q = q.Arg("name", name) - q = q.Arg("plaintext", plaintext) - - return &Secret{ - q: q, - c: r.c, - } -} - -// Loads a socket by its ID. -// -// Deprecated: Use LoadSocketFromID instead. -func (r *Client) Socket(id SocketID) *Socket { - q := r.q.Select("socket") - q = q.Arg("id", id) - - return &Socket{ - q: q, - c: r.c, - } -} - -func (r *Client) Syft() *Syft { - q := r.q.Select("syft") - - return &Syft{ - q: q, - c: r.c, - } -} - -// Create a new TypeDef. -func (r *Client) TypeDef() *TypeDef { - q := r.q.Select("typeDef") - - return &TypeDef{ - q: q, - c: r.c, - } -} - -func (r *Client) Wolfi() *Wolfi { - q := r.q.Select("wolfi") - - return &Wolfi{ - q: q, - c: r.c, - } -} - -// A reference to a secret value, which can be handled more safely than the value itself. -type Secret struct { - q *querybuilder.Selection - c graphql.Client - - id *SecretID - plaintext *string -} - -// A unique identifier for this Secret. -func (r *Secret) ID(ctx context.Context) (SecretID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response SecretID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Secret) XXX_GraphQLType() string { - return "Secret" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Secret) XXX_GraphQLIDType() string { - return "SecretID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Secret) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Secret) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Secret) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadSecretFromID(SecretID(id)) - return nil -} - -// The value of this secret. -func (r *Secret) Plaintext(ctx context.Context) (string, error) { - if r.plaintext != nil { - return *r.plaintext, nil - } - q := r.q.Select("plaintext") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A content-addressed service providing TCP connectivity. -type Service struct { - q *querybuilder.Selection - c graphql.Client - - endpoint *string - hostname *string - id *ServiceID - start *ServiceID - stop *ServiceID - up *Void -} - -// ServiceEndpointOpts contains options for Service.Endpoint -type ServiceEndpointOpts struct { - // The exposed port number for the endpoint - Port int - // Return a URL with the given scheme, eg. http for http:// - Scheme string -} - -// Retrieves an endpoint that clients can use to reach this container. -// -// If no port is specified, the first exposed port is used. If none exist an error is returned. -// -// If a scheme is specified, a URL is returned. Otherwise, a host:port pair is returned. -func (r *Service) Endpoint(ctx context.Context, opts ...ServiceEndpointOpts) (string, error) { - if r.endpoint != nil { - return *r.endpoint, nil - } - q := r.q.Select("endpoint") - for i := len(opts) - 1; i >= 0; i-- { - // `port` optional argument - if !querybuilder.IsZeroValue(opts[i].Port) { - q = q.Arg("port", opts[i].Port) - } - // `scheme` optional argument - if !querybuilder.IsZeroValue(opts[i].Scheme) { - q = q.Arg("scheme", opts[i].Scheme) - } - } - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Retrieves a hostname which can be used by clients to reach this container. -func (r *Service) Hostname(ctx context.Context) (string, error) { - if r.hostname != nil { - return *r.hostname, nil - } - q := r.q.Select("hostname") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A unique identifier for this Service. -func (r *Service) ID(ctx context.Context) (ServiceID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response ServiceID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Service) XXX_GraphQLType() string { - return "Service" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Service) XXX_GraphQLIDType() string { - return "ServiceID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Service) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Service) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Service) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadServiceFromID(ServiceID(id)) - return nil -} - -// Retrieves the list of ports provided by the service. -func (r *Service) Ports(ctx context.Context) ([]Port, error) { - q := r.q.Select("ports") - - q = q.Select("id") - - type ports struct { - Id PortID - } - - convert := func(fields []ports) []Port { - out := []Port{} - - for i := range fields { - val := Port{id: &fields[i].Id} - val.q = querybuilder.Query().Select("loadPortFromID").Arg("id", fields[i].Id) - val.c = r.c - out = append(out, val) - } - - return out - } - var response []ports - - q = q.Bind(&response) - - err := q.Execute(ctx, r.c) - if err != nil { - return nil, err - } - - return convert(response), nil -} - -// Start the service and wait for its health checks to succeed. -// -// Services bound to a Container do not need to be manually started. -func (r *Service) Start(ctx context.Context) (*Service, error) { - q := r.q.Select("start") - - return r, q.Execute(ctx, r.c) -} - -// ServiceStopOpts contains options for Service.Stop -type ServiceStopOpts struct { - // Immediately kill the service without waiting for a graceful exit - Kill bool -} - -// Stop the service. -func (r *Service) Stop(ctx context.Context, opts ...ServiceStopOpts) (*Service, error) { - q := r.q.Select("stop") - for i := len(opts) - 1; i >= 0; i-- { - // `kill` optional argument - if !querybuilder.IsZeroValue(opts[i].Kill) { - q = q.Arg("kill", opts[i].Kill) - } - } - - return r, q.Execute(ctx, r.c) -} - -// ServiceUpOpts contains options for Service.Up -type ServiceUpOpts struct { - // List of frontend/backend port mappings to forward. - // - // Frontend is the port accepting traffic on the host, backend is the service port. - Ports []PortForward - // Bind each tunnel port to a random port on the host. - Random bool -} - -// Creates a tunnel that forwards traffic from the caller's network to this service. -func (r *Service) Up(ctx context.Context, opts ...ServiceUpOpts) (Void, error) { - if r.up != nil { - return *r.up, nil - } - q := r.q.Select("up") - for i := len(opts) - 1; i >= 0; i-- { - // `ports` optional argument - if !querybuilder.IsZeroValue(opts[i].Ports) { - q = q.Arg("ports", opts[i].Ports) - } - // `random` optional argument - if !querybuilder.IsZeroValue(opts[i].Random) { - q = q.Arg("random", opts[i].Random) - } - } - - var response Void - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A Unix or TCP/IP socket that can be mounted into a container. -type Socket struct { - q *querybuilder.Selection - c graphql.Client - - id *SocketID -} - -// A unique identifier for this Socket. -func (r *Socket) ID(ctx context.Context) (SocketID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response SocketID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Socket) XXX_GraphQLType() string { - return "Socket" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Socket) XXX_GraphQLIDType() string { - return "SocketID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Socket) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Socket) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Socket) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadSocketFromID(SocketID(id)) - return nil -} - -type Syft struct { - q *querybuilder.Selection - c graphql.Client - - id *SyftID -} - -// A unique identifier for this Syft. -func (r *Syft) ID(ctx context.Context) (SyftID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response SyftID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Syft) XXX_GraphQLType() string { - return "Syft" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Syft) XXX_GraphQLIDType() string { - return "SyftID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Syft) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Syft) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Syft) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadSyftFromID(SyftID(id)) - return nil -} - -// SyftSbomOpts contains options for Syft.Sbom -type SyftSbomOpts struct { - // - // The image to run the job in - // - Image string - // - // The output format - // - Output string -} - -// Generate a software bill of materials -func (r *Syft) Sbom(src *Directory, outputFile string, opts ...SyftSbomOpts) *File { - assertNotNil("src", src) - q := r.q.Select("sbom") - for i := len(opts) - 1; i >= 0; i-- { - // `image` optional argument - if !querybuilder.IsZeroValue(opts[i].Image) { - q = q.Arg("image", opts[i].Image) - } - // `output` optional argument - if !querybuilder.IsZeroValue(opts[i].Output) { - q = q.Arg("output", opts[i].Output) - } - } - q = q.Arg("src", src) - q = q.Arg("outputFile", outputFile) - - return &File{ - q: q, - c: r.c, - } -} - -// An interactive terminal that clients can connect to. -type Terminal struct { - q *querybuilder.Selection - c graphql.Client - - id *TerminalID - websocketEndpoint *string -} - -// A unique identifier for this Terminal. -func (r *Terminal) ID(ctx context.Context) (TerminalID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response TerminalID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Terminal) XXX_GraphQLType() string { - return "Terminal" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Terminal) XXX_GraphQLIDType() string { - return "TerminalID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Terminal) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Terminal) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Terminal) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadTerminalFromID(TerminalID(id)) - return nil -} - -// An http endpoint at which this terminal can be connected to over a websocket. -func (r *Terminal) WebsocketEndpoint(ctx context.Context) (string, error) { - if r.websocketEndpoint != nil { - return *r.websocketEndpoint, nil - } - q := r.q.Select("websocketEndpoint") - - var response string - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// A definition of a parameter or return type in a Module. -type TypeDef struct { - q *querybuilder.Selection - c graphql.Client - - id *TypeDefID - kind *TypeDefKind - optional *bool -} -type WithTypeDefFunc func(r *TypeDef) *TypeDef - -// With calls the provided function with current TypeDef. -// -// This is useful for reusability and readability by not breaking the calling chain. -func (r *TypeDef) With(f WithTypeDefFunc) *TypeDef { - return f(r) -} - -// If kind is INPUT, the input-specific type definition. If kind is not INPUT, this will be null. -func (r *TypeDef) AsInput() *InputTypeDef { - q := r.q.Select("asInput") - - return &InputTypeDef{ - q: q, - c: r.c, - } -} - -// If kind is INTERFACE, the interface-specific type definition. If kind is not INTERFACE, this will be null. -func (r *TypeDef) AsInterface() *InterfaceTypeDef { - q := r.q.Select("asInterface") - - return &InterfaceTypeDef{ - q: q, - c: r.c, - } -} - -// If kind is LIST, the list-specific type definition. If kind is not LIST, this will be null. -func (r *TypeDef) AsList() *ListTypeDef { - q := r.q.Select("asList") - - return &ListTypeDef{ - q: q, - c: r.c, - } -} - -// If kind is OBJECT, the object-specific type definition. If kind is not OBJECT, this will be null. -func (r *TypeDef) AsObject() *ObjectTypeDef { - q := r.q.Select("asObject") - - return &ObjectTypeDef{ - q: q, - c: r.c, - } -} - -// A unique identifier for this TypeDef. -func (r *TypeDef) ID(ctx context.Context) (TypeDefID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response TypeDefID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *TypeDef) XXX_GraphQLType() string { - return "TypeDef" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *TypeDef) XXX_GraphQLIDType() string { - return "TypeDefID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *TypeDef) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *TypeDef) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *TypeDef) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadTypeDefFromID(TypeDefID(id)) - return nil -} - -// The kind of type this is (e.g. primitive, list, object). -func (r *TypeDef) Kind(ctx context.Context) (TypeDefKind, error) { - if r.kind != nil { - return *r.kind, nil - } - q := r.q.Select("kind") - - var response TypeDefKind - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Whether this type can be set to null. Defaults to false. -func (r *TypeDef) Optional(ctx context.Context) (bool, error) { - if r.optional != nil { - return *r.optional, nil - } - q := r.q.Select("optional") - - var response bool - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// Adds a function for constructing a new instance of an Object TypeDef, failing if the type is not an object. -func (r *TypeDef) WithConstructor(function *Function) *TypeDef { - assertNotNil("function", function) - q := r.q.Select("withConstructor") - q = q.Arg("function", function) - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// TypeDefWithFieldOpts contains options for TypeDef.WithField -type TypeDefWithFieldOpts struct { - // A doc string for the field, if any - Description string -} - -// Adds a static field for an Object TypeDef, failing if the type is not an object. -func (r *TypeDef) WithField(name string, typeDef *TypeDef, opts ...TypeDefWithFieldOpts) *TypeDef { - assertNotNil("typeDef", typeDef) - q := r.q.Select("withField") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - } - q = q.Arg("name", name) - q = q.Arg("typeDef", typeDef) - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// Adds a function for an Object or Interface TypeDef, failing if the type is not one of those kinds. -func (r *TypeDef) WithFunction(function *Function) *TypeDef { - assertNotNil("function", function) - q := r.q.Select("withFunction") - q = q.Arg("function", function) - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// TypeDefWithInterfaceOpts contains options for TypeDef.WithInterface -type TypeDefWithInterfaceOpts struct { - Description string -} - -// Returns a TypeDef of kind Interface with the provided name. -func (r *TypeDef) WithInterface(name string, opts ...TypeDefWithInterfaceOpts) *TypeDef { - q := r.q.Select("withInterface") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - } - q = q.Arg("name", name) - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// Sets the kind of the type. -func (r *TypeDef) WithKind(kind TypeDefKind) *TypeDef { - q := r.q.Select("withKind") - q = q.Arg("kind", kind) - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// Returns a TypeDef of kind List with the provided type for its elements. -func (r *TypeDef) WithListOf(elementType *TypeDef) *TypeDef { - assertNotNil("elementType", elementType) - q := r.q.Select("withListOf") - q = q.Arg("elementType", elementType) - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// TypeDefWithObjectOpts contains options for TypeDef.WithObject -type TypeDefWithObjectOpts struct { - Description string -} - -// Returns a TypeDef of kind Object with the provided name. -// -// Note that an object's fields and functions may be omitted if the intent is only to refer to an object. This is how functions are able to return their own object, or any other circular reference. -func (r *TypeDef) WithObject(name string, opts ...TypeDefWithObjectOpts) *TypeDef { - q := r.q.Select("withObject") - for i := len(opts) - 1; i >= 0; i-- { - // `description` optional argument - if !querybuilder.IsZeroValue(opts[i].Description) { - q = q.Arg("description", opts[i].Description) - } - } - q = q.Arg("name", name) - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// Sets whether this type can be set to null. -func (r *TypeDef) WithOptional(optional bool) *TypeDef { - q := r.q.Select("withOptional") - q = q.Arg("optional", optional) - - return &TypeDef{ - q: q, - c: r.c, - } -} - -// A Dagger Module to integrate with Wolfi Linux -// https://wolfi.dev -type Wolfi struct { - q *querybuilder.Selection - c graphql.Client - - id *WolfiID -} - -// WolfiContainerOpts contains options for Wolfi.Container -type WolfiContainerOpts struct { - // - // APK packages to install - // - Packages []string - // - // Overlay images to merge on top of the base. - // See https://twitter.com/ibuildthecloud/status/1721306361999597884 - // - Overlays []*Container -} - -// Build a Wolfi Linux container -func (r *Wolfi) Container(opts ...WolfiContainerOpts) *Container { - q := r.q.Select("container") - for i := len(opts) - 1; i >= 0; i-- { - // `packages` optional argument - if !querybuilder.IsZeroValue(opts[i].Packages) { - q = q.Arg("packages", opts[i].Packages) - } - // `overlays` optional argument - if !querybuilder.IsZeroValue(opts[i].Overlays) { - q = q.Arg("overlays", opts[i].Overlays) - } - } - - return &Container{ - q: q, - c: r.c, - } -} - -// A unique identifier for this Wolfi. -func (r *Wolfi) ID(ctx context.Context) (WolfiID, error) { - if r.id != nil { - return *r.id, nil - } - q := r.q.Select("id") - - var response WolfiID - - q = q.Bind(&response) - return response, q.Execute(ctx, r.c) -} - -// XXX_GraphQLType is an internal function. It returns the native GraphQL type name -func (r *Wolfi) XXX_GraphQLType() string { - return "Wolfi" -} - -// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object -func (r *Wolfi) XXX_GraphQLIDType() string { - return "WolfiID" -} - -// XXX_GraphQLID is an internal function. It returns the underlying type ID -func (r *Wolfi) XXX_GraphQLID(ctx context.Context) (string, error) { - id, err := r.ID(ctx) - if err != nil { - return "", err - } - return string(id), nil -} - -func (r *Wolfi) MarshalJSON() ([]byte, error) { - id, err := r.ID(context.Background()) - if err != nil { - return nil, err - } - return json.Marshal(id) -} -func (r *Wolfi) UnmarshalJSON(bs []byte) error { - var id string - err := json.Unmarshal(bs, &id) - if err != nil { - return err - } - *r = *dag.LoadWolfiFromID(WolfiID(id)) - return nil -} - -type CacheSharingMode string - -func (CacheSharingMode) IsEnum() {} - -const ( - // Shares the cache volume amongst many build pipelines, but will serialize the writes - Locked CacheSharingMode = "LOCKED" - - // Keeps a cache volume for a single build pipeline - Private CacheSharingMode = "PRIVATE" - - // Shares the cache volume amongst many build pipelines - Shared CacheSharingMode = "SHARED" -) - -type ImageLayerCompression string - -func (ImageLayerCompression) IsEnum() {} - -const ( - Estargz ImageLayerCompression = "EStarGZ" - - Gzip ImageLayerCompression = "Gzip" - - Uncompressed ImageLayerCompression = "Uncompressed" - - Zstd ImageLayerCompression = "Zstd" -) - -type ImageMediaTypes string - -func (ImageMediaTypes) IsEnum() {} - -const ( - Dockermediatypes ImageMediaTypes = "DockerMediaTypes" - - Ocimediatypes ImageMediaTypes = "OCIMediaTypes" -) - -type ModuleSourceKind string - -func (ModuleSourceKind) IsEnum() {} - -const ( - GitSource ModuleSourceKind = "GIT_SOURCE" - - LocalSource ModuleSourceKind = "LOCAL_SOURCE" -) - -type NetworkProtocol string - -func (NetworkProtocol) IsEnum() {} - -const ( - Tcp NetworkProtocol = "TCP" - - Udp NetworkProtocol = "UDP" -) - -type TypeDefKind string - -func (TypeDefKind) IsEnum() {} - -const ( - // A boolean value. - BooleanKind TypeDefKind = "BOOLEAN_KIND" - - // A graphql input type, used only when representing the core API via TypeDefs. - InputKind TypeDefKind = "INPUT_KIND" - - // An integer value. - IntegerKind TypeDefKind = "INTEGER_KIND" - - // A named type of functions that can be matched+implemented by other objects+interfaces. - // - // Always paired with an InterfaceTypeDef. - InterfaceKind TypeDefKind = "INTERFACE_KIND" - - // A list of values all having the same type. - // - // Always paired with a ListTypeDef. - ListKind TypeDefKind = "LIST_KIND" - - // A named type defined in the GraphQL schema, with fields and functions. - // - // Always paired with an ObjectTypeDef. - ObjectKind TypeDefKind = "OBJECT_KIND" - - // A string value. - StringKind TypeDefKind = "STRING_KIND" - - // A special kind used to signify that no value is returned. - // - // This is used for functions that have no return value. The outer TypeDef specifying this Kind is always Optional, as the Void is never actually represented. - VoidKind TypeDefKind = "VOID_KIND" -) - -type Client struct { - c graphql.Client - q *querybuilder.Selection -} - -var dag = initDag() - -// initializing the var dag directly rather than using -// an init func so that users can successfully use dag -// in any global var initialization of their own code -func initDag() *Client { - gqlClient, q := getClientParams() - return &Client{ - c: gqlClient, - q: q, - } -} - -func getClientParams() (graphql.Client, *querybuilder.Selection) { - portStr, ok := os.LookupEnv("DAGGER_SESSION_PORT") - if !ok { - panic("DAGGER_SESSION_PORT is not set") - } - port, err := strconv.Atoi(portStr) - if err != nil { - panic(fmt.Errorf("DAGGER_SESSION_PORT %q is invalid: %w", portStr, err)) - } - - sessionToken := os.Getenv("DAGGER_SESSION_TOKEN") - if sessionToken == "" { - panic("DAGGER_SESSION_TOKEN is not set") - } - - host := fmt.Sprintf("127.0.0.1:%d", port) - - dialTransport := &http.Transport{ - DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { - return net.Dial("tcp", host) - }, - } - httpClient := &http.Client{ - Transport: roundTripperFunc(func(r *http.Request) (*http.Response, error) { - r.SetBasicAuth(sessionToken, "") - return dialTransport.RoundTrip(r) - }), - } - gqlClient := errorWrappedClient{graphql.NewClient(fmt.Sprintf("http://%s/query", host), httpClient)} - - return gqlClient, querybuilder.Query() -} - -// TODO: pollutes namespace, move to non internal package in dagger.io/dagger -type roundTripperFunc func(*http.Request) (*http.Response, error) - -func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) { - return fn(req) -} - -type errorWrappedClient struct { - graphql.Client -} - -func (c errorWrappedClient) MakeRequest(ctx context.Context, req *graphql.Request, resp *graphql.Response) error { - err := c.Client.MakeRequest(ctx, req, resp) - if err != nil { - if e := getCustomError(err); e != nil { - return e - } - return err - } - return nil -} - -func (r *BuildAndRelease) UnmarshalJSON(bs []byte) error { - var concrete struct{} - err := json.Unmarshal(bs, &concrete) - if err != nil { - return err - } - return nil -} - -func main() { - ctx := context.Background() - - fnCall := dag.CurrentFunctionCall() - parentName, err := fnCall.ParentName(ctx) - if err != nil { - fmt.Println(err.Error()) - os.Exit(2) - } - fnName, err := fnCall.Name(ctx) - if err != nil { - fmt.Println(err.Error()) - os.Exit(2) - } - parentJson, err := fnCall.Parent(ctx) - if err != nil { - fmt.Println(err.Error()) - os.Exit(2) - } - fnArgs, err := fnCall.InputArgs(ctx) - if err != nil { - fmt.Println(err.Error()) - os.Exit(2) - } - - inputArgs := map[string][]byte{} - for _, fnArg := range fnArgs { - argName, err := fnArg.Name(ctx) - if err != nil { - fmt.Println(err.Error()) - os.Exit(2) - } - argValue, err := fnArg.Value(ctx) - if err != nil { - fmt.Println(err.Error()) - os.Exit(2) - } - inputArgs[argName] = []byte(argValue) - } - - result, err := invoke(ctx, []byte(parentJson), parentName, fnName, inputArgs) - if err != nil { - fmt.Println(err.Error()) - os.Exit(2) - } - resultBytes, err := json.Marshal(result) - if err != nil { - fmt.Println(err.Error()) - os.Exit(2) - } - _, err = fnCall.ReturnValue(ctx, JSON(resultBytes)) - if err != nil { - fmt.Println(err.Error()) - os.Exit(2) - } -} - -func invoke(ctx context.Context, parentJSON []byte, parentName string, fnName string, inputArgs map[string][]byte) (_ any, err error) { - switch parentName { - case "BuildAndRelease": - switch fnName { - case "BuildAndPublish": - var parent BuildAndRelease - err = json.Unmarshal(parentJSON, &parent) - if err != nil { - panic(fmt.Errorf("%s: %w", "failed to unmarshal parent object", err)) - } - var proj *Directory - if inputArgs["proj"] != nil { - err = json.Unmarshal([]byte(inputArgs["proj"]), &proj) - if err != nil { - panic(fmt.Errorf("%s: %w", "failed to unmarshal input arg proj", err)) - } - } - return (*BuildAndRelease).BuildAndPublish(&parent, ctx, proj) - default: - return nil, fmt.Errorf("unknown function %s", fnName) - } - case "": - return dag.Module(). - WithObject( - dag.TypeDef().WithObject("BuildAndRelease"). - WithFunction( - dag.Function("BuildAndPublish", - dag.TypeDef().WithKind(StringKind)). - WithArg("proj", dag.TypeDef().WithObject("Directory")))), nil - default: - return nil, fmt.Errorf("unknown object %s", parentName) - } -} diff --git a/chainloop-demo/dagger/build-and-release/querybuilder/marshal.go b/chainloop-demo/dagger/build-and-release/querybuilder/marshal.go deleted file mode 100644 index 1f5468a..0000000 --- a/chainloop-demo/dagger/build-and-release/querybuilder/marshal.go +++ /dev/null @@ -1,162 +0,0 @@ -package querybuilder - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "reflect" - "strings" - - gqlgen "github.com/99designs/gqlgen/graphql" - "golang.org/x/exp/slices" - "golang.org/x/sync/errgroup" -) - -// GraphQLMarshaller is an internal interface for marshalling an object into GraphQL. -type GraphQLMarshaller interface { - // XXX_GraphQLType is an internal function. It returns the native GraphQL type name - XXX_GraphQLType() string - // XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object - XXX_GraphQLIDType() string - // XXX_GraphqlID is an internal function. It returns the underlying type ID - XXX_GraphQLID(ctx context.Context) (string, error) - json.Marshaler -} - -const ( - GraphQLMarshallerType = "XXX_GraphQLType" - GraphQLMarshallerIDType = "XXX_GraphQLIDType" - GraphQLMarshallerID = "XXX_GraphQLID" -) - -type enum interface { - IsEnum() -} - -var ( - gqlMarshaller = reflect.TypeOf((*GraphQLMarshaller)(nil)).Elem() - enumT = reflect.TypeOf((*enum)(nil)).Elem() -) - -func MarshalGQL(ctx context.Context, v any) (string, error) { - return marshalValue(ctx, reflect.ValueOf(v)) -} - -func marshalValue(ctx context.Context, v reflect.Value) (string, error) { - t := v.Type() - - if t.Implements(gqlMarshaller) { - return marshalCustom(ctx, v) - } - - switch t.Kind() { - case reflect.Bool: - return fmt.Sprintf("%t", v.Bool()), nil - case reflect.Int: - return fmt.Sprintf("%d", v.Int()), nil - case reflect.String: - if t.Implements(enumT) { - // enums render as their literal value - return v.String(), nil - } - - // escape strings following graphQL spec - // https://github.com/graphql/graphql-spec/blob/main/spec/Section%202%20--%20Language.md#string-value - var buf bytes.Buffer - gqlgen.MarshalString(v.String()).MarshalGQL(&buf) - return buf.String(), nil - case reflect.Pointer, reflect.Interface: - if v.IsNil() { - return "null", nil - } - return marshalValue(ctx, v.Elem()) - case reflect.Slice: - n := v.Len() - elems := make([]string, n) - eg, gctx := errgroup.WithContext(ctx) - for i := 0; i < n; i++ { - i := i - eg.Go(func() error { - m, err := marshalValue(gctx, v.Index(i)) - if err != nil { - return err - } - elems[i] = m - return nil - }) - } - if err := eg.Wait(); err != nil { - return "", err - } - return fmt.Sprintf("[%s]", strings.Join(elems, ",")), nil - case reflect.Struct: - n := v.NumField() - elems := make([]string, n) - eg, gctx := errgroup.WithContext(ctx) - for i := 0; i < n; i++ { - i := i - eg.Go(func() error { - f := t.Field(i) - fv := v.Field(i) - name := f.Name - jsonTag := strings.Split(f.Tag.Get("json"), ",") - if jsonTag[0] != "" { - name = jsonTag[0] - } - isOptional := slices.Contains(jsonTag[1:], "omitempty") - if isOptional && IsZeroValue(fv.Interface()) { - return nil - } - m, err := marshalValue(gctx, fv) - if err != nil { - return err - } - if m != `""` && m != "null" { - elems[i] = fmt.Sprintf("%s:%s", name, m) - } - return nil - }) - } - if err := eg.Wait(); err != nil { - return "", err - } - nonNullElems := make([]string, 0, n) - for _, elem := range elems { - if elem != "" { - nonNullElems = append(nonNullElems, elem) - } - } - return fmt.Sprintf("{%s}", strings.Join(nonNullElems, ",")), nil - default: - panic(fmt.Errorf("unsupported argument of kind %s", t.Kind())) - } -} - -func marshalCustom(ctx context.Context, v reflect.Value) (string, error) { - result := v.MethodByName(GraphQLMarshallerID).Call([]reflect.Value{ - reflect.ValueOf(ctx), - }) - if len(result) != 2 { - panic(result) - } - err := result[1].Interface() - if err != nil { - return "", err.(error) - } - - return fmt.Sprintf("%q", result[0].String()), nil -} - -func IsZeroValue(value any) bool { - v := reflect.ValueOf(value) - kind := v.Type().Kind() - switch kind { - case reflect.Pointer: - return v.IsNil() - case reflect.Slice, reflect.Array: - return v.Len() == 0 - default: - return v.IsZero() - } -} diff --git a/chainloop-demo/dagger/build-and-release/querybuilder/querybuilder.go b/chainloop-demo/dagger/build-and-release/querybuilder/querybuilder.go deleted file mode 100644 index c2841e5..0000000 --- a/chainloop-demo/dagger/build-and-release/querybuilder/querybuilder.go +++ /dev/null @@ -1,183 +0,0 @@ -package querybuilder - -import ( - "context" - "encoding/json" - "fmt" - "strings" - "sync" - - "github.com/Khan/genqlient/graphql" - "golang.org/x/sync/errgroup" -) - -func Query() *Selection { - return &Selection{} -} - -type Selection struct { - name string - alias string - args map[string]*argument - bind interface{} - - prev *Selection -} - -func (s *Selection) path() []*Selection { - selections := []*Selection{} - for sel := s; sel.prev != nil; sel = sel.prev { - selections = append([]*Selection{sel}, selections...) - } - - return selections -} - -func (s *Selection) SelectWithAlias(alias, name string) *Selection { - sel := &Selection{ - name: name, - prev: s, - alias: alias, - } - return sel -} - -func (s *Selection) Select(name string) *Selection { - return s.SelectWithAlias("", name) -} - -func (s *Selection) Arg(name string, value any) *Selection { - sel := *s - if sel.args == nil { - sel.args = map[string]*argument{} - } - - sel.args[name] = &argument{ - value: value, - } - return &sel -} - -func (s *Selection) Bind(v interface{}) *Selection { - sel := *s - sel.bind = v - return &sel -} - -func (s *Selection) marshalArguments(ctx context.Context) error { - eg, gctx := errgroup.WithContext(ctx) - for _, sel := range s.path() { - for _, arg := range sel.args { - arg := arg - eg.Go(func() error { - return arg.marshal(gctx) - }) - } - } - - return eg.Wait() -} - -func (s *Selection) Build(ctx context.Context) (string, error) { - if err := s.marshalArguments(ctx); err != nil { - return "", err - } - - var b strings.Builder - b.WriteString("query") - - path := s.path() - - for _, sel := range path { - b.WriteRune('{') - - if sel.alias != "" { - b.WriteString(sel.alias) - b.WriteRune(':') - } - - b.WriteString(sel.name) - - if len(sel.args) > 0 { - b.WriteRune('(') - i := 0 - for name, arg := range sel.args { - if i > 0 { - b.WriteString(", ") - } - b.WriteString(name) - b.WriteRune(':') - b.WriteString(arg.marshalled) - i++ - } - b.WriteRune(')') - } - } - - b.WriteString(strings.Repeat("}", len(path))) - return b.String(), nil -} - -func (s *Selection) unpack(data interface{}) error { - for _, i := range s.path() { - k := i.name - if i.alias != "" { - k = i.alias - } - - // Try to assert type of the value - switch f := data.(type) { - case map[string]interface{}: - data = f[k] - case []interface{}: - data = f - default: - fmt.Printf("type not found %s\n", f) - } - - if i.bind != nil { - marshalled, err := json.Marshal(data) - if err != nil { - return err - } - json.Unmarshal(marshalled, s.bind) - } - } - - return nil -} - -func (s *Selection) Execute(ctx context.Context, c graphql.Client) error { - query, err := s.Build(ctx) - if err != nil { - return err - } - - var response any - err = c.MakeRequest(ctx, - &graphql.Request{ - Query: query, - }, - &graphql.Response{Data: &response}, - ) - if err != nil { - return err - } - - return s.unpack(response) -} - -type argument struct { - value any - - marshalled string - marshalledErr error - once sync.Once -} - -func (a *argument) marshal(ctx context.Context) error { - a.once.Do(func() { - a.marshalled, a.marshalledErr = MarshalGQL(ctx, a.value) - }) - return a.marshalledErr -} diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index 465fe64..c845121 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -19,6 +19,5 @@ "source": "github.com/shykes/daggerverse/wolfi@f678bfe29024559abec0ac77fbbd558bc8402cdf" } ], - "source": "build-and-release", "engineVersion": "v0.9.10" } diff --git a/chainloop-demo/dagger/build-and-release/main.go b/chainloop-demo/dagger/main.go similarity index 97% rename from chainloop-demo/dagger/build-and-release/main.go rename to chainloop-demo/dagger/main.go index 9d81d89..8498cbf 100644 --- a/chainloop-demo/dagger/build-and-release/main.go +++ b/chainloop-demo/dagger/main.go @@ -9,7 +9,7 @@ import ( type BuildAndRelease struct{} -// Build and Publish a go-application as a container image +// Build and Publish a GO application as a container image // Attest the pieces of evidence to Chainloop func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { var err error From 5c57b50c01b0b09104755c354cbd247e926c1ae2 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 23:11:11 +0100 Subject: [PATCH 14/34] update module Signed-off-by: Miguel Martinez Trivino --- chainloop-demo/dagger/go.mod | 3 +++ go.mod | 10 ---------- go.sum | 26 -------------------------- 3 files changed, 3 insertions(+), 36 deletions(-) create mode 100644 chainloop-demo/dagger/go.mod diff --git a/chainloop-demo/dagger/go.mod b/chainloop-demo/dagger/go.mod new file mode 100644 index 0000000..1c91cdf --- /dev/null +++ b/chainloop-demo/dagger/go.mod @@ -0,0 +1,3 @@ +module demo + +go 1.21.1 diff --git a/go.mod b/go.mod index f12562b..6705826 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,6 @@ module github.com/chainloop-dev/integration-demo go 1.21 require ( - github.com/99designs/gqlgen v0.17.44 - github.com/Khan/genqlient v0.6.0 github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f github.com/mattn/go-sqlite3 v1.14.16 - github.com/vektah/gqlparser/v2 v2.5.11 - golang.org/x/exp v0.0.0-20240213143201-ec583247a57a - golang.org/x/sync v0.6.0 -) - -require ( - github.com/google/uuid v1.6.0 // indirect - github.com/sosodev/duration v1.2.0 // indirect ) diff --git a/go.sum b/go.sum index f0d2d48..4f2ade7 100644 --- a/go.sum +++ b/go.sum @@ -1,30 +1,4 @@ -github.com/99designs/gqlgen v0.17.44 h1:OS2wLk/67Y+vXM75XHbwRnNYJcbuJd4OBL76RX3NQQA= -github.com/99designs/gqlgen v0.17.44/go.mod h1:UTCu3xpK2mLI5qcMNw+HKDiEL77it/1XtAjisC4sLwM= -github.com/Khan/genqlient v0.6.0 h1:Bwb1170ekuNIVIwTJEqvO8y7RxBxXu639VJOkKSrwAk= -github.com/Khan/genqlient v0.6.0/go.mod h1:rvChwWVTqXhiapdhLDV4bp9tz/Xvtewwkon4DpWWCRM= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f h1:gOO/tNZMjjvTKZWpY7YnXC72ULNLErRtp94LountVE8= github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/sosodev/duration v1.2.0 h1:pqK/FLSjsAADWY74SyWDCjOcd5l7H8GSnnOGEB9A1Us= -github.com/sosodev/duration v1.2.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= -github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 0a681986862976b740ee8bac5775c961d8e00a29 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 23:13:26 +0100 Subject: [PATCH 15/34] update module Signed-off-by: Miguel Martinez Trivino --- chainloop-demo/dagger/.gitignore | 2 ++ chainloop-demo/dagger/dagger.json | 1 + chainloop-demo/dagger/go.mod | 10 +++++++++ chainloop-demo/dagger/go.sum | 35 +++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 chainloop-demo/dagger/.gitignore create mode 100644 chainloop-demo/dagger/go.sum diff --git a/chainloop-demo/dagger/.gitignore b/chainloop-demo/dagger/.gitignore new file mode 100644 index 0000000..c3fbf8c --- /dev/null +++ b/chainloop-demo/dagger/.gitignore @@ -0,0 +1,2 @@ +/querybuilder/ +/dagger.gen.go diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index c845121..41bf56f 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -19,5 +19,6 @@ "source": "github.com/shykes/daggerverse/wolfi@f678bfe29024559abec0ac77fbbd558bc8402cdf" } ], + "source": ".", "engineVersion": "v0.9.10" } diff --git a/chainloop-demo/dagger/go.mod b/chainloop-demo/dagger/go.mod index 1c91cdf..b4a8e7c 100644 --- a/chainloop-demo/dagger/go.mod +++ b/chainloop-demo/dagger/go.mod @@ -1,3 +1,13 @@ module demo go 1.21.1 + +require ( + github.com/99designs/gqlgen v0.17.31 + github.com/Khan/genqlient v0.6.0 + github.com/vektah/gqlparser/v2 v2.5.6 + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa + golang.org/x/sync v0.6.0 +) + +require github.com/stretchr/testify v1.8.3 // indirect diff --git a/chainloop-demo/dagger/go.sum b/chainloop-demo/dagger/go.sum new file mode 100644 index 0000000..3ad50f0 --- /dev/null +++ b/chainloop-demo/dagger/go.sum @@ -0,0 +1,35 @@ +github.com/99designs/gqlgen v0.17.31 h1:VncSQ82VxieHkea8tz11p7h/zSbvHSxSDZfywqWt158= +github.com/99designs/gqlgen v0.17.31/go.mod h1:i4rEatMrzzu6RXaHydq1nmEPZkb3bKQsnxNRHS4DQB4= +github.com/Khan/genqlient v0.6.0 h1:Bwb1170ekuNIVIwTJEqvO8y7RxBxXu639VJOkKSrwAk= +github.com/Khan/genqlient v0.6.0/go.mod h1:rvChwWVTqXhiapdhLDV4bp9tz/Xvtewwkon4DpWWCRM= +github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/vektah/gqlparser/v2 v2.5.6 h1:Ou14T0N1s191eRMZ1gARVqohcbe1e8FrcONScsq8cRU= +github.com/vektah/gqlparser/v2 v2.5.6/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From d6984c88136c8ed4c3530e273eaca8bc1a72b165 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 23:14:37 +0100 Subject: [PATCH 16/34] update module Signed-off-by: Miguel Martinez Trivino --- chainloop-demo/dagger/dagger.json | 2 +- chainloop-demo/dagger/{ => src}/go.mod | 0 chainloop-demo/dagger/{ => src}/go.sum | 0 chainloop-demo/dagger/{ => src}/main.go | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename chainloop-demo/dagger/{ => src}/go.mod (100%) rename chainloop-demo/dagger/{ => src}/go.sum (100%) rename chainloop-demo/dagger/{ => src}/main.go (100%) diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index 41bf56f..312cdf9 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -19,6 +19,6 @@ "source": "github.com/shykes/daggerverse/wolfi@f678bfe29024559abec0ac77fbbd558bc8402cdf" } ], - "source": ".", + "source": "./src", "engineVersion": "v0.9.10" } diff --git a/chainloop-demo/dagger/go.mod b/chainloop-demo/dagger/src/go.mod similarity index 100% rename from chainloop-demo/dagger/go.mod rename to chainloop-demo/dagger/src/go.mod diff --git a/chainloop-demo/dagger/go.sum b/chainloop-demo/dagger/src/go.sum similarity index 100% rename from chainloop-demo/dagger/go.sum rename to chainloop-demo/dagger/src/go.sum diff --git a/chainloop-demo/dagger/main.go b/chainloop-demo/dagger/src/main.go similarity index 100% rename from chainloop-demo/dagger/main.go rename to chainloop-demo/dagger/src/main.go From 7498b33b7bc482167adcb743721a825365e39d13 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 23:16:29 +0100 Subject: [PATCH 17/34] update module Signed-off-by: Miguel Martinez Trivino --- chainloop-demo/dagger/dagger.json | 2 +- chainloop-demo/dagger/{ => src}/.gitattributes | 0 chainloop-demo/dagger/{ => src}/.gitignore | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename chainloop-demo/dagger/{ => src}/.gitattributes (100%) rename chainloop-demo/dagger/{ => src}/.gitignore (100%) diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index 312cdf9..bc3fdad 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -19,6 +19,6 @@ "source": "github.com/shykes/daggerverse/wolfi@f678bfe29024559abec0ac77fbbd558bc8402cdf" } ], - "source": "./src", + "source": "src", "engineVersion": "v0.9.10" } diff --git a/chainloop-demo/dagger/.gitattributes b/chainloop-demo/dagger/src/.gitattributes similarity index 100% rename from chainloop-demo/dagger/.gitattributes rename to chainloop-demo/dagger/src/.gitattributes diff --git a/chainloop-demo/dagger/.gitignore b/chainloop-demo/dagger/src/.gitignore similarity index 100% rename from chainloop-demo/dagger/.gitignore rename to chainloop-demo/dagger/src/.gitignore From c6dcdbbbccec3c9363af788ac5cc816b85bdf0bf Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 23:19:14 +0100 Subject: [PATCH 18/34] update module Signed-off-by: Miguel Martinez Trivino --- chainloop-demo/dagger/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 chainloop-demo/dagger/README.md diff --git a/chainloop-demo/dagger/README.md b/chainloop-demo/dagger/README.md new file mode 100644 index 0000000..a25141d --- /dev/null +++ b/chainloop-demo/dagger/README.md @@ -0,0 +1,10 @@ + +Build a Go application, package it in a container image, generate its Software Bill Of Materials (SBOM) and attest the result using the Chainloop platform. + +```json +dagger call build-and-publish \ + --proj path/to/go-project \ + --chainloop-token env:CHAINLOOP_TOKEN \ + --chainloop-signing-key file:path/to/cosign.key \ + --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD +``` \ No newline at end of file From 2084a59cad3f34d92d1e92cbb4a9db9766425170 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 20 Feb 2024 23:28:46 +0100 Subject: [PATCH 19/34] feat: add dagger Signed-off-by: Miguel Martinez Trivino --- .github/workflows/release_dagger.yaml | 36 +++++++++++++++++++++++++++ chainloop-demo/dagger/README.md | 4 +-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/release_dagger.yaml diff --git a/.github/workflows/release_dagger.yaml b/.github/workflows/release_dagger.yaml new file mode 100644 index 0000000..1c87625 --- /dev/null +++ b/.github/workflows/release_dagger.yaml @@ -0,0 +1,36 @@ +name: Release using Dagger + +on: + push: + branches: + - main + +jobs: + release: + name: Release + runs-on: ubuntu-latest + permissions: + packages: write + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install Dagger CLI + run: | + curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh + + - name: Build and Publish + run: | + dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ + --proj . \ + --chainloop-token env:CHAINLOOP_TOKEN \ + --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ + --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD + + env: + CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} + DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} + CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} diff --git a/chainloop-demo/dagger/README.md b/chainloop-demo/dagger/README.md index a25141d..dc51049 100644 --- a/chainloop-demo/dagger/README.md +++ b/chainloop-demo/dagger/README.md @@ -1,8 +1,8 @@ Build a Go application, package it in a container image, generate its Software Bill Of Materials (SBOM) and attest the result using the Chainloop platform. -```json -dagger call build-and-publish \ +```sh +$ dagger call build-and-publish \ --proj path/to/go-project \ --chainloop-token env:CHAINLOOP_TOKEN \ --chainloop-signing-key file:path/to/cosign.key \ From 68124498d067bcf57cc0a5f0f0db7337958deece Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 21 Feb 2024 09:27:27 +0100 Subject: [PATCH 20/34] chore: improve dagger Signed-off-by: Miguel Martinez Trivino --- .github/workflows/release_dagger.yaml | 9 ++++----- chainloop-demo/dagger/README.md | 6 ++++-- chainloop-demo/dagger/src/main.go | 16 +++++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release_dagger.yaml b/.github/workflows/release_dagger.yaml index 1c87625..1432189 100644 --- a/.github/workflows/release_dagger.yaml +++ b/.github/workflows/release_dagger.yaml @@ -24,11 +24,10 @@ jobs: - name: Build and Publish run: | dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ - --proj . \ - --chainloop-token env:CHAINLOOP_TOKEN \ - --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ - --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD - + --proj . \ + --chainloop-token env:CHAINLOOP_TOKEN \ + --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ + --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD env: CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} diff --git a/chainloop-demo/dagger/README.md b/chainloop-demo/dagger/README.md index dc51049..dc9a39c 100644 --- a/chainloop-demo/dagger/README.md +++ b/chainloop-demo/dagger/README.md @@ -1,8 +1,10 @@ -Build a Go application, package it in a container image, generate its Software Bill Of Materials (SBOM) and attest the result using the Chainloop platform. +Dagger Module that builds a Go application, packages it in a container image, generates its Software Bill Of Materials (SBOM) and attests the result using the Chainloop platform. + +More info about attestation crafting [here](https://docs.chainloop.dev/getting-started/attestation-crafting) ```sh -$ dagger call build-and-publish \ +$ dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ --proj path/to/go-project \ --chainloop-token env:CHAINLOOP_TOKEN \ --chainloop-signing-key file:path/to/cosign.key \ diff --git a/chainloop-demo/dagger/src/main.go b/chainloop-demo/dagger/src/main.go index 8498cbf..4b90ce3 100644 --- a/chainloop-demo/dagger/src/main.go +++ b/chainloop-demo/dagger/src/main.go @@ -9,8 +9,10 @@ import ( type BuildAndRelease struct{} -// Build and Publish a GO application as a container image -// Attest the pieces of evidence to Chainloop +// - Build, package and publish a Go application as a container image +// - Generate a CycloneDX Software Bill Of Materials using Syft +// - Attest the pieces of evidence (binary, container image, and SBOM) using Chainloop +// https://docs.chainloop.dev/getting-started/attestation-crafting func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { var err error chainloopClient := dag.Chainloop(chainloopToken) @@ -21,7 +23,7 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, return "", fmt.Errorf("failed to initialize attestation: %w", err) } - // Finish the attestation once we are done + // Finish/Mark as failed the attestation once we are done defer func() { // If there was an error in the process, mark the attestation as failed in Chainloop if err != nil { @@ -32,17 +34,17 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, } }() - // build artifacts + // Build software artifacts res, err := m.doBuildAndPublish(ctx, proj) if err != nil { - return "", fmt.Errorf("failed to build and publish: %w", err) + return "", fmt.Errorf("failed to build and publish artifacts: %w", err) } // Attest the pieces of evidence // Container image _, err = chainloopClient.AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: res.imageRepo}) if err != nil { - return "", fmt.Errorf("failed to add image piece of evidence: %w", err) + return "", fmt.Errorf("failed to add container image piece of evidence: %w", err) } // Binary @@ -83,7 +85,7 @@ func (m *BuildAndRelease) doBuildAndPublish(ctx context.Context, proj *Directory WithEntrypoint([]string{"/server"}). Publish(ctx, fmt.Sprintf("ttl.sh/chainloop-demo-%.0f", math.Floor(rand.Float64()*10000000))) //#nosec if err != nil { - return nil, err + return nil, fmt.Errorf("failed to build and publish container image: %w", err) } return &buildResult{imageRepo: imageRepo, sbom: sbom, binary: binary}, nil From bf3ae12f6449bade5677f63700c370821111ae2e Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 6 Mar 2024 17:54:24 +0100 Subject: [PATCH 21/34] chore: remove Chainloop to reset demo Signed-off-by: Miguel Martinez Trivino --- .github/workflows/release_dagger.yaml | 8 +---- chainloop-demo/dagger/src/main.go | 44 ++------------------------- 2 files changed, 3 insertions(+), 49 deletions(-) diff --git a/.github/workflows/release_dagger.yaml b/.github/workflows/release_dagger.yaml index 1432189..01c515b 100644 --- a/.github/workflows/release_dagger.yaml +++ b/.github/workflows/release_dagger.yaml @@ -24,12 +24,6 @@ jobs: - name: Build and Publish run: | dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ - --proj . \ - --chainloop-token env:CHAINLOOP_TOKEN \ - --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ - --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD + --proj . env: - CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} - CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} - CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} diff --git a/chainloop-demo/dagger/src/main.go b/chainloop-demo/dagger/src/main.go index 4b90ce3..1b5a571 100644 --- a/chainloop-demo/dagger/src/main.go +++ b/chainloop-demo/dagger/src/main.go @@ -11,28 +11,8 @@ type BuildAndRelease struct{} // - Build, package and publish a Go application as a container image // - Generate a CycloneDX Software Bill Of Materials using Syft -// - Attest the pieces of evidence (binary, container image, and SBOM) using Chainloop -// https://docs.chainloop.dev/getting-started/attestation-crafting -func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) (string, error) { var err error - chainloopClient := dag.Chainloop(chainloopToken) - - // Initialize the attestation - attestationID, err := chainloopClient.AttestationInit(ctx, ChainloopAttestationInitOpts{Repository: proj}) - if err != nil { - return "", fmt.Errorf("failed to initialize attestation: %w", err) - } - - // Finish/Mark as failed the attestation once we are done - defer func() { - // If there was an error in the process, mark the attestation as failed in Chainloop - if err != nil { - chainloopClient.AttestationReset(ctx, attestationID, ChainloopAttestationResetOpts{Reason: err.Error()}) - } else { - // Push the attestation to Chainloop - _, err = chainloopClient.AttestationPush(ctx, attestationID, chainloopSigningKey, chainloopPassphrase) - } - }() // Build software artifacts res, err := m.doBuildAndPublish(ctx, proj) @@ -40,27 +20,7 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, return "", fmt.Errorf("failed to build and publish artifacts: %w", err) } - // Attest the pieces of evidence - // Container image - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: res.imageRepo}) - if err != nil { - return "", fmt.Errorf("failed to add container image piece of evidence: %w", err) - } - - // Binary - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "binary", ChainloopAttestationAddOpts{Path: res.binary}) - if err != nil { - return "", fmt.Errorf("failed to add binary piece of evidence: %w", err) - } - - // SBOM - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "sbom", ChainloopAttestationAddOpts{Path: res.sbom}) - if err != nil { - return "", fmt.Errorf("failed to add SBOM piece of evidence: %w", err) - } - - // Return information about the attestation - return chainloopClient.AttestationStatus(ctx, attestationID) + return res.imageRepo, nil } type buildResult struct { From dafcdb46acadf82cd7634d5377c63476fbdc87c6 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 6 Mar 2024 17:57:15 +0100 Subject: [PATCH 22/34] Revert "chore: remove Chainloop to reset demo" This reverts commit bf3ae12f6449bade5677f63700c370821111ae2e. --- .github/workflows/release_dagger.yaml | 8 ++++- chainloop-demo/dagger/src/main.go | 44 +++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release_dagger.yaml b/.github/workflows/release_dagger.yaml index 01c515b..1432189 100644 --- a/.github/workflows/release_dagger.yaml +++ b/.github/workflows/release_dagger.yaml @@ -24,6 +24,12 @@ jobs: - name: Build and Publish run: | dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ - --proj . + --proj . \ + --chainloop-token env:CHAINLOOP_TOKEN \ + --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ + --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD env: + CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} + CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} diff --git a/chainloop-demo/dagger/src/main.go b/chainloop-demo/dagger/src/main.go index 1b5a571..4b90ce3 100644 --- a/chainloop-demo/dagger/src/main.go +++ b/chainloop-demo/dagger/src/main.go @@ -11,8 +11,28 @@ type BuildAndRelease struct{} // - Build, package and publish a Go application as a container image // - Generate a CycloneDX Software Bill Of Materials using Syft -func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) (string, error) { +// - Attest the pieces of evidence (binary, container image, and SBOM) using Chainloop +// https://docs.chainloop.dev/getting-started/attestation-crafting +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { var err error + chainloopClient := dag.Chainloop(chainloopToken) + + // Initialize the attestation + attestationID, err := chainloopClient.AttestationInit(ctx, ChainloopAttestationInitOpts{Repository: proj}) + if err != nil { + return "", fmt.Errorf("failed to initialize attestation: %w", err) + } + + // Finish/Mark as failed the attestation once we are done + defer func() { + // If there was an error in the process, mark the attestation as failed in Chainloop + if err != nil { + chainloopClient.AttestationReset(ctx, attestationID, ChainloopAttestationResetOpts{Reason: err.Error()}) + } else { + // Push the attestation to Chainloop + _, err = chainloopClient.AttestationPush(ctx, attestationID, chainloopSigningKey, chainloopPassphrase) + } + }() // Build software artifacts res, err := m.doBuildAndPublish(ctx, proj) @@ -20,7 +40,27 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) return "", fmt.Errorf("failed to build and publish artifacts: %w", err) } - return res.imageRepo, nil + // Attest the pieces of evidence + // Container image + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: res.imageRepo}) + if err != nil { + return "", fmt.Errorf("failed to add container image piece of evidence: %w", err) + } + + // Binary + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "binary", ChainloopAttestationAddOpts{Path: res.binary}) + if err != nil { + return "", fmt.Errorf("failed to add binary piece of evidence: %w", err) + } + + // SBOM + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "sbom", ChainloopAttestationAddOpts{Path: res.sbom}) + if err != nil { + return "", fmt.Errorf("failed to add SBOM piece of evidence: %w", err) + } + + // Return information about the attestation + return chainloopClient.AttestationStatus(ctx, attestationID) } type buildResult struct { From a9ef292a1d66f8ebfb929fba83e3fd68dcb38f48 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 6 Mar 2024 18:01:29 +0100 Subject: [PATCH 23/34] Revert "Enable Chainloop Attestation" --- .github/workflows/release_dagger.yaml | 8 +---- chainloop-demo/dagger/src/main.go | 44 ++------------------------- 2 files changed, 3 insertions(+), 49 deletions(-) diff --git a/.github/workflows/release_dagger.yaml b/.github/workflows/release_dagger.yaml index 1432189..01c515b 100644 --- a/.github/workflows/release_dagger.yaml +++ b/.github/workflows/release_dagger.yaml @@ -24,12 +24,6 @@ jobs: - name: Build and Publish run: | dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ - --proj . \ - --chainloop-token env:CHAINLOOP_TOKEN \ - --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ - --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD + --proj . env: - CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} - CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} - CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} diff --git a/chainloop-demo/dagger/src/main.go b/chainloop-demo/dagger/src/main.go index 4b90ce3..1b5a571 100644 --- a/chainloop-demo/dagger/src/main.go +++ b/chainloop-demo/dagger/src/main.go @@ -11,28 +11,8 @@ type BuildAndRelease struct{} // - Build, package and publish a Go application as a container image // - Generate a CycloneDX Software Bill Of Materials using Syft -// - Attest the pieces of evidence (binary, container image, and SBOM) using Chainloop -// https://docs.chainloop.dev/getting-started/attestation-crafting -func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) (string, error) { var err error - chainloopClient := dag.Chainloop(chainloopToken) - - // Initialize the attestation - attestationID, err := chainloopClient.AttestationInit(ctx, ChainloopAttestationInitOpts{Repository: proj}) - if err != nil { - return "", fmt.Errorf("failed to initialize attestation: %w", err) - } - - // Finish/Mark as failed the attestation once we are done - defer func() { - // If there was an error in the process, mark the attestation as failed in Chainloop - if err != nil { - chainloopClient.AttestationReset(ctx, attestationID, ChainloopAttestationResetOpts{Reason: err.Error()}) - } else { - // Push the attestation to Chainloop - _, err = chainloopClient.AttestationPush(ctx, attestationID, chainloopSigningKey, chainloopPassphrase) - } - }() // Build software artifacts res, err := m.doBuildAndPublish(ctx, proj) @@ -40,27 +20,7 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, return "", fmt.Errorf("failed to build and publish artifacts: %w", err) } - // Attest the pieces of evidence - // Container image - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: res.imageRepo}) - if err != nil { - return "", fmt.Errorf("failed to add container image piece of evidence: %w", err) - } - - // Binary - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "binary", ChainloopAttestationAddOpts{Path: res.binary}) - if err != nil { - return "", fmt.Errorf("failed to add binary piece of evidence: %w", err) - } - - // SBOM - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "sbom", ChainloopAttestationAddOpts{Path: res.sbom}) - if err != nil { - return "", fmt.Errorf("failed to add SBOM piece of evidence: %w", err) - } - - // Return information about the attestation - return chainloopClient.AttestationStatus(ctx, attestationID) + return res.imageRepo, nil } type buildResult struct { From f8a3ff980e88464eecfcc0afc405eac8fcbe2287 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 6 Mar 2024 18:06:07 +0100 Subject: [PATCH 24/34] Revert "chore: remove Chainloop to reset demo" This reverts commit bf3ae12f6449bade5677f63700c370821111ae2e. --- .github/workflows/release_dagger.yaml | 8 ++++- chainloop-demo/dagger/src/main.go | 44 +++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release_dagger.yaml b/.github/workflows/release_dagger.yaml index 01c515b..1432189 100644 --- a/.github/workflows/release_dagger.yaml +++ b/.github/workflows/release_dagger.yaml @@ -24,6 +24,12 @@ jobs: - name: Build and Publish run: | dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ - --proj . + --proj . \ + --chainloop-token env:CHAINLOOP_TOKEN \ + --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ + --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD env: + CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} + CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} diff --git a/chainloop-demo/dagger/src/main.go b/chainloop-demo/dagger/src/main.go index 1b5a571..4b90ce3 100644 --- a/chainloop-demo/dagger/src/main.go +++ b/chainloop-demo/dagger/src/main.go @@ -11,8 +11,28 @@ type BuildAndRelease struct{} // - Build, package and publish a Go application as a container image // - Generate a CycloneDX Software Bill Of Materials using Syft -func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) (string, error) { +// - Attest the pieces of evidence (binary, container image, and SBOM) using Chainloop +// https://docs.chainloop.dev/getting-started/attestation-crafting +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { var err error + chainloopClient := dag.Chainloop(chainloopToken) + + // Initialize the attestation + attestationID, err := chainloopClient.AttestationInit(ctx, ChainloopAttestationInitOpts{Repository: proj}) + if err != nil { + return "", fmt.Errorf("failed to initialize attestation: %w", err) + } + + // Finish/Mark as failed the attestation once we are done + defer func() { + // If there was an error in the process, mark the attestation as failed in Chainloop + if err != nil { + chainloopClient.AttestationReset(ctx, attestationID, ChainloopAttestationResetOpts{Reason: err.Error()}) + } else { + // Push the attestation to Chainloop + _, err = chainloopClient.AttestationPush(ctx, attestationID, chainloopSigningKey, chainloopPassphrase) + } + }() // Build software artifacts res, err := m.doBuildAndPublish(ctx, proj) @@ -20,7 +40,27 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) return "", fmt.Errorf("failed to build and publish artifacts: %w", err) } - return res.imageRepo, nil + // Attest the pieces of evidence + // Container image + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: res.imageRepo}) + if err != nil { + return "", fmt.Errorf("failed to add container image piece of evidence: %w", err) + } + + // Binary + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "binary", ChainloopAttestationAddOpts{Path: res.binary}) + if err != nil { + return "", fmt.Errorf("failed to add binary piece of evidence: %w", err) + } + + // SBOM + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "sbom", ChainloopAttestationAddOpts{Path: res.sbom}) + if err != nil { + return "", fmt.Errorf("failed to add SBOM piece of evidence: %w", err) + } + + // Return information about the attestation + return chainloopClient.AttestationStatus(ctx, attestationID) } type buildResult struct { From ee2f435b7182a8beb8b08af00a21735d4deffdb3 Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 6 Mar 2024 18:08:20 +0100 Subject: [PATCH 25/34] feat: update dagger Signed-off-by: Miguel Martinez Trivino --- chainloop-demo/dagger/dagger.json | 4 ++-- chainloop-demo/dagger/src/.gitattributes | 2 ++ chainloop-demo/dagger/src/.gitignore | 1 + chainloop-demo/dagger/src/go.mod | 2 +- chainloop-demo/dagger/src/go.sum | 4 ++-- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index bc3fdad..fc0a7ba 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -4,7 +4,7 @@ "dependencies": [ { "name": "chainloop", - "source": "github.com/chainloop-dev/chainloop/extras/dagger@ae2e814ef5f33b2098371349235a2f387217af2f" + "source": "github.com/chainloop-dev/chainloop/extras/dagger@00d64321852ace5804ff3cbf1e478acd0cf91460" }, { "name": "golang", @@ -20,5 +20,5 @@ } ], "source": "src", - "engineVersion": "v0.9.10" + "engineVersion": "v0.10.1" } diff --git a/chainloop-demo/dagger/src/.gitattributes b/chainloop-demo/dagger/src/.gitattributes index bd21599..b94d9fd 100644 --- a/chainloop-demo/dagger/src/.gitattributes +++ b/chainloop-demo/dagger/src/.gitattributes @@ -1,2 +1,4 @@ /dagger.gen.go linguist-generated /querybuilder/** linguist-generated +/internal/dagger/** linguist-generated +/internal/querybuilder/** linguist-generated diff --git a/chainloop-demo/dagger/src/.gitignore b/chainloop-demo/dagger/src/.gitignore index c3fbf8c..ae28417 100644 --- a/chainloop-demo/dagger/src/.gitignore +++ b/chainloop-demo/dagger/src/.gitignore @@ -1,2 +1,3 @@ /querybuilder/ /dagger.gen.go +/internal diff --git a/chainloop-demo/dagger/src/go.mod b/chainloop-demo/dagger/src/go.mod index b4a8e7c..8557c1b 100644 --- a/chainloop-demo/dagger/src/go.mod +++ b/chainloop-demo/dagger/src/go.mod @@ -10,4 +10,4 @@ require ( golang.org/x/sync v0.6.0 ) -require github.com/stretchr/testify v1.8.3 // indirect +require github.com/stretchr/testify v1.9.0 // indirect diff --git a/chainloop-demo/dagger/src/go.sum b/chainloop-demo/dagger/src/go.sum index 3ad50f0..6b16e9f 100644 --- a/chainloop-demo/dagger/src/go.sum +++ b/chainloop-demo/dagger/src/go.sum @@ -19,8 +19,8 @@ github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vektah/gqlparser/v2 v2.5.6 h1:Ou14T0N1s191eRMZ1gARVqohcbe1e8FrcONScsq8cRU= github.com/vektah/gqlparser/v2 v2.5.6/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= From a512a41fee08c556113f8d4f2e90bf21d7f0754a Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 6 Mar 2024 18:11:42 +0100 Subject: [PATCH 26/34] chore: revert demo Signed-off-by: Miguel Martinez Trivino --- .github/workflows/release_dagger.yaml | 8 +---- chainloop-demo/dagger/dagger.json | 4 --- chainloop-demo/dagger/src/main.go | 44 ++------------------------- 3 files changed, 3 insertions(+), 53 deletions(-) diff --git a/.github/workflows/release_dagger.yaml b/.github/workflows/release_dagger.yaml index 1432189..01c515b 100644 --- a/.github/workflows/release_dagger.yaml +++ b/.github/workflows/release_dagger.yaml @@ -24,12 +24,6 @@ jobs: - name: Build and Publish run: | dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ - --proj . \ - --chainloop-token env:CHAINLOOP_TOKEN \ - --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ - --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD + --proj . env: - CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} - CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} - CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index fc0a7ba..60dfefd 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -2,10 +2,6 @@ "name": "build-and-release", "sdk": "go", "dependencies": [ - { - "name": "chainloop", - "source": "github.com/chainloop-dev/chainloop/extras/dagger@00d64321852ace5804ff3cbf1e478acd0cf91460" - }, { "name": "golang", "source": "github.com/kpenfound/dagger-modules/golang@5cb802660efb1242e5d7beb382f772f0a3f34616" diff --git a/chainloop-demo/dagger/src/main.go b/chainloop-demo/dagger/src/main.go index 4b90ce3..1b5a571 100644 --- a/chainloop-demo/dagger/src/main.go +++ b/chainloop-demo/dagger/src/main.go @@ -11,28 +11,8 @@ type BuildAndRelease struct{} // - Build, package and publish a Go application as a container image // - Generate a CycloneDX Software Bill Of Materials using Syft -// - Attest the pieces of evidence (binary, container image, and SBOM) using Chainloop -// https://docs.chainloop.dev/getting-started/attestation-crafting -func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) (string, error) { var err error - chainloopClient := dag.Chainloop(chainloopToken) - - // Initialize the attestation - attestationID, err := chainloopClient.AttestationInit(ctx, ChainloopAttestationInitOpts{Repository: proj}) - if err != nil { - return "", fmt.Errorf("failed to initialize attestation: %w", err) - } - - // Finish/Mark as failed the attestation once we are done - defer func() { - // If there was an error in the process, mark the attestation as failed in Chainloop - if err != nil { - chainloopClient.AttestationReset(ctx, attestationID, ChainloopAttestationResetOpts{Reason: err.Error()}) - } else { - // Push the attestation to Chainloop - _, err = chainloopClient.AttestationPush(ctx, attestationID, chainloopSigningKey, chainloopPassphrase) - } - }() // Build software artifacts res, err := m.doBuildAndPublish(ctx, proj) @@ -40,27 +20,7 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, return "", fmt.Errorf("failed to build and publish artifacts: %w", err) } - // Attest the pieces of evidence - // Container image - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: res.imageRepo}) - if err != nil { - return "", fmt.Errorf("failed to add container image piece of evidence: %w", err) - } - - // Binary - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "binary", ChainloopAttestationAddOpts{Path: res.binary}) - if err != nil { - return "", fmt.Errorf("failed to add binary piece of evidence: %w", err) - } - - // SBOM - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "sbom", ChainloopAttestationAddOpts{Path: res.sbom}) - if err != nil { - return "", fmt.Errorf("failed to add SBOM piece of evidence: %w", err) - } - - // Return information about the attestation - return chainloopClient.AttestationStatus(ctx, attestationID) + return res.imageRepo, nil } type buildResult struct { From e82b6015e0bf6b8c44a5d28a2856c6b9819c2bec Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Wed, 6 Mar 2024 18:12:04 +0100 Subject: [PATCH 27/34] Revert "chore: revert demo" This reverts commit a512a41fee08c556113f8d4f2e90bf21d7f0754a. --- .github/workflows/release_dagger.yaml | 8 ++++- chainloop-demo/dagger/dagger.json | 4 +++ chainloop-demo/dagger/src/main.go | 44 +++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release_dagger.yaml b/.github/workflows/release_dagger.yaml index 01c515b..1432189 100644 --- a/.github/workflows/release_dagger.yaml +++ b/.github/workflows/release_dagger.yaml @@ -24,6 +24,12 @@ jobs: - name: Build and Publish run: | dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ - --proj . + --proj . \ + --chainloop-token env:CHAINLOOP_TOKEN \ + --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ + --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD env: + CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} + CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index 60dfefd..fc0a7ba 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -2,6 +2,10 @@ "name": "build-and-release", "sdk": "go", "dependencies": [ + { + "name": "chainloop", + "source": "github.com/chainloop-dev/chainloop/extras/dagger@00d64321852ace5804ff3cbf1e478acd0cf91460" + }, { "name": "golang", "source": "github.com/kpenfound/dagger-modules/golang@5cb802660efb1242e5d7beb382f772f0a3f34616" diff --git a/chainloop-demo/dagger/src/main.go b/chainloop-demo/dagger/src/main.go index 1b5a571..4b90ce3 100644 --- a/chainloop-demo/dagger/src/main.go +++ b/chainloop-demo/dagger/src/main.go @@ -11,8 +11,28 @@ type BuildAndRelease struct{} // - Build, package and publish a Go application as a container image // - Generate a CycloneDX Software Bill Of Materials using Syft -func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) (string, error) { +// - Attest the pieces of evidence (binary, container image, and SBOM) using Chainloop +// https://docs.chainloop.dev/getting-started/attestation-crafting +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { var err error + chainloopClient := dag.Chainloop(chainloopToken) + + // Initialize the attestation + attestationID, err := chainloopClient.AttestationInit(ctx, ChainloopAttestationInitOpts{Repository: proj}) + if err != nil { + return "", fmt.Errorf("failed to initialize attestation: %w", err) + } + + // Finish/Mark as failed the attestation once we are done + defer func() { + // If there was an error in the process, mark the attestation as failed in Chainloop + if err != nil { + chainloopClient.AttestationReset(ctx, attestationID, ChainloopAttestationResetOpts{Reason: err.Error()}) + } else { + // Push the attestation to Chainloop + _, err = chainloopClient.AttestationPush(ctx, attestationID, chainloopSigningKey, chainloopPassphrase) + } + }() // Build software artifacts res, err := m.doBuildAndPublish(ctx, proj) @@ -20,7 +40,27 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory) return "", fmt.Errorf("failed to build and publish artifacts: %w", err) } - return res.imageRepo, nil + // Attest the pieces of evidence + // Container image + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: res.imageRepo}) + if err != nil { + return "", fmt.Errorf("failed to add container image piece of evidence: %w", err) + } + + // Binary + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "binary", ChainloopAttestationAddOpts{Path: res.binary}) + if err != nil { + return "", fmt.Errorf("failed to add binary piece of evidence: %w", err) + } + + // SBOM + _, err = chainloopClient.AttestationAdd(ctx, attestationID, "sbom", ChainloopAttestationAddOpts{Path: res.sbom}) + if err != nil { + return "", fmt.Errorf("failed to add SBOM piece of evidence: %w", err) + } + + // Return information about the attestation + return chainloopClient.AttestationStatus(ctx, attestationID) } type buildResult struct { From af25ccee4d94ebc4b8e80252791518397e71f92f Mon Sep 17 00:00:00 2001 From: Miguel Martinez Trivino Date: Tue, 12 Mar 2024 10:53:01 +0100 Subject: [PATCH 28/34] chore(ci): update Dagger module Signed-off-by: Miguel Martinez Trivino --- chainloop-demo/dagger/dagger.json | 2 +- chainloop-demo/dagger/src/main.go | 40 +++++++++++++------------------ 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index fc0a7ba..02d018b 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -4,7 +4,7 @@ "dependencies": [ { "name": "chainloop", - "source": "github.com/chainloop-dev/chainloop/extras/dagger@00d64321852ace5804ff3cbf1e478acd0cf91460" + "source": "github.com/chainloop-dev/chainloop@1c059f79997a85e4643b227e16110df371906093" }, { "name": "golang", diff --git a/chainloop-demo/dagger/src/main.go b/chainloop-demo/dagger/src/main.go index 4b90ce3..f7b9504 100644 --- a/chainloop-demo/dagger/src/main.go +++ b/chainloop-demo/dagger/src/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "demo/internal/dagger" "fmt" "math" "math/rand" @@ -13,12 +14,12 @@ type BuildAndRelease struct{} // - Generate a CycloneDX Software Bill Of Materials using Syft // - Attest the pieces of evidence (binary, container image, and SBOM) using Chainloop // https://docs.chainloop.dev/getting-started/attestation-crafting -func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (string, error) { - var err error - chainloopClient := dag.Chainloop(chainloopToken) - +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (status string, err error) { // Initialize the attestation - attestationID, err := chainloopClient.AttestationInit(ctx, ChainloopAttestationInitOpts{Repository: proj}) + attestation := dag.Chainloop().Init(chainloopToken, dagger.ChainloopInitOpts{Repository: proj}) + // Force the execution of the init method + // If Sync is not executed, init will happen at the end of the function + _, err = attestation.Sync(ctx) if err != nil { return "", fmt.Errorf("failed to initialize attestation: %w", err) } @@ -27,10 +28,10 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, defer func() { // If there was an error in the process, mark the attestation as failed in Chainloop if err != nil { - chainloopClient.AttestationReset(ctx, attestationID, ChainloopAttestationResetOpts{Reason: err.Error()}) + _, _ = attestation.MarkFailed(ctx, dagger.ChainloopAttestationMarkFailedOpts{Reason: err.Error()}) } else { // Push the attestation to Chainloop - _, err = chainloopClient.AttestationPush(ctx, attestationID, chainloopSigningKey, chainloopPassphrase) + _, err = attestation.Push(ctx, chainloopSigningKey, chainloopPassphrase) } }() @@ -41,26 +42,17 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, } // Attest the pieces of evidence - // Container image - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "image", ChainloopAttestationAddOpts{Value: res.imageRepo}) - if err != nil { - return "", fmt.Errorf("failed to add container image piece of evidence: %w", err) - } - - // Binary - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "binary", ChainloopAttestationAddOpts{Path: res.binary}) - if err != nil { - return "", fmt.Errorf("failed to add binary piece of evidence: %w", err) - } - - // SBOM - _, err = chainloopClient.AttestationAdd(ctx, attestationID, "sbom", ChainloopAttestationAddOpts{Path: res.sbom}) - if err != nil { - return "", fmt.Errorf("failed to add SBOM piece of evidence: %w", err) + attestation = attestation. + // Container image + AddRawEvidence("image", res.imageRepo). + // Binary + AddFileEvidence("binary", res.binary) + if _, err := attestation.Sync(ctx); err != nil { + return "", fmt.Errorf("failed to add evidence to attestation: %w", err) } // Return information about the attestation - return chainloopClient.AttestationStatus(ctx, attestationID) + return attestation.Status(ctx) } type buildResult struct { From c156d4d98cbd2ce4ce62c2680a0d92729d032df9 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Thu, 30 May 2024 15:16:34 +0200 Subject: [PATCH 29/34] add github releaser workflow Signed-off-by: Javier Rodriguez --- .github/workflows/github_release.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/github_release.yaml diff --git a/.github/workflows/github_release.yaml b/.github/workflows/github_release.yaml new file mode 100644 index 0000000..dd02732 --- /dev/null +++ b/.github/workflows/github_release.yaml @@ -0,0 +1,21 @@ +name: Release + +on: + release: + types: [published] + +permissions: + contents: write + +jobs: + release: + name: Attest GitHub Release + uses: chainloop-dev/labs/.github/workflows/chainloop_github_release.yml@417bad33ca08beaa785ae6a6b933406cd7b935cb + with: + project: "chainloop" + workflow_name: "chainloop-vault-release" + additional_materials: "ghcr.io/chainloop-dev/chainloop/control-plane:${{ github.ref_name }},ghcr.io/chainloop-dev/chainloop/artifact-cas:${{ github.ref_name }},ghcr.io/chainloop-dev/chainloop/cli:${{ github.ref_name }}" + secrets: + api_token: ${{ secrets.CHAINLOOP_API_TOKEN }} + cosign_key: ${{ secrets.COSIGN_KEY }} + cosign_password: ${{ secrets.COSIGN_PASSWORD }} From d319c7b29d9b058f9170e51bcbf13f994473b420 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Thu, 30 May 2024 15:29:18 +0200 Subject: [PATCH 30/34] Modify env name Signed-off-by: Javier Rodriguez --- .github/workflows/github_release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github_release.yaml b/.github/workflows/github_release.yaml index dd02732..ff40e11 100644 --- a/.github/workflows/github_release.yaml +++ b/.github/workflows/github_release.yaml @@ -17,5 +17,5 @@ jobs: additional_materials: "ghcr.io/chainloop-dev/chainloop/control-plane:${{ github.ref_name }},ghcr.io/chainloop-dev/chainloop/artifact-cas:${{ github.ref_name }},ghcr.io/chainloop-dev/chainloop/cli:${{ github.ref_name }}" secrets: api_token: ${{ secrets.CHAINLOOP_API_TOKEN }} - cosign_key: ${{ secrets.COSIGN_KEY }} + cosign_key: ${{ secrets.COSIGN_PRIVATE_KEY }} cosign_password: ${{ secrets.COSIGN_PASSWORD }} From cf753096120db0b3155b1c7b647cdf2d54effc19 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Thu, 30 May 2024 15:35:04 +0200 Subject: [PATCH 31/34] Bump chainloop version Signed-off-by: Javier Rodriguez --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 0661961..393afc3 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -107,5 +107,5 @@ jobs: run: | chainloop attestation reset --trigger cancellation env: - CHAINLOOP_VERSION: 0.12.0 + CHAINLOOP_VERSION: 0.89.0 CHAINLOOP_ROBOT_ACCOUNT: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} From 0de1dc561747b1e16b97dd13df4d99844a32df01 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Thu, 30 May 2024 15:41:07 +0200 Subject: [PATCH 32/34] update versions on release.yaml Signed-off-by: Javier Rodriguez --- .github/workflows/release.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 393afc3..7b25439 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,14 +17,14 @@ jobs: - name: Install Cosign uses: sigstore/cosign-installer@main with: - cosign-release: 'v2.0.2' + cosign-release: 'v2.2.3' - name: Install Chainloop run: | curl -sfL https://docs.chainloop.dev/install.sh | bash -s -- --version v${{ env.CHAINLOOP_VERSION }} - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: fetch-depth: 0 @@ -34,7 +34,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version: 1.21 - name: Docker login to Github Packages uses: docker/login-action@v2 From 6e1f75857e3be437eafb7226de171d17462350c2 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Wed, 5 Jun 2024 16:50:55 +0200 Subject: [PATCH 33/34] feat(workflows-integration-demo): Update dagger pipeline to use workflow-name Signed-off-by: Javier Rodriguez --- .github/workflows/release.yaml | 111 ----------------------- .github/workflows/release_dagger.yaml | 4 +- chainloop-demo/dagger/dagger.json | 4 +- chainloop-demo/dagger/src/.gitattributes | 1 + chainloop-demo/dagger/src/.gitignore | 3 + chainloop-demo/dagger/src/go.mod | 32 ++++++- chainloop-demo/dagger/src/go.sum | 78 +++++++++++----- chainloop-demo/dagger/src/main.go | 13 ++- 8 files changed, 101 insertions(+), 145 deletions(-) delete mode 100644 .github/workflows/release.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index 7b25439..0000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,111 +0,0 @@ -name: Release - -on: - push: - tags: - - "v*.*.*" - -jobs: - release: - name: Release - runs-on: ubuntu-latest - if: github.ref_type == 'tag' - permissions: - packages: write - contents: write # required for goreleaser - steps: - - name: Install Cosign - uses: sigstore/cosign-installer@main - with: - cosign-release: 'v2.2.3' - - - name: Install Chainloop - run: | - curl -sfL https://docs.chainloop.dev/install.sh | bash -s -- --version v${{ env.CHAINLOOP_VERSION }} - - - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - with: - fetch-depth: 0 - - - name: Initialize Attestation - run: chainloop attestation init # --contract-revision 2 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: 1.21 - - - name: Docker login to Github Packages - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Run Go Releaser - id: release - uses: goreleaser/goreleaser-action@v3 - with: - distribution: goreleaser - version: latest - args: release --rm-dist - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} - COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} - - - uses: anchore/sbom-action@v0 - with: - image: ${{ env.IMAGE }} - format: cyclonedx-json - artifact-name: sbom.cyclonedx.json - output-file: /tmp/sbom.cyclonedx.json - env: - IMAGE: ghcr.io/chainloop-dev/integration-demo:${{ github.ref_name }} - - - uses: anchore/sbom-action@v0 - with: - image: ${{ env.IMAGE }} - format: spdx-json - artifact-name: sbom.spdx.json - output-file: /tmp/sbom.spdx.json - env: - IMAGE: ghcr.io/chainloop-dev/integration-demo:${{ github.ref_name }} - - - name: Add Container Image Artifact - run: chainloop attestation add --name image --value ghcr.io/chainloop-dev/integration-demo:${{ github.ref_name }} - - - name: Add CycloneDX SBOM Artifact - run: chainloop attestation add --name sbom --value /tmp/sbom.cyclonedx.json - - - name: Add SPDX SBOM Artifact - run: chainloop attestation add --name sbom-spdx --value /tmp/sbom.spdx.json - - - name: Add Binary Artifact - run: | - BINARY_PATH="$(echo -n '${{ steps.release.outputs.metadata }}' | jq -r '"dist/" + .project_name + "_" + .version + "_" + .runtime.goos + "_" + .runtime.goarch + ".tar.gz"')" - - chainloop attestation add --name binary --value ${BINARY_PATH} - - - name: Finish and Record Attestation - if: ${{ success() }} - run: | - chainloop attestation status --full - chainloop attestation push --key env://CHAINLOOP_SIGNING_KEY - env: - CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} - CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} - - - name: Mark attestation as failed - if: ${{ failure() }} - run: | - chainloop attestation reset - - - name: Mark attestation as cancelled - if: ${{ cancelled() }} - run: | - chainloop attestation reset --trigger cancellation - env: - CHAINLOOP_VERSION: 0.89.0 - CHAINLOOP_ROBOT_ACCOUNT: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} diff --git a/.github/workflows/release_dagger.yaml b/.github/workflows/release_dagger.yaml index 1432189..e8ff5ea 100644 --- a/.github/workflows/release_dagger.yaml +++ b/.github/workflows/release_dagger.yaml @@ -25,11 +25,13 @@ jobs: run: | dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ --proj . \ + --chainloop-name $CHAINLOOP_WORKFLOW_NAME \ --chainloop-token env:CHAINLOOP_TOKEN \ --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD env: - CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_ROBOT_ACCOUNT }} + CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_TOKEN }} DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }} CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} + CHAINLOOP_WORKFLOW_NAME: "build-and-release" diff --git a/chainloop-demo/dagger/dagger.json b/chainloop-demo/dagger/dagger.json index 02d018b..0b15597 100644 --- a/chainloop-demo/dagger/dagger.json +++ b/chainloop-demo/dagger/dagger.json @@ -4,7 +4,7 @@ "dependencies": [ { "name": "chainloop", - "source": "github.com/chainloop-dev/chainloop@1c059f79997a85e4643b227e16110df371906093" + "source": "github.com/chainloop-dev/chainloop@122e8a4e8643ea2f9632ba246544d274e2de4344" }, { "name": "golang", @@ -20,5 +20,5 @@ } ], "source": "src", - "engineVersion": "v0.10.1" + "engineVersion": "v0.11.6" } diff --git a/chainloop-demo/dagger/src/.gitattributes b/chainloop-demo/dagger/src/.gitattributes index b94d9fd..738cf71 100644 --- a/chainloop-demo/dagger/src/.gitattributes +++ b/chainloop-demo/dagger/src/.gitattributes @@ -2,3 +2,4 @@ /querybuilder/** linguist-generated /internal/dagger/** linguist-generated /internal/querybuilder/** linguist-generated +/internal/telemetry/** linguist-generated diff --git a/chainloop-demo/dagger/src/.gitignore b/chainloop-demo/dagger/src/.gitignore index ae28417..6440b09 100644 --- a/chainloop-demo/dagger/src/.gitignore +++ b/chainloop-demo/dagger/src/.gitignore @@ -1,3 +1,6 @@ /querybuilder/ /dagger.gen.go /internal +/internal/dagger +/internal/querybuilder +/internal/telemetry diff --git a/chainloop-demo/dagger/src/go.mod b/chainloop-demo/dagger/src/go.mod index 8557c1b..a07f780 100644 --- a/chainloop-demo/dagger/src/go.mod +++ b/chainloop-demo/dagger/src/go.mod @@ -3,11 +3,33 @@ module demo go 1.21.1 require ( - github.com/99designs/gqlgen v0.17.31 - github.com/Khan/genqlient v0.6.0 - github.com/vektah/gqlparser/v2 v2.5.6 + github.com/99designs/gqlgen v0.17.44 + github.com/Khan/genqlient v0.7.0 + github.com/vektah/gqlparser/v2 v2.5.11 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.6.0 + golang.org/x/sync v0.7.0 ) -require github.com/stretchr/testify v1.9.0 // indirect +require ( + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect + github.com/sosodev/duration v1.2.0 // indirect + go.opentelemetry.io/otel v1.26.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 + go.opentelemetry.io/otel/metric v1.26.0 // indirect + go.opentelemetry.io/otel/sdk v1.26.0 + go.opentelemetry.io/otel/trace v1.26.0 + go.opentelemetry.io/proto/otlp v1.2.0 // indirect + golang.org/x/net v0.23.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/text v0.14.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect + google.golang.org/grpc v1.63.2 + google.golang.org/protobuf v1.33.0 // indirect +) diff --git a/chainloop-demo/dagger/src/go.sum b/chainloop-demo/dagger/src/go.sum index 6b16e9f..ac31010 100644 --- a/chainloop-demo/dagger/src/go.sum +++ b/chainloop-demo/dagger/src/go.sum @@ -1,35 +1,71 @@ -github.com/99designs/gqlgen v0.17.31 h1:VncSQ82VxieHkea8tz11p7h/zSbvHSxSDZfywqWt158= -github.com/99designs/gqlgen v0.17.31/go.mod h1:i4rEatMrzzu6RXaHydq1nmEPZkb3bKQsnxNRHS4DQB4= -github.com/Khan/genqlient v0.6.0 h1:Bwb1170ekuNIVIwTJEqvO8y7RxBxXu639VJOkKSrwAk= -github.com/Khan/genqlient v0.6.0/go.mod h1:rvChwWVTqXhiapdhLDV4bp9tz/Xvtewwkon4DpWWCRM= -github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/99designs/gqlgen v0.17.44 h1:OS2wLk/67Y+vXM75XHbwRnNYJcbuJd4OBL76RX3NQQA= +github.com/99designs/gqlgen v0.17.44/go.mod h1:UTCu3xpK2mLI5qcMNw+HKDiEL77it/1XtAjisC4sLwM= +github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= +github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/sosodev/duration v1.2.0 h1:pqK/FLSjsAADWY74SyWDCjOcd5l7H8GSnnOGEB9A1Us= +github.com/sosodev/duration v1.2.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.6 h1:Ou14T0N1s191eRMZ1gARVqohcbe1e8FrcONScsq8cRU= -github.com/vektah/gqlparser/v2 v2.5.6/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= +github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= +github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/gyxsuYtuE/JFxsQRtcCDtMrO2qMvlfXALU5wkzI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38= +go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= +go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= +go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= +go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= +go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/chainloop-demo/dagger/src/main.go b/chainloop-demo/dagger/src/main.go index f7b9504..21c49af 100644 --- a/chainloop-demo/dagger/src/main.go +++ b/chainloop-demo/dagger/src/main.go @@ -14,9 +14,9 @@ type BuildAndRelease struct{} // - Generate a CycloneDX Software Bill Of Materials using Syft // - Attest the pieces of evidence (binary, container image, and SBOM) using Chainloop // https://docs.chainloop.dev/getting-started/attestation-crafting -func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (status string, err error) { +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, name string, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (status string, err error) { // Initialize the attestation - attestation := dag.Chainloop().Init(chainloopToken, dagger.ChainloopInitOpts{Repository: proj}) + attestation := dag.Chainloop().Init(chainloopToken, name, dagger.ChainloopInitOpts{Repository: proj}) // Force the execution of the init method // If Sync is not executed, init will happen at the end of the function _, err = attestation.Sync(ctx) @@ -31,7 +31,10 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, _, _ = attestation.MarkFailed(ctx, dagger.ChainloopAttestationMarkFailedOpts{Reason: err.Error()}) } else { // Push the attestation to Chainloop - _, err = attestation.Push(ctx, chainloopSigningKey, chainloopPassphrase) + _, err = attestation.Push(ctx, dagger.ChainloopAttestationPushOpts{ + Key: chainloopSigningKey, + Passphrase: chainloopPassphrase, + }) } }() @@ -44,9 +47,9 @@ func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, // Attest the pieces of evidence attestation = attestation. // Container image - AddRawEvidence("image", res.imageRepo). + AddRawEvidence(res.imageRepo, dagger.ChainloopAttestationAddRawEvidenceOpts{Name: "image"}). // Binary - AddFileEvidence("binary", res.binary) + AddFileEvidence(res.binary, dagger.ChainloopAttestationAddFileEvidenceOpts{Name: "binary"}) if _, err := attestation.Sync(ctx); err != nil { return "", fmt.Errorf("failed to add evidence to attestation: %w", err) } From 15382266f92c1d5d2e90244b16bbeb80d214395f Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 21 Jun 2024 16:00:33 +0200 Subject: [PATCH 34/34] fix function parameter Signed-off-by: Javier Rodriguez --- .github/workflows/release_dagger.yaml | 2 +- chainloop-demo/dagger/src/main.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release_dagger.yaml b/.github/workflows/release_dagger.yaml index e8ff5ea..6dfdc02 100644 --- a/.github/workflows/release_dagger.yaml +++ b/.github/workflows/release_dagger.yaml @@ -25,7 +25,7 @@ jobs: run: | dagger call -m github.com/chainloop-dev/integration-demo/chainloop-demo/dagger build-and-publish \ --proj . \ - --chainloop-name $CHAINLOOP_WORKFLOW_NAME \ + --chainloop-workflow-name $CHAINLOOP_WORKFLOW_NAME \ --chainloop-token env:CHAINLOOP_TOKEN \ --chainloop-signing-key env:CHAINLOOP_SIGNING_KEY \ --chainloop-passphrase env:CHAINLOOP_SIGNING_PASSWORD diff --git a/chainloop-demo/dagger/src/main.go b/chainloop-demo/dagger/src/main.go index 21c49af..0df7a21 100644 --- a/chainloop-demo/dagger/src/main.go +++ b/chainloop-demo/dagger/src/main.go @@ -14,9 +14,9 @@ type BuildAndRelease struct{} // - Generate a CycloneDX Software Bill Of Materials using Syft // - Attest the pieces of evidence (binary, container image, and SBOM) using Chainloop // https://docs.chainloop.dev/getting-started/attestation-crafting -func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, name string, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (status string, err error) { +func (m *BuildAndRelease) BuildAndPublish(ctx context.Context, proj *Directory, chainloopWorkflowName string, chainloopToken, chainloopSigningKey, chainloopPassphrase *Secret) (status string, err error) { // Initialize the attestation - attestation := dag.Chainloop().Init(chainloopToken, name, dagger.ChainloopInitOpts{Repository: proj}) + attestation := dag.Chainloop().Init(chainloopToken, chainloopWorkflowName, dagger.ChainloopInitOpts{Repository: proj}) // Force the execution of the init method // If Sync is not executed, init will happen at the end of the function _, err = attestation.Sync(ctx)