Commit b18e12d8 authored by Yann Hodique's avatar Yann Hodique Committed by GitHub

feat(kurtosis-devnet): deduplicate all builds (#13705)

Avoid rebuilding the same artifacts, as long as the inputs are the
same. This enables us to be as careless as we want on the template
definition side, and still build everything only once.
parent 83187273
...@@ -96,14 +96,9 @@ func (m *Main) localContractArtifactsOption(dir string) tmpl.TemplateContextOpti ...@@ -96,14 +96,9 @@ func (m *Main) localContractArtifactsOption(dir string) tmpl.TemplateContextOpti
return tmpl.WithFunction("localContractArtifacts", func(layer string) (string, error) { return tmpl.WithFunction("localContractArtifacts", func(layer string) (string, error) {
bundlePath := contractsBundlePath(layer) bundlePath := contractsBundlePath(layer)
// we're in a temp dir, so we can skip the build if the file already
// exists: it'll be the same file! In particular, since we're ignoring
// layer for now, skip the 2nd build.
if _, err := os.Stat(bundlePath); err != nil {
if err := contractBuilder.Build(layer, bundlePath); err != nil { if err := contractBuilder.Build(layer, bundlePath); err != nil {
return "", err return "", err
} }
}
log.Printf("%s: contract artifacts available at: %s\n", layer, contractsURL) log.Printf("%s: contract artifacts available at: %s\n", layer, contractsURL)
return contractsURL, nil return contractsURL, nil
......
...@@ -17,6 +17,8 @@ type ContractBuilder struct { ...@@ -17,6 +17,8 @@ type ContractBuilder struct {
// Dry run mode // Dry run mode
dryRun bool dryRun bool
builtContracts map[string]interface{}
} }
const ( const (
...@@ -55,6 +57,7 @@ func NewContractBuilder(opts ...ContractBuilderOptions) *ContractBuilder { ...@@ -55,6 +57,7 @@ func NewContractBuilder(opts ...ContractBuilderOptions) *ContractBuilder {
baseDir: ".", baseDir: ".",
cmdTemplate: defaultContractTemplate, cmdTemplate: defaultContractTemplate,
dryRun: false, dryRun: false,
builtContracts: make(map[string]interface{}),
} }
for _, opt := range opts { for _, opt := range opts {
...@@ -66,17 +69,21 @@ func NewContractBuilder(opts ...ContractBuilderOptions) *ContractBuilder { ...@@ -66,17 +69,21 @@ func NewContractBuilder(opts ...ContractBuilderOptions) *ContractBuilder {
// templateData holds the data for the command template // templateData holds the data for the command template
type contractTemplateData struct { type contractTemplateData struct {
Layer string
BundlePath string BundlePath string
} }
// Build executes the contract build command // Build executes the contract build command
func (b *ContractBuilder) Build(layer string, bundlePath string) error { func (b *ContractBuilder) Build(_layer string, bundlePath string) error {
// since we ignore layer for now, we can skip the build if the file already
// exists: it'll be the same file!
if _, ok := b.builtContracts[bundlePath]; ok {
return nil
}
log.Printf("Building contracts bundle: %s", bundlePath) log.Printf("Building contracts bundle: %s", bundlePath)
// Prepare template data // Prepare template data
data := contractTemplateData{ data := contractTemplateData{
Layer: layer,
BundlePath: bundlePath, BundlePath: bundlePath,
} }
...@@ -97,5 +104,6 @@ func (b *ContractBuilder) Build(layer string, bundlePath string) error { ...@@ -97,5 +104,6 @@ func (b *ContractBuilder) Build(layer string, bundlePath string) error {
} }
} }
b.builtContracts[bundlePath] = struct{}{}
return nil return nil
} }
...@@ -16,6 +16,8 @@ type DockerBuilder struct { ...@@ -16,6 +16,8 @@ type DockerBuilder struct {
cmdTemplate *template.Template cmdTemplate *template.Template
// Dry run mode // Dry run mode
dryRun bool dryRun bool
builtImages map[string]string
} }
const cmdTemplateStr = "just {{.ProjectName}}-image {{.ImageTag}}" const cmdTemplateStr = "just {{.ProjectName}}-image {{.ImageTag}}"
...@@ -52,6 +54,7 @@ func NewDockerBuilder(opts ...DockerBuilderOptions) *DockerBuilder { ...@@ -52,6 +54,7 @@ func NewDockerBuilder(opts ...DockerBuilderOptions) *DockerBuilder {
baseDir: ".", baseDir: ".",
cmdTemplate: defaultCmdTemplate, cmdTemplate: defaultCmdTemplate,
dryRun: false, dryRun: false,
builtImages: make(map[string]string),
} }
for _, opt := range opts { for _, opt := range opts {
...@@ -69,6 +72,10 @@ type templateData struct { ...@@ -69,6 +72,10 @@ type templateData struct {
// Build executes the docker build command for the given project and image tag // Build executes the docker build command for the given project and image tag
func (b *DockerBuilder) Build(projectName, imageTag string) (string, error) { func (b *DockerBuilder) Build(projectName, imageTag string) (string, error) {
if builtImage, ok := b.builtImages[projectName]; ok {
return builtImage, nil
}
log.Printf("Building docker image for project: %s with tag: %s", projectName, imageTag) log.Printf("Building docker image for project: %s with tag: %s", projectName, imageTag)
// Prepare template data // Prepare template data
data := templateData{ data := templateData{
...@@ -94,5 +101,6 @@ func (b *DockerBuilder) Build(projectName, imageTag string) (string, error) { ...@@ -94,5 +101,6 @@ func (b *DockerBuilder) Build(projectName, imageTag string) (string, error) {
} }
// Return the image tag as confirmation of successful build // Return the image tag as confirmation of successful build
b.builtImages[projectName] = imageTag
return imageTag, nil return imageTag, nil
} }
...@@ -13,6 +13,8 @@ type PrestateBuilder struct { ...@@ -13,6 +13,8 @@ type PrestateBuilder struct {
baseDir string baseDir string
cmdTemplate *template.Template cmdTemplate *template.Template
dryRun bool dryRun bool
builtPrestates map[string]interface{}
} }
const ( const (
...@@ -51,6 +53,7 @@ func NewPrestateBuilder(opts ...PrestateBuilderOptions) *PrestateBuilder { ...@@ -51,6 +53,7 @@ func NewPrestateBuilder(opts ...PrestateBuilderOptions) *PrestateBuilder {
baseDir: ".", baseDir: ".",
cmdTemplate: defaultPrestateTemplate, cmdTemplate: defaultPrestateTemplate,
dryRun: false, dryRun: false,
builtPrestates: make(map[string]interface{}),
} }
for _, opt := range opts { for _, opt := range opts {
...@@ -67,6 +70,10 @@ type prestateTemplateData struct { ...@@ -67,6 +70,10 @@ type prestateTemplateData struct {
// Build executes the prestate build command // Build executes the prestate build command
func (b *PrestateBuilder) Build(path string) error { func (b *PrestateBuilder) Build(path string) error {
if _, ok := b.builtPrestates[path]; ok {
return nil
}
log.Printf("Building prestate: %s", path) log.Printf("Building prestate: %s", path)
// Prepare template data // Prepare template data
...@@ -91,5 +98,6 @@ func (b *PrestateBuilder) Build(path string) error { ...@@ -91,5 +98,6 @@ func (b *PrestateBuilder) Build(path string) error {
} }
} }
b.builtPrestates[path] = struct{}{}
return nil return nil
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment