Repository: GoogleContainerTools/skaffold
Pull request #7698 (2022-07-28 02:16:53)

refactor: change ptr *manifest.ManifestByConfig to struct
while working on #7697, I realized Render returned a ptr *manifest.ManifestByConfig. 

This return struct does not need to be a pointer. 
```
type ManifestListByConfig struct {
	manifests map[string]ManifestList

	// configNames is use to preserve the order of the configs added to the map, and be able to go through them in the added order.
	configNames []string
}
```
Both the fields in struct are slice and a map. Maps and slices are both reference types and hence keys should be updated in the struct


Patch:
diff --git a/pkg/skaffold/deploy/cloudrun/deploy.go b/pkg/skaffold/deploy/cloudrun/deploy.go
index 949e09e28..6fff6fcea 100644
--- a/pkg/skaffold/deploy/cloudrun/deploy.go
+++ b/pkg/skaffold/deploy/cloudrun/deploy.go
@@ -80,7 +80,7 @@ func NewDeployer(cfg Config, labeller *label.DefaultLabeller, crDeploy *latest.C
 }
 
 // Deploy creates a Cloud Run service using the provided manifest.
-func (d *Deployer) Deploy(ctx context.Context, out io.Writer, artifacts []graph.Artifact, manifestsByConfig *manifest.ManifestListByConfig) error {
+func (d *Deployer) Deploy(ctx context.Context, out io.Writer, artifacts []graph.Artifact, manifestsByConfig manifest.ManifestListByConfig) error {
 	manifests := manifestsByConfig.GetForConfig(d.ConfigName())
 
 	for _, manifest := range manifests {
@@ -101,7 +101,7 @@ func (d *Deployer) Dependencies() ([]string, error) {
 }
 
 // Cleanup deletes the created Cloud Run services
-func (d *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, byConfig *manifest.ManifestListByConfig) error {
+func (d *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, byConfig manifest.ManifestListByConfig) error {
 	return d.deleteRunService(ctx, out, dryRun, byConfig.GetForConfig(d.configName))
 }
 
diff --git a/pkg/skaffold/deploy/deploy.go b/pkg/skaffold/deploy/deploy.go
index 3456796e1..f7db5afa3 100644
--- a/pkg/skaffold/deploy/deploy.go
+++ b/pkg/skaffold/deploy/deploy.go
@@ -34,14 +34,14 @@ import (
 type Deployer interface {
 	// Deploy should ensure that the build results are deployed to the Kubernetes
 	// cluster.
-	Deploy(context.Context, io.Writer, []graph.Artifact, *manifest.ManifestListByConfig) error
+	Deploy(context.Context, io.Writer, []graph.Artifact, manifest.ManifestListByConfig) error
 
 	// Dependencies returns a list of files that the deployer depends on.
 	// In dev mode, a redeploy will be triggered
 	Dependencies() ([]string, error)
 
 	// Cleanup deletes what was deployed by calling Deploy.
-	Cleanup(context.Context, io.Writer, bool, *manifest.ManifestListByConfig) error
+	Cleanup(context.Context, io.Writer, bool, manifest.ManifestListByConfig) error
 
 	// GetDebugger returns a Deployer's implementation of a Debugger
 	GetDebugger() debug.Debugger
diff --git a/pkg/skaffold/deploy/deploy_mux.go b/pkg/skaffold/deploy/deploy_mux.go
index 953314b07..ff1a84a24 100644
--- a/pkg/skaffold/deploy/deploy_mux.go
+++ b/pkg/skaffold/deploy/deploy_mux.go
@@ -107,7 +107,7 @@ func (m DeployerMux) ConfigName() string {
 	return ""
 }
 
-func (m DeployerMux) Deploy(ctx context.Context, w io.Writer, as []graph.Artifact, l *manifest.ManifestListByConfig) error {
+func (m DeployerMux) Deploy(ctx context.Context, w io.Writer, as []graph.Artifact, l manifest.ManifestListByConfig) error {
 	for i, deployer := range m.deployers {
 		eventV2.DeployInProgress(i)
 		w, ctx = output.WithEventContext(ctx, w, constants.Deploy, strconv.Itoa(i))
@@ -160,7 +160,7 @@ func (m DeployerMux) Dependencies() ([]string, error) {
 	return deps.ToList(), nil
 }
 
-func (m DeployerMux) Cleanup(ctx context.Context, w io.Writer, dryRun bool, manifestsByConfig *manifest.ManifestListByConfig) error {
+func (m DeployerMux) Cleanup(ctx context.Context, w io.Writer, dryRun bool, manifestsByConfig manifest.ManifestListByConfig) error {
 	for _, deployer := range m.deployers {
 		ctx, endTrace := instrumentation.StartTrace(ctx, "Cleanup")
 		if dryRun {
diff --git a/pkg/skaffold/deploy/docker/deploy.go b/pkg/skaffold/deploy/docker/deploy.go
index 1226eb069..f6dad5b82 100644
--- a/pkg/skaffold/deploy/docker/deploy.go
+++ b/pkg/skaffold/deploy/docker/deploy.go
@@ -117,7 +117,7 @@ func (d *Deployer) TrackContainerFromBuild(artifact graph.Artifact, container tr
 
 // Deploy deploys built artifacts by creating containers in the local docker daemon
 // from each artifact's image.
-func (d *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, _ *manifest.ManifestListByConfig) error {
+func (d *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, _ manifest.ManifestListByConfig) error {
 	var err error
 	d.once.Do(func() {
 		err = d.client.NetworkCreate(ctx, d.network)
@@ -295,7 +295,7 @@ func (d *Deployer) Dependencies() ([]string, error) {
 	return nil, nil
 }
 
-func (d *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, _ *manifest.ManifestListByConfig) error {
+func (d *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, _ manifest.ManifestListByConfig) error {
 	if dryRun {
 		for _, container := range d.tracker.DeployedContainers() {
 			output.Yellow.Fprintln(out, container.ID)
diff --git a/pkg/skaffold/deploy/helm/helm.go b/pkg/skaffold/deploy/helm/helm.go
index 9dbb6c0d4..be423c7f1 100644
--- a/pkg/skaffold/deploy/helm/helm.go
+++ b/pkg/skaffold/deploy/helm/helm.go
@@ -223,7 +223,7 @@ func (h *Deployer) TrackBuildArtifacts(artifacts []graph.Artifact) {
 }
 
 // Deploy deploys the build results to the Kubernetes cluster
-func (h *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, _ *manifest.ManifestListByConfig) error {
+func (h *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, _ manifest.ManifestListByConfig) error {
 	ctx, endTrace := instrumentation.StartTrace(ctx, "Deploy", map[string]string{
 		"DeployerType": "helm",
 	})
@@ -355,7 +355,7 @@ func (h *Deployer) Dependencies() ([]string, error) {
 }
 
 // Cleanup deletes what was deployed by calling Deploy.
-func (h *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, _ *manifest.ManifestListByConfig) error {
+func (h *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, _ manifest.ManifestListByConfig) error {
 	instrumentation.AddAttributesToCurrentSpanFromContext(ctx, map[string]string{
 		"DeployerType": "helm",
 	})
diff --git a/pkg/skaffold/deploy/kpt/kpt.go b/pkg/skaffold/deploy/kpt/kpt.go
index d0e50bc96..e205be408 100644
--- a/pkg/skaffold/deploy/kpt/kpt.go
+++ b/pkg/skaffold/deploy/kpt/kpt.go
@@ -306,7 +306,7 @@ func kptfileInitIfNot(ctx context.Context, out io.Writer, k *Deployer) error {
 	return nil
 }
 
-func (k *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, _ *manifest.ManifestListByConfig) error {
+func (k *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, _ manifest.ManifestListByConfig) error {
 	if err := kptInitFunc(ctx, out, k); err != nil {
 		return err
 	}
@@ -367,7 +367,7 @@ func (k *Deployer) Dependencies() ([]string, error) {
 }
 
 // Cleanup deletes what was deployed by calling `kpt live destroy`.
-func (k *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, _ *manifest.ManifestListByConfig) error {
+func (k *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, _ manifest.ManifestListByConfig) error {
 	instrumentation.AddAttributesToCurrentSpanFromContext(ctx, map[string]string{
 		"DeployerType": deployerName,
 	})
diff --git a/pkg/skaffold/deploy/kubectl/kubectl.go b/pkg/skaffold/deploy/kubectl/kubectl.go
index 96de62064..9285a8508 100644
--- a/pkg/skaffold/deploy/kubectl/kubectl.go
+++ b/pkg/skaffold/deploy/kubectl/kubectl.go
@@ -174,7 +174,7 @@ func (k *Deployer) trackNamespaces(namespaces []string) {
 
 // Deploy templates the provided manifests with a simple `find and replace` and
 // runs `kubectl apply` on those manifests
-func (k *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, manifestsByConfig *manifest.ManifestListByConfig) error {
+func (k *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, manifestsByConfig manifest.ManifestListByConfig) error {
 	manifests := manifestsByConfig.GetForConfig(k.ConfigName())
 	var (
 		err      error
@@ -348,11 +348,9 @@ func (k *Deployer) readRemoteManifest(ctx context.Context, name string) ([]byte,
 }
 
 // Cleanup deletes what was deployed by calling Deploy.
-func (k *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, manifestsByConfig *manifest.ManifestListByConfig) error {
+func (k *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, manifestsByConfig manifest.ManifestListByConfig) error {
 	var manifests manifest.ManifestList
-	if manifestsByConfig != nil {
-		manifests = append(manifests, manifestsByConfig.GetForConfig(k.ConfigName())...)
-	}
+	manifests = append(manifests, manifestsByConfig.GetForConfig(k.ConfigName())...)
 	instrumentation.AddAttributesToCurrentSpanFromContext(ctx, map[string]string{
 		"DeployerType": "kubectl",
 	})
diff --git a/pkg/skaffold/deploy/kustomize/kustomize.go b/pkg/skaffold/deploy/kustomize/kustomize.go
index d002cde0b..b14a9ba51 100644
--- a/pkg/skaffold/deploy/kustomize/kustomize.go
+++ b/pkg/skaffold/deploy/kustomize/kustomize.go
@@ -260,7 +260,7 @@ func kubectlVersionCheck(kubectl kubectl.CLI) bool {
 }
 
 // Deploy runs `kubectl apply` on the manifest generated by kustomize.
-func (k *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, _ *manifest.ManifestListByConfig) error {
+func (k *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, _ manifest.ManifestListByConfig) error {
 	instrumentation.AddAttributesToCurrentSpanFromContext(ctx, map[string]string{
 		"DeployerType": "kustomize",
 	})
@@ -369,7 +369,7 @@ func (k *Deployer) renderManifests(ctx context.Context, out io.Writer, builds []
 }
 
 // Cleanup deletes what was deployed by calling Deploy.
-func (k *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, _ *manifest.ManifestListByConfig) error {
+func (k *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, _ manifest.ManifestListByConfig) error {
 	instrumentation.AddAttributesToCurrentSpanFromContext(ctx, map[string]string{
 		"DeployerType": "kustomize",
 	})
diff --git a/pkg/skaffold/render/renderer/helm/helm.go b/pkg/skaffold/render/renderer/helm/helm.go
index dd2321210..52fc0043f 100644
--- a/pkg/skaffold/render/renderer/helm/helm.go
+++ b/pkg/skaffold/render/renderer/helm/helm.go
@@ -82,7 +82,7 @@ func New(cfg render.Config, rCfg latest.RenderConfig, labels map[string]string,
 	}, nil
 }
 
-func (h Helm) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, _ bool) (*manifest.ManifestListByConfig, error) {
+func (h Helm) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, _ bool) (manifest.ManifestListByConfig, error) {
 	_, endTrace := instrumentation.StartTrace(ctx, "Render_HelmManifests")
 	log.Entry(ctx).Infof("rendering using helm")
 	instrumentation.AddAttributesToCurrentSpanFromContext(ctx, map[string]string{
@@ -93,7 +93,7 @@ func (h Helm) Render(ctx context.Context, out io.Writer, builds []graph.Artifact
 	endTrace()
 	manifestListByConfig := manifest.NewManifestListByConfig()
 	manifestListByConfig.Add(h.configName, manifests)
-	return &manifestListByConfig, err
+	return manifestListByConfig, err
 }
 
 func (h Helm) generateHelmManifests(ctx context.Context, builds []graph.Artifact) (manifest.ManifestList, error) {
diff --git a/pkg/skaffold/render/renderer/kpt/kpt.go b/pkg/skaffold/render/renderer/kpt/kpt.go
index ba2af1682..54981e9e3 100644
--- a/pkg/skaffold/render/renderer/kpt/kpt.go
+++ b/pkg/skaffold/render/renderer/kpt/kpt.go
@@ -99,7 +99,8 @@ func New(cfg render.Config, rCfg latest.RenderConfig, hydrationDir string, label
 	}, nil
 }
 
-func (r *Kpt) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, _ bool) (*manifest.ManifestListByConfig, error) {
+func (r *Kpt) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error) {
+	var ml manifest.ManifestListByConfig
 	kptfilePath := filepath.Join(r.hydrationDir, kptfile.KptFileName)
 	kfConfig := &kptfile.KptFile{}
 
@@ -113,11 +114,11 @@ func (r *Kpt) Render(ctx context.Context, out io.Writer, builds []graph.Artifact
 	if _, err := os.Stat(kptfilePath); os.IsNotExist(err) {
 		if err := os.MkdirAll(r.hydrationDir, os.ModePerm); err != nil {
 			endTrace(instrumentation.TraceEndError(fmt.Errorf("create hydration dir %v:%w", r.hydrationDir, err)))
-			return nil, err
+			return ml, err
 		}
 		cmd := exec.CommandContext(ctx, "kpt", "pkg", "init", r.hydrationDir)
 		if _, err := util.RunCmdOut(ctx, cmd); err != nil {
-			return nil, sErrors.NewError(err,
+			return ml, sErrors.NewError(err,
 				&proto.ActionableErr{
 					Message: fmt.Sprintf("unable to initialize Kptfile in %v", r.hydrationDir),
 					ErrCode: proto.StatusCode_RENDER_KPTFILE_INIT_ERR,
@@ -136,27 +137,27 @@ func (r *Kpt) Render(ctx context.Context, out io.Writer, builds []graph.Artifact
 	if err != nil {
 		endTrace(instrumentation.TraceEndError(fmt.Errorf("read Kptfile from %v: %w",
 			filepath.Dir(kptfilePath), err)))
-		return nil, err
+		return ml, err
 	}
 	if err := yaml.UnmarshalStrict(kptfileBytes, &kfConfig); err != nil {
-		return nil, errors.ParseKptfileError(err, r.hydrationDir)
+		return ml, errors.ParseKptfileError(err, r.hydrationDir)
 	}
 	if err := os.RemoveAll(r.hydrationDir); err != nil {
-		return nil, errors.DeleteKptfileError(err, r.hydrationDir)
+		return ml, errors.DeleteKptfileError(err, r.hydrationDir)
 	}
 	endTrace()
 	manifests, errH := rUtil.GenerateHydratedManifests(ctx, out, builds, r.Generator, r.labels, r.transformAllowlist, r.transformDenylist)
 	if err != nil {
-		return nil, errH
+		return ml, errH
 	}
 	// Write generated dry manifests.
 	_, endTrace = instrumentation.StartTrace(ctx, "Render_cacheDryConfig")
 	dryConfigPath := filepath.Join(r.hydrationDir, DryFileName)
 	if err := os.MkdirAll(r.hydrationDir, os.ModePerm); err != nil {
-		return nil, err
+		return ml, err
 	}
 	if err := manifest.Write(manifests.String(), dryConfigPath, io.Discard); err != nil {
-		return nil, err
+		return ml, err
 	}
 	endTrace()
 	if kfConfig.Pipeline == nil {
@@ -165,16 +166,16 @@ func (r *Kpt) Render(ctx context.Context, out io.Writer, builds []graph.Artifact
 	kfConfig.Pipeline.Validators = r.GetDeclarativeValidators()
 	kfConfig.Pipeline.Mutators, err = r.GetDeclarativeTransformers()
 	if err != nil {
-		return nil, err
+		return ml, err
 	}
 	configByte, err := yaml.Marshal(kfConfig)
 	if err != nil {
-		return nil, err
+		return ml, err
 	}
 	if err = os.WriteFile(kptfilePath, configByte, 0644); err != nil {
 		manifestListByConfig := manifest.NewManifestListByConfig()
 		manifestListByConfig.Add(r.configName, manifests)
-		return &manifestListByConfig, err
+		return manifestListByConfig, err
 	}
 	endTrace()
 
@@ -185,13 +186,13 @@ func (r *Kpt) Render(ctx context.Context, out io.Writer, builds []graph.Artifact
 	if err := util.RunCmd(ctx, cmd); err != nil {
 		endTrace(instrumentation.TraceEndError(err))
 		// TODO(yuwenma): How to guide users when they face kpt error (may due to bad user config)?
-		return nil, err
+		return ml, err
 	}
 	return r.unwrapManifests(ctx, out)
 }
 
 // unwrapManifests converts the structured manifest to a flatten format
-func (r *Kpt) unwrapManifests(ctx context.Context, out io.Writer) (*manifest.ManifestListByConfig, error) {
+func (r *Kpt) unwrapManifests(ctx context.Context, out io.Writer) (manifest.ManifestListByConfig, error) {
 	var m manifest.ManifestList
 	rCtx, endTrace := instrumentation.StartTrace(ctx, "Render_outputManifests")
 	cmd := exec.CommandContext(rCtx, "kpt", "fn", "source", r.hydrationDir, "-o", "unwrap")
@@ -202,10 +203,10 @@ func (r *Kpt) unwrapManifests(ctx context.Context, out io.Writer) (*manifest.Man
 		endTrace(instrumentation.TraceEndError(err))
 		manifestListByConfig := manifest.NewManifestListByConfig()
 		manifestListByConfig.Add(r.configName, m)
-		return &manifestListByConfig, err
+		return manifestListByConfig, err
 	}
 	m = append(m, buf)
 	manifestListByConfig := manifest.NewManifestListByConfig()
 	manifestListByConfig.Add(r.configName, m)
-	return &manifestListByConfig, nil
+	return manifestListByConfig, nil
 }
diff --git a/pkg/skaffold/render/renderer/kubectl/kubectl.go b/pkg/skaffold/render/renderer/kubectl/kubectl.go
index 0d8ae4d95..324e6e193 100644
--- a/pkg/skaffold/render/renderer/kubectl/kubectl.go
+++ b/pkg/skaffold/render/renderer/kubectl/kubectl.go
@@ -58,7 +58,7 @@ func New(cfg render.Config, rCfg latest.RenderConfig, labels map[string]string,
 	}, nil
 }
 
-func (r Kubectl) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, _ bool) (*manifest.ManifestListByConfig, error) {
+func (r Kubectl) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error) {
 	_, endTrace := instrumentation.StartTrace(ctx, "Render_KubectlManifests")
 	log.Entry(ctx).Infof("rendering using kubectl")
 	instrumentation.AddAttributesToCurrentSpanFromContext(ctx, map[string]string{
@@ -68,5 +68,5 @@ func (r Kubectl) Render(ctx context.Context, out io.Writer, builds []graph.Artif
 	endTrace()
 	manifestListByConfig := manifest.NewManifestListByConfig()
 	manifestListByConfig.Add(r.configName, manifests)
-	return &manifestListByConfig, err
+	return manifestListByConfig, err
 }
diff --git a/pkg/skaffold/render/renderer/noop/noop.go b/pkg/skaffold/render/renderer/noop/noop.go
index e45f209ec..661b3ebf3 100644
--- a/pkg/skaffold/render/renderer/noop/noop.go
+++ b/pkg/skaffold/render/renderer/noop/noop.go
@@ -34,9 +34,9 @@ func New(_ latest.RenderConfig, _, _ string, _ map[string]string) (Noop, error)
 	return Noop{}, nil
 }
 
-func (r Noop) Render(_ context.Context, _ io.Writer, _ []graph.Artifact, _ bool) (*manifest.ManifestListByConfig, error) {
+func (r Noop) Render(ctx context.Context, out io.Writer, artifacts []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error) {
 	manifestListByConfig := manifest.NewManifestListByConfig()
-	return &manifestListByConfig, nil
+	return manifestListByConfig, nil
 }
 
 func (r Noop) ManifestDeps() ([]string, error) {
diff --git a/pkg/skaffold/render/renderer/render_mux.go b/pkg/skaffold/render/renderer/render_mux.go
index 74454154d..8b1eb3ebd 100644
--- a/pkg/skaffold/render/renderer/render_mux.go
+++ b/pkg/skaffold/render/renderer/render_mux.go
@@ -41,7 +41,7 @@ func NewRenderMux(renderers []Renderer) Renderer {
 	return RenderMux{renderers: renderers}
 }
 
-func (r RenderMux) Render(ctx context.Context, out io.Writer, artifacts []graph.Artifact, offline bool) (*manifest.ManifestListByConfig, error) {
+func (r RenderMux) Render(ctx context.Context, out io.Writer, artifacts []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error) {
 	allManifests := manifest.NewManifestListByConfig()
 	for i, renderer := range r.renderers {
 		eventV2.RendererInProgress(i)
@@ -51,7 +51,7 @@ func (r RenderMux) Render(ctx context.Context, out io.Writer, artifacts []graph.
 		if err != nil {
 			eventV2.RendererFailed(i, err)
 			endTrace(instrumentation.TraceEndError(err))
-			return nil, err
+			return manifest.NewManifestListByConfig(), err
 		}
 
 		for _, configName := range manifestsByConfig.ConfigNames() {
@@ -65,7 +65,7 @@ func (r RenderMux) Render(ctx context.Context, out io.Writer, artifacts []graph.
 		eventV2.RendererSucceeded(i)
 		endTrace()
 	}
-	return &allManifests, nil
+	return allManifests, nil
 }
 
 func (r RenderMux) ManifestDeps() ([]string, error) {
diff --git a/pkg/skaffold/render/renderer/renderer.go b/pkg/skaffold/render/renderer/renderer.go
index aecb245ba..ceaaffd20 100644
--- a/pkg/skaffold/render/renderer/renderer.go
+++ b/pkg/skaffold/render/renderer/renderer.go
@@ -32,7 +32,7 @@ import (
 )
 
 type Renderer interface {
-	Render(ctx context.Context, out io.Writer, artifacts []graph.Artifact, offline bool) (*manifest.ManifestListByConfig, error)
+	Render(ctx context.Context, out io.Writer, artifacts []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error)
 	// ManifestDeps returns the user kubernetes manifests to file watcher. In dev mode, a "redeploy" will be triggered
 	// if any of the "Dependencies" manifest is changed.
 	ManifestDeps() ([]string, error)
diff --git a/pkg/skaffold/runner/notification.go b/pkg/skaffold/runner/notification.go
index 813eb3e73..50d5067a3 100644
--- a/pkg/skaffold/runner/notification.go
+++ b/pkg/skaffold/runner/notification.go
@@ -42,7 +42,7 @@ type withNotification struct {
 	deploy.Deployer
 }
 
-func (w withNotification) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, l *manifest.ManifestListByConfig) error {
+func (w withNotification) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, l manifest.ManifestListByConfig) error {
 	err := w.Deployer.Deploy(ctx, out, builds, l)
 	if err != nil {
 		fmt.Fprint(out, terminalBell)
diff --git a/pkg/skaffold/runner/runner.go b/pkg/skaffold/runner/runner.go
index 56053140f..7c9296f64 100644
--- a/pkg/skaffold/runner/runner.go
+++ b/pkg/skaffold/runner/runner.go
@@ -35,17 +35,17 @@ type Runner interface {
 	Apply(context.Context, io.Writer) error
 	ApplyDefaultRepo(tag string) (string, error)
 	Build(context.Context, io.Writer, []*latest.Artifact) ([]graph.Artifact, error)
-	Cleanup(context.Context, io.Writer, bool, *manifest.ManifestListByConfig) error
+	Cleanup(context.Context, io.Writer, bool, manifest.ManifestListByConfig) error
 	Dev(context.Context, io.Writer, []*latest.Artifact) error
 	// Deploy and DeployAndLog: Do they need the `graph.Artifact` and could use render output.
-	Deploy(context.Context, io.Writer, []graph.Artifact, *manifest.ManifestListByConfig) error
-	DeployAndLog(context.Context, io.Writer, []graph.Artifact, *manifest.ManifestListByConfig) error
+	Deploy(context.Context, io.Writer, []graph.Artifact, manifest.ManifestListByConfig) error
+	DeployAndLog(context.Context, io.Writer, []graph.Artifact, manifest.ManifestListByConfig) error
 	GeneratePipeline(context.Context, io.Writer, []util.VersionedConfig, []string, string) error
 	HasBuilt() bool
 	HasDeployed() bool
 	Prune(context.Context, io.Writer) error
 
-	Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (*manifest.ManifestListByConfig, error)
+	Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error)
 	Test(context.Context, io.Writer, []graph.Artifact) error
 	Verify(context.Context, io.Writer, []graph.Artifact) error
 	VerifyAndLog(context.Context, io.Writer, []graph.Artifact) error
diff --git a/pkg/skaffold/runner/timings.go b/pkg/skaffold/runner/timings.go
index 6d2be1104..e07a83aee 100644
--- a/pkg/skaffold/runner/timings.go
+++ b/pkg/skaffold/runner/timings.go
@@ -83,19 +83,19 @@ func (w withTimings) Test(ctx context.Context, out io.Writer, builds []graph.Art
 	return nil
 }
 
-func (w withTimings) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (*manifest.ManifestListByConfig, error) {
+func (w withTimings) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error) {
 	start := time.Now()
 	log.Entry(ctx).Infoln("Starting render...")
 
 	manifestsLists, err := w.Renderer.Render(ctx, out, builds, offline)
 	if err != nil {
-		return nil, err
+		return manifest.NewManifestListByConfig(), err
 	}
 	log.Entry(ctx).Infoln("Render completed in", timeutil.Humanize(time.Since(start)))
 	return manifestsLists, nil
 }
 
-func (w withTimings) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, l *manifest.ManifestListByConfig) error {
+func (w withTimings) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, l manifest.ManifestListByConfig) error {
 	start := time.Now()
 	output.Default.Fprintln(out, "Starting deploy...")
 
@@ -107,7 +107,7 @@ func (w withTimings) Deploy(ctx context.Context, out io.Writer, builds []graph.A
 	return err
 }
 
-func (w withTimings) Cleanup(ctx context.Context, out io.Writer, dryRun bool, config *manifest.ManifestListByConfig) error {
+func (w withTimings) Cleanup(ctx context.Context, out io.Writer, dryRun bool, config manifest.ManifestListByConfig) error {
 	start := time.Now()
 	output.Default.Fprintln(out, "Cleaning up...")
 
diff --git a/pkg/skaffold/runner/v2/apply.go b/pkg/skaffold/runner/v2/apply.go
index 22d979ce0..9549a73d3 100644
--- a/pkg/skaffold/runner/v2/apply.go
+++ b/pkg/skaffold/runner/v2/apply.go
@@ -61,7 +61,7 @@ func (r *SkaffoldRunner) applyResources(ctx context.Context, out io.Writer, arti
 	event.DeployInProgress()
 	ctx, endTrace := instrumentation.StartTrace(ctx, "applyResources_Deploying")
 	defer endTrace()
-	err = r.deployer.Deploy(ctx, deployOut, artifacts, &list)
+	err = r.deployer.Deploy(ctx, deployOut, artifacts, list)
 	postDeployFn()
 	if err != nil {
 		event.DeployFailed(err)
diff --git a/pkg/skaffold/runner/v2/cleanup.go b/pkg/skaffold/runner/v2/cleanup.go
index 1fb93e7ec..7210c9a38 100644
--- a/pkg/skaffold/runner/v2/cleanup.go
+++ b/pkg/skaffold/runner/v2/cleanup.go
@@ -22,6 +22,6 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/manifest"
 )
 
-func (r *SkaffoldRunner) Cleanup(ctx context.Context, out io.Writer, dryRun bool, manifestListByConfig *manifest.ManifestListByConfig) error {
+func (r *SkaffoldRunner) Cleanup(ctx context.Context, out io.Writer, dryRun bool, manifestListByConfig manifest.ManifestListByConfig) error {
 	return r.deployer.Cleanup(ctx, out, dryRun, manifestListByConfig)
 }
diff --git a/pkg/skaffold/runner/v2/deploy.go b/pkg/skaffold/runner/v2/deploy.go
index fe528e049..d8698d67e 100644
--- a/pkg/skaffold/runner/v2/deploy.go
+++ b/pkg/skaffold/runner/v2/deploy.go
@@ -34,7 +34,7 @@ import (
 )
 
 // DeployAndLog deploys a list of already built artifacts and optionally show the logs.
-func (r *SkaffoldRunner) DeployAndLog(ctx context.Context, out io.Writer, artifacts []graph.Artifact, list *manifest.ManifestListByConfig) error {
+func (r *SkaffoldRunner) DeployAndLog(ctx context.Context, out io.Writer, artifacts []graph.Artifact, list manifest.ManifestListByConfig) error {
 	defer r.deployer.GetLogger().Stop()
 
 	// Logs should be retrieved up to just before the deploy
@@ -63,7 +63,7 @@ func (r *SkaffoldRunner) DeployAndLog(ctx context.Context, out io.Writer, artifa
 	return nil
 }
 
-func (r *SkaffoldRunner) Deploy(ctx context.Context, out io.Writer, artifacts []graph.Artifact, list *manifest.ManifestListByConfig) error {
+func (r *SkaffoldRunner) Deploy(ctx context.Context, out io.Writer, artifacts []graph.Artifact, list manifest.ManifestListByConfig) error {
 	defer r.deployer.GetStatusMonitor().Reset()
 
 	out, ctx = output.WithEventContext(ctx, out, constants.Deploy, constants.SubtaskIDNone)
diff --git a/pkg/skaffold/runner/v2/render.go b/pkg/skaffold/runner/v2/render.go
index df4b51fc0..0eed61d18 100644
--- a/pkg/skaffold/runner/v2/render.go
+++ b/pkg/skaffold/runner/v2/render.go
@@ -31,10 +31,10 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/render/util"
 )
 
-func (r *SkaffoldRunner) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (*manifest.ManifestListByConfig, error) {
+func (r *SkaffoldRunner) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error) {
 	renderOut, postRenderFn, err := util.WithLogFile(time.Now().Format(util.TimeFormat)+".log", out, r.runCtx.Muted())
 	if err != nil {
-		return nil, err
+		return manifest.ManifestListByConfig{}, err
 	}
 	defer postRenderFn()
 
@@ -45,7 +45,7 @@ func (r *SkaffoldRunner) Render(ctx context.Context, out io.Writer, builds []gra
 				// remote digest to platform dependant build not supported
 				digest, err := docker.RemoteDigest(a.Tag, r.runCtx, nil)
 				if err != nil {
-					return nil, fmt.Errorf("failed to resolve the digest of %s: does the image exist remotely?", a.Tag)
+					return manifest.ManifestListByConfig{}, fmt.Errorf("failed to resolve the digest of %s: does the image exist remotely?", a.Tag)
 				}
 				builds[i].Tag = build.TagWithDigest(a.Tag, digest)
 			}
@@ -59,7 +59,7 @@ func (r *SkaffoldRunner) Render(ctx context.Context, out io.Writer, builds []gra
 	manifestList, err := r.renderer.Render(ctx, renderOut, builds, offline)
 	if err != nil {
 		endTrace(instrumentation.TraceEndError(err))
-		return nil, err
+		return manifest.ManifestListByConfig{}, err
 	}
 
 	endTrace()


Test patch:
diff --git a/cmd/skaffold/app/cmd/dev_test.go b/cmd/skaffold/app/cmd/dev_test.go
index ff5d3347b..574dcd596 100644
--- a/cmd/skaffold/app/cmd/dev_test.go
+++ b/cmd/skaffold/app/cmd/dev_test.go
@@ -37,7 +37,7 @@ type mockDevRunner struct {
 	hasDeployed       bool
 	errDev            error
 	calls             []string
-	manifestsByConfig *manifest.ManifestListByConfig
+	manifestsByConfig manifest.ManifestListByConfig
 }
 
 func (r *mockDevRunner) Dev(context.Context, io.Writer, []*latest.Artifact) error {
@@ -60,12 +60,12 @@ func (r *mockDevRunner) Prune(context.Context, io.Writer) error {
 	return nil
 }
 
-func (r *mockDevRunner) Cleanup(context.Context, io.Writer, bool, *manifest.ManifestListByConfig) error {
+func (r *mockDevRunner) Cleanup(context.Context, io.Writer, bool, manifest.ManifestListByConfig) error {
 	r.calls = append(r.calls, "Cleanup")
 	return nil
 }
 
-func (r *mockDevRunner) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (*manifest.ManifestListByConfig, error) {
+func (r *mockDevRunner) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error) {
 	r.calls = append(r.calls, "Render")
 	return r.manifestsByConfig, nil
 }
@@ -146,11 +146,11 @@ func (m *mockConfigChangeRunner) Prune(context.Context, io.Writer) error {
 	return nil
 }
 
-func (m *mockConfigChangeRunner) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (*manifest.ManifestListByConfig, error) {
-	return nil, nil
+func (m *mockConfigChangeRunner) Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error) {
+	return manifest.ManifestListByConfig{}, nil
 }
 
-func (m *mockConfigChangeRunner) Cleanup(context.Context, io.Writer, bool, *manifest.ManifestListByConfig) error {
+func (m *mockConfigChangeRunner) Cleanup(context.Context, io.Writer, bool, manifest.ManifestListByConfig) error {
 	return nil
 }
 
diff --git a/cmd/skaffold/app/cmd/run_test.go b/cmd/skaffold/app/cmd/run_test.go
index 59a51a919..310a9e2a1 100644
--- a/cmd/skaffold/app/cmd/run_test.go
+++ b/cmd/skaffold/app/cmd/run_test.go
@@ -72,15 +72,15 @@ func (r *mockRunRunner) Test(context.Context, io.Writer, []graph.Artifact) error
 	return nil
 }
 
-func (r *mockRunRunner) DeployAndLog(context.Context, io.Writer, []graph.Artifact, *manifest.ManifestListByConfig) error {
+func (r *mockRunRunner) DeployAndLog(context.Context, io.Writer, []graph.Artifact, manifest.ManifestListByConfig) error {
 	r.deployRan = true
 	return nil
 }
 
-func (r *mockRunRunner) Render(context.Context, io.Writer, []graph.Artifact, bool) (*manifest.ManifestListByConfig, error) {
+func (r *mockRunRunner) Render(context.Context, io.Writer, []graph.Artifact, bool) (manifest.ManifestListByConfig, error) {
 	r.renderRan = true
 	manifestListByConfig := manifest.NewManifestListByConfig()
-	return &manifestListByConfig, nil
+	return manifestListByConfig, nil
 }
 
 func TestDoRun(t *testing.T) {
diff --git a/pkg/skaffold/deploy/cloudrun/deploy_test.go b/pkg/skaffold/deploy/cloudrun/deploy_test.go
index 382ba5292..e525a83ea 100644
--- a/pkg/skaffold/deploy/cloudrun/deploy_test.go
+++ b/pkg/skaffold/deploy/cloudrun/deploy_test.go
@@ -131,7 +131,7 @@ func TestDeploy(tOuter *testing.T) {
 			manifestList, _ := json.Marshal(test.toDeploy)
 			manifestsByConfig := manifest.NewManifestListByConfig()
 			manifestsByConfig.Add(configName, manifest.ManifestList{manifestList})
-			err := deployer.Deploy(context.Background(), os.Stderr, []graph.Artifact{}, &manifestsByConfig)
+			err := deployer.Deploy(context.Background(), os.Stderr, []graph.Artifact{}, manifestsByConfig)
 			if test.errCode == proto.StatusCode_OK && err != nil {
 				t.Fatalf("Expected success but got err: %v", err)
 			} else if test.errCode != proto.StatusCode_OK {
@@ -250,7 +250,7 @@ func TestDeployRewrites(tOuter *testing.T) {
 			manifests := [][]byte{m}
 			manifestByConfig := manifest.NewManifestListByConfig()
 			manifestByConfig.Add("", manifests)
-			err := deployer.Deploy(context.Background(), os.Stderr, []graph.Artifact{}, &manifestByConfig)
+			err := deployer.Deploy(context.Background(), os.Stderr, []graph.Artifact{}, manifestByConfig)
 			if err != nil {
 				t.Fatalf("Expected success but got err: %v", err)
 			}
@@ -331,7 +331,7 @@ func TestCleanup(tOuter *testing.T) {
 			manifest, _ := json.Marshal(test.toDelete)
 			manifests := [][]byte{manifest}
 			manifestListByConfig.Add(configName, manifests)
-			err := deployer.Cleanup(context.Background(), os.Stderr, false, &manifestListByConfig)
+			err := deployer.Cleanup(context.Background(), os.Stderr, false, manifestListByConfig)
 			if test.httpErr == 0 && err != nil {
 				t.Fatalf("Expected success but got err: %v", err)
 			} else if test.httpErr != 0 && err == nil {
diff --git a/pkg/skaffold/deploy/deploy_mux_test.go b/pkg/skaffold/deploy/deploy_mux_test.go
index 9f9fc6796..6813cf74c 100644
--- a/pkg/skaffold/deploy/deploy_mux_test.go
+++ b/pkg/skaffold/deploy/deploy_mux_test.go
@@ -87,7 +87,7 @@ func (m *MockDeployer) Dependencies() ([]string, error) {
 	return m.dependencies, m.dependenciesErr
 }
 
-func (m *MockDeployer) Cleanup(context.Context, io.Writer, bool, *manifest.ManifestListByConfig) error {
+func (m *MockDeployer) Cleanup(context.Context, io.Writer, bool, manifest.ManifestListByConfig) error {
 	return m.cleanupErr
 }
 
@@ -111,7 +111,7 @@ func (m *MockDeployer) WithCleanupErr(err error) *MockDeployer {
 	return m
 }
 
-func (m *MockDeployer) Deploy(context.Context, io.Writer, []graph.Artifact, *manifest.ManifestListByConfig) error {
+func (m *MockDeployer) Deploy(context.Context, io.Writer, []graph.Artifact, manifest.ManifestListByConfig) error {
 	return m.deployErr
 }
 
@@ -161,7 +161,7 @@ func TestDeployerMux_Deploy(t *testing.T) {
 				NewMockDeployer().WithDeployErr(test.err2),
 			}, false)
 
-			err := deployerMux.Deploy(context.Background(), nil, nil, nil)
+			err := deployerMux.Deploy(context.Background(), nil, nil, manifest.NewManifestListByConfig())
 
 			testutil.CheckError(t, test.shouldErr, err)
 		})
diff --git a/pkg/skaffold/deploy/helm/helm_test.go b/pkg/skaffold/deploy/helm/helm_test.go
index 2502dcb72..9982d1ac9 100644
--- a/pkg/skaffold/deploy/helm/helm_test.go
+++ b/pkg/skaffold/deploy/helm/helm_test.go
@@ -39,6 +39,7 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/client"
 	kubectx "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/context"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/logger"
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/manifest"
 	rhelm "github.com/GoogleContainerTools/skaffold/pkg/skaffold/render/renderer/helm"
 	runcontext "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext/v2"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
@@ -945,7 +946,7 @@ func TestHelmDeploy(t *testing.T) {
 			}
 			deployer.pkgTmpDir = tmpDir
 			// Deploy returns nil unless `helm get all <release>` is set up to return actual release info
-			err = deployer.Deploy(context.Background(), io.Discard, test.builds, nil)
+			err = deployer.Deploy(context.Background(), io.Discard, test.builds, manifest.ManifestListByConfig{})
 			t.CheckError(test.shouldErr, err)
 			t.CheckDeepEqual(test.expectedWarnings, fakeWarner.Warnings)
 			t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expectedNamespaces, *deployer.namespaces)
@@ -1027,7 +1028,7 @@ func TestHelmCleanup(t *testing.T) {
 			}, &label.DefaultLabeller{}, &test.helm, nil, "default")
 			t.RequireNoError(err)
 
-			deployer.Cleanup(context.Background(), io.Discard, test.dryRun, nil)
+			deployer.Cleanup(context.Background(), io.Discard, test.dryRun, manifest.ManifestListByConfig{})
 
 			t.CheckDeepEqual(test.expectedWarnings, fakeWarner.Warnings)
 		})
diff --git a/pkg/skaffold/deploy/kpt/kpt_test.go b/pkg/skaffold/deploy/kpt/kpt_test.go
index 0b838370d..a4b9fd8b5 100644
--- a/pkg/skaffold/deploy/kpt/kpt_test.go
+++ b/pkg/skaffold/deploy/kpt/kpt_test.go
@@ -27,6 +27,7 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy/label"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/manifest"
 	runcontext "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext/v2"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
@@ -175,7 +176,7 @@ func TestDeploy(t *testing.T) {
 
 			k, err := NewDeployer(&kptConfig{}, &label.DefaultLabeller{}, &test.kpt, config.SkaffoldOptions{}, "default")
 			t.CheckNoError(err)
-			err = k.Deploy(context.Background(), io.Discard, test.builds, nil)
+			err = k.Deploy(context.Background(), io.Discard, test.builds, manifest.ManifestListByConfig{})
 			t.CheckNoError(err)
 			fmt.Fprintf(os.Stdout, "deployer namespaces: %+v\n", *k.namespaces)
 			t.CheckDeepEqual(*k.namespaces, []string{"test-kptv2"})
diff --git a/pkg/skaffold/deploy/kubectl/kubectl_test.go b/pkg/skaffold/deploy/kubectl/kubectl_test.go
index a9edb4d47..42baf6fca 100644
--- a/pkg/skaffold/deploy/kubectl/kubectl_test.go
+++ b/pkg/skaffold/deploy/kubectl/kubectl_test.go
@@ -383,7 +383,7 @@ func TestKubectlDeployerRemoteCleanup(t *testing.T) {
 			}, &label.DefaultLabeller{}, &test.kubectl, "default")
 			t.RequireNoError(err)
 
-			err = k.Cleanup(context.Background(), io.Discard, false, nil)
+			err = k.Cleanup(context.Background(), io.Discard, false, manifest.ManifestListByConfig{})
 
 			t.CheckNoError(err)
 		})
@@ -425,7 +425,7 @@ func TestKubectlRedeploy(t *testing.T) {
 		err = deployer.Deploy(context.Background(), io.Discard, []graph.Artifact{
 			{ImageName: "leeroy-web", Tag: "leeroy-web:v1"},
 			{ImageName: "leeroy-app", Tag: "leeroy-app:v1"},
-		}, &manifestListByConfig)
+		}, manifestListByConfig)
 		t.CheckNoError(err)
 
 		// Deploy one manifest since only one image is updated
@@ -436,7 +436,7 @@ func TestKubectlRedeploy(t *testing.T) {
 		err = deployer.Deploy(context.Background(), io.Discard, []graph.Artifact{
 			{ImageName: "leeroy-web", Tag: "leeroy-web:v1"},
 			{ImageName: "leeroy-app", Tag: "leeroy-app:v2"},
-		}, &manifestListByConfig)
+		}, manifestListByConfig)
 		t.CheckNoError(err)
 
 		// Deploy zero manifest since no image is updated
@@ -444,7 +444,7 @@ func TestKubectlRedeploy(t *testing.T) {
 		err = deployer.Deploy(context.Background(), io.Discard, []graph.Artifact{
 			{ImageName: "leeroy-web", Tag: "leeroy-web:v1"},
 			{ImageName: "leeroy-app", Tag: "leeroy-app:v2"},
-		}, &emptyManifestList)
+		}, emptyManifestList)
 		t.CheckErrorContains("nothing to deploy", err)
 	})
 }
@@ -498,7 +498,7 @@ func TestKubectlWaitForDeletions(t *testing.T) {
 
 		err = deployer.Deploy(context.Background(), &out, []graph.Artifact{
 			{ImageName: "leeroy-web", Tag: "leeroy-web:v1"},
-		}, &manifestListByConfig)
+		}, manifestListByConfig)
 
 		t.CheckNoError(err)
 		t.CheckDeepEqual(` - 2 resources are marked for deletion, waiting for completion: "leeroy-web", "leeroy-app"
@@ -540,7 +540,7 @@ func TestKubectlWaitForDeletionsFails(t *testing.T) {
 
 		err = deployer.Deploy(context.Background(), io.Discard, []graph.Artifact{
 			{ImageName: "leeroy-web", Tag: "leeroy-web:v1"},
-		}, &manifestListByConfig)
+		}, manifestListByConfig)
 
 		t.CheckErrorContains(`2 resources failed to complete their deletion before a new deployment: "leeroy-web", "leeroy-app"`, err)
 	})
diff --git a/pkg/skaffold/deploy/kustomize/kustomize_test.go b/pkg/skaffold/deploy/kustomize/kustomize_test.go
index 8e3fde0e5..f2e3b926e 100644
--- a/pkg/skaffold/deploy/kustomize/kustomize_test.go
+++ b/pkg/skaffold/deploy/kustomize/kustomize_test.go
@@ -33,6 +33,7 @@ import (
 	ctl "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubectl"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/client"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/logger"
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/manifest"
 	runcontext "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext/v2"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
@@ -214,7 +215,7 @@ func TestKustomizeDeploy(t *testing.T) {
 					Namespace: skaffoldNamespaceOption,
 				}}}, &label.DefaultLabeller{}, &test.kustomize, "default")
 			t.RequireNoError(err)
-			err = k.Deploy(context.Background(), io.Discard, test.builds, nil)
+			err = k.Deploy(context.Background(), io.Discard, test.builds, manifest.ManifestListByConfig{})
 
 			t.CheckError(test.shouldErr, err)
 		})
@@ -291,7 +292,7 @@ func TestKustomizeCleanup(t *testing.T) {
 					Namespace: kubectl.TestNamespace}},
 			}, &label.DefaultLabeller{}, &test.kustomize, "default")
 			t.RequireNoError(err)
-			err = k.Cleanup(context.Background(), io.Discard, test.dryRun, nil)
+			err = k.Cleanup(context.Background(), io.Discard, test.dryRun, manifest.ManifestListByConfig{})
 
 			t.CheckError(test.shouldErr, err)
 		})
diff --git a/pkg/skaffold/render/renderer/render_mux_test.go b/pkg/skaffold/render/renderer/render_mux_test.go
index 08ce03c45..5c95e70c4 100644
--- a/pkg/skaffold/render/renderer/render_mux_test.go
+++ b/pkg/skaffold/render/renderer/render_mux_test.go
@@ -47,7 +47,7 @@ func TestRenderMux_Render(t *testing.T) {
 			expectedDeps: []string{"file1.txt", "file2.txt", "file3.txt"},
 		},
 		{
-			name: "short-circuits when first call fails",
+			name: "returns empty string when any call fails",
 			renderers: []Renderer{
 				mock{manifests: "manifest-1", deps: []string{"file1.txt"}},
 				mock{deps: []string{"file2.txt"}, shouldErr: true}},
@@ -55,7 +55,7 @@ func TestRenderMux_Render(t *testing.T) {
 			shouldErr:    true,
 		},
 		{
-			name: "short-circuits when second call fails",
+			name: "short-circuits when first call fails",
 			renderers: []Renderer{
 				mock{deps: []string{"file1.txt"}, shouldErr: true},
 				mock{manifests: "manifest-2", deps: []string{"file2.txt"}}},
@@ -76,10 +76,7 @@ func TestRenderMux_Render(t *testing.T) {
 			mux := NewRenderMux(tc.renderers)
 			buf := &bytes.Buffer{}
 			actual, err := mux.Render(context.Background(), buf, nil, true)
-			actualValue := ""
-			if actual != nil {
-				actualValue = actual.String()
-			}
+			actualValue := actual.String()
 			t.CheckErrorAndDeepEqual(tc.shouldErr, err, tc.expected, actualValue)
 			actualDeps, errD := mux.ManifestDeps()
 			t.CheckNoError(errD)
@@ -99,12 +96,12 @@ func (m mock) ManifestDeps() ([]string, error) {
 	return m.deps, nil
 }
 
-func (m mock) Render(context.Context, io.Writer, []graph.Artifact, bool) (*manifest.ManifestListByConfig, error) {
+func (m mock) Render(context.Context, io.Writer, []graph.Artifact, bool) (manifest.ManifestListByConfig, error) {
 	if m.shouldErr {
-		return nil, fmt.Errorf("render error")
+		return manifest.ManifestListByConfig{}, fmt.Errorf("render error")
 	}
 	manifests, err := manifest.Load(bytes.NewReader([]byte(m.manifests)))
 	manifestListByConfig := manifest.NewManifestListByConfig()
 	manifestListByConfig.Add(m.configName, manifests)
-	return &manifestListByConfig, err
+	return manifestListByConfig, err
 }
diff --git a/pkg/skaffold/runner/timings_test.go b/pkg/skaffold/runner/timings_test.go
index 43ad2e134..b93cdf241 100644
--- a/pkg/skaffold/runner/timings_test.go
+++ b/pkg/skaffold/runner/timings_test.go
@@ -74,11 +74,11 @@ type mockRenderer struct {
 	err bool
 }
 
-func (m *mockRenderer) Render(context.Context, io.Writer, []graph.Artifact, bool) (*manifest.ManifestListByConfig, error) {
+func (m *mockRenderer) Render(context.Context, io.Writer, []graph.Artifact, bool) (manifest.ManifestListByConfig, error) {
 	if m.err {
-		return nil, errors.New("Unable to render")
+		return manifest.NewManifestListByConfig(), errors.New("Unable to render")
 	}
-	return nil, nil
+	return manifest.NewManifestListByConfig(), nil
 }
 
 func (m *mockRenderer) ManifestDeps() ([]string, error) {
@@ -93,14 +93,14 @@ type mockDeployer struct {
 	err bool
 }
 
-func (m *mockDeployer) Deploy(context.Context, io.Writer, []graph.Artifact, *manifest.ManifestListByConfig) error {
+func (m *mockDeployer) Deploy(context.Context, io.Writer, []graph.Artifact, manifest.ManifestListByConfig) error {
 	if m.err {
 		return errors.New("Unable to deploy")
 	}
 	return nil
 }
 
-func (m *mockDeployer) Cleanup(context.Context, io.Writer, bool, *manifest.ManifestListByConfig) error {
+func (m *mockDeployer) Cleanup(context.Context, io.Writer, bool, manifest.ManifestListByConfig) error {
 	if m.err {
 		return errors.New("Unable to cleanup")
 	}
@@ -283,7 +283,7 @@ func TestTimingsDeploy(t *testing.T) {
 			_, _, _, deployer := WithTimings(nil, nil, nil, d, false)
 
 			var out bytes.Buffer
-			err := deployer.Deploy(context.Background(), &out, nil, nil)
+			err := deployer.Deploy(context.Background(), &out, nil, manifest.NewManifestListByConfig())
 
 			t.CheckError(test.shouldErr, err)
 			t.CheckMatches(test.shouldOutput, out.String())
@@ -320,7 +320,7 @@ func TestTimingsCleanup(t *testing.T) {
 			_, _, _, deployer := WithTimings(nil, nil, nil, d, false)
 
 			var out bytes.Buffer
-			err := deployer.Cleanup(context.Background(), &out, false, nil)
+			err := deployer.Cleanup(context.Background(), &out, false, manifest.NewManifestListByConfig())
 
 			t.CheckError(test.shouldErr, err)
 			t.CheckMatches(test.shouldOutput, out.String())
diff --git a/pkg/skaffold/runner/v2/deploy_test.go b/pkg/skaffold/runner/v2/deploy_test.go
index 2a9fd0d21..a2c67fc71 100644
--- a/pkg/skaffold/runner/v2/deploy_test.go
+++ b/pkg/skaffold/runner/v2/deploy_test.go
@@ -28,6 +28,7 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/client"
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/manifest"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner"
 	runcontext "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext/v2"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
@@ -62,7 +63,7 @@ func TestDeploy(t *testing.T) {
 			err := r.Deploy(context.Background(), out, []graph.Artifact{
 				{ImageName: "img1", Tag: "img1:tag1"},
 				{ImageName: "img2", Tag: "img2:tag2"},
-			}, nil)
+			}, manifest.ManifestListByConfig{})
 			t.CheckError(test.shouldErr, err)
 		})
 	}
@@ -86,7 +87,7 @@ func TestSkaffoldDeployRenderOnly(t *testing.T) {
 		}
 		var builds []graph.Artifact
 
-		err = r.Deploy(context.Background(), io.Discard, builds, nil)
+		err = r.Deploy(context.Background(), io.Discard, builds, manifest.ManifestListByConfig{})
 
 		t.CheckNoError(err)
 	})
diff --git a/pkg/skaffold/runner/v2/runner_test.go b/pkg/skaffold/runner/v2/runner_test.go
index 07feabdce..9bb9579eb 100644
--- a/pkg/skaffold/runner/v2/runner_test.go
+++ b/pkg/skaffold/runner/v2/runner_test.go
@@ -143,7 +143,7 @@ func (t *TestBench) TestDependencies(context.Context, *latest.Artifact) ([]strin
 	return nil, nil
 }
 func (t *TestBench) Dependencies() ([]string, error) { return nil, nil }
-func (t *TestBench) Cleanup(ctx context.Context, out io.Writer, dryRun bool, byConfig *manifest.ManifestListByConfig) error {
+func (t *TestBench) Cleanup(ctx context.Context, out io.Writer, dryRun bool, byConfig manifest.ManifestListByConfig) error {
 	return nil
 }
 func (t *TestBench) Prune(ctx context.Context, out io.Writer) error { return nil }
@@ -202,7 +202,7 @@ func (t *TestBench) Test(_ context.Context, _ io.Writer, artifacts []graph.Artif
 	return nil
 }
 
-func (t *TestBench) Deploy(_ context.Context, _ io.Writer, artifacts []graph.Artifact, manifests *manifest.ManifestListByConfig) error {
+func (t *TestBench) Deploy(_ context.Context, _ io.Writer, artifacts []graph.Artifact, manifests manifest.ManifestListByConfig) error {
 	if len(t.deployErrors) > 0 {
 		err := t.deployErrors[0]
 		t.deployErrors = t.deployErrors[1:]
@@ -219,16 +219,16 @@ func (t *TestBench) ConfigName() string {
 	return ""
 }
 
-func (t *TestBench) Render(_ context.Context, _ io.Writer, artifacts []graph.Artifact, _ bool) (*manifest.ManifestListByConfig, error) {
+func (t *TestBench) Render(ctx context.Context, out io.Writer, artifacts []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error) {
 	if len(t.renderErrors) > 0 {
 		err := t.renderErrors[0]
 		t.renderErrors = t.renderErrors[1:]
 		if err != nil {
-			return nil, err
+			return manifest.NewManifestListByConfig(), err
 		}
 	}
 	t.currentActions.Rendered = findTags(artifacts)
-	return nil, nil
+	return manifest.NewManifestListByConfig(), nil
 }
 
 func (t *TestBench) ManifestDeps() ([]string, error) {