Repository: GoogleContainerTools/skaffold
Pull request #8201 (2022-12-08 03:39:47)

chore: update error message for build failure due to failed image push
<!-- Thank you for your contribution! -->

<!-- Include if applicable: -->
Fixes: #6717 <!-- tracking issues that this PR will close -->

**Description**
<!-- Describe your changes here. The more detail, the easier the review! -->
Now on build failure due to failed image push when running `skaffold dev` or `skaffold debug` etc, show the error message:
```
Build Failed. No push access to specified image repository. Try running with `--default-repo` flag. Otherwise start a local kubernetes cluster like `minikube`.
``` 

codecov[bot]: # [Codecov](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) Report
> Merging [#8201](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) (df1521b) into [main](https://codecov.io/gh/GoogleContainerTools/skaffold/commit/290280e8c6c19231e9ed5b5c027f2c01d22f75be?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) (290280e) will **decrease** coverage by `4.36%`.
> The diff coverage is `53.26%`.

```diff
@@            Coverage Diff             @@
##             main    #8201      +/-   ##
==========================================
- Coverage   70.48%   66.11%   -4.37%     
==========================================
  Files         515      601      +86     
  Lines       23150    29436    +6286     
==========================================
+ Hits        16317    19463    +3146     
- Misses       5776     8512    +2736     
- Partials     1057     1461     +404     
```


| [Impacted Files](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) | Coverage Δ | |
|---|---|---|
| [cmd/skaffold/app/cmd/completion.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvY29tcGxldGlvbi5nbw==) | `13.04% <0.00%> (-1.25%)` | :arrow_down: |
| [cmd/skaffold/app/cmd/credits/export.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvY3JlZGl0cy9leHBvcnQuZ28=) | `0.00% <0.00%> (ø)` | |
| [cmd/skaffold/app/cmd/deploy.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvZGVwbG95Lmdv) | `40.90% <0.00%> (-12.94%)` | :arrow_down: |
| [cmd/skaffold/app/cmd/test.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvdGVzdC5nbw==) | `44.44% <0.00%> (ø)` | |
| [cmd/skaffold/app/exitcode.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9leGl0Y29kZS5nbw==) | `100.00% <ø> (+6.66%)` | :arrow_up: |
| [cmd/skaffold/skaffold.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL3NrYWZmb2xkLmdv) | `0.00% <0.00%> (ø)` | |
| [cmd/skaffold/app/cmd/inspect\_tests.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvaW5zcGVjdF90ZXN0cy5nbw==) | `62.50% <14.28%> (-1.14%)` | :arrow_down: |
| [cmd/skaffold/app/cmd/render.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvcmVuZGVyLmdv) | `35.48% <18.18%> (-5.90%)` | :arrow_down: |
| [cmd/skaffold/app/cmd/lsp.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvbHNwLmdv) | `28.12% <28.12%> (ø)` | |
| [cmd/skaffold/app/cmd/run.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvcnVuLmdv) | `64.28% <33.33%> (-9.63%)` | :arrow_down: |
| ... and [396 more](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/8201/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) | |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools)


Patch:
diff --git a/docs-v2/content/en/docs/environment/templating.md b/docs-v2/content/en/docs/environment/templating.md
index dad639cf1..ac1168a21 100644
--- a/docs-v2/content/en/docs/environment/templating.md
+++ b/docs-v2/content/en/docs/environment/templating.md
@@ -37,6 +37,7 @@ List of variables that are available for templating:
 * For the `envTemplate` tagger:
   * `IMAGE_NAME` - the artifact's image name - the [image name rewriting]({{< relref "/docs/environment/image-registries.md" >}}) acts after the template is calculated
 * For Helm deployments:
-  * `IMAGE_NAME`, `IMAGE_TAG`, `IMAGE_DIGEST` - the first (by order of declaration in `build.artifacts`) artifact's image name, tag, and sha256 digest. Note: the [image name rewriting]({{< relref "/docs/environment/image-registries.md" >}}) acts after the template is calculated.
-  * `IMAGE_NAME2`, `IMAGE_TAG2`, `IMAGE_DIGEST2` - the 2nd artifact's image name, tag, and sha256 digest
-  * `IMAGE_NAMEN`, `IMAGE_TAGN`, `IMAGE_DIGESTN` - the Nth artifact's image name, tag, and sha256 digest
+  * `IMAGE_NAME`, `IMAGE_TAG`, `IMAGE_DIGEST, IMAGE_DOMAIN, IMAGE_REPO_NO_DOMAIN` - the first (by order of declaration in `build.artifacts`) artifact's image name, repo, tag, sha256 digest, registry/domain and repository w/o the registry/domain prefixed . Note: the [image name rewriting]({{< relref "/docs/environment/image-registries.md" >}}) acts after the template is calculated.
+  * `IMAGE_NAME_<artifact-name>`, `IMAGE_REPO_<artifact-name>`, `IMAGE_TAG_<artifact-name>`, `IMAGE_DIGEST_<artifact-name>` - the named artifact's image name, repo, tag, and sha256 digest. NOTE: When used in for templating all `/` and `-` chars must be changed to `_` characters as go templates do not accept `/` and `-`.
+  * `IMAGE_NAME2`, `IMAGE_REPO2`, `IMAGE_TAG2`, `IMAGE_DIGEST2` - the 2nd artifact's image name, tag, and sha256 digest
+  * `IMAGE_NAME2`, `IMAGE_REPON`, `IMAGE_TAGN`, `IMAGE_DIGESTN` - the Nth artifact's image name, tag, and sha256 digest
diff --git a/pkg/skaffold/build/build_problems.go b/pkg/skaffold/build/build_problems.go
index 1aeffa356..b5fca1619 100644
--- a/pkg/skaffold/build/build_problems.go
+++ b/pkg/skaffold/build/build_problems.go
@@ -134,10 +134,15 @@ func suggestBuildPushAccessDeniedAction(cfg interface{}) []*proto.Suggestion {
 			return append(suggestions, makeAuthSuggestionsForRepo(defaultRepo))
 		}
 	}
