Skip to content

Commit dacaf2b

Browse files
committed
add skaffold build --push flag
What is the problem being solved? Fixes GoogleContainerTools#5667, adding --push flag to skaffold build. This --push flag overrides any skaffold.yaml "build.local.push: false" configuration for a build allowing easier artifact pushing after local dev without having to modify yaml configuration. Why is this the best approach? This approach follows the style and convention for adding a flag that has been used prior for adding a flag used by a single command, similar to GoogleContainerTools#4039. Additionally this approach does not change the skaffold build default push behaviour to be false, instead only taking precendence when the --push flag is set true which is the intended use case. What other approaches did you consider? N/A What side effects will this approach have? The addition of this single flag should not have side effects on skaffold functionally outside of --push, the default behavior for skaffold build will be preserved w/o --push specified. What future work remains to be done? N/A
1 parent ca4886f commit dacaf2b

File tree

6 files changed

+122
-2
lines changed

6 files changed

+122
-2
lines changed

cmd/skaffold/app/cmd/build.go

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func NewCmdBuild() *cobra.Command {
5555
{Value: buildFormatFlag, Name: "output", Shorthand: "o", DefValue: defaultBuildFormatTemplate, Usage: "Used in conjunction with --quiet flag. " + buildFormatFlag.Usage()},
5656
{Value: &buildOutputFlag, Name: "file-output", DefValue: "", Usage: "Filename to write build images to"},
5757
{Value: &opts.DryRun, Name: "dry-run", DefValue: false, Usage: "Don't build images, just compute the tag for each artifact.", IsEnum: true},
58+
{Value: &opts.PushImages, Name: "push", DefValue: nil, Usage: "Push the built images to the specified image repository.", IsEnum: true, NoOptDefVal: "true"},
5859
}).
5960
WithHouseKeepingMessages().
6061
NoArgs(doBuild)

docs/content/en/docs/references/cli/_index.md

+2
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ Options:
202202
-o, --output={{json .}}: Used in conjunction with --quiet flag. Format output with go-template. For full struct documentation, see https://godoc.org/github.com/GoogleContainerTools/skaffold/cmd/skaffold/app/flags#BuildOutput
203203
-p, --profile=[]: Activate profiles by name (prefixed with `-` to disable a profile)
204204
--profile-auto-activation=true: Set to false to disable profile auto activation
205+
--push=: Push the built images to the specified image repository.
205206
-q, --quiet=false: Suppress the build output and print image built on success. See --output to format output.
206207
--remote-cache-dir='': Specify the location of the git repositories cache (default $HOME/.skaffold/repos)
207208
--rpc-http-port=50052: tcp port to expose event REST API over HTTP
@@ -239,6 +240,7 @@ Env vars:
239240
* `SKAFFOLD_OUTPUT` (same as `--output`)
240241
* `SKAFFOLD_PROFILE` (same as `--profile`)
241242
* `SKAFFOLD_PROFILE_AUTO_ACTIVATION` (same as `--profile-auto-activation`)
243+
* `SKAFFOLD_PUSH` (same as `--push`)
242244
* `SKAFFOLD_QUIET` (same as `--quiet`)
243245
* `SKAFFOLD_REMOTE_CACHE_DIR` (same as `--remote-cache-dir`)
244246
* `SKAFFOLD_RPC_HTTP_PORT` (same as `--rpc-http-port`)

pkg/skaffold/config/options.go

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ type SkaffoldOptions struct {
7979
DigestSource string
8080
WatchPollInterval int
8181
DefaultRepo StringOrUndefined
82+
PushImages BoolOrUndefined
8283
CustomLabels []string
8384
TargetImages []string
8485
Profiles []string

pkg/skaffold/runner/build_deploy_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ import (
2424

2525
"k8s.io/client-go/tools/clientcmd/api"
2626

27+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
2728
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
2829
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/client"
2930
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
31+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
3032
"github.com/GoogleContainerTools/skaffold/testutil"
3133
)
3234

@@ -171,6 +173,22 @@ func TestBuildDryRun(t *testing.T) {
171173
})
172174
}
173175

