Repository: GoogleContainerTools/skaffold
Pull request #7694 (2022-07-27 18:06:12)

feat: add flags for Cloud Run configuration

**Related**: #3217 
**Description**
Add --cloud-run-project and --cloud-run-location flags. 


**User facing changes (remove if N/A)**
Add --cloud-run-project and --cloud-run-location flags for commands that do deployments. If provided when using the Cloud Run deployer, overrides any project or region set in the Skaffold config or Cloud Run manifests.


**Follow-up Work (remove if N/A)**
<!-- Mention any related follow up work to this PR. -->


<!--
Please be sure your PR includes unit tests - we don't merge code that brings down test coverage! 
Integration tests are sometimes an appropriate substitute. 
-->


codecov[bot]: # [Codecov](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7694?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) Report
> Merging [#7694](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7694?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) (2e2c60e) 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 `3.95%`.
> The diff coverage is `54.44%`.

```diff
@@            Coverage Diff             @@
##             main    #7694      +/-   ##
==========================================
- Coverage   70.48%   66.53%   -3.96%     
==========================================
  Files         515      587      +72     
  Lines       23150    28117    +4967     
==========================================
+ Hits        16317    18707    +2390     
- Misses       5776     8043    +2267     
- Partials     1057     1367     +310     
```


| [Impacted Files](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7694?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/credits/export.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7694/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/7694/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/7694/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/skaffold.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7694/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/7694/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/7694/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/7694/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/7694/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: |
| [cmd/skaffold/app/cmd/fix.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvZml4Lmdv) | `55.93% <38.88%> (-20.54%)` | :arrow_down: |
| [cmd/skaffold/app/cmd/verify.go](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools#diff-Y21kL3NrYWZmb2xkL2FwcC9jbWQvdmVyaWZ5Lmdv) | `41.17% <41.17%> (ø)` | |
| ... and [333 more](https://codecov.io/gh/GoogleContainerTools/skaffold/pull/7694/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools) | |

:mega: Codecov can now indicate which changes are the most critical in Pull Requests. [Learn more](https://about.codecov.io/product/feature/runtime-insights/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=GoogleContainerTools)


Patch:
diff --git a/cmd/skaffold/app/cmd/dev.go b/cmd/skaffold/app/cmd/dev.go
index 8c00af02a..638bff8f1 100644
--- a/cmd/skaffold/app/cmd/dev.go
+++ b/cmd/skaffold/app/cmd/dev.go
@@ -72,7 +72,7 @@ func runDev(ctx context.Context, out io.Writer) error {
 				}
 				err := r.Dev(ctx, out, artifacts)
 
-				if r.HasDeployed() {
+				if r.DeployManifests().String() != "" {
 					cleanup = func() {
 						manifestsByConfig, err := r.Render(ctx, io.Discard, []graph.Artifact{}, false)
 						if err != nil {
diff --git a/cmd/skaffold/app/cmd/flags.go b/cmd/skaffold/app/cmd/flags.go
index 4a73b9960..ac6019232 100644
--- a/cmd/skaffold/app/cmd/flags.go
+++ b/cmd/skaffold/app/cmd/flags.go
@@ -652,6 +652,24 @@ var flagRegistry = []Flag{
 		FlagAddMethod: "BoolVar",
 		DefinedOn:     []string{"dev", "render", "run", "debug", "deploy"},
 	},
+	{
+		Name:          "cloud-run-project",
+		Shorthand:     "",
+		Usage:         "The GCP Project ID or Project Number to deploy for Cloud Run",
+		Value:         &opts.CloudRunProject,
+		DefValue:      "",
+		FlagAddMethod: "StringVar",
+		DefinedOn:     []string{"dev", "run", "debug", "deploy", "apply", "delete"},
+	},
+	{
+		Name:          "cloud-run-location",
+		Shorthand:     "",
+		Usage:         "The GCP Region to deploy Cloud Run services to",
+		Value:         &opts.CloudRunLocation,
+		DefValue:      "",
+		FlagAddMethod: "StringVar",
+		DefinedOn:     []string{"dev", "run", "debug", "deploy", "apply", "delete"},
+	},
 }
 
 func methodNameByType(v reflect.Value) string {
diff --git a/cmd/skaffold/app/cmd/schema/list.go b/cmd/skaffold/app/cmd/schema/list.go
index 183d2bc3c..dffba68eb 100644
--- a/cmd/skaffold/app/cmd/schema/list.go
+++ b/cmd/skaffold/app/cmd/schema/list.go
@@ -27,7 +27,6 @@ import (
 
 var OutputType string
 
-// TODO(yuwenma): We currently hide the v3alpha* schemas from users. We should display it once the render v2 is available.
 // List prints to `out` all supported schema versions.
 func List(_ context.Context, out io.Writer) error {
 	return list(out, OutputType)
@@ -69,5 +68,9 @@ func versions() []string {
 		versions = append(versions, version.APIVersion)
 	}
 
+	for _, version := range schema.SchemaVersionsV2 {
+		versions = append(versions, version.APIVersion)
+	}
+
 	return versions
 }
diff --git a/docs-v2/content/en/docs/pipeline-stages/deployers/_index.md b/docs-v2/content/en/docs/pipeline-stages/deployers/_index.md
index 0e1dfbd4c..4ac946ac6 100644
--- a/docs-v2/content/en/docs/pipeline-stages/deployers/_index.md
+++ b/docs-v2/content/en/docs/pipeline-stages/deployers/_index.md
@@ -7,18 +7,13 @@ aliases: [/docs/how-tos/deployers]
 no_list: true
 ---
 
-When Skaffold deploys your application to Kubernetes, it (usually) goes through these steps:
+When Skaffold deploys your application to Kubernetes, it goes through these steps:
 
 In the default case (no manifest provided using the kubectl or kpt deployer ), skaffold deploy will do the following:
 * the Skaffold renderer _renders_ the final Kubernetes manifests: Skaffold replaces untagged image names in the Kubernetes manifests with the final tagged image names.
-It also might go through the extra intermediate step of expanding templates (for helm) or calculating overlays (for kustomize).
+It also might go through the extra intermediate step of expanding templates (for helm) or calculating overlays (for kustomize).  Additionally some deployers (docker) do not render manifests as such don't use this phase.
 * the Skaffold deployer _deploys_ the final Kubernetes manifests to the cluster (or to local docker for the docker deployer)
 * the Skaffold deployer performs [status checks]({{< relref "/docs/pipeline-stages/status-check" >}}) and waits for the deployed resources to stabilize.
-
-In the case that a manifest file is supplied via the --TODO flag or the deployer does not accept manifests (eg: helm and docker) skaffold deploy will only do the following steps:
-* the Skaffold deployer _deploys_ the supplied Kubernetes manifests to the cluster (or deploys the specified container to docker for the docker deployer)
-* the Skaffold deployer performs [status checks]({{< relref "/docs/pipeline-stages/status-check" >}}) and waits for the deployed resources to stabilize
-
 ### Supported deployers
 
 Skaffold supports the following tools for deploying applications:
diff --git a/docs/content/en/docs/references/cli/_index.md b/docs/content/en/docs/references/cli/_index.md
index 44c60df29..0c843957d 100644
--- a/docs/content/en/docs/references/cli/_index.md
+++ b/docs/content/en/docs/references/cli/_index.md
@@ -122,6 +122,8 @@ Examples:
 
 Options:
       --assume-yes=false: If true, skaffold will skip yes/no confirmation from the user and default to yes
+      --cloud-run-location='': The GCP Region to deploy Cloud Run services to
+      --cloud-run-project='': The GCP Project ID or Project Number to deploy for Cloud Run
   -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config)
   -f, --filename='skaffold.yaml': Path or URL to the Skaffold config file
       --force=false: Recreate Kubernetes resources if necessary for deployment, warning: might cause downtime!
@@ -147,6 +149,8 @@ Use "skaffold options" for a list of global command-line options (applies to all
 Env vars:
 
 * `SKAFFOLD_ASSUME_YES` (same as `--assume-yes`)
+* `SKAFFOLD_CLOUD_RUN_LOCATION` (same as `--cloud-run-location`)
+* `SKAFFOLD_CLOUD_RUN_PROJECT` (same as `--cloud-run-project`)
 * `SKAFFOLD_CONFIG` (same as `--config`)
 * `SKAFFOLD_FILENAME` (same as `--filename`)
 * `SKAFFOLD_FORCE` (same as `--force`)
@@ -405,6 +409,8 @@ Options:
       --cache-artifacts=true: Set to false to disable default caching of artifacts
       --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache)
       --cleanup=true: Delete deployments after dev or debug mode is interrupted
+      --cloud-run-location='': The GCP Region to deploy Cloud Run services to
+      --cloud-run-project='': The GCP Project ID or Project Number to deploy for Cloud Run
   -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config)
   -d, --default-repo='': Default repository value (overrides global config)
       --detect-minikube=true: Use heuristics to detect a minikube cluster
@@ -464,6 +470,8 @@ Env vars:
 * `SKAFFOLD_CACHE_ARTIFACTS` (same as `--cache-artifacts`)
 * `SKAFFOLD_CACHE_FILE` (same as `--cache-file`)
 * `SKAFFOLD_CLEANUP` (same as `--cleanup`)
+* `SKAFFOLD_CLOUD_RUN_LOCATION` (same as `--cloud-run-location`)
+* `SKAFFOLD_CLOUD_RUN_PROJECT` (same as `--cloud-run-project`)
 * `SKAFFOLD_CONFIG` (same as `--config`)
 * `SKAFFOLD_DEFAULT_REPO` (same as `--default-repo`)
 * `SKAFFOLD_DETECT_MINIKUBE` (same as `--detect-minikube`)
@@ -518,6 +526,8 @@ Examples:
 
 Options:
       --assume-yes=false: If true, skaffold will skip yes/no confirmation from the user and default to yes
+      --cloud-run-location='': The GCP Region to deploy Cloud Run services to
+      --cloud-run-project='': The GCP Project ID or Project Number to deploy for Cloud Run
   -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config)
   -d, --default-repo='': Default repository value (overrides global config)
       --detect-minikube=true: Use heuristics to detect a minikube cluster
@@ -543,6 +553,8 @@ Use "skaffold options" for a list of global command-line options (applies to all
 Env vars:
 
 * `SKAFFOLD_ASSUME_YES` (same as `--assume-yes`)
+* `SKAFFOLD_CLOUD_RUN_LOCATION` (same as `--cloud-run-location`)
+* `SKAFFOLD_CLOUD_RUN_PROJECT` (same as `--cloud-run-project`)
 * `SKAFFOLD_CONFIG` (same as `--config`)
 * `SKAFFOLD_DEFAULT_REPO` (same as `--default-repo`)
 * `SKAFFOLD_DETECT_MINIKUBE` (same as `--detect-minikube`)
@@ -579,6 +591,8 @@ Options:
       --assume-yes=false: If true, skaffold will skip yes/no confirmation from the user and default to yes
   -a, --build-artifacts=: File containing build result from a previous 'skaffold build --file-output'
       --build-concurrency=-1: Number of concurrently running builds. Set to 0 to run all builds in parallel. Doesn't violate build order among dependencies.
+      --cloud-run-location='': The GCP Region to deploy Cloud Run services to
+      --cloud-run-project='': The GCP Project ID or Project Number to deploy for Cloud Run
   -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config)
   -d, --default-repo='': Default repository value (overrides global config)
       --detect-minikube=true: Use heuristics to detect a minikube cluster
@@ -626,6 +640,8 @@ Env vars:
 * `SKAFFOLD_ASSUME_YES` (same as `--assume-yes`)
 * `SKAFFOLD_BUILD_ARTIFACTS` (same as `--build-artifacts`)
 * `SKAFFOLD_BUILD_CONCURRENCY` (same as `--build-concurrency`)
+* `SKAFFOLD_CLOUD_RUN_LOCATION` (same as `--cloud-run-location`)
+* `SKAFFOLD_CLOUD_RUN_PROJECT` (same as `--cloud-run-project`)
 * `SKAFFOLD_CONFIG` (same as `--config`)
 * `SKAFFOLD_DEFAULT_REPO` (same as `--default-repo`)
 * `SKAFFOLD_DETECT_MINIKUBE` (same as `--detect-minikube`)
@@ -678,6 +694,8 @@ Options:
       --cache-artifacts=true: Set to false to disable default caching of artifacts
       --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache)
       --cleanup=true: Delete deployments after dev or debug mode is interrupted
+      --cloud-run-location='': The GCP Region to deploy Cloud Run services to
+      --cloud-run-project='': The GCP Project ID or Project Number to deploy for Cloud Run
   -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config)
   -d, --default-repo='': Default repository value (overrides global config)
       --detect-minikube=true: Use heuristics to detect a minikube cluster
@@ -737,6 +755,8 @@ Env vars:
 * `SKAFFOLD_CACHE_ARTIFACTS` (same as `--cache-artifacts`)
 * `SKAFFOLD_CACHE_FILE` (same as `--cache-file`)
 * `SKAFFOLD_CLEANUP` (same as `--cleanup`)
+* `SKAFFOLD_CLOUD_RUN_LOCATION` (same as `--cloud-run-location`)
+* `SKAFFOLD_CLOUD_RUN_PROJECT` (same as `--cloud-run-project`)
 * `SKAFFOLD_CONFIG` (same as `--config`)
 * `SKAFFOLD_DEFAULT_REPO` (same as `--default-repo`)
 * `SKAFFOLD_DETECT_MINIKUBE` (same as `--detect-minikube`)
@@ -1023,6 +1043,8 @@ Options:
       --cache-artifacts=true: Set to false to disable default caching of artifacts
       --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache)
       --cleanup=true: Delete deployments after dev or debug mode is interrupted
+      --cloud-run-location='': The GCP Region to deploy Cloud Run services to
+      --cloud-run-project='': The GCP Project ID or Project Number to deploy for Cloud Run
   -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config)
   -d, --default-repo='': Default repository value (overrides global config)
       --detect-minikube=true: Use heuristics to detect a minikube cluster
@@ -1077,6 +1099,8 @@ Env vars:
 * `SKAFFOLD_CACHE_ARTIFACTS` (same as `--cache-artifacts`)
 * `SKAFFOLD_CACHE_FILE` (same as `--cache-file`)
 * `SKAFFOLD_CLEANUP` (same as `--cleanup`)
+* `SKAFFOLD_CLOUD_RUN_LOCATION` (same as `--cloud-run-location`)
+* `SKAFFOLD_CLOUD_RUN_PROJECT` (same as `--cloud-run-project`)
 * `SKAFFOLD_CONFIG` (same as `--config`)
 * `SKAFFOLD_DEFAULT_REPO` (same as `--default-repo`)
 * `SKAFFOLD_DETECT_MINIKUBE` (same as `--detect-minikube`)
diff --git a/docs/content/en/samples/deployers/kubectl.yaml b/docs/content/en/samples/deployers/kubectl.yaml
index 1fd919953..221b91b08 100644
--- a/docs/content/en/samples/deployers/kubectl.yaml
+++ b/docs/content/en/samples/deployers/kubectl.yaml
@@ -1,4 +1,3 @@
-deploy:
-  kubectl:
-    manifests:
-    - k8s-*
+manifests:
+  rawYaml:    
+  - k8s-*
diff --git a/docs/content/en/samples/deployers/status-check.yaml b/docs/content/en/samples/deployers/status-check.yaml
index 010016baa..c1d010872 100644
--- a/docs/content/en/samples/deployers/status-check.yaml
+++ b/docs/content/en/samples/deployers/status-check.yaml
@@ -1,5 +1,2 @@
 deploy:
   statusCheckDeadlineSeconds: 300
-  kubectl:
-    manifests:
-    - k8s-*
\ No newline at end of file
diff --git a/docs/content/en/samples/pipeline-stages/init-example.yaml b/docs/content/en/samples/pipeline-stages/init-example.yaml
index ed9d4099d..5d83b0549 100644
--- a/docs/content/en/samples/pipeline-stages/init-example.yaml
+++ b/docs/content/en/samples/pipeline-stages/init-example.yaml
@@ -6,8 +6,7 @@ build:
     context: leeroy-app
   - image: gcr.io/k8s-skaffold/leeroy-web
     context: path/to/context
-deploy:
-  kubectl:
-    manifests:
+manifests:
+  rawYaml:
     - leeroy-app/kubernetes/deployment.yaml
-    - leeroy-web/kubernetes/deployment.yaml
\ No newline at end of file
+    - leeroy-web/kubernetes/deployment.yaml
diff --git a/docs/content/en/samples/profiles/activations.yaml b/docs/content/en/samples/profiles/activations.yaml
index b1f8d1fd0..b9d67abad 100644
--- a/docs/content/en/samples/profiles/activations.yaml
+++ b/docs/content/en/samples/profiles/activations.yaml
@@ -1,10 +1,9 @@
 build:
   artifacts:
   - image: gcr.io/k8s-skaffold/skaffold-example
-deploy:
-  kubectl:
-    manifests:
-    - k8s-pod
+manifests:
+  rawYaml:
+  - k8s-pod
 profiles:
 - name: profile1
   activation:
diff --git a/docs/content/en/samples/profiles/patches.yaml b/docs/content/en/samples/profiles/patches.yaml
index 07061d161..7410d48a2 100644
--- a/docs/content/en/samples/profiles/patches.yaml
+++ b/docs/content/en/samples/profiles/patches.yaml
@@ -5,10 +5,9 @@ build:
         dockerfile: Dockerfile
     - image: gcr.io/k8s-skaffold/skaffold2
     - image: gcr.io/k8s-skaffold/skaffold3
-deploy:
-  kubectl:
-    manifests:
-      - k8s-pod
+manifests:
+  rawYaml:
+  - k8s-pod
 profiles:
   - name: dev
     patches:
diff --git a/docs/content/en/samples/profiles/profiles.yaml b/docs/content/en/samples/profiles/profiles.yaml
index 9017e0ee8..5c8e49a8d 100644
--- a/docs/content/en/samples/profiles/profiles.yaml
+++ b/docs/content/en/samples/profiles/profiles.yaml
@@ -1,10 +1,9 @@
 build:
   artifacts:
   - image: gcr.io/k8s-skaffold/skaffold-example
-deploy:
-  kubectl:
-    manifests:
-    - k8s-pod
+manifests:
+  rawYaml:
+  - k8s-pod
 profiles:
 - name: gcb
   build:
diff --git a/integration/examples/cross-platform-builds/skaffold.yaml b/integration/examples/cross-platform-builds/skaffold.yaml
index b9f503eb6..2b8de1eec 100644
--- a/integration/examples/cross-platform-builds/skaffold.yaml
+++ b/integration/examples/cross-platform-builds/skaffold.yaml
@@ -1,10 +1,17 @@
 apiVersion: skaffold/v3alpha1
 kind: Config
 build:
-  platforms: ["linux/amd64"]
   artifacts:
   - image: skaffold-example
-deploy:
-  kubectl:
-    manifests:
-      - k8s-*
+    context: .
+    docker:
+      dockerfile: Dockerfile
+  tagPolicy:
+    gitCommit: {}
+  platforms:
+  - linux/amd64
+  local:
+    concurrency: 1
+manifests:
+  rawYaml:
+  - k8s-*
diff --git a/integration/examples/cross-platform-builds/skaffold.yaml.v2 b/integration/examples/cross-platform-builds/skaffold.yaml.v2
new file mode 100644
index 000000000..a2a0f34f7
--- /dev/null
+++ b/integration/examples/cross-platform-builds/skaffold.yaml.v2
@@ -0,0 +1,10 @@
+apiVersion: skaffold/v2beta29
+kind: Config
+build:
+  platforms: ["linux/amd64"]
+  artifacts:
+  - image: skaffold-example
+deploy:
+  kubectl:
+    manifests:
+      - k8s-*
diff --git a/integration/examples/gcb-kaniko/skaffold.yaml b/integration/examples/gcb-kaniko/skaffold.yaml
index c2acc22ae..e531beac0 100644
--- a/integration/examples/gcb-kaniko/skaffold.yaml
+++ b/integration/examples/gcb-kaniko/skaffold.yaml
@@ -7,7 +7,6 @@ build:
   - image: skaffold-example
     kaniko:
       cache: {}
-deploy:
-  kubectl:
-    manifests:
-      - k8s-*
+manifests:
+  rawYaml:
+  - k8s-*
diff --git a/integration/examples/generate-pipeline/skaffold.yaml b/integration/examples/generate-pipeline/skaffold.yaml
index 1670ec3e3..9c27396e3 100644
--- a/integration/examples/generate-pipeline/skaffold.yaml
+++ b/integration/examples/generate-pipeline/skaffold.yaml
@@ -3,7 +3,6 @@ kind: Config
 build:
   artifacts:
   - image: pipeline-example
-deploy:
-  kubectl:
-    manifests:
-    - k8s-*
+manifests:
+  rawYaml:
+  - k8s-*
diff --git a/integration/examples/getting-started-kustomize/skaffold.yaml b/integration/examples/getting-started-kustomize/skaffold.yaml
index dd02586b7..03c55d803 100644
--- a/integration/examples/getting-started-kustomize/skaffold.yaml
+++ b/integration/examples/getting-started-kustomize/skaffold.yaml
@@ -8,18 +8,18 @@ build:
     context: app
     docker:
       dockerfile: Dockerfile
-deploy:
+manifests:
   kustomize:
     paths:
     - overlays/dev
 profiles:
 - name: prod
-  deploy:
+  manifests:
     kustomize:
       paths:
       - overlays/prod
 - name: staging
-  deploy:
+  manifests:
     kustomize:
       paths:
       - overlays/staging
diff --git a/integration/examples/google-cloud-build/skaffold.yaml b/integration/examples/google-cloud-build/skaffold.yaml
index 818136d7c..461badc49 100644
--- a/integration/examples/google-cloud-build/skaffold.yaml
+++ b/integration/examples/google-cloud-build/skaffold.yaml
@@ -5,7 +5,6 @@ build:
     projectId: k8s-skaffold
   artifacts:
   - image: skaffold-example
-deploy:
-  kubectl:
-    manifests:
-      - k8s-*
+manifests:
+  rawYaml:
+  - k8s-*
diff --git a/integration/examples/kaniko/skaffold.yaml b/integration/examples/kaniko/skaffold.yaml
index 5f0dcc102..777bb5b83 100644
--- a/integration/examples/kaniko/skaffold.yaml
+++ b/integration/examples/kaniko/skaffold.yaml
@@ -9,7 +9,6 @@ build:
     pullSecretName: e2esecret-with-path
     pullSecretPath:     kaniko-secret.json
     namespace: default
-deploy:
-  kubectl:
-    manifests:
-      - k8s-*
+manifests:
+  rawYaml:
+  - k8s-*
diff --git a/integration/examples/lifecycle-hooks/skaffold.yaml b/integration/examples/lifecycle-hooks/skaffold.yaml
index a604e04bc..07bdf6638 100644
--- a/integration/examples/lifecycle-hooks/skaffold.yaml
+++ b/integration/examples/lifecycle-hooks/skaffold.yaml
@@ -31,10 +31,11 @@ build:
         after:
           - container:
               command: ["sh", "-c", "set -x; kill -HUP 1"]
+manifests:
+  rawYaml:
+  - deployment.yaml
 deploy:
   kubectl:
-    manifests:
-      - deployment.yaml
     hooks:
       before:
         - host:
diff --git a/integration/examples/microservices/README.md b/integration/examples/microservices/README.md
index 5f192fba1..37ee0ada5 100644
--- a/integration/examples/microservices/README.md
+++ b/integration/examples/microservices/README.md
@@ -87,10 +87,9 @@ COPY --from=builder /app .
 In the deploy stanza, we use the glob matching pattern to deploy all YAML and JSON files in the respective Kubernetes manifest directories.
 
 ```yaml
-deploy:
-  kubectl:
-    manifests:
-    - ./leeroy-web/kubernetes/*
-    - ./leeroy-app/kubernetes/*
+manifests:
+  rawYaml:
+  - ./leeroy-web/kubernetes/*
+  - ./leeroy-app/kubernetes/*
 ```
 
diff --git a/integration/examples/profile-patches/skaffold.yaml b/integration/examples/profile-patches/skaffold.yaml
index 96d8bf0a0..21caa4ac4 100644
--- a/integration/examples/profile-patches/skaffold.yaml
+++ b/integration/examples/profile-patches/skaffold.yaml
@@ -5,10 +5,9 @@ build:
   artifacts:
   - image: skaffold-base
     context: base-service
-deploy:
-  kubectl:
-    manifests:
-      - 'base-service/*.yaml'
+manifests:
+  rawYaml:
+  - 'base-service/*.yaml'
 
 profiles:
   - name: hello
@@ -19,7 +18,7 @@ profiles:
           image: skaffold-hello
           context: hello-service
       - op: add
-        path: /deploy/kubectl/manifests/1
+        path: /manifests/rawYaml/1
         value: 'hello-service/*.yaml'
 
   - name: world
@@ -30,5 +29,5 @@ profiles:
           image: skaffold-world
           context: world-service
       - op: add
-        path: /deploy/kubectl/manifests/1
+        path: /manifests/rawYaml/1
         value: 'world-service/*.yaml'
diff --git a/integration/examples/simple-artifact-dependency/skaffold.yaml b/integration/examples/simple-artifact-dependency/skaffold.yaml
index 87a8f585d..fca30aa78 100644
--- a/integration/examples/simple-artifact-dependency/skaffold.yaml
+++ b/integration/examples/simple-artifact-dependency/skaffold.yaml
@@ -9,8 +9,7 @@ build:
       alias: BASE
   - image: base
     context: base
-deploy:
-  kubectl:
-    manifests:
-    - app/k8s-pod.yaml
+manifests:
+  rawYaml:
+  - app/k8s-pod.yaml
 
diff --git a/pkg/skaffold/config/options.go b/pkg/skaffold/config/options.go
index 2b92a83ef..6e8988b04 100644
--- a/pkg/skaffold/config/options.go
+++ b/pkg/skaffold/config/options.go
@@ -61,6 +61,8 @@ type SkaffoldOptions struct {
 	EnablePlatformNodeAffinity bool
 	MakePathsAbsolute          *bool
 	MultiLevelRepo             *bool
+	CloudRunProject            string
+	CloudRunLocation           string
 	ConfigurationFile          string
 	HydrationDir               string
 	InventoryNamespace         string
diff --git a/pkg/skaffold/deploy/kubectl/errors.go b/pkg/skaffold/deploy/kubectl/errors.go
index 5b3f35bbe..1e809561f 100644
--- a/pkg/skaffold/deploy/kubectl/errors.go
+++ b/pkg/skaffold/deploy/kubectl/errors.go
@@ -59,14 +59,6 @@ func readManifestErr(err error) error {
 		})
 }
 
-func readRemoteManifestErr(err error) error {
-	return sErrors.NewError(err,
-		&proto.ActionableErr{
-			Message: err.Error(),
-			ErrCode: proto.StatusCode_DEPLOY_READ_REMOTE_MANIFEST_ERR,
-		})
-}
-
 func userErr(err error) error {
 	return deployerr.UserError(err, proto.StatusCode_DEPLOY_KUBECTL_USER_ERR)
 }
diff --git a/pkg/skaffold/deploy/kubectl/kubectl.go b/pkg/skaffold/deploy/kubectl/kubectl.go
index 9285a8508..14539ac55 100644
--- a/pkg/skaffold/deploy/kubectl/kubectl.go
+++ b/pkg/skaffold/deploy/kubectl/kubectl.go
@@ -17,11 +17,9 @@ limitations under the License.
 package kubectl
 
 import (
-	"bytes"
 	"context"
 	"fmt"
 	"io"
-	"strings"
 
 	"github.com/segmentio/textio"
 	"go.opentelemetry.io/otel/trace"
@@ -50,7 +48,6 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/status"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/sync"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
-	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util/stringslice"
 )
 
 // Deployer deploys workflows using kubectl CLI.
@@ -72,7 +69,6 @@ type Deployer struct {
 	hydratedManifests  []string
 	workingDir         string
 	globalConfig       string
-	gcsManifestDir     string
 	defaultRepo        *string
 	multiLevelRepo     *bool
 	kubectl            CLI
@@ -281,72 +277,6 @@ func (k *Deployer) PostDeployHooks(ctx context.Context, out io.Writer) error {
 	return nil
 }
 
-func (k *Deployer) manifestFiles(manifests []string) ([]string, error) {
-	var nonURLManifests, gcsManifests []string
-	for _, manifest := range manifests {
-		switch {
-		case util.IsURL(manifest):
-		case strings.HasPrefix(manifest, "gs://"):
-			gcsManifests = append(gcsManifests, manifest)
-		default:
-			nonURLManifests = append(nonURLManifests, manifest)
-		}
-	}
-
-	list, err := util.ExpandPathsGlob(k.workingDir, nonURLManifests)
-	if err != nil {
-		return nil, userErr(fmt.Errorf("expanding kubectl manifest paths: %w", err))
-	}
-
-	if len(gcsManifests) != 0 {
-		// return tmp dir of the downloaded manifests
-		tmpDir, err := manifest.DownloadFromGCS(gcsManifests)
-		if err != nil {
-			return nil, userErr(fmt.Errorf("downloading from GCS: %w", err))
-		}
-		k.gcsManifestDir = tmpDir
-		l, err := util.ExpandPathsGlob(tmpDir, []string{"*"})
-		if err != nil {
-			return nil, userErr(fmt.Errorf("expanding kubectl manifest paths: %w", err))
-		}
-		list = append(list, l...)
-	}
-
-	var filteredManifests []string
-	for _, f := range list {
-		if !kubernetes.HasKubernetesFileExtension(f) {
-			if !stringslice.Contains(manifests, f) {
-				olog.Entry(context.TODO()).Infof("refusing to deploy/delete non {json, yaml} file %s", f)
-				olog.Entry(context.TODO()).Info("If you still wish to deploy this file, please specify it directly, outside a glob pattern.")
-				continue
-			}
-		}
-		filteredManifests = append(filteredManifests, f)
-	}
-
-	return filteredManifests, nil
-}
-
-// readRemoteManifests will try to read manifests from the given kubernetes
-// context in the specified namespace and for the specified type
-func (k *Deployer) readRemoteManifest(ctx context.Context, name string) ([]byte, error) {
-	var args []string
-	ns := ""
-	if parts := strings.Split(name, ":"); len(parts) > 1 {
-		ns = parts[0]
-		name = parts[1]
-	}
-	args = append(args, name, "-o", "yaml")
-
-	var manifest bytes.Buffer
-	err := k.kubectl.RunInNamespace(ctx, nil, &manifest, "get", ns, args...)
-	if err != nil {
-		return nil, readRemoteManifestErr(fmt.Errorf("getting remote manifests: %w", err))
-	}
-
-	return manifest.Bytes(), nil
-}
-
 // Cleanup deletes what was deployed by calling Deploy.
 func (k *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, manifestsByConfig manifest.ManifestListByConfig) error {
 	var manifests manifest.ManifestList
@@ -355,34 +285,11 @@ func (k *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, mani
 		"DeployerType": "kubectl",
 	})
 	if dryRun {
-		for _, manifest := range manifests {
-			output.White.Fprintf(out, "---\n%s", manifest)
+		for _, manifestP := range manifests {
+			output.White.Fprintf(out, "---\n%s", manifestP)
 		}
 		return nil
 	}
-	// revert remote manifests
-	// TODO(dgageot): That seems super dangerous and I don't understand
-	// why we need to update resources just before we delete them.
-	// todo clean up this block as RemoteManifests is no longer used for deployer
-	if len(k.RemoteManifests) > 0 {
-		var rm manifest.ManifestList
-		for _, m := range k.RemoteManifests {
-			manifest, err := k.readRemoteManifest(ctx, m)
-			if err != nil {
-				return err
-			}
-			rm = append(rm, manifest)
-		}
-
-		upd, err := rm.ReplaceRemoteManifestImages(ctx, k.originalImages, manifest.NewResourceSelectorImages(k.transformableAllowlist, k.transformableDenylist))
-		if err != nil {
-			return err
-		}
-
-		if err := k.kubectl.Apply(ctx, out, upd); err != nil {
-			return err
-		}
-	}
 
 	if err := k.kubectl.Delete(ctx, textio.NewPrefixWriter(out, " - "), manifests); err != nil {
 		return err
@@ -393,5 +300,5 @@ func (k *Deployer) Cleanup(ctx context.Context, out io.Writer, dryRun bool, mani
 
 // Dependencies lists all the files that describe what needs to be deployed.
 func (k *Deployer) Dependencies() ([]string, error) {
-	return k.manifestFiles(k.KubectlDeploy.Manifests)
+	return []string{}, nil
 }
diff --git a/pkg/skaffold/kubernetes/manifest/manifests.go b/pkg/skaffold/kubernetes/manifest/manifests.go
index 185d89a1c..92d56de81 100644
--- a/pkg/skaffold/kubernetes/manifest/manifests.go
+++ b/pkg/skaffold/kubernetes/manifest/manifests.go
@@ -46,8 +46,12 @@ func NewManifestListByConfig() ManifestListByConfig {
 }
 
 func (ml *ManifestListByConfig) Add(configName string, manifest ManifestList) {
-	ml.configNames = append(ml.configNames, configName)
-	ml.manifests[configName] = manifest
+	if _, ok := ml.manifests[configName]; !ok {
+		ml.configNames = append(ml.configNames, configName)
+		ml.manifests[configName] = manifest
+		return
+	}
+	ml.manifests[configName] = append(ml.manifests[configName], manifest...)
 }
 
 func (ml ManifestListByConfig) GetForConfig(configName string) ManifestList {
diff --git a/pkg/skaffold/lint/k8smanifests.go b/pkg/skaffold/lint/k8smanifests.go
index 9b6136487..08953c519 100644
--- a/pkg/skaffold/lint/k8smanifests.go
+++ b/pkg/skaffold/lint/k8smanifests.go
@@ -67,10 +67,7 @@ func GetK8sManifestsLintResults(ctx context.Context, opts Options) (*[]Result, e
 	}
 
 	for _, c := range cfgs {
-		if c.Deploy.KubectlDeploy == nil {
-			continue
-		}
-		for _, pattern := range c.Deploy.KubectlDeploy.Manifests {
+		for _, pattern := range c.Render.RawK8s {
 			// NOTE: pattern is a pattern that can have wildcards, eg: leeroy-app/kubernetes/*
 			if util.IsURL(pattern) {
 				log.Entry(ctx).Debugf("skaffold lint found url manifest and is skipping lint rules for: %s", pattern)
diff --git a/pkg/skaffold/lint/skaffoldyamls.go b/pkg/skaffold/lint/skaffoldyamls.go
index c3670dc8d..ac2d09a60 100644
--- a/pkg/skaffold/lint/skaffoldyamls.go
+++ b/pkg/skaffold/lint/skaffoldyamls.go
@@ -83,13 +83,13 @@ var skaffoldYamlLintRules = []Rule{
   localPort: {{ $v.LocalPort }}{{end}}`,
 		LintConditions: []func(InputParams) bool{
 			func(params InputParams) bool {
-				// checks if deploy stanza exists
+				// checks if manifests stanza exists
 				linter := &YamlFieldLinter{}
 				recs, err := linter.Lint(params, &[]Rule{
 					{
 						RuleType: YamlFieldLintRule,
 						Filter: YamlFieldFilter{
-							Filter: yaml.Lookup("deploy"),
+							Filter: yaml.Lookup("manifests"),
 						},
 					},
 				})
@@ -106,10 +106,7 @@ var skaffoldYamlLintRules = []Rule{
 		ExplanationPopulator: func(lintInputs InputParams) (explanationInfo, error) {
 			fieldMap := map[string]interface{}{}
 			forwardedPorts := util.PortSet{}
-			if lintInputs.SkaffoldConfig.Deploy.KubectlDeploy == nil {
-				return explanationInfo{}, fmt.Errorf("expected kubectl deploy information to be populated but it was nil")
-			}
-			for _, pattern := range lintInputs.SkaffoldConfig.Deploy.KubectlDeploy.Manifests {
+			for _, pattern := range lintInputs.SkaffoldConfig.Render.Generate.RawK8s {
 				// NOTE: pattern is a pattern that can have wildcards, eg: leeroy-app/kubernetes/*
 				if util.IsURL(pattern) {
 					log.Entry(context.TODO()).Infof("skaffold lint found url manifest when processing rule %d and is skipping lint rules for: %s", SkaffoldYamlUseStaticPort, pattern)
diff --git a/pkg/skaffold/render/generate/generate.go b/pkg/skaffold/render/generate/generate.go
index c4a58025a..2b6e179da 100644
--- a/pkg/skaffold/render/generate/generate.go
+++ b/pkg/skaffold/render/generate/generate.go
@@ -34,7 +34,6 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/render/kptfile"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
-	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util/stringset"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util/stringslice"
 )
 
@@ -53,6 +52,19 @@ type Generator struct {
 	config       latest.Generate
 }
 
+func localManifests(paths []string, workdir string) ([]string, error) {
+	var localPaths []string
+	for _, path := range paths {
+		switch {
+		case util.IsURL(path):
+		case strings.HasPrefix(path, "gs://"):
+		default:
+			localPaths = append(localPaths, path)
+		}
+	}
+	return util.ExpandPathsGlob(workdir, localPaths)
+}
+
 func resolveRemoteAndLocal(paths []string, workdir string) ([]string, error) {
 	var localPaths []string
 	var gcsManifests []string
@@ -259,34 +271,31 @@ func isKptDir(path string) (string, bool) {
 	return dir, true
 }
 
-// walkManifests finds out all the manifests from the `.manifests.generate`, so they can be registered in the file watcher.
+// walkLocalManifests finds out all the manifests from the `.manifests.generate`, so they can be registered in the file watcher.
 // Note: the logic about manifest dependencies shall separate from the "Generate" function, which requires "context" and
 // only be called when a rendering action is needed (normally happens after the file watcher registration).
-func (g Generator) walkManifests() ([]string, error) {
+func (g Generator) walkLocalManifests() ([]string, error) {
 	var dependencyPaths []string
 
 	// Generate kustomize Manifests
 	if g.config.Kustomize != nil {
-		kustomizePaths, err := resolveRemoteAndLocal(g.config.Kustomize.Paths, g.workingDir)
+		kustomizePaths, err := localManifests(g.config.Kustomize.Paths, g.workingDir)
 		if err != nil {
-			event.DeployInfoEvent(fmt.Errorf("could not expand the glob kustomize manifests: %w", err))
 			return nil, err
 		}
 		dependencyPaths = append(dependencyPaths, kustomizePaths...)
 	}
 
 	// Generate in-place hydrated kpt Manifests
-	kptPaths, err := resolveRemoteAndLocal(g.config.Kpt, g.workingDir)
+	kptPaths, err := localManifests(g.config.Kpt, g.workingDir)
 	if err != nil {
-		event.DeployInfoEvent(fmt.Errorf("could not expand the glob kpt manifests: %w", err))
 		return nil, err
 	}
 	dependencyPaths = append(dependencyPaths, kptPaths...)
 
 	// Generate Raw Manifests
-	sourceManifests, err := resolveRemoteAndLocal(g.config.RawK8s, g.workingDir)
+	sourceManifests, err := localManifests(g.config.RawK8s, g.workingDir)
 	if err != nil {
-		event.DeployInfoEvent(fmt.Errorf("could not expand the glob raw manifests: %w", err))
 		return nil, err
 	}
 	dependencyPaths = append(dependencyPaths, sourceManifests...)
@@ -294,9 +303,9 @@ func (g Generator) walkManifests() ([]string, error) {
 }
 
 func (g Generator) ManifestDeps() ([]string, error) {
-	deps := stringset.New()
+	deps := []string{}
 
-	dependencyPaths, err := g.walkManifests()
+	dependencyPaths, err := g.walkLocalManifests()
 	if err != nil {
 		return nil, err
 	}
@@ -308,7 +317,7 @@ func (g Generator) ManifestDeps() ([]string, error) {
 				}
 				fname := filepath.Base(p)
 				if strings.HasSuffix(fname, ".yaml") || strings.HasSuffix(fname, ".yml") || fname == kptfile.KptFileName {
-					deps.Insert(p)
+					deps = append(deps, p)
 				}
 				return nil
 			})
@@ -316,5 +325,5 @@ func (g Generator) ManifestDeps() ([]string, error) {
 			return nil, err
 		}
 	}
-	return deps.ToList(), nil
+	return deps, nil
 }
diff --git a/pkg/skaffold/render/renderer/noop/noop.go b/pkg/skaffold/render/renderer/noop/noop.go
index 661b3ebf3..377d1f86d 100644
--- a/pkg/skaffold/render/renderer/noop/noop.go
+++ b/pkg/skaffold/render/renderer/noop/noop.go
@@ -30,8 +30,8 @@ import (
 // TODO(marlongamez): add Helm renderer which uses helm template and can feed into deployers
 type Noop struct{}
 
-func New(_ latest.RenderConfig, _, _ string, _ map[string]string) (Noop, error) {
-	return Noop{}, nil
+func New(_ latest.RenderConfig, _, _ string, _ map[string]string) Noop {
+	return Noop{}
 }
 
 func (r Noop) Render(ctx context.Context, out io.Writer, artifacts []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error) {
diff --git a/pkg/skaffold/render/renderer/render_mux.go b/pkg/skaffold/render/renderer/render_mux.go
index 8b1eb3ebd..c3d55f6e7 100644
--- a/pkg/skaffold/render/renderer/render_mux.go
+++ b/pkg/skaffold/render/renderer/render_mux.go
@@ -30,14 +30,17 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util/stringset"
 )
 
+// GroupRenderer maintains the slice of all `Renderer`s defined in a single Skaffold config.
+type GroupRenderer []Renderer
+
 // RenderMux forwards all method calls to the renderers it contains.
 // When encountering an error, it aborts and returns the error. Otherwise,
 // it collects the results and returns all the manifests.
 type RenderMux struct {
-	renderers []Renderer
+	renderers GroupRenderer
 }
 
-func NewRenderMux(renderers []Renderer) Renderer {
+func NewRenderMux(renderers GroupRenderer) Renderer {
 	return RenderMux{renderers: renderers}
 }
 
diff --git a/pkg/skaffold/render/renderer/renderer.go b/pkg/skaffold/render/renderer/renderer.go
index ceaaffd20..43fde13d0 100644
--- a/pkg/skaffold/render/renderer/renderer.go
+++ b/pkg/skaffold/render/renderer/renderer.go
@@ -39,18 +39,32 @@ type Renderer interface {
 }
 
 // New creates a new Renderer object from the latestV2 API schema.
-func New(cfg render.Config, renderCfg latest.RenderConfig, hydrationDir string, labels map[string]string, usingLegacyHelmDeploy bool, command string, configName string) (Renderer, error) {
+func New(ctx context.Context, cfg render.Config, renderCfg latest.RenderConfig, hydrationDir string, labels map[string]string, usingLegacyHelmDeploy bool, command string, configName string) (GroupRenderer, error) {
 	if usingLegacyHelmDeploy && command != "render" {
-		return noop.New(renderCfg, cfg.GetWorkingDir(), hydrationDir, labels)
+		return GroupRenderer{noop.New(renderCfg, cfg.GetWorkingDir(), hydrationDir, labels)}, nil
 	}
-	if renderCfg.Validate == nil && renderCfg.Transform == nil && renderCfg.Helm != nil {
-		log.Entry(context.TODO()).Debug("setting up helm renderer")
-		return helm.New(cfg, renderCfg, labels, configName)
+	if renderCfg.Validate != nil && renderCfg.Transform != nil {
+		r, err := kpt.New(cfg, renderCfg, hydrationDir, labels, configName)
+		if err != nil {
+			return nil, err
+		}
+		log.Entry(ctx).Infof("setting up kpt renderer")
+		return GroupRenderer{r}, nil
 	}
-	if renderCfg.Validate == nil && renderCfg.Transform == nil && renderCfg.Kpt == nil {
-		log.Entry(context.TODO()).Debug("setting up kubectl renderer")
-		return kubectl.New(cfg, renderCfg, labels, configName)
+	var rs GroupRenderer
+	var r Renderer
+	var err error
+	if renderCfg.RawK8s != nil || renderCfg.Kustomize != nil {
+		if r, err = kubectl.New(cfg, renderCfg, labels, configName); err != nil {
+			return nil, err
+		}
+		rs = append(rs, r)
 	}
-	log.Entry(context.TODO()).Infof("setting up kpt renderer")
-	return kpt.New(cfg, renderCfg, hydrationDir, labels, configName)
+	if renderCfg.Helm != nil {
+		if r, err = helm.New(cfg, renderCfg, labels, configName); err != nil {
+			return nil, err
+		}
+		rs = append(rs, r)
+	}
+	return rs, nil
 }
diff --git a/pkg/skaffold/runner/deployer.go b/pkg/skaffold/runner/deployer.go
index f1f41ab64..fef9fca4d 100644
--- a/pkg/skaffold/runner/deployer.go
+++ b/pkg/skaffold/runner/deployer.go
@@ -99,7 +99,7 @@ func GetDeployer(ctx context.Context, runCtx *runcontext.RunContext, labeller *l
 				return nil, errors.New("skaffold apply called with both Cloud Run and Kubernetes deployers. Mixing deployment targets is not allowed" +
 					" when using the Cloud Run deployer")
 			}
-			return getCloudRunDeployer(runCtx, labeller)
+			return getCloudRunDeployer(runCtx, labeller, pipelines.Deployers(), "")
 		}
 		if len(helmNamespaces) > 1 || (nonHelmDeployFound && len(helmNamespaces) == 1) {
 			return nil, errors.New("skaffold apply called with conflicting namespaces set via skaffold.yaml. This is likely due to the use of the 'deploy.helm.releases.*.namespace' field which is not supported in apply.  Remove the 'deploy.helm.releases.*.namespace' field(s) and run skaffold apply again")
@@ -185,7 +185,7 @@ func GetDeployer(ctx context.Context, runCtx *runcontext.RunContext, labeller *l
 			deployers = append(deployers, deployer)
 		}
 		if d.CloudRunDeploy != nil {
-			deployer, err := cloudrun.NewDeployer(dCtx, labeller, d.CloudRunDeploy, configName)
+			deployer, err := getCloudRunDeployer(dCtx.RunContext, labeller, runCtx.DeployConfigs(), configName)
 			if err != nil {
 				return nil, err
 			}
@@ -312,21 +312,38 @@ func validateKubectlFlags(flags *latest.KubectlFlags, additional latest.KubectlF
 }
 
 /* The Cloud Run deployer for apply. Used when Cloud Run is specified. */
-func getCloudRunDeployer(runCtx *runcontext.RunContext, labeller *label.DefaultLabeller) (*cloudrun.Deployer, error) {
+func getCloudRunDeployer(runCtx *runcontext.RunContext, labeller *label.DefaultLabeller, deployers []latest.DeployConfig, configName string) (*cloudrun.Deployer, error) {
 	var region string
+	regionFlag := false
 	var defaultProject string
-	for _, d := range runCtx.DeployConfigs() {
+	projectFlag := false
+	if runCtx.Opts.CloudRunLocation != "" {
+		region = runCtx.Opts.CloudRunLocation
+		regionFlag = true
+	}
+	if runCtx.Opts.CloudRunProject != "" {
+		defaultProject = runCtx.Opts.CloudRunProject
+		projectFlag = true
+	}
+	for _, d := range deployers {
 		if d.CloudRunDeploy != nil {
 			crDeploy := d.CloudRunDeploy
-			if region != "" && region != crDeploy.Region {
-				return nil, fmt.Errorf("expected all Cloud Run deploys to be in the same region, found deploys to %s and %s", region, crDeploy.Region)
+			if !regionFlag {
+				// No region flag was provided, so take it from the config.
+				if region != "" && region != crDeploy.Region {
+					return nil, fmt.Errorf("expected all Cloud Run deploys to be in the same region, found deploys to %s and %s", region, crDeploy.Region)
+				}
+
+				region = crDeploy.Region
 			}
-			region = crDeploy.Region
-			if defaultProject != "" && defaultProject != crDeploy.ProjectID {
-				return nil, fmt.Errorf("expected all Cloud Run deploys to use the same project, found deploys to projects %s and %s", defaultProject, crDeploy.ProjectID)
+			if !projectFlag {
+				// No project flag was specified so take it from the config.
+				if defaultProject != "" && defaultProject != crDeploy.ProjectID {
+					return nil, fmt.Errorf("expected all Cloud Run deploys to use the same project, found deploys to projects %s and %s", defaultProject, crDeploy.ProjectID)
+				}
+				defaultProject = crDeploy.ProjectID
 			}
-			defaultProject = crDeploy.ProjectID
 		}
 	}
-	return cloudrun.NewDeployer(runCtx, labeller, &latest.CloudRunDeploy{Region: region, ProjectID: defaultProject}, "")
+	return cloudrun.NewDeployer(runCtx, labeller, &latest.CloudRunDeploy{Region: region, ProjectID: defaultProject}, configName)
 }
diff --git a/pkg/skaffold/runner/renderer.go b/pkg/skaffold/runner/renderer.go
index 20b23a269..3ff54bccf 100644
--- a/pkg/skaffold/runner/renderer.go
+++ b/pkg/skaffold/runner/renderer.go
@@ -27,13 +27,13 @@ import (
 func GetRenderer(ctx context.Context, runCtx *runcontext.RunContext, hydrationDir string, labels map[string]string, usingLegacyHelmDeploy bool) (renderer.Renderer, error) {
 	ps := runCtx.Pipelines.AllByConfigNames()
 
-	var renderers []renderer.Renderer
+	var renderers renderer.GroupRenderer
 	for configName, p := range ps {
-		r, err := renderer.New(runCtx, p.Render, hydrationDir, labels, usingLegacyHelmDeploy, runCtx.Opts.Command, configName)
+		rs, err := renderer.New(ctx, runCtx, p.Render, hydrationDir, labels, usingLegacyHelmDeploy, runCtx.Opts.Command, configName)
 		if err != nil {
 			return nil, err
 		}
-		renderers = append(renderers, r)
+		renderers = append(renderers, rs...)
 	}
 	return renderer.NewRenderMux(renderers), nil
 }
diff --git a/pkg/skaffold/runner/runner.go b/pkg/skaffold/runner/runner.go
index 7c9296f64..a9a1d89fe 100644
--- a/pkg/skaffold/runner/runner.go
+++ b/pkg/skaffold/runner/runner.go
@@ -42,7 +42,7 @@ type Runner interface {
 	DeployAndLog(context.Context, io.Writer, []graph.Artifact, manifest.ManifestListByConfig) error
 	GeneratePipeline(context.Context, io.Writer, []util.VersionedConfig, []string, string) error
 	HasBuilt() bool
-	HasDeployed() bool
+	DeployManifests() manifest.ManifestListByConfig
 	Prune(context.Context, io.Writer) error
 
 	Render(ctx context.Context, out io.Writer, builds []graph.Artifact, offline bool) (manifest.ManifestListByConfig, error)
diff --git a/pkg/skaffold/runner/v2/apply.go b/pkg/skaffold/runner/v2/apply.go
index 9549a73d3..6d3746382 100644
--- a/pkg/skaffold/runner/v2/apply.go
+++ b/pkg/skaffold/runner/v2/apply.go
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
+
 package v2
 
 import (
@@ -68,7 +69,7 @@ func (r *SkaffoldRunner) applyResources(ctx context.Context, out io.Writer, arti
 		endTrace(instrumentation.TraceEndError(err))
 		return err
 	}
-	r.hasDeployed = true
+	r.deployManifests = list
 	event.DeployComplete()
 	return nil
 }
diff --git a/pkg/skaffold/runner/v2/cleanup.go b/pkg/skaffold/runner/v2/cleanup.go
index 7210c9a38..264855667 100644
--- a/pkg/skaffold/runner/v2/cleanup.go
+++ b/pkg/skaffold/runner/v2/cleanup.go
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
+
 package v2
 
 import (
diff --git a/pkg/skaffold/runner/v2/deploy.go b/pkg/skaffold/runner/v2/deploy.go
index d8698d67e..1e5edfe31 100644
--- a/pkg/skaffold/runner/v2/deploy.go
+++ b/pkg/skaffold/runner/v2/deploy.go
@@ -110,7 +110,7 @@ See https://skaffold.dev/docs/pipeline-stages/taggers/#how-tagging-works`)
 
 	r.deployer.RegisterLocalImages(localAndBuiltImages)
 	err = r.deployer.Deploy(ctx, deployOut, artifacts, list)
-	r.hasDeployed = true // set even if deploy may have failed, because we want to cleanup any partially created resources
+	r.deployManifests = list // set even if deploy may have failed, because we want to cleanup any partially created resources
 	postDeployFn()
 	if err != nil {
 		event.DeployFailed(err)
diff --git a/pkg/skaffold/runner/v2/dev.go b/pkg/skaffold/runner/v2/dev.go
index 9fa2e26ac..37985d2a0 100644
--- a/pkg/skaffold/runner/v2/dev.go
+++ b/pkg/skaffold/runner/v2/dev.go
@@ -186,6 +186,7 @@ func (r *SkaffoldRunner) doDev(ctx context.Context, out io.Writer) error {
 			endTrace(instrumentation.TraceEndError(err))
 			return nil
 		}
+		r.deployManifests = manifests
 
 		if err := r.Deploy(childCtx, out, r.Builds, manifests); err != nil {
 			log.Entry(ctx).Warn("Skipping deploy due to error:", err)
@@ -348,6 +349,7 @@ func (r *SkaffoldRunner) Dev(ctx context.Context, out io.Writer, artifacts []*la
 
 	// First render
 	manifests, err := r.Render(ctx, out, r.Builds, true)
+	r.deployManifests = manifests
 	if err != nil {
 		event.DevLoopFailedInPhase(r.devIteration, constants.Render, err)
 		eventV2.TaskFailed(constants.DevLoop, err)
diff --git a/pkg/skaffold/runner/v2/render.go b/pkg/skaffold/runner/v2/render.go
index 0eed61d18..f3b222d8e 100644
--- a/pkg/skaffold/runner/v2/render.go
+++ b/pkg/skaffold/runner/v2/render.go
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
+
 package v2
 
 import (
diff --git a/pkg/skaffold/runner/v2/runner.go b/pkg/skaffold/runner/v2/runner.go
index 5cd7b7ce8..89a5a8833 100644
--- a/pkg/skaffold/runner/v2/runner.go
+++ b/pkg/skaffold/runner/v2/runner.go
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
+
 package v2
 
 import (
@@ -22,6 +23,7 @@ import (
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy/label"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/filemon"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/manifest"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/render/renderer"
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner"
@@ -50,13 +52,13 @@ type SkaffoldRunner struct {
 	sourceDependencies graph.SourceDependenciesCache
 	platforms          platform.Resolver
 
-	devIteration int
-	isLocalImage func(imageName string) (bool, error)
-	hasDeployed  bool
-	intents      *runner.Intents
+	devIteration    int
+	isLocalImage    func(imageName string) (bool, error)
+	deployManifests manifest.ManifestListByConfig
+	intents         *runner.Intents
 }
 
-// HasDeployed returns true if this runner has deployed something.
-func (r *SkaffoldRunner) HasDeployed() bool {
-	return r.hasDeployed
+// DeployManifests returns a list of manifest if this runner has deployed something.
+func (r *SkaffoldRunner) DeployManifests() manifest.ManifestListByConfig {
+	return r.deployManifests
 }
diff --git a/pkg/skaffold/runner/v2/verify.go b/pkg/skaffold/runner/v2/verify.go
index 2a1ceefac..cb455cce9 100644
--- a/pkg/skaffold/runner/v2/verify.go
+++ b/pkg/skaffold/runner/v2/verify.go
@@ -103,7 +103,6 @@ See https://skaffold.dev/docs/pipeline-stages/taggers/#how-tagging-works`)
 
 	r.verifier.RegisterLocalImages(localAndBuiltImages)
 	err = r.verifier.Verify(ctx, deployOut, artifacts)
-	r.hasDeployed = true // set even if deploy may have failed, because we want to cleanup any partially created resources
 	postDeployFn()
 	if err != nil {
 		eventV2.TaskFailed(constants.Verify, err)
diff --git a/pkg/skaffold/schema/v2beta29/upgrade.go b/pkg/skaffold/schema/v2beta29/upgrade.go
index c7d7f4d22..f8b5b61a8 100644
--- a/pkg/skaffold/schema/v2beta29/upgrade.go
+++ b/pkg/skaffold/schema/v2beta29/upgrade.go
@@ -45,7 +45,6 @@ func upgradeOnePipeline(oldPipeline, newPipeline interface{}) error {
 	// Copy kubectl deploy config to render config
 	if oldPL.Deploy.KubectlDeploy != nil {
 		newPL.Render.RawK8s = oldPL.Deploy.KubectlDeploy.Manifests
-		newPL.Deploy.KubectlDeploy.Manifests = nil
 	}
 
 	// Copy kustomize deploy config to render config
diff --git a/pkg/skaffold/schema/validation/validation.go b/pkg/skaffold/schema/validation/validation.go
index bd583d66b..b70e3a4c5 100644
--- a/pkg/skaffold/schema/validation/validation.go
+++ b/pkg/skaffold/schema/validation/validation.go
@@ -760,16 +760,13 @@ func validateKubectlManifests(configs parser.SkaffoldConfigSet) (errs []ErrorWit
 		if c.IsRemote {
 			continue
 		}
-		if c.Deploy.KubectlDeploy == nil {
-			continue
-		}
-		if len(c.Deploy.KubectlDeploy.Manifests) == 1 && c.Deploy.KubectlDeploy.Manifests[0] == constants.DefaultKubectlManifests[0] {
+		if len(c.Render.RawK8s) == 1 && c.Render.RawK8s[0] == constants.DefaultKubectlManifests[0] {
 			log.Entry(context.TODO()).Debug("skipping validating `kubectl` deployer manifests since only the default manifest list is defined")
 			continue
 		}
 
 		// validate that manifest files referenced in config exist
-		for _, pattern := range c.Deploy.KubectlDeploy.Manifests {
+		for _, pattern := range c.Render.RawK8s {
 			if util.IsURL(pattern) {
 				continue
 			}
@@ -787,7 +784,7 @@ func validateKubectlManifests(configs parser.SkaffoldConfigSet) (errs []ErrorWit
 				msg := fmt.Sprintf("Manifest file %q referenced in skaffold config could not be found", pattern)
 				errMsg := wrapWithContext(c, ErrorWithLocation{
 					Error:    fmt.Errorf(msg),
-					Location: c.YAMLInfos.Locate(&c.Deploy.KubectlDeploy.Manifests),
+					Location: c.YAMLInfos.Locate(&c.Render.RawK8s),
 				})
 				errs = append(errs, ErrorWithLocation{
 					Error: sErrors.NewError(errMsg[0].Error,


Test patch:
diff --git a/cmd/skaffold/app/cmd/dev_test.go b/cmd/skaffold/app/cmd/dev_test.go
index 574dcd596..092aa62d6 100644
--- a/cmd/skaffold/app/cmd/dev_test.go
+++ b/cmd/skaffold/app/cmd/dev_test.go
@@ -34,10 +34,9 @@ import (
 type mockDevRunner struct {
 	runner.Runner
 	hasBuilt          bool
-	hasDeployed       bool
 	errDev            error
 	calls             []string
-	manifestsByConfig manifest.ManifestListByConfig
+	deployedManifests manifest.ManifestListByConfig
 }
 
 func (r *mockDevRunner) Dev(context.Context, io.Writer, []*latest.Artifact) error {
@@ -50,9 +49,9 @@ func (r *mockDevRunner) HasBuilt() bool {
 	return r.hasBuilt
 }
 
-func (r *mockDevRunner) HasDeployed() bool {
-	r.calls = append(r.calls, "HasDeployed")
-	return r.hasDeployed
+func (r *mockDevRunner) DeployManifests() manifest.ManifestListByConfig {
+	r.calls = append(r.calls, "DeployManifests")
+	return r.deployedManifests
 }
 
 func (r *mockDevRunner) Prune(context.Context, io.Writer) error {
@@ -67,42 +66,44 @@ func (r *mockDevRunner) Cleanup(context.Context, io.Writer, bool, manifest.Manif
 
 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
+	return r.deployedManifests, nil
 }
 
 func TestDoDev(t *testing.T) {
 	tests := []struct {
-		description   string
-		hasBuilt      bool
-		hasDeployed   bool
-		expectedCalls []string
+		description       string
+		hasBuilt          bool
+		deployedManifests manifest.ManifestList
+		expectedCalls     []string
 	}{
 		{
-			description:   "cleanup and then prune",
-			hasBuilt:      true,
-			hasDeployed:   true,
-			expectedCalls: []string{"Dev", "HasDeployed", "HasBuilt", "Render", "Cleanup", "Prune"},
+			description:       "cleanup and then prune",
+			hasBuilt:          true,
+			deployedManifests: manifest.ManifestList{[]byte("dummy")},
+			expectedCalls:     []string{"Dev", "DeployManifests", "HasBuilt", "Render", "Cleanup", "Prune"},
 		},
 		{
-			description:   "hasn't deployed",
-			hasBuilt:      true,
-			hasDeployed:   false,
-			expectedCalls: []string{"Dev", "HasDeployed", "HasBuilt", "Prune"},
+			description:       "hasn't deployed",
+			hasBuilt:          true,
+			deployedManifests: manifest.ManifestList{},
+			expectedCalls:     []string{"Dev", "DeployManifests", "HasBuilt", "Prune"},
 		},
 		{
-			description:   "hasn't built",
-			hasBuilt:      false,
-			hasDeployed:   false,
-			expectedCalls: []string{"Dev", "HasDeployed", "HasBuilt"},
+			description:       "hasn't built",
+			hasBuilt:          false,
+			deployedManifests: manifest.ManifestList{},
+			expectedCalls:     []string{"Dev", "DeployManifests", "HasBuilt"},
 		},
 	}
 
 	for _, test := range tests {
 		testutil.Run(t, test.description, func(t *testutil.T) {
+			dm := manifest.NewManifestListByConfig()
+			dm.Add("test", test.deployedManifests)
 			mockRunner := &mockDevRunner{
-				hasBuilt:    test.hasBuilt,
-				hasDeployed: test.hasDeployed,
-				errDev:      context.Canceled,
+				hasBuilt:          test.hasBuilt,
+				deployedManifests: dm,
+				errDev:            context.Canceled,
 			}
 			t.Override(&createRunner, func(context.Context, io.Writer, config.SkaffoldOptions) (runner.Runner, []util.VersionedConfig, *runcontext.RunContext, error) {
 				return mockRunner, []util.VersionedConfig{&latest.SkaffoldConfig{}}, nil, nil
@@ -138,8 +139,8 @@ func (m *mockConfigChangeRunner) HasBuilt() bool {
 	return true
 }
 
-func (m *mockConfigChangeRunner) HasDeployed() bool {
-	return true
+func (m *mockConfigChangeRunner) DeployManifests() manifest.ManifestListByConfig {
+	return manifest.ManifestListByConfig{}
 }
 
 func (m *mockConfigChangeRunner) Prune(context.Context, io.Writer) error {
diff --git a/cmd/skaffold/app/cmd/fix_test.go b/cmd/skaffold/app/cmd/fix_test.go
index 81be22481..c274fc0d0 100644
--- a/cmd/skaffold/app/cmd/fix_test.go
+++ b/cmd/skaffold/app/cmd/fix_test.go
@@ -24,7 +24,6 @@ import (
 
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
 	v1 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1"
-	latestV1 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v2beta28"
 	"github.com/GoogleContainerTools/skaffold/testutil"
 )
 
@@ -38,7 +37,7 @@ func TestFix(t *testing.T) {
 	}{
 		{
 			description:   "v1alpha4 to latest",
-			targetVersion: latestV1.Version,
+			targetVersion: latest.Version,
 			inputYaml: `apiVersion: skaffold/v1alpha4
 kind: Config
 build:
@@ -66,15 +65,16 @@ test:
 - image: docker/image
   structureTests:
   - ./test/*
+manifests:
+  rawYaml:
+  - k8s/deployment.yaml
 deploy:
-  kubectl:
-    manifests:
-    - k8s/deployment.yaml
-`, latestV1.Version),
+  kubectl: {}
+`, latest.Version),
 		},
 		{
 			description:   "v1alpha1 to latest",
-			targetVersion: latestV1.Version,
+			targetVersion: latest.Version,
 			inputYaml: `apiVersion: skaffold/v1alpha1
 kind: Config
 build:
@@ -94,11 +94,12 @@ build:
   - image: docker/image
     docker:
       dockerfile: dockerfile.test
+manifests:
+  rawYaml:
+  - k8s/deployment.yaml
 deploy:
-  kubectl:
-    manifests:
-    - k8s/deployment.yaml
-`, latestV1.Version),
+  kubectl: {}
+`, latest.Version),
 		},
 		{
 			description:   "v1alpha1 to v1",
@@ -194,17 +195,18 @@ test:
 - image: docker/image
   structureTests:
   - ./test/*
+manifests:
+  rawYaml:
+  - k8s/deployment.yaml
 deploy:
-  kubectl:
-    manifests:
-    - k8s/deployment.yaml
-`, latestV1.Version)
+  kubectl: {}
+`, latest.Version)
 
 	testutil.Run(t, "", func(t *testutil.T) {
 		cfgFile := t.TempFile("config", []byte(inputYaml))
 
 		var b bytes.Buffer
-		err := fix(&b, cfgFile, cfgFile, latestV1.Version)
+		err := fix(&b, cfgFile, cfgFile, latest.Version)
 
 		output, _ := os.ReadFile(cfgFile)
 
diff --git a/cmd/skaffold/app/cmd/schema/list_test.go b/cmd/skaffold/app/cmd/schema/list_test.go
index 1a780cb5f..007ff2595 100644
--- a/cmd/skaffold/app/cmd/schema/list_test.go
+++ b/cmd/skaffold/app/cmd/schema/list_test.go
@@ -22,7 +22,7 @@ import (
 	"strings"
 	"testing"
 
-	latestV1 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v2beta29"
+	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
 	"github.com/GoogleContainerTools/skaffold/testutil"
 )
 
@@ -34,7 +34,7 @@ func TestListPlain(t *testing.T) {
 		t.CheckNoError(err)
 
 		versions := out.String()
-		t.CheckTrue(strings.HasSuffix(versions, latestV1.Version+"\n"))
+		t.CheckTrue(strings.HasSuffix(versions, latest.Version+"\n"))
 		t.CheckTrue(strings.HasPrefix(versions, `skaffold/v1alpha1
 skaffold/v1alpha2
 skaffold/v1alpha3
@@ -71,7 +71,7 @@ func TestListJson(t *testing.T) {
 
 		versions := out.String()
 		t.CheckTrue(strings.HasPrefix(versions, `{"versions":["skaffold/v1alpha1","skaffold/v1alpha2",`))
-		t.CheckTrue(strings.HasSuffix(versions, fmt.Sprintf(",\"%s\"]}\n", latestV1.Version)))
+		t.CheckTrue(strings.HasSuffix(versions, fmt.Sprintf(",\"%s\"]}\n", latest.Version)))
 	})
 }
 
diff --git a/integration/testdata/deploy-multiple/skaffold.yaml b/integration/testdata/deploy-multiple/skaffold.yaml
index 876d3a9b9..c16741cbc 100644
--- a/integration/testdata/deploy-multiple/skaffold.yaml
+++ b/integration/testdata/deploy-multiple/skaffold.yaml
@@ -11,10 +11,4 @@ manifests:
     paths:
       - ./kustomize
 deploy:
-  kustomize:
-    paths:
-    - ./kustomize
-
-  kubectl:
-    manifests:
-      - kubectl/k8s-pod.yaml
+  kubectl: {}
diff --git a/integration/testdata/diagnose/multi-config/diagnose.tmpl b/integration/testdata/diagnose/multi-config/diagnose.tmpl
index 25a6a8b69..393b8ea2f 100644
--- a/integration/testdata/diagnose/multi-config/diagnose.tmpl
+++ b/integration/testdata/diagnose/multi-config/diagnose.tmpl
@@ -12,10 +12,10 @@ build:
     gitCommit: {}
   local:
     concurrency: 1
+manifests:
+  rawYaml:
+  - /k8s/*
 deploy:
-  kubectl:
-    manifests:
-    - /k8s/*
   logs:
     prefix: container
 ---
@@ -33,10 +33,10 @@ build:
     gitCommit: {}
   local:
     concurrency: 1
+manifests:
+  rawYaml:
+  - /k8s/*
 deploy:
-  kubectl:
-    manifests:
-    - /k8s/*
   logs:
     prefix: container
 ---
@@ -52,9 +52,9 @@ build:
     gitCommit: {}
   local:
     concurrency: 1
+manifests:
+  rawYaml:
+  - /k8s/*
 deploy:
-  kubectl:
-    manifests:
-    - /k8s/*
   logs:
     prefix: container
diff --git a/integration/testdata/diagnose/multi-config/skaffold.yaml b/integration/testdata/diagnose/multi-config/skaffold.yaml
index 155c77c42..f3cbb07ab 100644
--- a/integration/testdata/diagnose/multi-config/skaffold.yaml
+++ b/integration/testdata/diagnose/multi-config/skaffold.yaml
@@ -7,7 +7,6 @@ build:
   artifacts:
   - image: app1
     context: foo
-deploy:
-  kubectl:
-    manifests:
-    - /k8s/*
+manifests:
+  rawYaml:
+  - /k8s/*
diff --git a/integration/testdata/diagnose/multi-config/skaffold2.yaml b/integration/testdata/diagnose/multi-config/skaffold2.yaml
index 9933935c0..de0c0fb4e 100644
--- a/integration/testdata/diagnose/multi-config/skaffold2.yaml
+++ b/integration/testdata/diagnose/multi-config/skaffold2.yaml
@@ -6,7 +6,6 @@ build:
   artifacts:
   - image: app2
     context: foo2
-deploy:
-  kubectl:
-    manifests:
-    - /k8s/*
+manifests:
+  rawYaml:
+  - /k8s/*
diff --git a/integration/testdata/diagnose/multi-config/skaffold3.yaml b/integration/testdata/diagnose/multi-config/skaffold3.yaml
index fd0cf6228..6cbb1efd7 100644
--- a/integration/testdata/diagnose/multi-config/skaffold3.yaml
+++ b/integration/testdata/diagnose/multi-config/skaffold3.yaml
@@ -6,7 +6,6 @@ build:
   artifacts:
   - image: app3
     context: foo3
-deploy:
-  kubectl:
-    manifests:
-    - /k8s/*
+manifests:
+  rawYaml:
+  - /k8s/*
diff --git a/integration/testdata/diagnose/temp-config/diagnose.tmpl b/integration/testdata/diagnose/temp-config/diagnose.tmpl
index 9603c0134..d21a5de8d 100644
--- a/integration/testdata/diagnose/temp-config/diagnose.tmpl
+++ b/integration/testdata/diagnose/temp-config/diagnose.tmpl
@@ -10,9 +10,9 @@ build:
     gitCommit: {}
   local:
     concurrency: 1
+manifests:
+  rawYaml:
+  - {{.Root}}/k8s-*
 deploy:
-  kubectl:
-    manifests:
-    - {{.Root}}/k8s-*
   logs:
     prefix: container
diff --git a/integration/testdata/diagnose/temp-config/skaffold.yaml b/integration/testdata/diagnose/temp-config/skaffold.yaml
index 1a671577a..adea0d850 100644
--- a/integration/testdata/diagnose/temp-config/skaffold.yaml
+++ b/integration/testdata/diagnose/temp-config/skaffold.yaml
@@ -3,7 +3,6 @@ kind: Config
 build:
   artifacts:
   - image: skaffold-example
-deploy:
-  kubectl:
-    manifests:
-    - k8s-*
+manifests:
+  rawYaml:
+  - k8s-*
diff --git a/integration/testdata/hello/skaffold.yaml b/integration/testdata/hello/skaffold.yaml
index bc5ed7168..61676b444 100644
--- a/integration/testdata/hello/skaffold.yaml
+++ b/integration/testdata/hello/skaffold.yaml
@@ -6,12 +6,10 @@ build:
 
 profiles:
   - name: pod
-    deploy:
-      kubectl:
-        manifests:
-          - k8s/pod.yaml
+    manifests:
+      rawYaml:
+      - k8s/pod.yaml
   - name: deployment
-    deploy:
-      kubectl:
-        manifests:
-          - k8s/deployment.yaml
\ No newline at end of file
+    manifests:
+      rawYaml:
+      - k8s/deployment.yaml
\ No newline at end of file
diff --git a/integration/testdata/init/compose/skaffold.yaml b/integration/testdata/init/compose/skaffold.yaml
index 56baeac11..ffff330d7 100644
--- a/integration/testdata/init/compose/skaffold.yaml
+++ b/integration/testdata/init/compose/skaffold.yaml
@@ -7,8 +7,7 @@ build:
   - image: gcr.io/k8s-skaffold/compose
     docker:
       dockerfile: Dockerfile
-deploy:
-  kubectl:
-    manifests:
-    - compose-deployment.yaml
-    - compose-service.yaml
+manifests:
+  rawYaml:
+  - compose-deployment.yaml
+  - compose-service.yaml
diff --git a/integration/testdata/init/hello-with-manifest/skaffold.yaml b/integration/testdata/init/hello-with-manifest/skaffold.yaml
index 01e4b15e8..a48d540d6 100644
--- a/integration/testdata/init/hello-with-manifest/skaffold.yaml
+++ b/integration/testdata/init/hello-with-manifest/skaffold.yaml
@@ -8,7 +8,6 @@ build:
     context: ../hello
     docker:
       dockerfile: Dockerfile
-deploy:
-  kubectl:
-    manifests:
-    - k8s-pod.yaml
+manifests:
+  rawYaml:
+  - k8s-pod.yaml
diff --git a/integration/testdata/kaniko-insecure-registry/app/skaffold.yaml b/integration/testdata/kaniko-insecure-registry/app/skaffold.yaml
index ecca87e44..adea0d850 100644
--- a/integration/testdata/kaniko-insecure-registry/app/skaffold.yaml
+++ b/integration/testdata/kaniko-insecure-registry/app/skaffold.yaml
@@ -3,7 +3,6 @@ kind: Config
 build:
   artifacts:
   - image: skaffold-example
-deploy:
-  kubectl:
-    manifests:
-      - k8s-*
+manifests:
+  rawYaml:
+  - k8s-*
diff --git a/integration/testdata/kaniko-insecure-registry/skaffold.yaml b/integration/testdata/kaniko-insecure-registry/skaffold.yaml
index cdf2ac937..19328c104 100644
--- a/integration/testdata/kaniko-insecure-registry/skaffold.yaml
+++ b/integration/testdata/kaniko-insecure-registry/skaffold.yaml
@@ -16,7 +16,6 @@ profiles:
         - image: devreg
           context: insecure-registry
           docker: {}
-    deploy:
-      kubectl:
-        manifests:
-          - insecure-registry/reg.yaml
+    manifests:
+      rawYaml:
+      - insecure-registry/reg.yaml
diff --git a/integration/testdata/kaniko-microservices/skaffold.yaml b/integration/testdata/kaniko-microservices/skaffold.yaml
index f1616a84b..fec33135f 100644
--- a/integration/testdata/kaniko-microservices/skaffold.yaml
+++ b/integration/testdata/kaniko-microservices/skaffold.yaml
@@ -23,8 +23,7 @@ build:
         cache: {}
   cluster:
     pullSecretName: e2esecret
-deploy:
-  kubectl:
-    manifests:
-      - ./leeroy-web/kubernetes/*
-      - ./leeroy-app/kubernetes/*
+manifests:
+  rawYaml:
+  - ./leeroy-web/kubernetes/*
+  - ./leeroy-app/kubernetes/*
diff --git a/integration/testdata/kaniko-target/skaffold.yaml b/integration/testdata/kaniko-target/skaffold.yaml
index 265557e6e..267e73ced 100644
--- a/integration/testdata/kaniko-target/skaffold.yaml
+++ b/integration/testdata/kaniko-target/skaffold.yaml
@@ -9,7 +9,6 @@ build:
   cluster:
     pullSecretName: e2esecret
     namespace: default
-deploy:
-  kubectl:
-    manifests:
-      - k8s-*
+manifests:
+  rawYaml:
+  - k8s-*
diff --git a/integration/testdata/skaffold-in-cluster/skaffold.yaml b/integration/testdata/skaffold-in-cluster/skaffold.yaml
index 3ff8f97ac..c1b76ec72 100644
--- a/integration/testdata/skaffold-in-cluster/skaffold.yaml
+++ b/integration/testdata/skaffold-in-cluster/skaffold.yaml
@@ -13,7 +13,7 @@ profiles:
         - image: skaffold-in-cluster-builder
           kaniko:
             cache: {}
-    deploy:
+    manifests:
       kustomize:
         path: build-step
   - name: build-target
diff --git a/pkg/skaffold/deploy/kubectl/kubectl_test.go b/pkg/skaffold/deploy/kubectl/kubectl_test.go
index 42baf6fca..917bd270c 100644
--- a/pkg/skaffold/deploy/kubectl/kubectl_test.go
+++ b/pkg/skaffold/deploy/kubectl/kubectl_test.go
@@ -344,56 +344,10 @@ func TestKubectlCleanup(t *testing.T) {
 	}
 }
 
-func TestKubectlDeployerRemoteCleanup(t *testing.T) {
-	tests := []struct {
-		description string
-		kubectl     latest.KubectlDeploy
-		commands    util.Command
-	}{
-		{
-			description: "cleanup success",
-			kubectl: latest.KubectlDeploy{
-				RemoteManifests: []string{"pod/leeroy-web"},
-			},
-			commands: testutil.
-				CmdRun("kubectl --context kubecontext --namespace testNamespace get pod/leeroy-web -o yaml").
-				AndRun("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true --wait=false -f -").
-				AndRunInput("kubectl --context kubecontext --namespace testNamespace apply -f -", DeploymentWebYAML),
-		},
-		{
-			description: "cleanup error",
-			kubectl: latest.KubectlDeploy{
-				RemoteManifests: []string{"anotherNamespace:pod/leeroy-web"},
-			},
-			commands: testutil.
-				CmdRun("kubectl --context kubecontext --namespace anotherNamespace get pod/leeroy-web -o yaml").
-				AndRun("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true --wait=false -f -").
-				AndRunInput("kubectl --context kubecontext --namespace anotherNamespace apply -f -", DeploymentWebYAML),
-		},
-	}
-	for _, test := range tests {
-		testutil.Run(t, "cleanup remote", func(t *testutil.T) {
-			t.Override(&util.DefaultExecCommand, test.commands)
-			tmpDir := t.NewTempDir()
-			tmpDir.Write("deployment.yaml", DeploymentWebYAML).Chdir()
-
-			k, err := NewDeployer(&kubectlConfig{
-				workingDir: ".",
-				RunContext: runcontext.RunContext{Opts: config.SkaffoldOptions{Namespace: TestNamespace}},
-			}, &label.DefaultLabeller{}, &test.kubectl, "default")
-			t.RequireNoError(err)
-
-			err = k.Cleanup(context.Background(), io.Discard, false, manifest.ManifestListByConfig{})
-
-			t.CheckNoError(err)
-		})
-	}
-}
-
 func TestKubectlRedeploy(t *testing.T) {
 	testutil.Run(t, "", func(t *testutil.T) {
 		t.Override(&client.Client, deployutil.MockK8sClient)
-		tmpDir := t.NewTempDir().
+		t.NewTempDir().
 			Write("deployment-web.yaml", DeploymentWebYAML).
 			Write("deployment-app.yaml", DeploymentAppYAML)
 
@@ -410,7 +364,7 @@ func TestKubectlRedeploy(t *testing.T) {
 				Enabled: true,
 				Delay:   0 * time.Millisecond,
 				Max:     10 * time.Second},
-		}, &label.DefaultLabeller{}, &latest.KubectlDeploy{Manifests: []string{tmpDir.Path("deployment-app.yaml"), tmpDir.Path("deployment-web.yaml")}}, configName)
+		}, &label.DefaultLabeller{}, &latest.KubectlDeploy{}, configName)
 		t.RequireNoError(err)
 
 		// Deploy both manifests
@@ -486,7 +440,7 @@ func TestKubectlWaitForDeletions(t *testing.T) {
 				Delay:   0 * time.Millisecond,
 				Max:     10 * time.Second,
 			},
-		}, &label.DefaultLabeller{}, &latest.KubectlDeploy{Manifests: []string{tmpDir.Path("deployment-web.yaml")}}, configName)
+		}, &label.DefaultLabeller{}, &latest.KubectlDeploy{}, configName)
 		t.RequireNoError(err)
 
 		var out bytes.Buffer
@@ -501,9 +455,6 @@ func TestKubectlWaitForDeletions(t *testing.T) {
 		}, manifestListByConfig)
 
 		t.CheckNoError(err)
-		t.CheckDeepEqual(` - 2 resources are marked for deletion, waiting for completion: "leeroy-web", "leeroy-app"
- - "leeroy-web" is marked for deletion, waiting for completion
-`, out.String())
 	})
 }
 
@@ -529,7 +480,7 @@ func TestKubectlWaitForDeletionsFails(t *testing.T) {
 				Delay:   10 * time.Second,
 				Max:     100 * time.Millisecond,
 			},
-		}, &label.DefaultLabeller{}, &latest.KubectlDeploy{Manifests: []string{tmpDir.Path("deployment-web.yaml")}}, configName)
+		}, &label.DefaultLabeller{}, &latest.KubectlDeploy{}, configName)
 		t.RequireNoError(err)
 
 		m, err := manifest.Load(bytes.NewReader([]byte(DeploymentWebYAMLv1)))
@@ -546,67 +497,6 @@ func TestKubectlWaitForDeletionsFails(t *testing.T) {
 	})
 }
 
-func TestDependencies(t *testing.T) {
-	tests := []struct {
-		description string
-		manifests   []string
-		expected    []string
-	}{
-		{
-			description: "no manifest",
-			manifests:   []string(nil),
-			expected:    []string(nil),
-		},
-		{
-			description: "missing manifest file",
-			manifests:   []string{"missing.yaml"},
-			expected:    []string(nil),
-		},
-		{
-			description: "ignore non-manifest",
-			manifests:   []string{"*.ignored"},
-			expected:    []string(nil),
-		},
-		{
-			description: "single manifest",
-			manifests:   []string{"deployment.yaml"},
-			expected:    []string{"deployment.yaml"},
-		},
-		{
-			description: "keep manifests order",
-			manifests:   []string{"01_name.yaml", "00_service.yaml"},
-			expected:    []string{"01_name.yaml", "00_service.yaml"},
-		},
-		{
-			description: "sort children",
-			manifests:   []string{"01/*.yaml", "00/*.yaml"},
-			expected:    []string{filepath.Join("01", "a.yaml"), filepath.Join("01", "b.yaml"), filepath.Join("00", "a.yaml"), filepath.Join("00", "b.yaml")},
-		},
-		{
-			description: "http manifest",
-			manifests:   []string{"deployment.yaml", "http://remote.yaml"},
-			expected:    []string{"deployment.yaml"},
-		},
-	}
-	for _, test := range tests {
-		testutil.Run(t, test.description, func(t *testutil.T) {
-			tmpDir := t.NewTempDir()
-			tmpDir.Touch("deployment.yaml", "01_name.yaml", "00_service.yaml", "empty.ignored").
-				Touch("01/a.yaml", "01/b.yaml").
-				Touch("00/b.yaml", "00/a.yaml").
-				Chdir()
-
-			k, err := NewDeployer(&kubectlConfig{}, &label.DefaultLabeller{}, &latest.KubectlDeploy{Manifests: test.manifests}, "default")
-			t.RequireNoError(err)
-
-			dependencies, err := k.Dependencies()
-
-			t.CheckNoError(err)
-			t.CheckDeepEqual(test.expected, dependencies)
-		})
-	}
-}
-
 func TestGCSManifests(t *testing.T) {
 	tests := []struct {
 		description string
diff --git a/pkg/skaffold/deploy/kustomize/kustomize_test.go b/pkg/skaffold/deploy/kustomize/kustomize_test.go
index f2e3b926e..7c65c3b36 100644
--- a/pkg/skaffold/deploy/kustomize/kustomize_test.go
+++ b/pkg/skaffold/deploy/kustomize/kustomize_test.go
@@ -292,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, manifest.ManifestListByConfig{})
+			err = k.Cleanup(context.Background(), io.Discard, test.dryRun, manifest.NewManifestListByConfig())
 
 			t.CheckError(test.shouldErr, err)
 		})
diff --git a/pkg/skaffold/initializer/testdata/init/hello-no-manifest/skaffold.yaml b/pkg/skaffold/initializer/testdata/init/hello-no-manifest/skaffold.yaml
index d0fdcd898..29c20ca35 100644
--- a/pkg/skaffold/initializer/testdata/init/hello-no-manifest/skaffold.yaml
+++ b/pkg/skaffold/initializer/testdata/init/hello-no-manifest/skaffold.yaml
@@ -5,7 +5,6 @@ metadata:
 build:
   artifacts:
   - image: skaffold-example
-deploy:
-  kubectl:
-    manifests:
-    - k8s-pod.yaml
+manifests:
+  rawYaml:
+  - k8s-pod.yaml
\ No newline at end of file
diff --git a/pkg/skaffold/kubernetes/manifest/manifests_test.go b/pkg/skaffold/kubernetes/manifest/manifests_test.go
index d23351701..1b1524fa6 100644
--- a/pkg/skaffold/kubernetes/manifest/manifests_test.go
+++ b/pkg/skaffold/kubernetes/manifest/manifests_test.go
@@ -162,3 +162,57 @@ func TestAppendServiceAndRoleBinding(t *testing.T) {
 	testutil.CheckDeepEqual(t, service, string(manifests[1]))
 	testutil.CheckDeepEqual(t, manifests.String(), roleBinding+"\n---\n"+service)
 }
+
+func TestManifestListByConfigAdd(t *testing.T) {
+	tests := []struct {
+		description string
+		mlbc        ManifestListByConfig
+		config      string
+		ml          ManifestList
+		expected    ManifestListByConfig
+	}{
+		{
+			description: "same config name appends to original list",
+			mlbc: ManifestListByConfig{
+				manifests: map[string]ManifestList{
+					"config-a": {[]byte(pod1)},
+				},
+				configNames: []string{"config-a"},
+			},
+			config: "config-a",
+			ml:     ManifestList{[]byte(pod2)},
+			expected: ManifestListByConfig{
+				manifests: map[string]ManifestList{
+					"config-a": {[]byte(pod1), []byte(pod2)},
+				},
+				configNames: []string{"config-a"},
+			},
+		},
+		{
+			description: "different config name appends to original list",
+			mlbc: ManifestListByConfig{
+				manifests: map[string]ManifestList{
+					"config-a": {[]byte(pod1)},
+				},
+				configNames: []string{"config-a"},
+			},
+			config: "config-b",
+			ml:     ManifestList{[]byte(pod2)},
+			expected: ManifestListByConfig{
+				manifests: map[string]ManifestList{
+					"config-a": {[]byte(pod1)},
+					"config-b": {[]byte(pod2)},
+				},
+				configNames: []string{"config-a", "config-b"},
+			},
+		},
+	}
+
+	for _, test := range tests {
+		testutil.Run(t, test.description, func(t *testutil.T) {
+			test.mlbc.Add(test.config, test.ml)
+			t.CheckDeepEqual(test.expected.configNames, test.mlbc.configNames)
+			t.CheckDeepEqual(test.expected.manifests, test.mlbc.manifests)
+		})
+	}
+}
diff --git a/pkg/skaffold/lint/k8smanifests_test.go b/pkg/skaffold/lint/k8smanifests_test.go
index 3307eef51..6b3ef4276 100644
--- a/pkg/skaffold/lint/k8smanifests_test.go
+++ b/pkg/skaffold/lint/k8smanifests_test.go
@@ -142,8 +142,7 @@ func TestGetK8sManifestsLintResults(t *testing.T) {
 				} else {
 					configSet = append(configSet, &parser.SkaffoldConfigEntry{SkaffoldConfig: &latest.SkaffoldConfig{
 						Metadata: latest.Metadata{Name: module},
-						Pipeline: latest.Pipeline{Deploy: latest.DeployConfig{DeployType: latest.DeployType{KubectlDeploy: &latest.KubectlDeploy{Manifests: []string{mp}}}}},
-					},
+						Pipeline: latest.Pipeline{Render: latest.RenderConfig{Generate: latest.Generate{RawK8s: []string{mp}}}}},
 					})
 				}
 
diff --git a/pkg/skaffold/lint/skaffoldyamls_test.go b/pkg/skaffold/lint/skaffoldyamls_test.go
index f56025c4a..5adc89590 100644
--- a/pkg/skaffold/lint/skaffoldyamls_test.go
+++ b/pkg/skaffold/lint/skaffoldyamls_test.go
@@ -45,6 +45,20 @@ deploy:
       - leeroy-app/kubernetes/*
 `
 
+var testSkaffoldYamlV3 = `apiVersion: skaffold/v3alpha1
+kind: Config
+build:
+  artifacts:
+    - image: leeroy-app
+      context: leeroy-app
+      requires:
+        - image: base
+          alias: BASE
+manifests:
+  rawYaml:
+  - leeroy-app/kubernetes/*
+`
+
 var testManifest = `apiVersion: v1
 kind: Service
 metadata:
@@ -148,14 +162,14 @@ func TestGetSkaffoldYamlsLintResults(t *testing.T) {
 		{
 			description:            "verify SkaffoldYamlUseStaticPort rule works as intended",
 			rules:                  []RuleID{SkaffoldYamlUseStaticPort},
-			moduleAndSkaffoldYamls: map[string]string{"cfg0": testSkaffoldYaml},
+			moduleAndSkaffoldYamls: map[string]string{"cfg0": testSkaffoldYamlV3},
 			modules:                []string{"cfg0"},
 			expected: map[string]*[]Result{
 				"cfg0": {
 					{
 						Rule:        ruleIDToskaffoldYamlRule[SkaffoldYamlUseStaticPort],
-						StartLine:   14,
-						EndLine:     15,
+						StartLine:   13,
+						EndLine:     14,
 						StartColumn: 1,
 						EndColumn:   0,
 						Explanation: "It is a skaffold best practice to specify a static port (vs skaffold dynamically choosing one) for port forwarding " +
@@ -205,9 +219,9 @@ func TestGetSkaffoldYamlsLintResults(t *testing.T) {
 				}
 				configSet = append(configSet, &parser.SkaffoldConfigEntry{SkaffoldConfig: &latest.SkaffoldConfig{
 					Metadata: latest.Metadata{Name: module},
-					Pipeline: latest.Pipeline{Deploy: latest.DeployConfig{DeployType: latest.DeployType{KubectlDeploy: &latest.KubectlDeploy{Manifests: []string{
+					Pipeline: latest.Pipeline{Render: latest.RenderConfig{Generate: latest.Generate{RawK8s: []string{
 						mp,
-					}}}}},
+					}}}},
 				},
 					SourceFile: fp,
 				})
diff --git a/pkg/skaffold/parser/config_test.go b/pkg/skaffold/parser/config_test.go
index d0add640f..ff3e47121 100644
--- a/pkg/skaffold/parser/config_test.go
+++ b/pkg/skaffold/parser/config_test.go
@@ -1348,37 +1348,34 @@ kind: Config
 build:
   artifacts:
     - image: app-0
-deploy:
-  kubectl:
-    manifests:
-      - manifests-0
+manifests:
+  rawYaml:
+    - manifests-0
 profiles:
   - name: profile-0
     build:
       artifacts:
         - image: app-0-profile
           context: app-0-profile
-    deploy:
-      kubectl:
-        manifests:
-          - manifests-0-profile
+    manifests:
+      rawYaml:
+      - manifests-0-profile
     patches:
       - op: replace
         path: /build/artifacts/0
         value:
           image: app-0-patch
       - op: add
-        path: /deploy/kubectl/manifests/1
+        path: /manifests/rawYaml/1
         value: 'manifests-1'
   - name: profile-1
     build:
       artifacts:
         - image: app-1-profile
           context: app-1-profile
-    deploy:
-      kubectl:
-        manifests:
-          - manifests-1-profile
+    manifests:
+      rawYaml:
+      - manifests-1-profile
 `
 
 func TestConfigLocationsParse(t *testing.T) {
@@ -1398,9 +1395,8 @@ func TestConfigLocationsParse(t *testing.T) {
 				{kyaml.Lookup("kind")},
 				{kyaml.Lookup("build")},
 				{kyaml.Lookup("build", "artifacts")},
-				{kyaml.Lookup("deploy")},
-				{kyaml.Lookup("deploy", "kubectl")},
-				{kyaml.Lookup("deploy", "kubectl", "manifests")},
+				{kyaml.Lookup("manifests")},
+				{kyaml.Lookup("manifests", "rawYaml")},
 			},
 		},
 		{
@@ -1426,9 +1422,9 @@ func TestConfigLocationsParse(t *testing.T) {
 					kyaml.Lookup("patches"), kyaml.GetElementByIndex(0), kyaml.Lookup("value"), kyaml.Lookup("image")},
 				{kyaml.Lookup("profiles"), kyaml.MatchElementList([]string{"name"}, []string{"profile-0"}),
 					kyaml.Lookup("patches"), kyaml.GetElementByIndex(1), kyaml.Lookup("value")},
-				{kyaml.Lookup("deploy")},
-				{kyaml.Lookup("profiles"), kyaml.MatchElementList([]string{"name"}, []string{"profile-0"}), kyaml.Lookup("deploy"), kyaml.Lookup("kubectl")},
-				{kyaml.Lookup("profiles"), kyaml.MatchElementList([]string{"name"}, []string{"profile-0"}), kyaml.Lookup("deploy"), kyaml.Lookup("kubectl"), kyaml.Lookup("manifests")},
+				{kyaml.Lookup("manifests")},
+				{kyaml.Lookup("profiles"), kyaml.MatchElementList([]string{"name"}, []string{"profile-0"}), kyaml.Lookup("manifests")},
+				{kyaml.Lookup("profiles"), kyaml.MatchElementList([]string{"name"}, []string{"profile-0"}), kyaml.Lookup("manifests"), kyaml.Lookup("rawYaml")},
 			},
 		},
 		{
@@ -1517,9 +1513,9 @@ func TestConfigLocationsLocate(t *testing.T) {
 			profiles:         []string{"profile-0"},
 			expected: []configlocations.Location{
 				{
-					StartLine:   24,
+					StartLine:   22,
 					StartColumn: 18,
-					EndLine:     25,
+					EndLine:     23,
 					EndColumn:   0,
 				},
 			},
@@ -1530,9 +1526,9 @@ func TestConfigLocationsLocate(t *testing.T) {
 			profiles:         []string{"profile-1"},
 			expected: []configlocations.Location{
 				{
-					StartLine:   31,
+					StartLine:   29,
 					StartColumn: 18,
-					EndLine:     32,
+					EndLine:     30,
 					EndColumn:   0,
 				},
 			},
diff --git a/pkg/skaffold/render/generate/generate_test.go b/pkg/skaffold/render/generate/generate_test.go
index d638b6e5d..cbc025362 100644
--- a/pkg/skaffold/render/generate/generate_test.go
+++ b/pkg/skaffold/render/generate/generate_test.go
@@ -246,10 +246,10 @@ func TestManifestDeps(t *testing.T) {
 				Kpt: []string{"kpt-sample"},
 			},
 			expected: []string{
-				"kpt-sample/Kptfile",
-				"kpt-sample/deployment.yaml",
 				"kustomize-sample/kustomization.yaml",
 				"kustomize-sample/patch.yaml",
+				"kpt-sample/Kptfile",
+				"kpt-sample/deployment.yaml",
 				"rawYaml-sample/pod.yaml",
 				"rawYaml-sample/pods2.yaml",
 			},
diff --git a/pkg/skaffold/render/renderer/kubectl/kubectl_test.go b/pkg/skaffold/render/renderer/kubectl/kubectl_test.go
index 0e4ba5337..cdfb07a79 100644
--- a/pkg/skaffold/render/renderer/kubectl/kubectl_test.go
+++ b/pkg/skaffold/render/renderer/kubectl/kubectl_test.go
@@ -18,6 +18,7 @@ package kubectl
 import (
 	"bytes"
 	"context"
+	"path/filepath"
 	"testing"
 
 	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
@@ -98,3 +99,72 @@ func TestRender(t *testing.T) {
 		})
 	}
 }
+
+func TestDependencies(t *testing.T) {
+	tests := []struct {
+		description string
+		manifests   []string
+		expected    []string
+	}{
+		{
+			description: "no manifest",
+			manifests:   []string(nil),
+			expected:    []string(nil),
+		},
+		{
+			description: "missing manifest file",
+			manifests:   []string{"missing.yaml"},
+			expected:    []string(nil),
+		},
+		{
+			description: "ignore non-manifest",
+			manifests:   []string{"*.ignored"},
+			expected:    []string(nil),
+		},
+		{
+			description: "single manifest",
+			manifests:   []string{"deployment.yaml"},
+			expected:    []string{"deployment.yaml"},
+		},
+		{
+			description: "keep manifests order",
+			manifests:   []string{"01_name.yaml", "00_service.yaml"},
+			expected:    []string{"01_name.yaml", "00_service.yaml"},
+		},
+		{
+			description: "sort children",
+			manifests:   []string{"01/*.yaml", "00/*.yaml"},
+			expected:    []string{filepath.Join("01", "a.yaml"), filepath.Join("01", "b.yaml"), filepath.Join("00", "a.yaml"), filepath.Join("00", "b.yaml")},
+		},
+		{
+			description: "http manifest",
+			manifests:   []string{"deployment.yaml", "http://remote.yaml"},
+			expected:    []string{"deployment.yaml"},
+		},
+	}
+	for _, test := range tests {
+		testutil.Run(t, test.description, func(t *testutil.T) {
+			tmpDir := t.NewTempDir()
+			tmpDir.Touch("deployment.yaml", "01_name.yaml", "00_service.yaml", "empty.ignored").
+				Touch("01/a.yaml", "01/b.yaml").
+				Touch("00/b.yaml", "00/a.yaml").
+				Chdir()
+
+			mockCfg := render.MockConfig{WorkingDir: tmpDir.Root()}
+			rCfg := latest.RenderConfig{
+				Generate: latest.Generate{RawK8s: test.manifests},
+			}
+			r, err := New(mockCfg, rCfg, map[string]string{}, "default")
+			t.CheckNoError(err)
+
+			dependencies, err := r.ManifestDeps()
+
+			t.CheckNoError(err)
+			expected := make([]string, len(test.expected))
+			for i, p := range test.expected {
+				expected[i] = filepath.Join(tmpDir.Root(), p)
+			}
+			t.CheckDeepEqual(expected, dependencies)
+		})
+	}
+}
diff --git a/pkg/skaffold/render/renderer/render_mux_test.go b/pkg/skaffold/render/renderer/render_mux_test.go
index 5c95e70c4..6fe72af4b 100644
--- a/pkg/skaffold/render/renderer/render_mux_test.go
+++ b/pkg/skaffold/render/renderer/render_mux_test.go
@@ -33,14 +33,14 @@ import (
 func TestRenderMux_Render(t *testing.T) {
 	tests := []struct {
 		name         string
-		renderers    []Renderer
+		renderers    GroupRenderer
 		expected     string
 		expectedDeps []string
 		shouldErr    bool
 	}{
 		{
 			name: "concatenates render results with separator",
-			renderers: []Renderer{
+			renderers: GroupRenderer{
 				mock{configName: "config1", manifests: "manifest-1", deps: []string{"file1.txt", "file2.txt"}},
 				mock{configName: "config2", manifests: "manifest-2", deps: []string{"file2.txt", "file3.txt"}}},
 			expected:     "manifest-1\n---\nmanifest-2",
@@ -48,7 +48,7 @@ func TestRenderMux_Render(t *testing.T) {
 		},
 		{
 			name: "returns empty string when any call fails",
-			renderers: []Renderer{
+			renderers: GroupRenderer{
 				mock{manifests: "manifest-1", deps: []string{"file1.txt"}},
 				mock{deps: []string{"file2.txt"}, shouldErr: true}},
 			expectedDeps: []string{"file1.txt", "file2.txt"},
@@ -56,7 +56,7 @@ func TestRenderMux_Render(t *testing.T) {
 		},
 		{
 			name: "short-circuits when first call fails",
-			renderers: []Renderer{
+			renderers: GroupRenderer{
 				mock{deps: []string{"file1.txt"}, shouldErr: true},
 				mock{manifests: "manifest-2", deps: []string{"file2.txt"}}},
 			expectedDeps: []string{"file1.txt", "file2.txt"},
diff --git a/pkg/skaffold/runner/deployer_test.go b/pkg/skaffold/runner/deployer_test.go
index a0b415da9..a75a8822e 100644
--- a/pkg/skaffold/runner/deployer_test.go
+++ b/pkg/skaffold/runner/deployer_test.go
@@ -470,3 +470,54 @@ func TestGetDefaultDeployer(tOuter *testing.T) {
 		}
 	})
 }
+
+func TestGetCloudRunDeployer(tOuter *testing.T) {
+	tests := []struct {
+		name     string
+		opts     config.SkaffoldOptions
+		cfgs     map[string]latest.DeployType
+		expected *cloudrun.Deployer
+		haveErr  bool
+	}{
+		{
+			name: "deploy one config with no flags set",
+			cfgs: map[string]latest.DeployType{"": {
+				CloudRunDeploy: &latest.CloudRunDeploy{ProjectID: "test-project", Region: "test-region"},
+			}},
+			expected: &cloudrun.Deployer{Project: "test-project", Region: "test-region"},
+		},
+		{
+			name: "deploy with two configs and conflicting processes",
+			cfgs: map[string]latest.DeployType{"": {
+				CloudRunDeploy: &latest.CloudRunDeploy{ProjectID: "test-project", Region: "test-region"}},
+				"second": {
+					CloudRunDeploy: &latest.CloudRunDeploy{ProjectID: "test-project2", Region: "test-region"},
+				},
+			},
+			haveErr: true,
+		},
+		{
+			name: "deploy with flags set overrides config",
+			opts: config.SkaffoldOptions{CloudRunProject: "overridden-project"},
+			cfgs: map[string]latest.DeployType{"": {
+				CloudRunDeploy: &latest.CloudRunDeploy{ProjectID: "test-project", Region: "test-region"},
+			}},
+			expected: &cloudrun.Deployer{Project: "overridden-project", Region: "test-region"},
+		},
+	}
+	for _, test := range tests {
+		testutil.Run(tOuter, test.name, func(t *testutil.T) {
+			pipelines := make(map[string]latest.Pipeline)
+			for name, config := range test.cfgs {
+				pipelines[name] = latest.Pipeline{Deploy: latest.DeployConfig{DeployType: config}}
+			}
+			rctx := &runcontext.RunContext{
+				Opts:      test.opts,
+				Pipelines: runcontext.NewPipelines(pipelines),
+			}
+			crDeployer, err := getCloudRunDeployer(rctx, &label.DefaultLabeller{}, rctx.DeployConfigs(), "")
+			t.CheckErrorAndFailNow(test.haveErr, err)
+			t.CheckDeepEqual(crDeployer, test.expected, cmpopts.IgnoreUnexported(cloudrun.Deployer{}))
+		})
+	}
+}
diff --git a/pkg/skaffold/schema/latest/config.go b/pkg/skaffold/schema/latest/config.go
index afec3de5a..98daf59a3 100644
--- a/pkg/skaffold/schema/latest/config.go
+++ b/pkg/skaffold/schema/latest/config.go
@@ -721,18 +721,12 @@ type DockerDeploy struct {
 // KubectlDeploy *beta* uses a client side `kubectl apply` to deploy manifests.
 // You'll need a `kubectl` CLI version installed that's compatible with your cluster.
 type KubectlDeploy struct {
-	// Manifests lists the Kubernetes yaml or json manifests.
-	// Defaults to `["k8s/*.yaml"]`.
-	// This field is no longer needed in render v2. If given, the v1 kubectl deployer will be triggered.
-	Manifests []string `yaml:"manifests,omitempty" skaffold:"filepath"`
+	// Flags are additional flags passed to `kubectl`.
+	Flags KubectlFlags `yaml:"flags,omitempty"`
 
 	// RemoteManifests lists Kubernetes manifests in remote clusters.
-	// This field is only used by v1 kubectl deployer.
 	RemoteManifests []string `yaml:"remoteManifests,omitempty"`
 
-	// Flags are additional flags passed to `kubectl`.
-	Flags KubectlFlags `yaml:"flags,omitempty"`
-
 	// DefaultNamespace is the default namespace passed to kubectl on deployment if no other override is given.
 	DefaultNamespace *string `yaml:"defaultNamespace,omitempty"`
 
diff --git a/pkg/skaffold/schema/profiles_test.go b/pkg/skaffold/schema/profiles_test.go
index 16dc9bbf8..776e79a12 100644
--- a/pkg/skaffold/schema/profiles_test.go
+++ b/pkg/skaffold/schema/profiles_test.go
@@ -36,10 +36,9 @@ func TestApplyPatch(t *testing.T) {
 	config := `build:
   artifacts:
   - image: example
-deploy:
-  kubectl:
-    manifests:
-    - k8s-*
+manifests:
+  rawYaml:
+  - k8s-*
 profiles:
 - name: patches
   patches:
@@ -56,7 +55,7 @@ profiles:
       docker:
         dockerfile: Dockerfile.second
   - op: remove
-    path: /deploy
+    path: /manifests
 `
 
 	testutil.Run(t, "", func(t *testutil.T) {
@@ -123,7 +122,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 				withProfiles(latest.Profile{
 					Name: "profile",
 					Pipeline: latest.Pipeline{
@@ -148,7 +147,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 			),
 		},
 		{
@@ -160,7 +159,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 				withProfiles(latest.Profile{
 					Name: "dev",
 					Pipeline: latest.Pipeline{
@@ -175,7 +174,7 @@ func TestApplyProfiles(t *testing.T) {
 					withShaTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 			),
 		},
 		{
@@ -187,7 +186,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 				withProfiles(latest.Profile{
 					Name: "profile",
 					Pipeline: latest.Pipeline{
@@ -214,7 +213,7 @@ func TestApplyProfiles(t *testing.T) {
 					withDockerArtifact("image", ".", "Dockerfile.DEV"),
 					withDockerArtifact("imageProd", ".", "Dockerfile.DEV"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 			),
 		},
 		{
@@ -225,7 +224,7 @@ func TestApplyProfiles(t *testing.T) {
 				withLocalBuild(
 					withGitTagger(),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 				withProfiles(latest.Profile{
 					Name: "profile",
 					Pipeline: latest.Pipeline{
@@ -242,7 +241,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 				),
 				withHelmDeploy(),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 			),
 		},
 		{
@@ -254,7 +253,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 				withProfiles(latest.Profile{
 					Name: "profile",
 					Patches: []latest.JSONPatch{{
@@ -268,7 +267,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("image", ".", "Dockerfile.DEV"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 			),
 		},
 		{
@@ -280,7 +279,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 				withProfiles(latest.Profile{
 					Name: "profile",
 					Patches: []latest.JSONPatch{{
@@ -424,7 +423,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 				withProfiles(latest.Profile{
 					Name: "dev",
 				},
@@ -443,7 +442,7 @@ func TestApplyProfiles(t *testing.T) {
 					withShaTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 			),
 		},
 		{
@@ -455,7 +454,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 				withProfiles(latest.Profile{
 					Name: "dev",
 				},
@@ -474,7 +473,7 @@ func TestApplyProfiles(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("image", ".", "Dockerfile"),
 				),
-				withKubectlDeploy("k8s/*.yaml"),
+				withRawK8s("k8s/*.yaml"),
 			),
 		},
 	}
diff --git a/pkg/skaffold/schema/validation/validation_test.go b/pkg/skaffold/schema/validation/validation_test.go
index c443b4988..9fc1b20a9 100644
--- a/pkg/skaffold/schema/validation/validation_test.go
+++ b/pkg/skaffold/schema/validation/validation_test.go
@@ -1617,11 +1617,9 @@ func TestValidateKubectlManifests(t *testing.T) {
 			configs: []*latest.SkaffoldConfig{
 				{
 					Pipeline: latest.Pipeline{
-						Deploy: latest.DeployConfig{
-							DeployType: latest.DeployType{
-								KubectlDeploy: &latest.KubectlDeploy{
-									Manifests: []string{filepath.Join(tempDir, "validation-test-exists.yaml")},
-								},
+						Render: latest.RenderConfig{
+							Generate: latest.Generate{
+								RawK8s: []string{filepath.Join(tempDir, "validation-test-exists.yaml")},
 							},
 						},
 					},
@@ -1634,11 +1632,9 @@ func TestValidateKubectlManifests(t *testing.T) {
 			configs: []*latest.SkaffoldConfig{
 				{
 					Pipeline: latest.Pipeline{
-						Deploy: latest.DeployConfig{
-							DeployType: latest.DeployType{
-								KubectlDeploy: &latest.KubectlDeploy{
-									Manifests: []string{filepath.Join(tempDir, "validation-test-missing.yaml")},
-								},
+						Render: latest.RenderConfig{
+							Generate: latest.Generate{
+								RawK8s: []string{filepath.Join(tempDir, "validation-test-missing.yaml")},
 							},
 						},
 					},
diff --git a/pkg/skaffold/schema/versions_test.go b/pkg/skaffold/schema/versions_test.go
index cd0b991d2..eff8523b9 100644
--- a/pkg/skaffold/schema/versions_test.go
+++ b/pkg/skaffold/schema/versions_test.go
@@ -49,8 +49,6 @@ build:
     gitCommit: {}
   artifacts:
   - image: example
-deploy:
-  kubectl: {}
 `
 	// This config has two tag policies set.
 	invalidConfig = `
@@ -79,11 +77,31 @@ build:
       target: //:example.tar
   googleCloudBuild:
     projectId: ID
-deploy:
-  kubectl:
-   manifests:
+manifests:
+  rawYaml:
    - dep.yaml
    - svc.yaml
+`
+	completeV1Config = `
+build:
+  tagPolicy:
+    sha256: {}
+  artifacts:
+  - image: image1
+    context: ./examples/app1
+    docker:
+      dockerfile: Dockerfile.dev
+  - image: image2
+    context: ./examples/app2
+    bazel:
+      target: //:example.tar
+  googleCloudBuild:
+    projectId: ID
+deploy:
+  kubectl:
+    manifests:
+    - dep.yaml
+    - svc.yaml
 `
 	minimalClusterConfig = `
 build:
@@ -126,6 +144,22 @@ build:
       path: /kaniko/.docker
 `
 
+	completeClusterConfigV1 = `
+build:
+  artifacts:
+  - image: image1
+    context: ./examples/app1
+    kaniko: {}
+  cluster:
+    pullSecretPath: /secret.json
+    pullSecretName: secret-name
+    namespace: nskaniko
+    timeout: 120m
+    dockerConfig:
+      secretName: config-name
+      path: /kaniko/.docker
+`
+
 	badConfig = "bad config"
 
 	invalidStatusCheckConfig = `
@@ -193,7 +227,7 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 		shouldErr   bool
 	}{
 		{
-			apiVersion:  []string{latestV1.Version},
+			apiVersion:  []string{latest.Version},
 			description: "Kaniko Volume Mount - ConfigMap",
 			config:      []string{kanikoConfigMap},
 			expected: []util.VersionedConfig{config(
@@ -215,7 +249,7 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 			)},
 		},
 		{
-			apiVersion:  []string{latestV1.Version},
+			apiVersion:  []string{latest.Version},
 			description: "Minimal config",
 			config:      []string{minimalConfig},
 			expected: []util.VersionedConfig{config(
@@ -237,7 +271,7 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 			)},
 		},
 		{
-			apiVersion:  []string{latestV1.Version},
+			apiVersion:  []string{latest.Version},
 			description: "Simple config",
 			config:      []string{simpleConfig},
 			expected: []util.VersionedConfig{config(
@@ -246,13 +280,13 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 					withGitTagger(),
 					withDockerArtifact("example", ".", "Dockerfile"),
 				),
-				withKubectlDeploy(),
+				withRawK8s(),
 				withLogsPrefix("container"),
 			)},
 		},
 		{
-			apiVersion:  []string{latestV1.Version},
-			description: "Complete config",
+			apiVersion:  []string{latest.Version},
+			description: "Complete config v1",
 			config:      []string{completeConfig},
 			expected: []util.VersionedConfig{config(
 				withGoogleCloudBuild("ID",
@@ -262,13 +296,12 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 				),
 				withRawK8s("dep.yaml", "svc.yaml"),
 				withLogsPrefix("container"),
-				withKubectlDeploy(),
 			)},
 		},
 		{
 			apiVersion:  []string{v2beta8.Version},
 			description: "Old version complete config",
-			config:      []string{completeConfig},
+			config:      []string{completeV1Config},
 			expected: []util.VersionedConfig{config(
 				withGoogleCloudBuild("ID",
 					withShaTagger(),
@@ -276,12 +309,12 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 					withBazelArtifact(),
 				),
 				withRawK8s("dep.yaml", "svc.yaml"),
+				withKubectlDeployer(),
 				withLogsPrefix("container"),
-				withKubectlDeploy(),
 			)},
 		},
 		{
-			apiVersion:  []string{latestV1.Version, latestV1.Version},
+			apiVersion:  []string{latest.Version, latest.Version},
 			description: "Multiple complete config with same API versions",
 			config:      []string{completeConfig, completeClusterConfig},
 			expected: []util.VersionedConfig{config(
@@ -292,7 +325,6 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 				),
 				withRawK8s("dep.yaml", "svc.yaml"),
 				withLogsPrefix("container"),
-				withKubectlDeploy(),
 			), config(
 				withClusterBuild("secret-name", "/secret", "nskaniko", "/secret.json", "120m",
 					withGitTagger(),
@@ -303,9 +335,9 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 			)},
 		},
 		{
-			apiVersion:  []string{latestV1.Version, v2beta8.Version},
+			apiVersion:  []string{latest.Version, v2beta8.Version},
 			description: "Multiple complete config with different API versions",
-			config:      []string{completeConfig, completeClusterConfig},
+			config:      []string{completeConfig, completeClusterConfigV1},
 			expected: []util.VersionedConfig{config(
 				withGoogleCloudBuild("ID",
 					withShaTagger(),
@@ -314,7 +346,6 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 				),
 				withRawK8s("dep.yaml", "svc.yaml"),
 				withLogsPrefix("container"),
-				withKubectlDeploy(),
 			), config(
 				withClusterBuild("secret-name", "/secret", "nskaniko", "/secret.json", "120m",
 					withGitTagger(),
@@ -325,7 +356,7 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 			)},
 		},
 		{
-			apiVersion:  []string{latestV1.Version},
+			apiVersion:  []string{latest.Version},
 			description: "Minimal Cluster config",
 			config:      []string{minimalClusterConfig},
 			expected: []util.VersionedConfig{config(
@@ -337,7 +368,7 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 			)},
 		},
 		{
-			apiVersion:  []string{latestV1.Version},
+			apiVersion:  []string{latest.Version},
 			description: "Complete Cluster config",
 			config:      []string{completeClusterConfig},
 			expected: []util.VersionedConfig{config(
@@ -350,13 +381,13 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 			)},
 		},
 		{
-			apiVersion:  []string{latestV1.Version},
+			apiVersion:  []string{latest.Version},
 			description: "Bad config",
 			config:      []string{badConfig},
 			shouldErr:   true,
 		},
 		{
-			apiVersion:  []string{latestV1.Version},
+			apiVersion:  []string{latest.Version},
 			description: "two taggers defined",
 			config:      []string{invalidConfig},
 			shouldErr:   true,
@@ -368,13 +399,13 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 			shouldErr:   true,
 		},
 		{
-			apiVersion:  []string{latestV1.Version},
+			apiVersion:  []string{latest.Version},
 			description: "invalid statusCheckDeadline",
 			config:      []string{invalidStatusCheckConfig},
 			shouldErr:   true,
 		},
 		{
-			apiVersion:  []string{latestV1.Version},
+			apiVersion:  []string{latest.Version},
 			description: "valid statusCheckDeadline",
 			config:      []string{validStatusCheckConfig},
 			expected: []util.VersionedConfig{config(
@@ -386,7 +417,7 @@ func TestParseConfigAndUpgrade(t *testing.T) {
 			)},
 		},
 		{
-			apiVersion:  []string{latestV1.Version},
+			apiVersion:  []string{latest.Version},
 			description: "custom log prefix",
 			config:      []string{customLogPrefix},
 			expected: []util.VersionedConfig{config(
@@ -533,17 +564,15 @@ func withDockerConfig(secretName string, path string) func(*latest.BuildConfig)
 	}
 }
 
-func withKubectlDeploy(manifests ...string) func(*latest.SkaffoldConfig) {
+func withRawK8s(manifests ...string) func(*latest.SkaffoldConfig) {
 	return func(cfg *latest.SkaffoldConfig) {
-		cfg.Deploy.DeployType.KubectlDeploy = &latest.KubectlDeploy{
-			Manifests: manifests,
-		}
+		cfg.Render.RawK8s = manifests
 	}
 }
 
-func withRawK8s(manifests ...string) func(*latest.SkaffoldConfig) {
+func withKubectlDeployer() func(*latest.SkaffoldConfig) {
 	return func(cfg *latest.SkaffoldConfig) {
-		cfg.Render.RawK8s = manifests
+		cfg.Deploy.KubectlDeploy = &latest.KubectlDeploy{}
 	}
 }