+	action := "Try running with `--default-repo` flag"
+	if buildCfg.Mode() != config.RunModes.Build {
+		// for `interactive` modes, also suggest user to use a local kubernetes cluster
+		action += ". Otherwise start a local kubernetes cluster like `minikube`"
+	}
 
 	return []*proto.Suggestion{{
 		SuggestionCode: proto.SuggestionCode_ADD_DEFAULT_REPO,
-		Action:         "Try running with `--default-repo` flag",
+		Action:         action,
 	}}
 }
 
diff --git a/pkg/skaffold/build/builder_mux.go b/pkg/skaffold/build/builder_mux.go
index 588b1c748..2b7a1d7c8 100644
--- a/pkg/skaffold/build/builder_mux.go
+++ b/pkg/skaffold/build/builder_mux.go
@@ -22,6 +22,7 @@ import (
 	"io"
 	"reflect"
 
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/hooks"
@@ -48,6 +49,7 @@ type Cache interface {
 type Config interface {
 	GetPipelines() []latest.Pipeline
 	DefaultRepo() *string
+	Mode() config.RunMode
 	MultiLevelRepo() *bool
 	GlobalConfig() string
 	BuildConcurrency() int


Test patch:
diff --git a/integration/build_cluster_test.go b/integration/build_cluster_test.go
index 28fd2f7d1..3fee83266 100644
--- a/integration/build_cluster_test.go
+++ b/integration/build_cluster_test.go
@@ -33,9 +33,6 @@ import (
 
 // run on GCP as this test requires a load balancer
 func TestBuildKanikoInsecureRegistry(t *testing.T) {
-	// TODO: This test shall pass once render v2 is completed.
-	t.SkipNow()
-
 	MarkIntegrationTest(t, NeedsGcp)
 
 	ns, client := SetupNamespace(t)
diff --git a/pkg/skaffold/build/build_problems_test.go b/pkg/skaffold/build/build_problems_test.go
index 256d563c6..0f0804663 100644
--- a/pkg/skaffold/build/build_problems_test.go
+++ b/pkg/skaffold/build/build_problems_test.go
@@ -52,13 +52,15 @@ func TestBuildProblems(t *testing.T) {
 	tests := []struct {
 		description string
 		context     config.ContextConfig
+		mode        config.RunMode
 		optRepo     string
 		err         error
 		expected    string
 		expectedAE  *proto.ActionableErr
 	}{
 		{
-			description: "Push access denied when neither default repo or global config is defined",
+			description: "Push access denied when neither default repo or global config is defined in `build` command",
+			mode:        config.RunModes.Build,
 			err:         fmt.Errorf("skaffold build failed: could not push image: denied: push access to resource"),
 			expected:    "Build Failed. No push access to specified image repository. Try running with `--default-repo` flag.",
 			expectedAE: &proto.ActionableErr{
@@ -70,6 +72,20 @@ func TestBuildProblems(t *testing.T) {
 				},
 				}},
 		},
+		{
+			description: "Push access denied when neither default repo or global config is defined in `dev` command",
+			mode:        config.RunModes.Dev,
+			err:         fmt.Errorf("skaffold build failed: could not push image: denied: push access to resource"),
+			expected:    "Build Failed. No push access to specified image repository. Try running with `--default-repo` flag. Otherwise start a local kubernetes cluster like `minikube`.",
+			expectedAE: &proto.ActionableErr{
+				ErrCode: proto.StatusCode_BUILD_PUSH_ACCESS_DENIED,
+				Message: "skaffold build failed: could not push image: denied: push access to resource",
+				Suggestions: []*proto.Suggestion{{
+					SuggestionCode: proto.SuggestionCode_ADD_DEFAULT_REPO,
+					Action:         "Try running with `--default-repo` flag. Otherwise start a local kubernetes cluster like `minikube`",
+				},
+				}},
+		},
 		{
 			description: "Push access denied when default repo is defined",
 			optRepo:     "gcr.io/test",
@@ -188,7 +204,7 @@ func TestBuildProblems(t *testing.T) {
 				pc.AddPhaseProblems(constants.Build, problems)
 				return pc
 			})
-			cfg := mockConfig{optRepo: test.optRepo}
+			cfg := mockConfig{optRepo: test.optRepo, mode: test.mode}
 			actual := sErrors.ShowAIError(&cfg, test.err)
 			t.CheckDeepEqual(test.expected, actual.Error())
 			actualAE := sErrors.ActionableErr(&cfg, constants.Build, test.err)
diff --git a/pkg/skaffold/build/builder_mux_test.go b/pkg/skaffold/build/builder_mux_test.go
index 05077afe7..fb454c71f 100644
--- a/pkg/skaffold/build/builder_mux_test.go
+++ b/pkg/skaffold/build/builder_mux_test.go
@@ -22,6 +22,7 @@ import (
 	"io"
 	"testing"
 
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
@@ -191,11 +192,13 @@ func TestGetConcurrency(t *testing.T) {
 
 type mockConfig struct {
 	pipelines []latest.Pipeline
+	mode      config.RunMode
 	optRepo   string
 }
 
 func (m *mockConfig) GetPipelines() []latest.Pipeline { return m.pipelines }
 func (m *mockConfig) GlobalConfig() string            { return "" }
+func (m *mockConfig) Mode() config.RunMode            { return m.mode }
 func (m *mockConfig) DefaultRepo() *string {
 	if m.optRepo != "" {
 		return &m.optRepo