Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,10 +400,14 @@ images:
env: GITHUB_TOKEN
# - id: npmrc
# file: ./.npmrc
cache_from: # buildx --cache-from sources
cache_from: # buildx --cache-from sources; empty-rendering
# entries are skipped, so an env-templated value enables caching only
# where the environment provides it (e.g. CI) and stays inert locally
- "type=registry,ref=ghcr.io/acme/myapp:buildcache"
cache_to: # buildx --cache-to destinations
# - '{{ index .Env "STEVEDORE_CACHE_FROM" }}'
cache_to: # buildx --cache-to destinations (same skip rule)
- "type=registry,ref=ghcr.io/acme/myapp:buildcache,mode=max"
# - '{{ index .Env "STEVEDORE_CACHE_TO" }}'
paths: # change-detection globs (see Monorepos); ** supported
- "services/myapp/**"
project: "" # or a .csproj to auto-derive paths from its graph
Expand Down
11 changes: 9 additions & 2 deletions internal/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,18 @@ func Build(r *run.Runner, s Spec) (string, error) {
for _, sec := range s.Secrets {
args = append(args, "--secret", secretArg(sec))
}
// Empty entries (e.g. a {{ index .Env "STEVEDORE_CACHE_TO" }} template rendering to
// "" outside CI) are skipped, so configs can gate caching on environment
// presence without breaking local builds.
for _, c := range s.CacheFrom {
args = append(args, "--cache-from", c)
if c != "" {
args = append(args, "--cache-from", c)
}
}
for _, c := range s.CacheTo {
args = append(args, "--cache-to", c)
if c != "" {
args = append(args, "--cache-to", c)
}
}
switch {
case s.Push:
Expand Down
35 changes: 35 additions & 0 deletions internal/builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package builder
import (
"os"
"path/filepath"
"strings"
"testing"

"github.com/blairham/stevedore/internal/config"
"github.com/blairham/stevedore/internal/run"
)

func TestSecretArg(t *testing.T) {
Expand Down Expand Up @@ -61,3 +63,36 @@ func TestReadDigest(t *testing.T) {
t.Error("expected error for missing file")
}
}

func TestBuildSkipsEmptyCacheEntries(t *testing.T) {
stderr, err := os.CreateTemp(t.TempDir(), "stderr")
if err != nil {
t.Fatal(err)
}
r := &run.Runner{DryRun: true, Stderr: stderr}

_, err = Build(r, Spec{
Dockerfile: "Dockerfile",
Context: ".",
CacheFrom: []string{"", "type=gha,scope=build"},
CacheTo: []string{""},
})
if err != nil {
t.Fatal(err)
}

out, err := os.ReadFile(stderr.Name())
if err != nil {
t.Fatal(err)
}
cmd := string(out)
if !strings.Contains(cmd, "--cache-from type=gha,scope=build") {
t.Errorf("non-empty cache_from entry missing from command: %s", cmd)
}
if strings.Count(cmd, "--cache-from") != 1 {
t.Errorf("empty cache_from entry should be skipped: %s", cmd)
}
if strings.Contains(cmd, "--cache-to") {
t.Errorf("empty cache_to entry should be skipped: %s", cmd)
}
}
6 changes: 4 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,14 @@ type Image struct {

// CacheFrom lists buildx --cache-from sources, e.g.
// "type=registry,ref=ghcr.io/acme/myapp:buildcache". Values may contain
// templates.
// templates; entries that render to an empty string are skipped, so a
// value like '{{ index .Env "STEVEDORE_CACHE_FROM" }}' enables caching only where
// the environment provides it (e.g. CI) without breaking local builds.
CacheFrom []string `yaml:"cache_from"`

// CacheTo lists buildx --cache-to destinations, e.g.
// "type=registry,ref=ghcr.io/acme/myapp:buildcache,mode=max". Values may
// contain templates.
// contain templates; empty-rendering entries are skipped (see CacheFrom).
CacheTo []string `yaml:"cache_to"`

// ExtraFlags are passed verbatim to `docker buildx build`.
Expand Down
Loading