176+
func TestBuildPushFlag(t *testing.T) {
177+
testutil.Run(t, "", func(t *testutil.T) {
178+
testBench := &TestBench{}
179+
artifacts := []*latest.Artifact{
180+
{ImageName: "img1"},
181+
{ImageName: "img2"},
182+
}
183+
runner := createRunner(t, testBench, nil, artifacts, nil)
184+
runner.runCtx.Opts.PushImages = config.NewBoolOrUndefined(util.BoolPtr(true))
185+
186+
_, err := runner.Build(context.Background(), ioutil.Discard, artifacts)
187+
188+
t.CheckNoError(err)
189+
})
190+
}
191+
174192
func TestDigestSources(t *testing.T) {
175193
artifacts := []*latest.Artifact{
176194
{ImageName: "img1"},

pkg/skaffold/runner/new.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,15 @@ func isImageLocal(runCtx *runcontext.RunContext, imageName string) (bool, error)
188188

189189
cl := runCtx.GetCluster()
190190
var pushImages bool
191-
if pipeline.Build.LocalBuild.Push == nil {
191+
192+
switch {
193+
case runCtx.Opts.PushImages.Value() != nil:
194+
logrus.Debugf("push value set via skaffold build --push flag, --push=%t", *runCtx.Opts.PushImages.Value())
195+
pushImages = *runCtx.Opts.PushImages.Value()
196+
case pipeline.Build.LocalBuild.Push == nil:
192197
pushImages = cl.PushImages
193198
logrus.Debugf("push value not present, defaulting to %t because cluster.PushImages is %t", pushImages, cl.PushImages)
194-
} else {
199+
default:
195200
pushImages = *pipeline.Build.LocalBuild.Push
196201
}
197202
return !pushImages, nil

pkg/skaffold/runner/new_test.go

+93
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"reflect"
2121
"testing"
2222

23+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
2324
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy"
2425
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy/helm"
2526
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy/kpt"
@@ -238,3 +239,95 @@ func TestGetDefaultDeployer(tOuter *testing.T) {
238239
}
239240
})
240241
}
242+
243+
func TestIsImageLocal(t *testing.T) {
244+
tests := []struct {
245+
description string
246+
pushImagesFlagVal *bool
247+
localBuildConfig *bool
248+
expected bool
249+
}{
250+
{
251+
description: "skaffold build --push=nil, pipeline.Build.LocalBuild.Push=nil",
252+
pushImagesFlagVal: nil,
253+
localBuildConfig: nil,
254+
expected: false,
255+
},
256+
{
257+
description: "skaffold build --push=nil, pipeline.Build.LocalBuild.Push=false",
258+
pushImagesFlagVal: nil,
259+
localBuildConfig: util.BoolPtr(false),
260+
expected: true,
261+
},
262+
{
263+
description: "skaffold build --push=nil, pipeline.Build.LocalBuild.Push=true",
264+
pushImagesFlagVal: nil,
265+
localBuildConfig: util.BoolPtr(true),
266+
expected: false,
267+
},
268+
{
269+
description: "skaffold build --push=false, pipeline.Build.LocalBuild.Push=nil",
270+
pushImagesFlagVal: util.BoolPtr(false),
271+
localBuildConfig: nil,
272+
expected: true,
273+
},
274+
{
275+
description: "skaffold build --push=false, pipeline.Build.LocalBuild.Push=false",
276+
pushImagesFlagVal: util.BoolPtr(false),
277+
localBuildConfig: util.BoolPtr(false),
278+
expected: true,
279+
},
280+
{
281+
description: "skaffold build --push=false, pipeline.Build.LocalBuild.Push=true",
282+
pushImagesFlagVal: util.BoolPtr(false),
283+
localBuildConfig: util.BoolPtr(true),
284+
expected: true,
285+
},
286+
{
287+
description: "skaffold build --push=true, pipeline.Build.LocalBuild.Push=nil",
288+
pushImagesFlagVal: util.BoolPtr(true),
289+
localBuildConfig: nil,
290+
expected: false,
291+
},
292+
{
293+
description: "skaffold build --push=true, pipeline.Build.LocalBuild.Push=nil",
294+
pushImagesFlagVal: util.BoolPtr(true),
295+
localBuildConfig: util.BoolPtr(false),
296+
expected: false,
297+
},
298+
{
299+
description: "skaffold build --push=true, pipeline.Build.LocalBuild.Push=nil",
300+
pushImagesFlagVal: util.BoolPtr(true),
301+
localBuildConfig: util.BoolPtr(true),
302+
expected: false,
303+
},
304+
}
305+
imageName := "testImage"
306+
for _, test := range tests {
307+
testutil.Run(t, test.description, func(t *testutil.T) {
308+
rctx := &runcontext.RunContext{
309+
Cluster: config.Cluster{
310+
PushImages: true,
311+
},
312+
Opts: config.SkaffoldOptions{
313+
PushImages: config.NewBoolOrUndefined(test.pushImagesFlagVal),
314+
},
315+
Pipelines: runcontext.NewPipelines([]latest.Pipeline{{
316+
Build: latest.BuildConfig{
317+
Artifacts: []*latest.Artifact{
318+
{ImageName: imageName},
319+
},
320+
BuildType: latest.BuildType{
321+
LocalBuild: &latest.LocalBuild{
322+
Push: test.localBuildConfig,
323+
},
324+
},
325+
},
326+
}})}
327+
output, _ := isImageLocal(rctx, imageName)
328+
if output != test.expected {
329+
t.Errorf("isImageLocal output was %t, expected: %t", output, test.expected)
330+
}
331+
})
332+
}
333+
}

0 commit comments

Comments
 (0)