Repository: GoogleContainerTools/skaffold (Go)

Issue:
[Feature request] Allow using environment variables for the `deploy.helm.releases[].repo` field
Hi,

We are using private helm repos and it will be very helpfull to allow using Go templates for the `deploy.helm.releases[].repo` field.

### Expected behavior

We want to replace `CHARTUSER` и `CHARTPASS` from env vars.

```yaml
...
deploy:
  helm:
    releases:
      - name: release-name
        repo: https://{{.CHARTUSER}}:{{.CHARTPASS}}@charts.site.com/
        remoteChart: my-private-chart
...
```

But it returns the error:
```
Error: invalid chart URL format: https://{{.CHARTUSER}}:{{.CHARTPASS}}@charts.site.com/
```

### Actual behavior

But this configuration works fine.

```yaml
...
deploy:
  helm:
    releases:
      - name: release-name
        repo: https://myrepouser:myrepopass@charts.site.com/
        remoteChart: my-private-chart
...
```

### Information

- Skaffold version: 1.22
- Operating system: macOS
- Installed via: skaffold.dev



Discussion:
@tejal29 to do add more details on where to make these changes. 
@tejal29 I think this is already defined in https://github.com/GoogleContainerTools/skaffold/issues/5709#issuecomment-826023341 .



Patch:
diff --git a/docs/content/en/docs/environment/templating.md b/docs/content/en/docs/environment/templating.md
index 24a26be01e7..5aebb54337d 100644
--- a/docs/content/en/docs/environment/templating.md
+++ b/docs/content/en/docs/environment/templating.md
@@ -21,6 +21,7 @@ List of fields that support templating:
 * `deploy.helm.releases.setValueTemplates` (see [Deploying with helm]({{< relref "/docs/pipeline-stages/deployers#deploying-with-helm)" >}}))
 * `deploy.helm.releases.name` (see [Deploying with helm]({{< relref "/docs/pipeline-stages/deployers#deploying-with-helm)" >}}))
 * `deploy.helm.releases.namespace` (see [Deploying with helm]({{< relref "/docs/pipeline-stages/deployers#deploying-with-helm)" >}}))
+* `deploy.helm.releases[].repo` (see [Deploying with helm]({{< relref "/docs/pipeline-stages/deployers#deploying-with-helm)" >}}))
 * `deploy.helm.releases.version` (see [Deploying with helm]({{< relref "/docs/pipeline-stages/deployers#deploying-with-helm)" >}}))
 * `deploy.kubectl.defaultNamespace`
 * `deploy.kustomize.defaultNamespace`
diff --git a/pkg/skaffold/deploy/helm/helm.go b/pkg/skaffold/deploy/helm/helm.go
index edd1ab172cc..4c7c8fb3978 100644
--- a/pkg/skaffold/deploy/helm/helm.go
+++ b/pkg/skaffold/deploy/helm/helm.go
@@ -245,7 +245,12 @@ func (h *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Art
 		if err != nil {
 			return userErr(fmt.Sprintf("cannot expand chart version %q", r.Version), err)
 		}
-		m, results, err := h.deployRelease(ctx, out, releaseName, r, builds, h.bV, chartVersion)
+
+		repo, err := util.ExpandEnvTemplateOrFail(r.Repo, nil)
+		if err != nil {
+			return userErr(fmt.Sprintf("cannot expand repo %q", r.Repo), err)
+		}
+		m, results, err := h.deployRelease(ctx, out, releaseName, r, builds, h.bV, chartVersion, repo)
 		if err != nil {
 			return userErr(fmt.Sprintf("deploying %q", releaseName), err)
 		}
@@ -461,7 +466,7 @@ func (h *Deployer) PostDeployHooks(ctx context.Context, out io.Writer) error {
 }
 
 // deployRelease deploys a single release; returns the deployed manifests, and the artifacts
-func (h *Deployer) deployRelease(ctx context.Context, out io.Writer, releaseName string, r latest.HelmRelease, builds []graph.Artifact, helmVersion semver.Version, chartVersion string) ([]byte, []types.Artifact, error) {
+func (h *Deployer) deployRelease(ctx context.Context, out io.Writer, releaseName string, r latest.HelmRelease, builds []graph.Artifact, helmVersion semver.Version, chartVersion string, repo string) ([]byte, []types.Artifact, error) {
 	var err error
 	opts := installOpts{
 		releaseName: releaseName,
@@ -470,7 +475,7 @@ func (h *Deployer) deployRelease(ctx context.Context, out io.Writer, releaseName
 		force:       h.forceDeploy,
 		chartPath:   chartSource(r),
 		helmVersion: helmVersion,
-		repo:        r.Repo,
+		repo:        repo,
 		version:     chartVersion,
 	}
 


Test patch:
diff --git a/pkg/skaffold/deploy/helm/helm_test.go b/pkg/skaffold/deploy/helm/helm_test.go
index e2c8d71753f..6c576a148ff 100644
--- a/pkg/skaffold/deploy/helm/helm_test.go
+++ b/pkg/skaffold/deploy/helm/helm_test.go
@@ -132,6 +132,13 @@ var testDeployConfigVersionTemplated = latest.LegacyHelmDeploy{
 		Version:   "{{.VERSION}}",
 	}},
 }
+var testDeployConfigRepoTemplated = latest.LegacyHelmDeploy{
+	Releases: []latest.HelmRelease{{
+		Name:      "skaffold-helm",
+		ChartPath: "examples/test",
+		Repo:      "https://{{.CHARTUSER}}:{{.CHARTPASS}}@charts.helm.sh/stable",
+	}},
+}
 
 var testDeployConfigSetFiles = latest.LegacyHelmDeploy{
 	Releases: []latest.HelmRelease{{
@@ -835,6 +842,20 @@ func TestHelmDeploy(t *testing.T) {
 			builds:             testBuilds,
 			expectedNamespaces: []string{""},
 		},
+		{
+			description: "deploy with templated repo",
+			commands: testutil.
+				CmdRunWithOutput("helm version --client", version31).
+				AndRun("helm --kube-context kubecontext get all skaffold-helm --kubeconfig kubeconfig").
+				AndRun("helm --kube-context kubecontext dep build examples/test --kubeconfig kubeconfig").
+				AndRunEnv("helm --kube-context kubecontext upgrade skaffold-helm examples/test --post-renderer SKAFFOLD-BINARY --repo https://foo:bar@charts.helm.sh/stable --kubeconfig kubeconfig",
+					[]string{"SKAFFOLD_FILENAME=test.yaml", "SKAFFOLD_CMDLINE=filter --kube-context kubecontext --build-artifacts TMPFILE --kubeconfig kubeconfig"}).
+				AndRunWithOutput("helm --kube-context kubecontext get all skaffold-helm --template {{.Release.Manifest}} --kubeconfig kubeconfig", validDeployYaml),
+			env:                []string{"CHARTUSER=foo", "CHARTPASS=bar"},
+			helm:               testDeployConfigRepoTemplated,
+			builds:             testBuilds,
+			expectedNamespaces: []string{""},
+		},
 		{
 			description: "deploy with setFiles",
 			commands: testutil.