Open kminehart opened 1 year ago
You mean basically something like go run ./cmd produce file://$PWD/output.deb
which then determines based on the output destination what needs to be done? In this case:
?
I'm thinking that somewhere in the application we have a list of artifacts and the pipelines for how they're produced.
A simple example / just sort of thinking out loud here.
package artifacts
type Artifact struct {
Dependencies []Artifact
// ... and other stuff, like a func that returns a dagger.File or dagger.Directory?
}
var Binaries = Artifact{...}
var Frontend = Artifact{...}
var Tarball = Artifact{Dependencies: []Artifact{Binaries,Frontend}}
var Deb = Artifact{
Dependencies: []string{Tarball},
}
var Artifacts = []Artifact{
Binaries,
Deb
Tarball,
Docker ...,
RPM...,
}
go run ./cmd --destination=file://dist --deb --docker --rpm
or
go ruin ./cmd --destination=file://dist --deb --docker --dry-run
Okidoki, will start working on this.
Pausing work on the PR for now until the current implementation has been verified. I'll then update the artifact-based implementation.
I've been thinking about this a little more lately and this could also really help with the containers/
and packages/
file getting huge and complicated.
I think we should start with what we want the interface to look like and then we work backwards.
The goals of the interface are:
Design:
Other CLI requirements:
deb:amd64
and I've also requested a targz:amd64
then it shouldgrafana-build \
-a deb:arm64 \
-a targz:arm64 \
-a targz:amd64 \
-a targz:plan9 \
--go-image=golang:1.21-alpine \
--destination=gs://grafana-prerelease
OR
grafana-build -i build.json \
--destination=gs://grafana-prerelease
{
"artifacts": [
"targz:amd64",
"targz:arm64",
"targz:plan9",
"deb:arm64"
],
"goImage": "golang:1.21-alpine"
}
As for the code, I think we can make things pretty isolated if we categorize them by artifact, like so:
type (
ContainerFunc func(d *dagger.Client, platform dagger.Platform, args []Argument) *dagger.Container
BuildFunc func(ctx context.Context, d *dagger.Client, c *dagger.Container, args []Argument) (*dagger.File, error)
PublishFunc func(ctx context.Context, d *dagger.Client, c *dagger.Container, args []Argument) error
)
type Artifact struct {
Name string
Requires []*Artifact
Arguments []Argument
Builder ContainerFunc
BuildFunc BuildFunc
Publisher ContainerFunc
PublishFunc PublishFunc
}
This will give us lots of opportunities to make more reusable functions / containers and categorize dagger code around the artifact that uses it.
Could we have -i
AND -a
? I'd like to be able to create a config file such as the build.json
described, but I would also like to run the commands declaratively for a one-off local build.
yeah I'm thinking we can do a hierarchy of values. Where the argument is available: Environment variables > CLI flags > config file
@kminehart I assume the status on this is that it was never started is that correct?
"Declarative"?
A declarative model allows users to define the end state rather than the process to reach that end state.
In a way, we are being somewhat declarative: to build
grafana
, andenterprise
together, you supply both flags, which is declarative.Problem
deb
command, one would need to run thepackage
command first.--dry-run
can't be easily accomplished.Solution
This problem could be solved by having a declarative API to define artifacts and how they're built.
Instead of defining a series of commands that do something, there should be one entrypoint, with only flags define the artifacts, and then modifiers that universally affect the entire pipeline.
Requirements
--dry-run
flag to view a list of artifacts that will be built and where they will end up.