feat(build): --no-cache build option (#516)

* feat: add --no-cache option to build subcommand

* docs: no cache docs

* refactor(buildkit): remove no-cache build option

* The no-cache option is no longer utilized in the BuildKit frontend logic.
* Updated documentation to reflect the removal of this parameter.

Generated-by: aiautocommit
This commit is contained in:
Michael Bianco
2026-07-21 15:25:25 -06:00
committed by GitHub
parent 94e3a74375
commit ba4ff74fbc
6 changed files with 69 additions and 2 deletions
+2
View File
@@ -61,6 +61,7 @@ type BuildWithBuildkitClientOptions struct {
ExportCache []string
CacheKey string
GitHubToken string
NoCache bool
}
func BuildWithBuildkitClient(appDir string, plan *plan.BuildPlan, opts BuildWithBuildkitClientOptions) error {
@@ -103,6 +104,7 @@ func BuildWithBuildkitClient(appDir string, plan *plan.BuildPlan, opts BuildWith
SecretsHash: opts.SecretsHash,
CacheKey: opts.CacheKey,
GitHubToken: opts.GitHubToken,
NoCache: opts.NoCache,
})
if err != nil {
return fmt.Errorf("error converting plan to LLB: %w", err)
+7 -1
View File
@@ -26,6 +26,7 @@ type BuildGraph struct {
Plan *plan.BuildPlan
Platform *specs.Platform
LocalState *llb.State
NoCache bool
githubToken string
secretsFile *llb.State
@@ -37,7 +38,7 @@ type BuildGraphOutput struct {
GraphEnv BuildEnvironment
}
func NewBuildGraph(plan *plan.BuildPlan, localState *llb.State, cacheStore *BuildKitCacheStore, secretsHash string, platform *specs.Platform, githubToken string) (*BuildGraph, error) {
func NewBuildGraph(plan *plan.BuildPlan, localState *llb.State, cacheStore *BuildKitCacheStore, secretsHash string, platform *specs.Platform, githubToken string, noCache bool) (*BuildGraph, error) {
var secretsFile *llb.State
if secretsHash != "" {
st := llb.Scratch().File(llb.Mkfile("/secrets-hash", 0644, []byte(secretsHash)), llb.WithCustomName("[railpack] secrets hash"))
@@ -51,6 +52,7 @@ func NewBuildGraph(plan *plan.BuildPlan, localState *llb.State, cacheStore *Buil
Plan: plan,
Platform: platform,
LocalState: localState,
NoCache: noCache,
githubToken: githubToken,
secretsFile: secretsFile,
@@ -254,6 +256,10 @@ func (g *BuildGraph) convertExecCommandToLLB(node *StepNode, cmd plan.ExecComman
opts = append(opts, llb.WithCustomName(cmd.CustomName))
}
if g.NoCache {
opts = append(opts, llb.IgnoreCache)
}
// These options mount all secrets as environments variables
// We want to add all secrets to all commands, even if they are not specified in the step
// Note: This does mean that if the number of secrets change, then the cache for every step will be invalidated
+49
View File
@@ -0,0 +1,49 @@
package build_llb
import (
"testing"
"github.com/moby/buildkit/client/llb"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/railwayapp/railpack/core/plan"
"github.com/stretchr/testify/require"
)
func TestBuildGraphNoCache(t *testing.T) {
p := &plan.BuildPlan{
Steps: []plan.Step{
{
Name: "test",
Caches: []string{"test-cache"},
},
},
Caches: map[string]*plan.Cache{
"test-cache": {
Directory: "/root/.cache",
},
},
}
localState := llb.Local("context")
cacheStore := NewBuildKitCacheStore("")
platform := specs.Platform{OS: "linux", Architecture: "amd64"}
t.Run("with NoCache=false", func(t *testing.T) {
g, err := NewBuildGraph(p, &localState, cacheStore, "", &platform, "", false)
require.NoError(t, err)
require.False(t, g.NoCache)
require.False(t, isCacheDisabled("test-cache"))
})
t.Run("with NoCache=true", func(t *testing.T) {
g, err := NewBuildGraph(p, &localState, cacheStore, "", &platform, "", true)
require.NoError(t, err)
require.True(t, g.NoCache)
// NoCache should NOT affect if caches are enabled or not, it just affects the layer cache
require.False(t, isCacheDisabled("test-cache"))
opts, err := g.getCacheMountOptions([]string{"test-cache"})
require.NoError(t, err)
require.Len(t, opts, 1)
})
}
+4 -1
View File
@@ -28,6 +28,9 @@ type ConvertPlanOptions struct {
// Token used to make authenticated API requests to GitHub to increase rate limits
GitHubToken string
// Do not use cache when building
NoCache bool
}
const (
@@ -45,7 +48,7 @@ func ConvertPlanToLLB(plan *p.BuildPlan, opts ConvertPlanOptions) (*llb.State, *
)
cacheStore := build_llb.NewBuildKitCacheStore(opts.CacheKey)
graph, err := build_llb.NewBuildGraph(plan, &localState, cacheStore, opts.SecretsHash, &platform, opts.GitHubToken)
graph, err := build_llb.NewBuildGraph(plan, &localState, cacheStore, opts.SecretsHash, &platform, opts.GitHubToken, opts.NoCache)
if err != nil {
return nil, nil, err
}
+6
View File
@@ -59,6 +59,11 @@ var BuildCommand = &cli.Command{
Name: "cache-to",
Usage: "Cache export destinations",
},
&cli.BoolFlag{
Name: "no-cache",
Usage: "Do not use cache when building",
Value: false,
},
&cli.BoolFlag{
Name: "dump-llb",
Hidden: true,
@@ -114,6 +119,7 @@ var BuildCommand = &cli.Command{
Secrets: env.Variables,
Platform: platformStr,
GitHubToken: os.Getenv("GITHUB_TOKEN"),
NoCache: cmd.Bool("no-cache"),
})
if err != nil {
return cli.Exit(err, 1)
+1
View File
@@ -42,6 +42,7 @@ railpack build [options] DIRECTORY
| `--cache-key` | Unique id to prefix to cache keys | |
| `--cache-from` | External cache sources (same as docker buildx). e.g. type=registry,ref=... | |
| `--cache-to` | Cache export destinations (same as docker buildx). e.g. type=registry,ref=... | |
| `--no-cache` | Do not use cache when building (boolean flag) | `false` |
`railpack build` uses credentials from your Docker CLI config
(`$DOCKER_CONFIG`, default `~/.docker/config.json`) so BuildKit can pull or