Files
Kevin Minehart 13f4cf162e CI: move grafana-build into pkg/build (#105640)
* move grafana-build into pkg/build
2025-05-20 10:48:00 -05:00

90 lines
4.2 KiB
Go

package pipeline
import (
"context"
"errors"
"log/slog"
"dagger.io/dagger"
)
var (
ErrorNotADirectory = errors.New("not a directory argument")
ErrorOptionNotSet = errors.New("expected option not set")
ErrorDependencyNotFound = errors.New("dependency not found")
)
type ArtifactType int
const (
ArtifactTypeFile ArtifactType = iota
ArtifactTypeDirectory
)
type ArtifactContainerOpts struct {
Log *slog.Logger
Client *dagger.Client
Platform dagger.Platform
State StateHandler
Store ArtifactStore
}
type ArtifactPublishFileOpts struct{}
type ArtifactPublishDirOpts struct{}
type ArtifactInitializer func(context.Context, *slog.Logger, string, StateHandler) (*Artifact, error)
// An Artifact is a file or a directory that is created when using the `-a / --artifact` flag.
// Each artifact can depend on other artifacts, and can be affected by 'flags' from the artifact string that describes this artifact.
// For example, the flags in the artifact string, 'targz:linux/amd64:grafana'
type ArtifactHandler interface {
Dependencies(ctx context.Context) ([]*Artifact, error)
Builder(ctx context.Context, opts *ArtifactContainerOpts) (*dagger.Container, error)
BuildFile(ctx context.Context, builder *dagger.Container, opts *ArtifactContainerOpts) (*dagger.File, error)
BuildDir(ctx context.Context, builder *dagger.Container, opts *ArtifactContainerOpts) (*dagger.Directory, error)
Publisher(ctx context.Context, opts *ArtifactContainerOpts) (*dagger.Container, error)
PublishFile(ctx context.Context, opts *ArtifactPublishFileOpts) error
PublishDir(ctx context.Context, opts *ArtifactPublishDirOpts) error
// Filename should return a deterministic file or folder name that this build will produce.
// This filename is used as a map key for caching, so implementers need to ensure that arguments or flags that affect the output
// also affect the filename to ensure that there are no collisions.
// For example, the backend for `linux/amd64` and `linux/arm64` should not both produce a `bin` folder, they should produce a
// `bin/linux-amd64` folder and a `bin/linux-arm64` folder. Callers can mount this as `bin` or whatever if they want.
Filename(ctx context.Context) (string, error)
VerifyFile(context.Context, *dagger.Client, *dagger.File) error
VerifyDirectory(context.Context, *dagger.Client, *dagger.Directory) error
}
type Artifact struct {
// ArtifactString is the artifact string provided by the user.
// If the artifact is being initialized as a dependency where an artifact string is not provided,
// then the artifactstring should be set with the parent's artifact string.
// For example, the targz artifact depends on the binary artifact. If a user requests a targz using the artifactstring
// 'targz:linux/amd64:grafana', then its dependencies should also have that ArtifactString.
// This value is really only used for logging.
ArtifactString string
Handler ArtifactHandler
// Type is the type of the artifact which is used when deciding whether to use BuildFile or BuildDir when building the artifact
Type ArtifactType
// Flags are the available list of flags that can individually contribute to the outcome of the artifact. Unlike arguments, flags are
// specific to the argument.
// For example, users can request the same argument with different flags:
// * targz:linux/amd64:grafana
// * targz:linux/amd64:grafana-enterprise
// The flags returned by this function should simply define what flags are allowed for this argument.
// A single flag can manipulate multiple options. For example, the 'boring' option modifies both the GOEXPERIMENT environment variable and ensures that the
// package is built with grafana enterprise.
// The options that the flag affects is in the flag itself. The options that the flag manipulates should be available to the callers by using the "Option" function.
// These flags are only set here so that the CLI can communicate what flags are possible.
Flags []Flag
}
// Apply applies the flag into the OptionsHandler.
// This is a good opportunity for an artifact to handle being given a Flag in a different way than just storing its options.
func (a *Artifact) Apply(f Flag, o OptionsHandler) error {
return o.Apply(f)
}