Repository: knative/client
Pull request #1037 (2020-09-30 11:31:23)

chore: Update version command for release v0.18.0
## Description
Mention serving/eventing vendor version v0.18.0


knative-prow-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative/client/pull/1037#" title="Author self-approved">navidshaikh</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative%2Fclient).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/knative/client/blob/master/OWNERS)~~ [navidshaikh]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
knative-prow-robot: @navidshaikh: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-client-integration-tests | 41605106c570cfea3be6ee48ab46e2c963a60df5 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative_client/1037/pull-knative-client-integration-tests/1311267510829453313) | `/test pull-knative-client-integration-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative_client/1037). [Your PR dashboard](https://gubernator.knative.dev/pr/navidshaikh).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->

Patch:
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index b91c885a..3f1e3161 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -18,14 +18,22 @@
 |===
 | | Description | PR
 
+| 🎁
+| Add subscription CRUD
+| https://github.com/knative/client/pull/1013[#1013]
+
 | 🐛
 | Fix service export example documentation
 | https://github.com/knative/client/pull/1006[#1006]
 
 | 🎁
-| Add support for service initialScale via `--scale-init` flag
+| Add support for service initialscale via `--scale-init` flag
 | https://github.com/knative/client/pull/990[#990]
 
+| 🎁
+| Add "--annotation-service" and "--annotation-revision" to kn service create/update
+| https://github.com/knative/client/pull/1029[#1029]
+
 |===
 
 ## v0.17.0 (2020-08-26)
diff --git a/docs/cmd/kn.md b/docs/cmd/kn.md
index affc0162..f00dd7e3 100644
--- a/docs/cmd/kn.md
+++ b/docs/cmd/kn.md
@@ -28,6 +28,7 @@ kn is the command line interface for managing Knative Serving and Eventing resou
 * [kn route](kn_route.md)	 - List and describe service routes
 * [kn service](kn_service.md)	 - Manage Knative services
 * [kn source](kn_source.md)	 - Manage event sources
+* [kn subscription](kn_subscription.md)	 - Manage event subscriptions
 * [kn trigger](kn_trigger.md)	 - Manage event triggers
 * [kn version](kn_version.md)	 - Show the version of this client
 
diff --git a/docs/cmd/kn_service_create.md b/docs/cmd/kn_service_create.md
index 0ffb240b..8441f158 100644
--- a/docs/cmd/kn_service_create.md
+++ b/docs/cmd/kn_service_create.md
@@ -53,48 +53,50 @@ kn service create NAME --image IMAGE
 ### Options
 
 ```
-  -a, --annotation stringArray        Service annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-).
-      --arg stringArray               Add argument to the container command. Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. You can use this flag multiple times.
-      --async                         DEPRECATED: please use --no-wait instead. Do not wait for 'service create' operation to be completed.
-      --autoscale-window string       Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s)
-      --cluster-local                 Specify that the service be private. (--no-cluster-local will make the service publicly available)
-      --cmd string                    Specify command to be used as entrypoint instead of default one. Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments.
-      --concurrency-limit int         Hard Limit of concurrent requests to be processed by a single replica.
-      --concurrency-target int        Recommendation for when to scale up based on the concurrent number of incoming request. Defaults to --concurrency-limit when given.
-      --concurrency-utilization int   Percentage of concurrent requests utilization before scaling up. (default 70)
-  -e, --env stringArray               Environment variable to set. NAME=value; you may provide this flag any number of times to set multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-).
-      --env-from stringArray          Add environment variables from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret:). Example: --env-from cm:myconfigmap or --env-from secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --env-from cm:myconfigmap-.
-  -f, --filename string               Create a service from file. The created service can be further modified by combining with other options. For example, -f /path/to/file --env NAME=value adds also an environment variable.
-      --force                         Create service forcefully, replaces existing service if any.
-  -h, --help                          help for create
-      --image string                  Image to run.
-  -l, --label stringArray             Labels to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-).
-      --label-revision stringArray    Revision label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over "label" flag.
-      --label-service stringArray     Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over "label" flag.
-      --limit strings                 The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
-      --limits-cpu string             DEPRECATED: please use --limit instead. The limits on the requested CPU (e.g., 1000m).
-      --limits-memory string          DEPRECATED: please use --limit instead. The limits on the requested memory (e.g., 1024Mi).
-      --lock-to-digest                Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true)
-      --mount stringArray             Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
-  -n, --namespace string              Specify the namespace to operate in.
-      --no-cluster-local              Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true)
-      --no-lock-to-digest             Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision)
-      --no-wait                       Do not wait for 'service create' operation to be completed.
-  -p, --port string                   The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'.
-      --pull-secret string            Image pull secret to set. An empty argument ("") clears the pull secret. The referenced secret must exist in the service's namespace.
-      --request strings               The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'.
-      --requests-cpu string           DEPRECATED: please use --request instead. The requested CPU (e.g., 250m).
-      --requests-memory string        DEPRECATED: please use --request instead. The requested memory (e.g., 64Mi).
-      --revision-name string          The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants. (default "{{.Service}}-{{.Random 5}}-{{.Generation}}")
-      --scale int                     Minimum and maximum number of replicas.
-      --scale-init int                Initial number of replicas with which a service starts. Can be 0 or a positive integer.
-      --scale-max int                 Maximum number of replicas.
-      --scale-min int                 Minimum number of replicas.
-      --service-account string        Service account name to set. An empty argument ("") clears the service account. The referenced service account must exist in the service's namespace.
-      --user int                      The user ID to run the container (e.g., 1001).
-      --volume stringArray            Add a volume from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret: or sc:). Example: --volume myvolume=cm:myconfigmap or --volume myvolume=secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --volume myvolume-.
-      --wait                          Wait for 'service create' operation to be completed. (default true)
-      --wait-timeout int              Seconds to wait before giving up on waiting for service to be ready. (default 600)
+  -a, --annotation stringArray            Annotations to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-).
+      --annotation-revision stringArray   Revision annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). This flag takes precedence over the "annotation" flag.
+      --annotation-service stringArray    Service annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). This flag takes precedence over the "annotation" flag.
+      --arg stringArray                   Add argument to the container command. Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. You can use this flag multiple times.
+      --async                             DEPRECATED: please use --no-wait instead. Do not wait for 'service create' operation to be completed.
+      --autoscale-window string           Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s)
+      --cluster-local                     Specify that the service be private. (--no-cluster-local will make the service publicly available)
+      --cmd string                        Specify command to be used as entrypoint instead of default one. Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments.
+      --concurrency-limit int             Hard Limit of concurrent requests to be processed by a single replica.
+      --concurrency-target int            Recommendation for when to scale up based on the concurrent number of incoming request. Defaults to --concurrency-limit when given.
+      --concurrency-utilization int       Percentage of concurrent requests utilization before scaling up. (default 70)
+  -e, --env stringArray                   Environment variable to set. NAME=value; you may provide this flag any number of times to set multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-).
+      --env-from stringArray              Add environment variables from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret:). Example: --env-from cm:myconfigmap or --env-from secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --env-from cm:myconfigmap-.
+  -f, --filename string                   Create a service from file. The created service can be further modified by combining with other options. For example, -f /path/to/file --env NAME=value adds also an environment variable.
+      --force                             Create service forcefully, replaces existing service if any.
+  -h, --help                              help for create
+      --image string                      Image to run.
+  -l, --label stringArray                 Labels to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-).
+      --label-revision stringArray        Revision label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag.
+      --label-service stringArray         Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag.
+      --limit strings                     The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
+      --limits-cpu string                 DEPRECATED: please use --limit instead. The limits on the requested CPU (e.g., 1000m).
+      --limits-memory string              DEPRECATED: please use --limit instead. The limits on the requested memory (e.g., 1024Mi).
+      --lock-to-digest                    Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true)
+      --mount stringArray                 Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
+  -n, --namespace string                  Specify the namespace to operate in.
+      --no-cluster-local                  Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true)
+      --no-lock-to-digest                 Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision)
+      --no-wait                           Do not wait for 'service create' operation to be completed.
+  -p, --port string                       The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'.
+      --pull-secret string                Image pull secret to set. An empty argument ("") clears the pull secret. The referenced secret must exist in the service's namespace.
+      --request strings                   The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'.
+      --requests-cpu string               DEPRECATED: please use --request instead. The requested CPU (e.g., 250m).
+      --requests-memory string            DEPRECATED: please use --request instead. The requested memory (e.g., 64Mi).
+      --revision-name string              The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants. (default "{{.Service}}-{{.Random 5}}-{{.Generation}}")
+      --scale int                         Minimum and maximum number of replicas.
+      --scale-init int                    Initial number of replicas with which a service starts. Can be 0 or a positive integer.
+      --scale-max int                     Maximum number of replicas.
+      --scale-min int                     Minimum number of replicas.
+      --service-account string            Service account name to set. An empty argument ("") clears the service account. The referenced service account must exist in the service's namespace.
+      --user int                          The user ID to run the container (e.g., 1001).
+      --volume stringArray                Add a volume from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret: or sc:). Example: --volume myvolume=cm:myconfigmap or --volume myvolume=secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --volume myvolume-.
+      --wait                              Wait for 'service create' operation to be completed. (default true)
+      --wait-timeout int                  Seconds to wait before giving up on waiting for service to be ready. (default 600)
 ```
 
 ### Options inherited from parent commands
diff --git a/docs/cmd/kn_service_update.md b/docs/cmd/kn_service_update.md
index 007a0292..0633a4e3 100644
--- a/docs/cmd/kn_service_update.md
+++ b/docs/cmd/kn_service_update.md
@@ -38,49 +38,51 @@ kn service update NAME
 ### Options
 
 ```
-  -a, --annotation stringArray        Service annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-).
-      --arg stringArray               Add argument to the container command. Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. You can use this flag multiple times.
-      --async                         DEPRECATED: please use --no-wait instead. Do not wait for 'service update' operation to be completed.
-      --autoscale-window string       Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s)
-      --cluster-local                 Specify that the service be private. (--no-cluster-local will make the service publicly available)
-      --cmd string                    Specify command to be used as entrypoint instead of default one. Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments.
-      --concurrency-limit int         Hard Limit of concurrent requests to be processed by a single replica.
-      --concurrency-target int        Recommendation for when to scale up based on the concurrent number of incoming request. Defaults to --concurrency-limit when given.
-      --concurrency-utilization int   Percentage of concurrent requests utilization before scaling up. (default 70)
-  -e, --env stringArray               Environment variable to set. NAME=value; you may provide this flag any number of times to set multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-).
-      --env-from stringArray          Add environment variables from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret:). Example: --env-from cm:myconfigmap or --env-from secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --env-from cm:myconfigmap-.
-  -h, --help                          help for update
-      --image string                  Image to run.
-  -l, --label stringArray             Labels to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-).
-      --label-revision stringArray    Revision label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over "label" flag.
-      --label-service stringArray     Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over "label" flag.
-      --limit strings                 The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
-      --limits-cpu string             DEPRECATED: please use --limit instead. The limits on the requested CPU (e.g., 1000m).
-      --limits-memory string          DEPRECATED: please use --limit instead. The limits on the requested memory (e.g., 1024Mi).
-      --lock-to-digest                Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true)
-      --mount stringArray             Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
-  -n, --namespace string              Specify the namespace to operate in.
-      --no-cluster-local              Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true)
-      --no-lock-to-digest             Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision)
-      --no-wait                       Do not wait for 'service update' operation to be completed.
-  -p, --port string                   The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'.
-      --pull-secret string            Image pull secret to set. An empty argument ("") clears the pull secret. The referenced secret must exist in the service's namespace.
-      --request strings               The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'.
-      --requests-cpu string           DEPRECATED: please use --request instead. The requested CPU (e.g., 250m).
-      --requests-memory string        DEPRECATED: please use --request instead. The requested memory (e.g., 64Mi).
-      --revision-name string          The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants. (default "{{.Service}}-{{.Random 5}}-{{.Generation}}")
-      --scale int                     Minimum and maximum number of replicas.
-      --scale-init int                Initial number of replicas with which a service starts. Can be 0 or a positive integer.
-      --scale-max int                 Maximum number of replicas.
-      --scale-min int                 Minimum number of replicas.
-      --service-account string        Service account name to set. An empty argument ("") clears the service account. The referenced service account must exist in the service's namespace.
-      --tag strings                   Set tag (format: --tag revisionRef=tagName) where revisionRef can be a revision or '@latest' string representing latest ready revision. This flag can be specified multiple times.
-      --traffic strings               Set traffic distribution (format: --traffic revisionRef=percent) where revisionRef can be a revision or a tag or '@latest' string representing latest ready revision. This flag can be given multiple times with percent summing up to 100%.
-      --untag strings                 Untag revision (format: --untag tagName). This flag can be specified multiple times.
-      --user int                      The user ID to run the container (e.g., 1001).
-      --volume stringArray            Add a volume from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret: or sc:). Example: --volume myvolume=cm:myconfigmap or --volume myvolume=secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --volume myvolume-.
-      --wait                          Wait for 'service update' operation to be completed. (default true)
-      --wait-timeout int              Seconds to wait before giving up on waiting for service to be ready. (default 600)
+  -a, --annotation stringArray            Annotations to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-).
+      --annotation-revision stringArray   Revision annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). This flag takes precedence over the "annotation" flag.
+      --annotation-service stringArray    Service annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). This flag takes precedence over the "annotation" flag.
+      --arg stringArray                   Add argument to the container command. Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. You can use this flag multiple times.
+      --async                             DEPRECATED: please use --no-wait instead. Do not wait for 'service update' operation to be completed.
+      --autoscale-window string           Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s)
+      --cluster-local                     Specify that the service be private. (--no-cluster-local will make the service publicly available)
+      --cmd string                        Specify command to be used as entrypoint instead of default one. Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments.
+      --concurrency-limit int             Hard Limit of concurrent requests to be processed by a single replica.
+      --concurrency-target int            Recommendation for when to scale up based on the concurrent number of incoming request. Defaults to --concurrency-limit when given.
+      --concurrency-utilization int       Percentage of concurrent requests utilization before scaling up. (default 70)
+  -e, --env stringArray                   Environment variable to set. NAME=value; you may provide this flag any number of times to set multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-).
+      --env-from stringArray              Add environment variables from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret:). Example: --env-from cm:myconfigmap or --env-from secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --env-from cm:myconfigmap-.
+  -h, --help                              help for update
+      --image string                      Image to run.
+  -l, --label stringArray                 Labels to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-).
+      --label-revision stringArray        Revision label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag.
+      --label-service stringArray         Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag.
+      --limit strings                     The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'.
+      --limits-cpu string                 DEPRECATED: please use --limit instead. The limits on the requested CPU (e.g., 1000m).
+      --limits-memory string              DEPRECATED: please use --limit instead. The limits on the requested memory (e.g., 1024Mi).
+      --lock-to-digest                    Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true)
+      --mount stringArray                 Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume.
+  -n, --namespace string                  Specify the namespace to operate in.
+      --no-cluster-local                  Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true)
+      --no-lock-to-digest                 Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision)
+      --no-wait                           Do not wait for 'service update' operation to be completed.
+  -p, --port string                       The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'.
+      --pull-secret string                Image pull secret to set. An empty argument ("") clears the pull secret. The referenced secret must exist in the service's namespace.
+      --request strings                   The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'.
+      --requests-cpu string               DEPRECATED: please use --request instead. The requested CPU (e.g., 250m).
+      --requests-memory string            DEPRECATED: please use --request instead. The requested memory (e.g., 64Mi).
+      --revision-name string              The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants. (default "{{.Service}}-{{.Random 5}}-{{.Generation}}")
+      --scale int                         Minimum and maximum number of replicas.
+      --scale-init int                    Initial number of replicas with which a service starts. Can be 0 or a positive integer.
+      --scale-max int                     Maximum number of replicas.
+      --scale-min int                     Minimum number of replicas.
+      --service-account string            Service account name to set. An empty argument ("") clears the service account. The referenced service account must exist in the service's namespace.
+      --tag strings                       Set tag (format: --tag revisionRef=tagName) where revisionRef can be a revision or '@latest' string representing latest ready revision. This flag can be specified multiple times.
+      --traffic strings                   Set traffic distribution (format: --traffic revisionRef=percent) where revisionRef can be a revision or a tag or '@latest' string representing latest ready revision. This flag can be given multiple times with percent summing up to 100%.
+      --untag strings                     Untag revision (format: --untag tagName). This flag can be specified multiple times.
+      --user int                          The user ID to run the container (e.g., 1001).
+      --volume stringArray                Add a volume from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret: or sc:). Example: --volume myvolume=cm:myconfigmap or --volume myvolume=secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --volume myvolume-.
+      --wait                              Wait for 'service update' operation to be completed. (default true)
+      --wait-timeout int                  Seconds to wait before giving up on waiting for service to be ready. (default 600)
 ```
 
 ### Options inherited from parent commands
diff --git a/docs/cmd/kn_source_apiserver_create.md b/docs/cmd/kn_source_apiserver_create.md
index d9b84bcc..a26f9627 100644
--- a/docs/cmd/kn_source_apiserver_create.md
+++ b/docs/cmd/kn_source_apiserver_create.md
@@ -30,7 +30,7 @@ kn source apiserver create NAME --resource RESOURCE --sink SINK
       --resource stringArray      Specification for which events to listen, in the format Kind:APIVersion:LabelSelector, e.g. "Event:v1:key=value".
                                   "LabelSelector" is a list of comma separated key value pairs. "LabelSelector" can be omitted, e.g. "Event:v1".
       --service-account string    Name of the service account to use to run this source
-  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink 'ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If prefix is not provided, it is considered as a Knative service.
+  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
 ```
 
 ### Options inherited from parent commands
diff --git a/docs/cmd/kn_source_apiserver_update.md b/docs/cmd/kn_source_apiserver_update.md
index e9672544..2982dd40 100644
--- a/docs/cmd/kn_source_apiserver_update.md
+++ b/docs/cmd/kn_source_apiserver_update.md
@@ -30,7 +30,7 @@ kn source apiserver update NAME
       --resource stringArray      Specification for which events to listen, in the format Kind:APIVersion:LabelSelector, e.g. "Event:v1:key=value".
                                   "LabelSelector" is a list of comma separated key value pairs. "LabelSelector" can be omitted, e.g. "Event:v1".
       --service-account string    Name of the service account to use to run this source
-  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink 'ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If prefix is not provided, it is considered as a Knative service.
+  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
 ```
 
 ### Options inherited from parent commands
diff --git a/docs/cmd/kn_source_binding_create.md b/docs/cmd/kn_source_binding_create.md
index abb619f0..0a36b9ba 100644
--- a/docs/cmd/kn_source_binding_create.md
+++ b/docs/cmd/kn_source_binding_create.md
@@ -24,7 +24,7 @@ kn source binding create NAME --subject SUBJECT --sink SINK
       --ce-override stringArray   Cloud Event overrides to apply before sending event to sink. Example: '--ce-override key=value' You may be provide this flag multiple times. To unset, append "-" to the key (e.g. --ce-override key-).
   -h, --help                      help for create
   -n, --namespace string          Specify the namespace to operate in.
-  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink 'ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If prefix is not provided, it is considered as a Knative service.
+  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
       --subject string            Subject which emits cloud events. This argument takes format kind:apiVersion:name for named resources or kind:apiVersion:labelKey1=value1,labelKey2=value2 for matching via a label selector
 ```
 
diff --git a/docs/cmd/kn_source_binding_update.md b/docs/cmd/kn_source_binding_update.md
index 82131378..b3a76743 100644
--- a/docs/cmd/kn_source_binding_update.md
+++ b/docs/cmd/kn_source_binding_update.md
@@ -24,7 +24,7 @@ kn source binding update NAME
       --ce-override stringArray   Cloud Event overrides to apply before sending event to sink. Example: '--ce-override key=value' You may be provide this flag multiple times. To unset, append "-" to the key (e.g. --ce-override key-).
   -h, --help                      help for update
   -n, --namespace string          Specify the namespace to operate in.
-  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink 'ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If prefix is not provided, it is considered as a Knative service.
+  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
       --subject string            Subject which emits cloud events. This argument takes format kind:apiVersion:name for named resources or kind:apiVersion:labelKey1=value1,labelKey2=value2 for matching via a label selector
 ```
 
diff --git a/docs/cmd/kn_source_ping_create.md b/docs/cmd/kn_source_ping_create.md
index 14f10355..d291b521 100644
--- a/docs/cmd/kn_source_ping_create.md
+++ b/docs/cmd/kn_source_ping_create.md
@@ -26,7 +26,7 @@ kn source ping create NAME --sink SINK
   -h, --help                      help for create
   -n, --namespace string          Specify the namespace to operate in.
       --schedule string           Optional schedule specification in crontab format (e.g. '*/2 * * * *' for every two minutes. By default fire every minute.
-  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink 'ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If prefix is not provided, it is considered as a Knative service.
+  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
 ```
 
 ### Options inherited from parent commands
diff --git a/docs/cmd/kn_source_ping_update.md b/docs/cmd/kn_source_ping_update.md
index fe09b806..99c1c693 100644
--- a/docs/cmd/kn_source_ping_update.md
+++ b/docs/cmd/kn_source_ping_update.md
@@ -26,7 +26,7 @@ kn source ping update NAME
   -h, --help                      help for update
   -n, --namespace string          Specify the namespace to operate in.
       --schedule string           Optional schedule specification in crontab format (e.g. '*/2 * * * *' for every two minutes. By default fire every minute.
-  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink 'ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If prefix is not provided, it is considered as a Knative service.
+  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
 ```
 
 ### Options inherited from parent commands
diff --git a/docs/cmd/kn_subscription.md b/docs/cmd/kn_subscription.md
new file mode 100644
index 00000000..640bb9a3
--- /dev/null
+++ b/docs/cmd/kn_subscription.md
@@ -0,0 +1,35 @@
+## kn subscription
+
+Manage event subscriptions
+
+### Synopsis
+
+Manage event subscriptions
+
+```
+kn subscription COMMAND
+```
+
+### Options
+
+```
+  -h, --help   help for subscription
+```
+
+### Options inherited from parent commands
+
+```
+      --config string       kn configuration file (default: ~/.config/kn/config.yaml)
+      --kubeconfig string   kubectl configuration file (default: ~/.kube/config)
+      --log-http            log http traffic
+```
+
+### SEE ALSO
+
+* [kn](kn.md)	 - kn manages Knative Serving and Eventing resources
+* [kn subscription create](kn_subscription_create.md)	 - Create a subscription
+* [kn subscription delete](kn_subscription_delete.md)	 - Delete a subscription
+* [kn subscription describe](kn_subscription_describe.md)	 - Show details of a subscription
+* [kn subscription list](kn_subscription_list.md)	 - List subscriptions
+* [kn subscription update](kn_subscription_update.md)	 - Update an event subscription
+
diff --git a/docs/cmd/kn_subscription_create.md b/docs/cmd/kn_subscription_create.md
new file mode 100644
index 00000000..a36fcc46
--- /dev/null
+++ b/docs/cmd/kn_subscription_create.md
@@ -0,0 +1,46 @@
+## kn subscription create
+
+Create a subscription
+
+### Synopsis
+
+Create a subscription
+
+```
+kn subscription create NAME
+```
+
+### Examples
+
+```
+
+  # Create a subscription 'sub0' from InMemoryChannel 'pipe0' to a subscriber ksvc 'receiver'
+  kn subscription create sub0 --channel imcv1beta1:pipe0 --sink ksvc:receiver
+
+  # Create a subscription 'sub1' from KafkaChannel 'k1' to ksvc 'mirror', reply to a broker 'nest' and DeadLetterSink to a ksvc 'bucket'
+  kn subscription create sub1 --channel messaging.knative.dev:v1alpha1:KafkaChannel:k1 --sink mirror --sink-reply broker:nest --sink-dead-letter bucket
+```
+
+### Options
+
+```
+      --channel string            Specify the channel to subscribe to. For the default channel, just use the name (e.g. 'mychannel'). A mapped channel type like 'imc' can be used as a prefix (e.g. 'imc:mychannel'). Finally you can specify the full coordinates to the referenced channel with Group:Version:Kind:Name (e.g. 'messaging.knative.dev:v1alpha1:KafkaChannel:mychannel').
+  -h, --help                      help for create
+  -n, --namespace string          Specify the namespace to operate in.
+  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
+      --sink-dead-letter string   Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink-dead-letter broker:nest' for a broker 'nest', '--sink-dead-letter https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink-dead-letter ksvc:receiver' or simply '--sink-dead-letter receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
+      --sink-reply string         Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink-reply broker:nest' for a broker 'nest', '--sink-reply https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink-reply ksvc:receiver' or simply '--sink-reply receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
+```
+
+### Options inherited from parent commands
+
+```
+      --config string       kn configuration file (default: ~/.config/kn/config.yaml)
+      --kubeconfig string   kubectl configuration file (default: ~/.kube/config)
+      --log-http            log http traffic
+```
+
+### SEE ALSO
+
+* [kn subscription](kn_subscription.md)	 - Manage event subscriptions
+
diff --git a/docs/cmd/kn_subscription_delete.md b/docs/cmd/kn_subscription_delete.md
new file mode 100644
index 00000000..c173f3aa
--- /dev/null
+++ b/docs/cmd/kn_subscription_delete.md
@@ -0,0 +1,39 @@
+## kn subscription delete
+
+Delete a subscription
+
+### Synopsis
+
+Delete a subscription
+
+```
+kn subscription delete NAME
+```
+
+### Examples
+
+```
+
+  # Delete a subscription 'sub0'
+  kn subscription delete sub0
+```
+
+### Options
+
+```
+  -h, --help               help for delete
+  -n, --namespace string   Specify the namespace to operate in.
+```
+
+### Options inherited from parent commands
+
+```
+      --config string       kn configuration file (default: ~/.config/kn/config.yaml)
+      --kubeconfig string   kubectl configuration file (default: ~/.kube/config)
+      --log-http            log http traffic
+```
+
+### SEE ALSO
+
+* [kn subscription](kn_subscription.md)	 - Manage event subscriptions
+
diff --git a/docs/cmd/kn_subscription_describe.md b/docs/cmd/kn_subscription_describe.md
new file mode 100644
index 00000000..e04c01de
--- /dev/null
+++ b/docs/cmd/kn_subscription_describe.md
@@ -0,0 +1,43 @@
+## kn subscription describe
+
+Show details of a subscription
+
+### Synopsis
+
+Show details of a subscription
+
+```
+kn subscription describe NAME
+```
+
+### Examples
+
+```
+
+  # Describe a subscription 'pipe'
+  kn subscription describe pipe
+```
+
+### Options
+
+```
+      --allow-missing-template-keys   If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
+  -h, --help                          help for describe
+  -n, --namespace string              Specify the namespace to operate in.
+  -o, --output string                 Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
+      --template string               Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
+  -v, --verbose                       More output.
+```
+
+### Options inherited from parent commands
+
+```
+      --config string       kn configuration file (default: ~/.config/kn/config.yaml)
+      --kubeconfig string   kubectl configuration file (default: ~/.kube/config)
+      --log-http            log http traffic
+```
+
+### SEE ALSO
+
+* [kn subscription](kn_subscription.md)	 - Manage event subscriptions
+
diff --git a/docs/cmd/kn_subscription_list.md b/docs/cmd/kn_subscription_list.md
new file mode 100644
index 00000000..4aead93a
--- /dev/null
+++ b/docs/cmd/kn_subscription_list.md
@@ -0,0 +1,47 @@
+## kn subscription list
+
+List subscriptions
+
+### Synopsis
+
+List subscriptions
+
+```
+kn subscription list
+```
+
+### Examples
+
+```
+
+  # List all subscriptions
+  kn subscription list
+
+  # List subscriptions in YAML format
+  kn subscription list -o yaml
+```
+
+### Options
+
+```
+  -A, --all-namespaces                If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.
+      --allow-missing-template-keys   If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
+  -h, --help                          help for list
+  -n, --namespace string              Specify the namespace to operate in.
+      --no-headers                    When using the default output format, don't print headers (default: print headers).
+  -o, --output string                 Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
+      --template string               Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
+```
+
+### Options inherited from parent commands
+
+```
+      --config string       kn configuration file (default: ~/.config/kn/config.yaml)
+      --kubeconfig string   kubectl configuration file (default: ~/.kube/config)
+      --log-http            log http traffic
+```
+
+### SEE ALSO
+
+* [kn subscription](kn_subscription.md)	 - Manage event subscriptions
+
diff --git a/docs/cmd/kn_subscription_update.md b/docs/cmd/kn_subscription_update.md
new file mode 100644
index 00000000..3ce6e6cd
--- /dev/null
+++ b/docs/cmd/kn_subscription_update.md
@@ -0,0 +1,45 @@
+## kn subscription update
+
+Update an event subscription
+
+### Synopsis
+
+Update an event subscription
+
+```
+kn subscription update NAME
+```
+
+### Examples
+
+```
+
+  # Update a subscription 'sub0' with a subscriber ksvc 'receiver'
+  kn subscription update sub0 --sink ksvc:receiver
+
+  # Update a subscription 'sub1' with subscriber ksvc 'mirror', reply to a broker 'nest' and DeadLetterSink to a ksvc 'bucket'
+  kn subscription update sub1 --sink mirror --sink-reply broker:nest --sink-dead-letter bucket
+```
+
+### Options
+
+```
+  -h, --help                      help for update
+  -n, --namespace string          Specify the namespace to operate in.
+  -s, --sink string               Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
+      --sink-dead-letter string   Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink-dead-letter broker:nest' for a broker 'nest', '--sink-dead-letter https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink-dead-letter ksvc:receiver' or simply '--sink-dead-letter receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
+      --sink-reply string         Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink-reply broker:nest' for a broker 'nest', '--sink-reply https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink-reply ksvc:receiver' or simply '--sink-reply receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
+```
+
+### Options inherited from parent commands
+
+```
+      --config string       kn configuration file (default: ~/.config/kn/config.yaml)
+      --kubeconfig string   kubectl configuration file (default: ~/.kube/config)
+      --log-http            log http traffic
+```
+
+### SEE ALSO
+
+* [kn subscription](kn_subscription.md)	 - Manage event subscriptions
+
diff --git a/docs/cmd/kn_trigger_create.md b/docs/cmd/kn_trigger_create.md
index e5ea45bf..f9c57ed0 100644
--- a/docs/cmd/kn_trigger_create.md
+++ b/docs/cmd/kn_trigger_create.md
@@ -29,7 +29,7 @@ kn trigger create NAME --sink SINK
   -h, --help               help for create
       --inject-broker      Create new broker with name default through common annotation
   -n, --namespace string   Specify the namespace to operate in.
-  -s, --sink string        Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink 'ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If prefix is not provided, it is considered as a Knative service.
+  -s, --sink string        Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
 ```
 
 ### Options inherited from parent commands
diff --git a/docs/cmd/kn_trigger_update.md b/docs/cmd/kn_trigger_update.md
index 761bd5cc..7a609489 100644
--- a/docs/cmd/kn_trigger_update.md
+++ b/docs/cmd/kn_trigger_update.md
@@ -33,7 +33,7 @@ kn trigger update NAME
   -h, --help               help for update
       --inject-broker      Create new broker with name default through common annotation
   -n, --namespace string   Specify the namespace to operate in.
-  -s, --sink string        Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink 'ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If prefix is not provided, it is considered as a Knative service.
+  -s, --sink string        Addressable sink for events. You can specify a broker, Knative service or URI. Examples: '--sink broker:nest' for a broker 'nest', '--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, '--sink ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. If a prefix is not provided, it is considered as a Knative service.
 ```
 
 ### Options inherited from parent commands
diff --git a/lib/printing/describe.go b/lib/printing/describe.go
new file mode 100644
index 00000000..a130ad64
--- /dev/null
+++ b/lib/printing/describe.go
@@ -0,0 +1,45 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 printing
+
+import (
+	"fmt"
+
+	"knative.dev/client/pkg/printers"
+	duckv1 "knative.dev/pkg/apis/duck/v1"
+)
+
+// DescribeSink prints the given 'sink' for the given prefix writer 'dw',
+// provide 'attribute' to print the section heading for this sink
+func DescribeSink(dw printers.PrefixWriter, attribute, namespace string, sink *duckv1.Destination) {
+	if sink == nil {
+		return
+	}
+	subWriter := dw.WriteAttribute(attribute, "")
+	ref := sink.Ref
+	if ref != nil {
+		subWriter.WriteAttribute("Name", sink.Ref.Name)
+		if sink.Ref.Namespace != "" && sink.Ref.Namespace != namespace {
+			subWriter.WriteAttribute("Namespace", sink.Ref.Namespace)
+		}
+		subWriter.WriteAttribute("Resource", fmt.Sprintf("%s (%s)", sink.Ref.Kind, sink.Ref.APIVersion))
+	}
+	uri := sink.URI
+	if uri != nil {
+		subWriter.WriteAttribute("URI", uri.String())
+	}
+}
diff --git a/pkg/dynamic/fake/fake.go b/pkg/dynamic/fake/fake.go
index c4c29568..a4529fa5 100644
--- a/pkg/dynamic/fake/fake.go
+++ b/pkg/dynamic/fake/fake.go
@@ -20,6 +20,7 @@ import (
 	dynamicfake "k8s.io/client-go/dynamic/fake"
 
 	eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1"
+	messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1"
 	servingv1 "knative.dev/serving/pkg/apis/serving/v1"
 
 	"knative.dev/client/pkg/dynamic"
@@ -30,6 +31,7 @@ func CreateFakeKnDynamicClient(testNamespace string, objects ...runtime.Object)
 	scheme := runtime.NewScheme()
 	scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "serving.knative.dev", Version: "v1", Kind: "Service"}, &servingv1.Service{})
 	scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "eventing.knative.dev", Version: "v1beta1", Kind: "Broker"}, &eventingv1beta1.Broker{})
+	scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "eventing.knative.dev", Version: "v1beta1", Kind: "Subscription"}, &messagingv1beta1.Subscription{})
 	client := dynamicfake.NewSimpleDynamicClient(scheme, objects...)
 	return dynamic.NewKnDynamicClient(client, testNamespace)
 }
diff --git a/pkg/kn/commands/flags/sink.go b/pkg/kn/commands/flags/sink.go
index dd9a63eb..abd3963e 100644
--- a/pkg/kn/commands/flags/sink.go
+++ b/pkg/kn/commands/flags/sink.go
@@ -33,17 +33,21 @@ type SinkFlags struct {
 	sink string
 }
 
-func (i *SinkFlags) Add(cmd *cobra.Command) {
-	cmd.Flags().StringVarP(&i.sink,
-		"sink",
-		"s",
-		"",
-		"Addressable sink for events. "+
-			"You can specify a broker, Knative service or URI. "+
-			"Examples: '--sink broker:nest' for a broker 'nest', "+
-			"'--sink https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, "+
-			"'--sink 'ksvc:receiver' or simply '--sink receiver' for a Knative service 'receiver'. "+
-			"If prefix is not provided, it is considered as a Knative service.")
+// AddWithFlagName configures sink flag with given flag name and a short flag name
+// pass empty short flag name if you dont want to set one
+func (i *SinkFlags) AddWithFlagName(cmd *cobra.Command, fname, short string) {
+	flag := "--" + fname
+	if short == "" {
+		cmd.Flags().StringVar(&i.sink, fname, "", "")
+	} else {
+		cmd.Flags().StringVarP(&i.sink, fname, short, "", "")
+	}
+	cmd.Flag(fname).Usage = "Addressable sink for events. " +
+		"You can specify a broker, Knative service or URI. " +
+		"Examples: '" + flag + " broker:nest' for a broker 'nest', " +
+		"'" + flag + " https://event.receiver.uri' for an URI with an 'http://' or 'https://' schema, " +
+		"'" + flag + " ksvc:receiver' or simply '" + flag + " receiver' for a Knative service 'receiver'. " +
+		"If a prefix is not provided, it is considered as a Knative service."
 
 	for _, p := range config.GlobalConfig.SinkMappings() {
 		//user configration might override the default configuration
@@ -55,6 +59,11 @@ func (i *SinkFlags) Add(cmd *cobra.Command) {
 	}
 }
 
+// Add configures sink flag with name 'sink' amd short name 's'
+func (i *SinkFlags) Add(cmd *cobra.Command) {
+	i.AddWithFlagName(cmd, "sink", "s")
+}
+
 // sinkPrefixes maps prefixes used for sinks to their GroupVersionResources.
 var sinkMappings = map[string]schema.GroupVersionResource{
 	"broker": {
diff --git a/pkg/kn/commands/service/configuration_edit_flags.go b/pkg/kn/commands/service/configuration_edit_flags.go
index 79158625..ebf31c5f 100644
--- a/pkg/kn/commands/service/configuration_edit_flags.go
+++ b/pkg/kn/commands/service/configuration_edit_flags.go
@@ -51,6 +51,8 @@ type ConfigurationEditFlags struct {
 	LabelsRevision         []string
 	RevisionName           string
 	Annotations            []string
+	AnnotationsService     []string
+	AnnotationsRevision    []string
 	ClusterLocal           bool
 	ScaleInit              int
 
@@ -127,13 +129,13 @@ func (p *ConfigurationEditFlags) addSharedFlags(command *cobra.Command) {
 		"Service label to set. name=value; you may provide this flag "+
 			"any number of times to set multiple labels. "+
 			"To unset, specify the label name followed by a \"-\" (e.g., name-). This flag takes "+
-			"precedence over \"label\" flag.")
+			"precedence over the \"label\" flag.")
 	p.markFlagMakesRevision("label-service")
 	command.Flags().StringArrayVarP(&p.LabelsRevision, "label-revision", "", []string{},
 		"Revision label to set. name=value; you may provide this flag "+
 			"any number of times to set multiple labels. "+
 			"To unset, specify the label name followed by a \"-\" (e.g., name-). This flag takes "+
-			"precedence over \"label\" flag.")
+			"precedence over the \"label\" flag.")
 	p.markFlagMakesRevision("label-revision")
 
 	command.Flags().StringVar(&p.RevisionName, "revision-name", "{{.Service}}-{{.Random 5}}-{{.Generation}}",
@@ -149,11 +151,25 @@ func (p *ConfigurationEditFlags) addSharedFlags(command *cobra.Command) {
 	// Don't mark as changing the revision.
 
 	command.Flags().StringArrayVarP(&p.Annotations, "annotation", "a", []string{},
-		"Service annotation to set. name=value; you may provide this flag "+
+		"Annotations to set for both Service and Revision. name=value; you may provide this flag "+
 			"any number of times to set multiple annotations. "+
 			"To unset, specify the annotation name followed by a \"-\" (e.g., name-).")
 	p.markFlagMakesRevision("annotation")
 
+	command.Flags().StringArrayVarP(&p.AnnotationsService, "annotation-service", "", []string{},
+		"Service annotation to set. name=value; you may provide this flag "+
+			"any number of times to set multiple annotations. "+
+			"To unset, specify the annotation name followed by a \"-\" (e.g., name-). This flag takes "+
+			"precedence over the \"annotation\" flag.")
+	p.markFlagMakesRevision("annotation-service")
+
+	command.Flags().StringArrayVarP(&p.AnnotationsRevision, "annotation-revision", "", []string{},
+		"Revision annotation to set. name=value; you may provide this flag "+
+			"any number of times to set multiple annotations. "+
+			"To unset, specify the annotation name followed by a \"-\" (e.g., name-). This flag takes "+
+			"precedence over the \"annotation\" flag.")
+	p.markFlagMakesRevision("annotation-revision")
+
 	command.Flags().IntVar(&p.ScaleInit, "scale-init", 0, "Initial number of replicas with which a service starts. Can be 0 or a positive integer.")
 	p.markFlagMakesRevision("scale-init")
 }
@@ -406,25 +422,47 @@ func (p *ConfigurationEditFlags) Apply(
 		}
 	}
 
-	if cmd.Flags().Changed("annotation") {
-		annotationsMap, err := util.MapFromArrayAllowingSingles(p.Annotations, "=")
+	if cmd.Flags().Changed("annotation") || cmd.Flags().Changed("annotation-service") || cmd.Flags().Changed("annotation-revision") {
+		annotationsAllMap, err := util.MapFromArrayAllowingSingles(p.Annotations, "=")
 		if err != nil {
 			return fmt.Errorf("Invalid --annotation: %w", err)
 		}
+		annotationRevisionFlagMap, err := util.MapFromArrayAllowingSingles(p.AnnotationsRevision, "=")
+		if err != nil {
+			return fmt.Errorf("Invalid --annotation-revision: %w", err)
+		}
+		annotationServiceFlagMap, err := util.MapFromArrayAllowingSingles(p.AnnotationsService, "=")
+		if err != nil {
+			return fmt.Errorf("Invalid --annotation-service: %w", err)
+		}
+
+		annotationsToRemove := util.ParseMinusSuffix(annotationsAllMap)
+
+		revisionAnnotations := make(util.StringMap)
+		revisionAnnotations.Merge(annotationsAllMap)
+		revisionAnnotations.Merge(annotationRevisionFlagMap)
+		err = servinglib.UpdateRevisionTemplateAnnotations(template, revisionAnnotations, annotationsToRemove)
+		if err != nil {
+			return err
+		}
+
+		serviceAnnotations := make(util.StringMap)
 
-		annotationsToRemove := util.ParseMinusSuffix(annotationsMap)
 		// Service Annotations can't contain Autoscaling ones
-		serviceAnnotations := make(map[string]string)
-		for key, value := range annotationsMap {
+
+		for key, value := range annotationsAllMap {
 			if !strings.HasPrefix(key, autoscaling.GroupName) {
 				serviceAnnotations[key] = value
 			}
 		}
-		// Add all user provided annotations to RevisionTemplate
-		err = servinglib.UpdateRevisionTemplateAnnotations(template, annotationsMap, annotationsToRemove)
-		if err != nil {
-			return err
+
+		for key, value := range annotationServiceFlagMap {
+			if strings.HasPrefix(key, autoscaling.GroupName) {
+				return fmt.Errorf("service can not have auto-scaling related annotation: %s , please update using '--annotation-revision'", key)
+			}
+			serviceAnnotations[key] = value
 		}
+
 		err = servinglib.UpdateServiceAnnotations(service, serviceAnnotations, annotationsToRemove)
 		if err != nil {
 			return err
diff --git a/pkg/kn/commands/subscription/create.go b/pkg/kn/commands/subscription/create.go
new file mode 100644
index 00000000..867555c4
--- /dev/null
+++ b/pkg/kn/commands/subscription/create.go
@@ -0,0 +1,116 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/spf13/cobra"
+
+	knerrors "knative.dev/client/pkg/errors"
+	"knative.dev/client/pkg/kn/commands"
+	"knative.dev/client/pkg/kn/commands/flags"
+	knflags "knative.dev/client/pkg/kn/flags"
+	knmessagingv1beta1 "knative.dev/client/pkg/messaging/v1beta1"
+)
+
+// NewSubscriptionCreateCommand to create event subscriptions
+func NewSubscriptionCreateCommand(p *commands.KnParams) *cobra.Command {
+	var (
+		crefFlag                           knflags.ChannelRef
+		subscriberFlag, replyFlag, dlsFlag flags.SinkFlags
+	)
+
+	cmd := &cobra.Command{
+		Use:   "create NAME",
+		Short: "Create a subscription",
+		Example: `
+  # Create a subscription 'sub0' from InMemoryChannel 'pipe0' to a subscriber ksvc 'receiver'
+  kn subscription create sub0 --channel imcv1beta1:pipe0 --sink ksvc:receiver
+
+  # Create a subscription 'sub1' from KafkaChannel 'k1' to ksvc 'mirror', reply to a broker 'nest' and DeadLetterSink to a ksvc 'bucket'
+  kn subscription create sub1 --channel messaging.knative.dev:v1alpha1:KafkaChannel:k1 --sink mirror --sink-reply broker:nest --sink-dead-letter bucket`,
+
+		RunE: func(cmd *cobra.Command, args []string) (err error) {
+			if len(args) != 1 {
+				return errors.New("'kn subscription create' requires the subscription name given as single argument")
+			}
+			name := args[0]
+
+			if crefFlag.Cref == "" {
+				return errors.New("'kn subscription create' requires the channel reference provided with --channel flag")
+			}
+
+			namespace, err := p.GetNamespace(cmd)
+			if err != nil {
+				return err
+			}
+
+			dynamicClient, err := p.NewDynamicClient(namespace)
+			if err != nil {
+				return err
+			}
+
+			client, err := newSubscriptionClient(p, cmd)
+			if err != nil {
+				return err
+			}
+
+			sb := knmessagingv1beta1.NewSubscriptionBuilder(name)
+
+			cref, err := crefFlag.Parse()
+			if err != nil {
+				return err
+			}
+			sb.Channel(cref)
+
+			sub, err := subscriberFlag.ResolveSink(dynamicClient, namespace)
+			if err != nil {
+				return err
+			}
+			sb.Subscriber(sub)
+
+			rep, err := replyFlag.ResolveSink(dynamicClient, namespace)
+			if err != nil {
+				return err
+			}
+			sb.Reply(rep)
+
+			ds, err := dlsFlag.ResolveSink(dynamicClient, namespace)
+			if err != nil {
+				return err
+			}
+			sb.DeadLetterSink(ds)
+
+			err = client.CreateSubscription(sb.Build())
+			if err != nil {
+				return knerrors.GetError(err)
+			}
+
+			fmt.Fprintf(cmd.OutOrStdout(), "Subscription '%s' created in namespace '%s'.\n", name, namespace)
+			return nil
+		},
+	}
+	commands.AddNamespaceFlags(cmd.Flags(), false)
+	crefFlag.Add(cmd.Flags())
+	// add subscriber flag as `--sink`
+	subscriberFlag.Add(cmd)
+	replyFlag.AddWithFlagName(cmd, "sink-reply", "")
+	dlsFlag.AddWithFlagName(cmd, "sink-dead-letter", "")
+	return cmd
+}
diff --git a/pkg/kn/commands/subscription/delete.go b/pkg/kn/commands/subscription/delete.go
new file mode 100644
index 00000000..9fdd0fd7
--- /dev/null
+++ b/pkg/kn/commands/subscription/delete.go
@@ -0,0 +1,57 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/spf13/cobra"
+	"knative.dev/client/pkg/kn/commands"
+)
+
+// NewSubscriptionDeleteCommand is for deleting a Subscription
+func NewSubscriptionDeleteCommand(p *commands.KnParams) *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "delete NAME",
+		Short: "Delete a subscription",
+		Example: `
+  # Delete a subscription 'sub0'
+  kn subscription delete sub0`,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			if len(args) != 1 {
+				return errors.New("'kn subscription delete' requires the subscription name as single argument")
+			}
+			name := args[0]
+
+			subscriptionClient, err := newSubscriptionClient(p, cmd)
+			if err != nil {
+				return err
+			}
+
+			err = subscriptionClient.DeleteSubscription(name)
+			if err != nil {
+				return err
+			}
+
+			fmt.Fprintf(cmd.OutOrStdout(), "Subscription '%s' deleted in namespace '%s'.\n", name, subscriptionClient.Namespace())
+			return nil
+		},
+	}
+	commands.AddNamespaceFlags(cmd.Flags(), false)
+	return cmd
+}
diff --git a/pkg/kn/commands/subscription/describe.go b/pkg/kn/commands/subscription/describe.go
new file mode 100644
index 00000000..4e24bba6
--- /dev/null
+++ b/pkg/kn/commands/subscription/describe.go
@@ -0,0 +1,110 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/spf13/cobra"
+
+	"k8s.io/cli-runtime/pkg/genericclioptions"
+	messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1"
+
+	"knative.dev/client/lib/printing"
+	knerrors "knative.dev/client/pkg/errors"
+	"knative.dev/client/pkg/kn/commands"
+	"knative.dev/client/pkg/printers"
+)
+
+// NewSubscriptionDescribeCommand returns a new command for describe a subscription object
+func NewSubscriptionDescribeCommand(p *commands.KnParams) *cobra.Command {
+
+	// For machine readable output
+	machineReadablePrintFlags := genericclioptions.NewPrintFlags("")
+
+	cmd := &cobra.Command{
+		Use:   "describe NAME",
+		Short: "Show details of a subscription",
+		Example: `
+  # Describe a subscription 'pipe'
+  kn subscription describe pipe`,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			if len(args) != 1 {
+				return errors.New("'kn subscription describe' requires the subscription name given as single argument")
+			}
+			name := args[0]
+
+			client, err := newSubscriptionClient(p, cmd)
+			if err != nil {
+				return err
+			}
+
+			subscription, err := client.GetSubscription(name)
+			if err != nil {
+				return knerrors.GetError(err)
+			}
+
+			out := cmd.OutOrStdout()
+
+			if machineReadablePrintFlags.OutputFlagSpecified() {
+				printer, err := machineReadablePrintFlags.ToPrinter()
+				if err != nil {
+					return err
+				}
+				return printer.PrintObj(subscription, out)
+			}
+
+			dw := printers.NewPrefixWriter(out)
+
+			printDetails, err := cmd.Flags().GetBool("verbose")
+			if err != nil {
+				return err
+			}
+
+			writeSubscription(dw, subscription, printDetails)
+			dw.WriteLine()
+			if err := dw.Flush(); err != nil {
+				return err
+			}
+
+			// Condition info
+			commands.WriteConditions(dw, subscription.Status.Conditions, printDetails)
+			if err := dw.Flush(); err != nil {
+				return err
+			}
+
+			return nil
+		},
+	}
+	flags := cmd.Flags()
+	commands.AddNamespaceFlags(flags, false)
+	flags.BoolP("verbose", "v", false, "More output.")
+	machineReadablePrintFlags.AddFlags(cmd)
+	return cmd
+}
+
+func writeSubscription(dw printers.PrefixWriter, subscription *messagingv1beta1.Subscription, printDetails bool) {
+	commands.WriteMetadata(dw, &subscription.ObjectMeta, printDetails)
+	ctype := fmt.Sprintf("%s:%s (%s)", subscription.Spec.Channel.Kind, subscription.Spec.Channel.Name, subscription.Spec.Channel.APIVersion)
+	dw.WriteAttribute("Channel", ctype)
+	printing.DescribeSink(dw, "Subscriber", subscription.Namespace, subscription.Spec.Subscriber)
+	printing.DescribeSink(dw, "Reply", subscription.Namespace, subscription.Spec.Reply)
+	if subscription.Spec.DeepCopy().Delivery != nil {
+		printing.DescribeSink(dw, "DeadLetterSink", subscription.Namespace, subscription.Spec.Delivery.DeadLetterSink)
+	}
+}
diff --git a/pkg/kn/commands/subscription/flags.go b/pkg/kn/commands/subscription/flags.go
new file mode 100644
index 00000000..d5495b6b
--- /dev/null
+++ b/pkg/kn/commands/subscription/flags.go
@@ -0,0 +1,139 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"sort"
+
+	metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
+	"k8s.io/apimachinery/pkg/runtime"
+
+	"knative.dev/client/pkg/kn/commands"
+	"knative.dev/client/pkg/kn/commands/flags"
+	hprinters "knative.dev/client/pkg/printers"
+
+	messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1"
+)
+
+// ListHandlers handles printing human readable table for `kn subscription list` command's output
+func ListHandlers(h hprinters.PrintHandler) {
+	subscriptionColumnDefinitions := []metav1beta1.TableColumnDefinition{
+		{Name: "Namespace", Type: "string", Description: "Namespace of the subscription", Priority: 0},
+		{Name: "Name", Type: "string", Description: "Name of the subscription", Priority: 1},
+		{Name: "Channel", Type: "string", Description: "Channel of the subcription", Priority: 1},
+		{Name: "Subscriber", Type: "string", Description: "Subscriber sink of the subscription", Priority: 1},
+		{Name: "Reply", Type: "string", Description: "Reply sink of the subscription", Priority: 1},
+		{Name: "Dead Letter Sink", Type: "string", Description: "DeadLetterSink of the subscription", Priority: 1},
+		{Name: "Ready", Type: "string", Description: "Ready state of the subscription", Priority: 1},
+		{Name: "Reason", Type: "string", Description: "Reason for non ready subscription", Priority: 1},
+	}
+	h.TableHandler(subscriptionColumnDefinitions, printSubscription)
+	h.TableHandler(subscriptionColumnDefinitions, printSubscriptionList)
+}
+
+// printSubscription populates a single row of Subscription list
+func printSubscription(subscription *messagingv1beta1.Subscription, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
+	row := metav1beta1.TableRow{
+		Object: runtime.RawExtension{Object: subscription},
+	}
+
+	name := subscription.Name
+	ctype := subscription.Spec.Channel.Kind
+	channel := subscription.Spec.Channel.Name
+
+	var subscriber, reply, dls string
+	if subscription.Spec.Subscriber != nil {
+		subscriber = flags.SinkToString(*subscription.Spec.Subscriber)
+	} else {
+		subscriber = ""
+	}
+	if subscription.Spec.Reply != nil {
+		reply = flags.SinkToString(*subscription.Spec.Reply)
+	} else {
+		reply = ""
+	}
+	if subscription.Spec.Delivery != nil && subscription.Spec.Delivery.DeadLetterSink != nil {
+		dls = flags.SinkToString(*subscription.Spec.Delivery.DeadLetterSink)
+	} else {
+		dls = ""
+	}
+	ready := commands.ReadyCondition(subscription.Status.Conditions)
+	reason := commands.NonReadyConditionReason(subscription.Status.Conditions)
+
+	if options.AllNamespaces {
+		row.Cells = append(row.Cells, subscription.Namespace)
+	}
+
+	row.Cells = append(row.Cells, name, ctype+":"+channel, subscriber, reply, dls, ready, reason)
+	return []metav1beta1.TableRow{row}, nil
+}
+
+// printSubscriptionList populates the Subscription list table rows
+func printSubscriptionList(subscriptionList *messagingv1beta1.SubscriptionList, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
+	if options.AllNamespaces {
+		return printSubscriptionListWithNamespace(subscriptionList, options)
+	}
+
+	rows := make([]metav1beta1.TableRow, 0, len(subscriptionList.Items))
+
+	sort.SliceStable(subscriptionList.Items, func(i, j int) bool {
+		return subscriptionList.Items[i].GetName() < subscriptionList.Items[j].GetName()
+	})
+
+	for _, item := range subscriptionList.Items {
+		row, err := printSubscription(&item, options)
+		if err != nil {
+			return nil, err
+		}
+
+		rows = append(rows, row...)
+	}
+	return rows, nil
+}
+
+// printSubscriptionListWithNamespace populates the knative service table rows with namespace column
+func printSubscriptionListWithNamespace(subscriptionList *messagingv1beta1.SubscriptionList, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
+	rows := make([]metav1beta1.TableRow, 0, len(subscriptionList.Items))
+
+	// temporary slice for sorting services in non-default namespace
+	var others []metav1beta1.TableRow
+
+	for _, subscription := range subscriptionList.Items {
+		// Fill in with services in `default` namespace at first
+		if subscription.Namespace == "default" {
+			r, err := printSubscription(&subscription, options)
+			if err != nil {
+				return nil, err
+			}
+			rows = append(rows, r...)
+			continue
+		}
+		// put other services in temporary slice
+		r, err := printSubscription(&subscription, options)
+		if err != nil {
+			return nil, err
+		}
+		others = append(others, r...)
+	}
+
+	// sort other services list alphabetically by namespace
+	sort.SliceStable(others, func(i, j int) bool {
+		return others[i].Cells[0].(string) < others[j].Cells[0].(string)
+	})
+
+	return append(rows, others...), nil
+}
diff --git a/pkg/kn/commands/subscription/list.go b/pkg/kn/commands/subscription/list.go
new file mode 100644
index 00000000..8ee749d2
--- /dev/null
+++ b/pkg/kn/commands/subscription/list.go
@@ -0,0 +1,75 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+
+	"knative.dev/client/pkg/kn/commands"
+	"knative.dev/client/pkg/kn/commands/flags"
+)
+
+// NewSubscriptionListCommand is for listing subscription objects
+func NewSubscriptionListCommand(p *commands.KnParams) *cobra.Command {
+	listFlags := flags.NewListPrintFlags(ListHandlers)
+
+	listCommand := &cobra.Command{
+		Use:   "list",
+		Short: "List subscriptions",
+		Example: `
+  # List all subscriptions
+  kn subscription list
+
+  # List subscriptions in YAML format
+  kn subscription list -o yaml`,
+
+		RunE: func(cmd *cobra.Command, args []string) (err error) {
+			// TODO: filter list by given subscription name
+
+			client, err := newSubscriptionClient(p, cmd)
+			if err != nil {
+				return err
+			}
+
+			subscriptionList, err := client.ListSubscription()
+			if err != nil {
+				return err
+			}
+
+			if subscriptionList == nil || len(subscriptionList.Items) == 0 {
+				fmt.Fprintf(cmd.OutOrStdout(), "No subscriptions found.\n")
+				return nil
+			}
+
+			if client.Namespace() == "" {
+				listFlags.EnsureWithNamespace()
+			}
+
+			err = listFlags.Print(subscriptionList, cmd.OutOrStdout())
+			if err != nil {
+				return err
+			}
+
+			return nil
+		},
+	}
+	commands.AddNamespaceFlags(listCommand.Flags(), true)
+	listFlags.AddFlags(listCommand)
+	return listCommand
+}
diff --git a/pkg/kn/commands/subscription/subscription.go b/pkg/kn/commands/subscription/subscription.go
new file mode 100644
index 00000000..ca6bec0c
--- /dev/null
+++ b/pkg/kn/commands/subscription/subscription.go
@@ -0,0 +1,71 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"github.com/spf13/cobra"
+
+	"k8s.io/client-go/tools/clientcmd"
+	clientv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1beta1"
+
+	"knative.dev/client/pkg/kn/commands"
+	messagingv1beta1 "knative.dev/client/pkg/messaging/v1beta1"
+)
+
+// NewSubscriptionCommand to manage event subscriptions
+func NewSubscriptionCommand(p *commands.KnParams) *cobra.Command {
+	subscriptionCmd := &cobra.Command{
+		Use:     "subscription COMMAND",
+		Short:   "Manage event subscriptions",
+		Aliases: []string{"subscriptions", "sub"},
+	}
+	subscriptionCmd.AddCommand(NewSubscriptionCreateCommand(p))
+	subscriptionCmd.AddCommand(NewSubscriptionUpdateCommand(p))
+	subscriptionCmd.AddCommand(NewSubscriptionListCommand(p))
+	subscriptionCmd.AddCommand(NewSubscriptionDeleteCommand(p))
+	subscriptionCmd.AddCommand(NewSubscriptionDescribeCommand(p))
+	return subscriptionCmd
+}
+
+var subscriptionClientFactory func(config clientcmd.ClientConfig, namespace string) (messagingv1beta1.KnSubscriptionsClient, error)
+
+func newSubscriptionClient(p *commands.KnParams, cmd *cobra.Command) (messagingv1beta1.KnSubscriptionsClient, error) {
+	namespace, err := p.GetNamespace(cmd)
+	if err != nil {
+		return nil, err
+	}
+
+	if subscriptionClientFactory != nil {
+		config, err := p.GetClientConfig()
+		if err != nil {
+			return nil, err
+		}
+		return subscriptionClientFactory(config, namespace)
+	}
+
+	clientConfig, err := p.RestConfig()
+	if err != nil {
+		return nil, err
+	}
+
+	client, err := clientv1beta1.NewForConfig(clientConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	return messagingv1beta1.NewKnMessagingClient(client, namespace).SubscriptionsClient(), nil
+}
diff --git a/pkg/kn/commands/subscription/update.go b/pkg/kn/commands/subscription/update.go
new file mode 100644
index 00000000..87be5523
--- /dev/null
+++ b/pkg/kn/commands/subscription/update.go
@@ -0,0 +1,105 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/spf13/cobra"
+
+	knerrors "knative.dev/client/pkg/errors"
+	"knative.dev/client/pkg/kn/commands"
+	"knative.dev/client/pkg/kn/commands/flags"
+	knmessagingv1beta1 "knative.dev/client/pkg/messaging/v1beta1"
+)
+
+// NewSubscriptionUpdateCommand to update event subscriptions
+func NewSubscriptionUpdateCommand(p *commands.KnParams) *cobra.Command {
+	var subscriberFlag, replyFlag, dlsFlag flags.SinkFlags
+	cmd := &cobra.Command{
+		Use:   "update NAME",
+		Short: "Update an event subscription",
+		Example: `
+  # Update a subscription 'sub0' with a subscriber ksvc 'receiver'
+  kn subscription update sub0 --sink ksvc:receiver
+
+  # Update a subscription 'sub1' with subscriber ksvc 'mirror', reply to a broker 'nest' and DeadLetterSink to a ksvc 'bucket'
+  kn subscription update sub1 --sink mirror --sink-reply broker:nest --sink-dead-letter bucket`,
+
+		RunE: func(cmd *cobra.Command, args []string) (err error) {
+			if len(args) != 1 {
+				return errors.New("'kn subscription update' requires the subscription name given as single argument")
+			}
+			name := args[0]
+
+			namespace, err := p.GetNamespace(cmd)
+			if err != nil {
+				return err
+			}
+
+			dynamicClient, err := p.NewDynamicClient(namespace)
+			if err != nil {
+				return err
+			}
+
+			client, err := newSubscriptionClient(p, cmd)
+			if err != nil {
+				return err
+			}
+
+			foundSub, err := client.GetSubscription(name)
+			if err != nil {
+				return err
+			}
+
+			sb := knmessagingv1beta1.NewSubscriptionBuilderFromExisting(foundSub)
+
+			sub, err := subscriberFlag.ResolveSink(dynamicClient, namespace)
+			if err != nil {
+				return err
+			}
+			sb.Subscriber(sub)
+
+			rep, err := replyFlag.ResolveSink(dynamicClient, namespace)
+			if err != nil {
+				return err
+			}
+			sb.Reply(rep)
+
+			ds, err := dlsFlag.ResolveSink(dynamicClient, namespace)
+			if err != nil {
+				return err
+			}
+			sb.DeadLetterSink(ds)
+
+			err = client.UpdateSubscription(sb.Build())
+			if err != nil {
+				return knerrors.GetError(err)
+			}
+
+			fmt.Fprintf(cmd.OutOrStdout(), "Subscription '%s' updated in namespace '%s'.\n", name, namespace)
+			return nil
+		},
+	}
+	commands.AddNamespaceFlags(cmd.Flags(), false)
+	// add subscriber flag as `--sink`
+	subscriberFlag.Add(cmd)
+	replyFlag.AddWithFlagName(cmd, "sink-reply", "")
+	dlsFlag.AddWithFlagName(cmd, "sink-dead-letter", "")
+	return cmd
+}
diff --git a/pkg/kn/commands/version/version.go b/pkg/kn/commands/version/version.go
index 7f9aee64..f0596341 100644
--- a/pkg/kn/commands/version/version.go
+++ b/pkg/kn/commands/version/version.go
@@ -31,11 +31,11 @@ var GitRevision string
 // update this var as we add more deps
 var apiVersions = map[string][]string{
 	"serving": {
-		"serving.knative.dev/v1 (knative-serving v0.17.0)",
+		"serving.knative.dev/v1 (knative-serving v0.18.0)",
 	},
 	"eventing": {
-		"sources.knative.dev/v1alpha2 (knative-eventing v0.17.0)",
-		"eventing.knative.dev/v1beta1 (knative-eventing v0.17.0)",
+		"sources.knative.dev/v1alpha2 (knative-eventing v0.18.0)",
+		"eventing.knative.dev/v1beta1 (knative-eventing v0.18.0)",
 	},
 }
 
diff --git a/pkg/kn/flags/channel_types.go b/pkg/kn/flags/channel_types.go
index 4a5c726a..102476cb 100644
--- a/pkg/kn/flags/channel_types.go
+++ b/pkg/kn/flags/channel_types.go
@@ -19,6 +19,7 @@ import (
 	"strings"
 
 	"github.com/spf13/pflag"
+	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 
 	"knative.dev/client/pkg/kn/config"
@@ -28,6 +29,25 @@ type ChannelTypeFlags struct {
 	ctype string
 }
 
+type ChannelRef struct {
+	Cref string
+}
+
+// ctypeMappings maps aliases used for channel types to their GroupVersionKind
+var ctypeMappings = map[string]schema.GroupVersionKind{
+	"imcv1beta1": {
+		Group:   "messaging.knative.dev",
+		Version: "v1beta1",
+		Kind:    "InMemoryChannel",
+	},
+	"imc": {
+		Group:   "messaging.knative.dev",
+		Version: "v1",
+		Kind:    "InMemoryChannel",
+	},
+}
+
+// Add sets channel type flag definition to given flagset
 func (i *ChannelTypeFlags) Add(f *pflag.FlagSet) {
 	f.StringVar(&i.ctype,
 		"type",
@@ -48,20 +68,7 @@ func (i *ChannelTypeFlags) Add(f *pflag.FlagSet) {
 	}
 }
 
-// ctypeMappings maps aliases used for channel types to their GroupVersionKind
-var ctypeMappings = map[string]schema.GroupVersionKind{
-	"imcv1beta1": {
-		Group:   "messaging.knative.dev",
-		Version: "v1beta1",
-		Kind:    "InMemoryChannel",
-	},
-	"imc": {
-		Group:   "messaging.knative.dev",
-		Version: "v1",
-		Kind:    "InMemoryChannel",
-	},
-}
-
+// Parse parses the CLI value for channel type flag and populates GVK or returns error
 func (i *ChannelTypeFlags) Parse() (*schema.GroupVersionKind, error) {
 	parts := strings.Split(i.ctype, ":")
 	switch len(parts) {
@@ -79,3 +86,38 @@ func (i *ChannelTypeFlags) Parse() (*schema.GroupVersionKind, error) {
 		return nil, fmt.Errorf("Error: incorrect value '%s' for '--type', must be in the format 'Group:Version:Kind' or configure an alias in kn config", i.ctype)
 	}
 }
+
+// Add sets channel reference flag definition to given flagset
+func (i *ChannelRef) Add(f *pflag.FlagSet) {
+	f.StringVar(&i.Cref,
+		"channel",
+		"",
+		"Specify the channel to subscribe to. For the default channel, "+
+			"just use the name (e.g. 'mychannel'). A mapped channel type like 'imc' "+
+			"can be used as a prefix (e.g. 'imc:mychannel'). "+
+			"Finally you can specify the full coordinates to the referenced channel "+
+			"with Group:Version:Kind:Name (e.g. 'messaging.knative.dev:v1alpha1:KafkaChannel:mychannel').")
+}
+
+// Parse parses the CLI value for channel ref flag and populates object reference or return error
+func (i *ChannelRef) Parse() (*corev1.ObjectReference, error) {
+	parts := strings.Split(i.Cref, ":")
+	switch len(parts) {
+	// if no prefix is given, defer to "messaging.knative.dev/v1beta1:Channel"
+	case 1:
+		return &corev1.ObjectReference{Kind: "Channel", APIVersion: "messaging.knative.dev/v1beta1", Name: parts[0]}, nil
+	case 2:
+		if typ, ok := ctypeMappings[parts[0]]; ok {
+			return &corev1.ObjectReference{Kind: typ.Kind, APIVersion: typ.GroupVersion().String(), Name: parts[1]}, nil
+		}
+		return nil, fmt.Errorf("Error: unknown alias '%s' for '--channel', please configure the alias in kn config or specify in the format '--channel Group:Version:Kind:Name'", parts[0])
+	case 4:
+		if parts[0] == "" || parts[1] == "" || parts[2] == "" || parts[3] == "" {
+			return nil, fmt.Errorf("Error: incorrect value '%s' for '--channel', must be in the format 'Group:Version:Kind:Name' or configure an alias in kn config and refer as: '--channel ALIAS:NAME'", i.Cref)
+		}
+		return &corev1.ObjectReference{Kind: parts[2], APIVersion: parts[0] + "/" + parts[1], Name: parts[3]}, nil
+	default:
+		return nil, fmt.Errorf("Error: incorrect value '%s' for '--channel', must be in the format 'Group:Version:Kind:Name' or configure an alias in kn config and refer as: '--channel ALIAS:NAME'", i.Cref)
+	}
+	return nil, nil
+}
diff --git a/pkg/kn/root/root.go b/pkg/kn/root/root.go
index 4aa663c1..80b8b681 100644
--- a/pkg/kn/root/root.go
+++ b/pkg/kn/root/root.go
@@ -35,6 +35,7 @@ import (
 	"knative.dev/client/pkg/kn/commands/route"
 	"knative.dev/client/pkg/kn/commands/service"
 	"knative.dev/client/pkg/kn/commands/source"
+	"knative.dev/client/pkg/kn/commands/subscription"
 	"knative.dev/client/pkg/kn/commands/trigger"
 	"knative.dev/client/pkg/kn/commands/version"
 	"knative.dev/client/pkg/kn/config"
@@ -95,6 +96,7 @@ func NewRootCommand(helpFuncs *template.FuncMap) (*cobra.Command, error) {
 				broker.NewBrokerCommand(p),
 				trigger.NewTriggerCommand(p),
 				channel.NewChannelCommand(p),
+				subscription.NewSubscriptionCommand(p),
 			},
 		},
 		{
diff --git a/pkg/messaging/v1beta1/client.go b/pkg/messaging/v1beta1/client.go
index 196a5bf6..9a6c4868 100644
--- a/pkg/messaging/v1beta1/client.go
+++ b/pkg/messaging/v1beta1/client.go
@@ -28,6 +28,9 @@ import (
 type KnMessagingClient interface {
 	// Get the Channels client
 	ChannelsClient() KnChannelsClient
+
+	// Get the Subscriptions client
+	SubscriptionsClient() KnSubscriptionsClient
 }
 
 // messagingClient holds Messaging client interface and namespace
@@ -49,6 +52,11 @@ func (c *messagingClient) ChannelsClient() KnChannelsClient {
 	return newKnChannelsClient(c.client.Channels(c.namespace), c.namespace)
 }
 
+// SubscriptionsClient for working with Subscriptions
+func (c *messagingClient) SubscriptionsClient() KnSubscriptionsClient {
+	return newKnSubscriptionsClient(c.client.Subscriptions(c.namespace), c.namespace)
+}
+
 // update GVK of object
 func updateMessagingGVK(obj runtime.Object) error {
 	return util.UpdateGroupVersionKindWithScheme(obj, messagingv1beta1.SchemeGroupVersion, scheme.Scheme)
diff --git a/pkg/messaging/v1beta1/subscriptions_client.go b/pkg/messaging/v1beta1/subscriptions_client.go
new file mode 100644
index 00000000..ddc6fbb0
--- /dev/null
+++ b/pkg/messaging/v1beta1/subscriptions_client.go
@@ -0,0 +1,193 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 v1beta1
+
+import (
+	"context"
+
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1"
+	"knative.dev/eventing/pkg/apis/messaging/v1beta1"
+	clientv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1beta1"
+	duckv1 "knative.dev/pkg/apis/duck/v1"
+
+	knerrors "knative.dev/client/pkg/errors"
+)
+
+// KnSubscriptionsClient for interacting with Subscriptions
+type KnSubscriptionsClient interface {
+
+	// GetSubscription returns a Subscription by its name
+	GetSubscription(name string) (*v1beta1.Subscription, error)
+
+	// CreteSubscription creates a Subscription with given spec
+	CreateSubscription(subscription *v1beta1.Subscription) error
+
+	// UpdateSubscription updates a Subscription with given spec
+	UpdateSubscription(subscription *v1beta1.Subscription) error
+
+	// DeleteSubscription deletes a Subscription by its name
+	DeleteSubscription(name string) error
+
+	// ListSubscription lists all Subscriptions
+	ListSubscription() (*v1beta1.SubscriptionList, error)
+
+	// Namespace returns the namespace for this subscription client
+	Namespace() string
+}
+
+// subscriptionsClient struct holds the client interface and namespace
+type subscriptionsClient struct {
+	client    clientv1beta1.SubscriptionInterface
+	namespace string
+}
+
+// newKnSubscriptionsClient returns kn subscriptions client
+func newKnSubscriptionsClient(client clientv1beta1.SubscriptionInterface, namespace string) KnSubscriptionsClient {
+	return &subscriptionsClient{
+		client:    client,
+		namespace: namespace,
+	}
+}
+
+// Get the namespace for which this client is created
+func (c *subscriptionsClient) Namespace() string {
+	return c.namespace
+}
+
+// GetSubscription gets Subscription by its name
+func (c *subscriptionsClient) GetSubscription(name string) (*v1beta1.Subscription, error) {
+	subscription, err := c.client.Get(context.TODO(), name, metav1.GetOptions{})
+	if err != nil {
+		return nil, knerrors.GetError(err)
+	}
+	err = updateMessagingGVK(subscription)
+	if err != nil {
+		return nil, err
+	}
+	return subscription, nil
+}
+
+// CreateSubscription creates Subscription with given spec
+func (c *subscriptionsClient) CreateSubscription(subscription *v1beta1.Subscription) error {
+	_, err := c.client.Create(context.TODO(), subscription, metav1.CreateOptions{})
+	return knerrors.GetError(err)
+}
+
+// UpdateSubscription creates Subscription with given spec
+func (c *subscriptionsClient) UpdateSubscription(subscription *v1beta1.Subscription) error {
+	_, err := c.client.Update(context.TODO(), subscription, metav1.UpdateOptions{})
+	return knerrors.GetError(err)
+}
+
+// DeleteSubscription deletes Subscription by its name
+func (c *subscriptionsClient) DeleteSubscription(name string) error {
+	return knerrors.GetError(c.client.Delete(context.TODO(), name, metav1.DeleteOptions{}))
+}
+
+// ListSubscription lists subscriptions in configured namespace
+func (c *subscriptionsClient) ListSubscription() (*v1beta1.SubscriptionList, error) {
+	subscriptionList, err := c.client.List(context.TODO(), metav1.ListOptions{})
+	if err != nil {
+		return nil, knerrors.GetError(err)
+	}
+
+	return updateSubscriptionListGVK(subscriptionList)
+}
+
+func updateSubscriptionListGVK(subscriptionList *v1beta1.SubscriptionList) (*v1beta1.SubscriptionList, error) {
+	subscriptionListNew := subscriptionList.DeepCopy()
+	err := updateMessagingGVK(subscriptionListNew)
+	if err != nil {
+		return nil, err
+	}
+
+	subscriptionListNew.Items = make([]v1beta1.Subscription, len(subscriptionList.Items))
+	for idx, subscription := range subscriptionList.Items {
+		subscriptionClone := subscription.DeepCopy()
+		err := updateMessagingGVK(subscriptionClone)
+		if err != nil {
+			return nil, err
+		}
+		subscriptionListNew.Items[idx] = *subscriptionClone
+	}
+	return subscriptionListNew, nil
+}
+
+// SubscriptionBuilder is for building the Subscription object
+type SubscriptionBuilder struct {
+	subscription *v1beta1.Subscription
+}
+
+// NewSubscriptionBuilder for building Subscription object
+func NewSubscriptionBuilder(name string) *SubscriptionBuilder {
+	return &SubscriptionBuilder{subscription: &v1beta1.Subscription{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: name,
+		},
+	}}
+}
+
+// NewSubscriptionBuilderFromExisting for building Subscription object from existing Subscription object
+func NewSubscriptionBuilderFromExisting(subs *v1beta1.Subscription) *SubscriptionBuilder {
+	return &SubscriptionBuilder{subscription: subs.DeepCopy()}
+}
+
+// Channel sets the channel reference for this subscription
+func (s *SubscriptionBuilder) Channel(channel *corev1.ObjectReference) *SubscriptionBuilder {
+	if channel == nil {
+		return s
+	}
+
+	s.subscription.Spec.Channel = *channel
+	return s
+}
+
+func (s *SubscriptionBuilder) Subscriber(subs *duckv1.Destination) *SubscriptionBuilder {
+	if subs == nil {
+		return s
+	}
+
+	s.subscription.Spec.Subscriber = subs
+	return s
+}
+
+func (s *SubscriptionBuilder) Reply(reply *duckv1.Destination) *SubscriptionBuilder {
+	if reply == nil {
+		return s
+	}
+
+	s.subscription.Spec.Reply = reply
+	return s
+}
+
+func (s *SubscriptionBuilder) DeadLetterSink(dls *duckv1.Destination) *SubscriptionBuilder {
+	if dls == nil {
+		return s
+	}
+
+	ds := &eventingduckv1beta1.DeliverySpec{}
+	ds.DeadLetterSink = dls
+	s.subscription.Spec.Delivery = ds
+	return s
+}
+
+// Build returns the Subscription object from the builder
+func (s *SubscriptionBuilder) Build() *v1beta1.Subscription {
+	return s.subscription
+}
diff --git a/pkg/messaging/v1beta1/subscriptions_client_mock.go b/pkg/messaging/v1beta1/subscriptions_client_mock.go
new file mode 100644
index 00000000..7123d1da
--- /dev/null
+++ b/pkg/messaging/v1beta1/subscriptions_client_mock.go
@@ -0,0 +1,121 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 v1beta1
+
+import (
+	"testing"
+
+	"knative.dev/eventing/pkg/apis/messaging/v1beta1"
+
+	"knative.dev/client/pkg/util/mock"
+)
+
+type MockKnSubscriptionsClient struct {
+	t         *testing.T
+	recorder  *SubscriptionsRecorder
+	namespace string
+}
+
+// NewMockKnSubscriptionsClient returns a new mock instance which you need to record for
+func NewMockKnSubscriptionsClient(t *testing.T, ns ...string) *MockKnSubscriptionsClient {
+	namespace := "default"
+	if len(ns) > 0 {
+		namespace = ns[0]
+	}
+	return &MockKnSubscriptionsClient{
+		t:        t,
+		recorder: &SubscriptionsRecorder{mock.NewRecorder(t, namespace)},
+	}
+}
+
+// Ensure that the interface is implemented
+var _ KnSubscriptionsClient = &MockKnSubscriptionsClient{}
+
+// recorder for service
+type SubscriptionsRecorder struct {
+	r *mock.Recorder
+}
+
+// Recorder returns the recorder for registering API calls
+func (c *MockKnSubscriptionsClient) Recorder() *SubscriptionsRecorder {
+	return c.recorder
+}
+
+// Namespace of this client
+func (c *MockKnSubscriptionsClient) Namespace() string {
+	return c.recorder.r.Namespace()
+}
+
+// CreateSubscription records a call for CreateSubscription with the expected error
+func (sr *SubscriptionsRecorder) CreateSubscription(subscription interface{}, err error) {
+	sr.r.Add("CreateSubscription", []interface{}{subscription}, []interface{}{err})
+}
+
+// CreateSubscription performs a previously recorded action, failing if non has been registered
+func (c *MockKnSubscriptionsClient) CreateSubscription(subscription *v1beta1.Subscription) error {
+	call := c.recorder.r.VerifyCall("CreateSubscription", subscription)
+	return mock.ErrorOrNil(call.Result[0])
+}
+
+// GetSubscription records a call for GetSubscription with the expected object or error. Either subscriptions or err should be nil
+func (sr *SubscriptionsRecorder) GetSubscription(name interface{}, subscription *v1beta1.Subscription, err error) {
+	sr.r.Add("GetSubscription", []interface{}{name}, []interface{}{subscription, err})
+}
+
+// GetSubscription performs a previously recorded action, failing if non has been registered
+func (c *MockKnSubscriptionsClient) GetSubscription(name string) (*v1beta1.Subscription, error) {
+	call := c.recorder.r.VerifyCall("GetSubscription", name)
+	return call.Result[0].(*v1beta1.Subscription), mock.ErrorOrNil(call.Result[1])
+}
+
+// DeleteSubscription records a call for DeleteSubscription with the expected error (nil if none)
+func (sr *SubscriptionsRecorder) DeleteSubscription(name interface{}, err error) {
+	sr.r.Add("DeleteSubscription", []interface{}{name}, []interface{}{err})
+}
+
+// DeleteSubscription performs a previously recorded action, failing if non has been registered
+func (c *MockKnSubscriptionsClient) DeleteSubscription(name string) error {
+	call := c.recorder.r.VerifyCall("DeleteSubscription", name)
+	return mock.ErrorOrNil(call.Result[0])
+}
+
+// ListSubscription records a call for ListSubscription with the expected error (nil if none)
+func (sr *SubscriptionsRecorder) ListSubscription(subscriptionsList *v1beta1.SubscriptionList, err error) {
+	sr.r.Add("ListSubscription", []interface{}{}, []interface{}{subscriptionsList, err})
+}
+
+// ListSubscription performs a previously recorded action, failing if non has been registered
+func (c *MockKnSubscriptionsClient) ListSubscription() (*v1beta1.SubscriptionList, error) {
+	call := c.recorder.r.VerifyCall("ListSubscription")
+	return call.Result[0].(*v1beta1.SubscriptionList), mock.ErrorOrNil(call.Result[1])
+}
+
+// UpdateSubscription records a call for CreateSubscription with the expected error
+func (sr *SubscriptionsRecorder) UpdateSubscription(subscription interface{}, err error) {
+	sr.r.Add("UpdateSubscription", []interface{}{subscription}, []interface{}{err})
+}
+
+// UpdateSubscription performs a previously recorded action, failing if non has been registered
+func (c *MockKnSubscriptionsClient) UpdateSubscription(subscription *v1beta1.Subscription) error {
+	call := c.recorder.r.VerifyCall("UpdateSubscription", subscription)
+	return mock.ErrorOrNil(call.Result[0])
+}
+
+// Validates validates whether every recorded action has been called
+func (sr *SubscriptionsRecorder) Validate() {
+	sr.r.CheckThatAllRecordedMethodsHaveBeenCalled()
+}


Test patch:
diff --git a/lib/test/subscription.go b/lib/test/subscription.go
new file mode 100644
index 00000000..08734f6c
--- /dev/null
+++ b/lib/test/subscription.go
@@ -0,0 +1,61 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 test
+
+import (
+	"gotest.tools/assert"
+
+	"knative.dev/client/pkg/util"
+)
+
+func SubscriptionCreate(r *KnRunResultCollector, sname string, args ...string) {
+	cmd := []string{"subscription", "create", sname}
+	cmd = append(cmd, args...)
+	out := r.KnTest().Kn().Run(cmd...)
+	r.AssertNoError(out)
+	assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "subscription", sname, "created"))
+}
+
+func SubscriptionList(r *KnRunResultCollector, args ...string) string {
+	cmd := []string{"subscription", "list"}
+	cmd = append(cmd, args...)
+	out := r.KnTest().Kn().Run(cmd...)
+	r.AssertNoError(out)
+	return out.Stdout
+}
+
+func SubscriptionDescribe(r *KnRunResultCollector, sname string, args ...string) string {
+	cmd := []string{"subscription", "describe", sname}
+	cmd = append(cmd, args...)
+	out := r.KnTest().Kn().Run(cmd...)
+	r.AssertNoError(out)
+	return out.Stdout
+}
+
+func SubscriptionDelete(r *KnRunResultCollector, sname string) {
+	out := r.KnTest().Kn().Run("subscription", "delete", sname)
+	r.AssertNoError(out)
+	assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "subscription", sname, "deleted"))
+}
+
+func SubscriptionUpdate(r *KnRunResultCollector, sname string, args ...string) {
+	cmd := []string{"subscription", "update", sname}
+	cmd = append(cmd, args...)
+	out := r.KnTest().Kn().Run(cmd...)
+	r.AssertNoError(out)
+	assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "subscription", sname, "updated"))
+}
diff --git a/pkg/kn/commands/flags/sink_test.go b/pkg/kn/commands/flags/sink_test.go
index c3a3e9a9..5a047014 100644
--- a/pkg/kn/commands/flags/sink_test.go
+++ b/pkg/kn/commands/flags/sink_test.go
@@ -17,6 +17,7 @@ package flags
 import (
 	"testing"
 
+	"github.com/spf13/cobra"
 	"gotest.tools/assert"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1"
@@ -33,6 +34,40 @@ type resolveCase struct {
 	errContents string
 }
 
+type sinkFlagAddTestCases struct {
+	flagName          string
+	expectedFlagName  string
+	expectedShortName string
+}
+
+func TestSinkFlagAdd(t *testing.T) {
+	cases := []*sinkFlagAddTestCases{
+		{
+			"",
+			"sink",
+			"s",
+		},
+		{
+			"subscriber",
+			"subscriber",
+			"",
+		},
+	}
+	for _, tc := range cases {
+		c := &cobra.Command{Use: "sinktest"}
+		sinkFlags := new(SinkFlags)
+		if tc.flagName == "" {
+			sinkFlags.Add(c)
+			assert.Equal(t, tc.expectedFlagName, c.Flag("sink").Name)
+			assert.Equal(t, tc.expectedShortName, c.Flag("sink").Shorthand)
+		} else {
+			sinkFlags.AddWithFlagName(c, tc.flagName, "")
+			assert.Equal(t, tc.expectedFlagName, c.Flag(tc.flagName).Name)
+			assert.Equal(t, tc.expectedShortName, c.Flag(tc.flagName).Shorthand)
+		}
+	}
+}
+
 func TestResolve(t *testing.T) {
 	targetExampleCom, err := apis.ParseURL("http://target.example.com")
 	mysvc := &servingv1.Service{
diff --git a/pkg/kn/commands/service/create_mock_test.go b/pkg/kn/commands/service/create_mock_test.go
index 0c919ee7..d62a38a5 100644
--- a/pkg/kn/commands/service/create_mock_test.go
+++ b/pkg/kn/commands/service/create_mock_test.go
@@ -579,6 +579,106 @@ func TestServiceCreateWithAnnotations(t *testing.T) {
 	r.Validate()
 }
 
+func TestServiceCreateWithRevisionAndServiceAnnotations(t *testing.T) {
+	client := knclient.NewMockKnServiceClient(t)
+
+	r := client.Recorder()
+	r.GetService("foo", nil, errors.NewNotFound(servingv1.Resource("service"), "foo"))
+
+	service := getService("foo")
+	template := &service.Spec.Template
+
+	service.ObjectMeta.Annotations = map[string]string{
+		"foo": "bar",
+	}
+
+	template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz"
+	template.ObjectMeta.Annotations = map[string]string{
+		autoscaling.InitialScaleAnnotationKey: "1", // autoscaling in only added Revision Template
+		servinglib.UserImageAnnotationKey:     "gcr.io/foo/bar:baz",
+	}
+
+	r.CreateService(service, nil)
+
+	output, err := executeServiceCommand(client, "create", "foo", "--image", "gcr.io/foo/bar:baz",
+		"--annotation-service", "foo=bar",
+		"--annotation-revision", autoscaling.InitialScaleAnnotationKey+"=1",
+		"--no-wait", "--revision-name=")
+	assert.NilError(t, err)
+	assert.Assert(t, util.ContainsAll(output, "created", "foo", "default"))
+
+	r.Validate()
+}
+
+func TestServiceCreateWithRevisionAnnotations(t *testing.T) {
+	client := knclient.NewMockKnServiceClient(t)
+
+	r := client.Recorder()
+	r.GetService("foo", nil, errors.NewNotFound(servingv1.Resource("service"), "foo"))
+
+	service := getService("foo")
+	template := &service.Spec.Template
+
+	template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz"
+	template.ObjectMeta.Annotations = map[string]string{
+		autoscaling.InitialScaleAnnotationKey: "1", // autoscaling in only added Revision Template
+		servinglib.UserImageAnnotationKey:     "gcr.io/foo/bar:baz",
+	}
+
+	r.CreateService(service, nil)
+
+	output, err := executeServiceCommand(client, "create", "foo", "--image", "gcr.io/foo/bar:baz",
+		"--annotation-revision", autoscaling.InitialScaleAnnotationKey+"=1",
+		"--no-wait", "--revision-name=")
+	assert.NilError(t, err)
+	assert.Assert(t, util.ContainsAll(output, "created", "foo", "default"))
+
+	r.Validate()
+}
+
+func TestServiceCreateWithServiceAnnotations(t *testing.T) {
+	client := knclient.NewMockKnServiceClient(t)
+
+	r := client.Recorder()
+	r.GetService("foo", nil, errors.NewNotFound(servingv1.Resource("service"), "foo"))
+
+	service := getService("foo")
+	template := &service.Spec.Template
+
+	service.ObjectMeta.Annotations = map[string]string{
+		"foo": "bar",
+	}
+
+	template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz"
+	template.ObjectMeta.Annotations = map[string]string{
+		servinglib.UserImageAnnotationKey: "gcr.io/foo/bar:baz",
+	}
+
+	r.CreateService(service, nil)
+
+	output, err := executeServiceCommand(client, "create", "foo", "--image", "gcr.io/foo/bar:baz",
+		"--annotation-service", "foo=bar",
+		"--no-wait", "--revision-name=")
+	assert.NilError(t, err)
+	assert.Assert(t, util.ContainsAll(output, "created", "foo", "default"))
+
+	r.Validate()
+}
+
+func TestServiceCreateWithAutoScaleServiceAnnotationsError(t *testing.T) {
+	client := knclient.NewMockKnServiceClient(t)
+
+	r := client.Recorder()
+
+	output, err := executeServiceCommand(client, "create", "foo", "--image", "gcr.io/foo/bar:baz",
+		"--annotation-service", autoscaling.InitialScaleAnnotationKey+"=1",
+		"--no-wait", "--revision-name=")
+	assert.Assert(t, err != nil)
+	assert.Assert(t, util.ContainsAll(output, "service can not have auto-scaling related annotation", "autoscaling.knative.dev/initialScale"))
+
+	r.Validate()
+}
+
 func getServiceWithUrl(name string, urlName string) *servingv1.Service {
 	service := servingv1.Service{}
 	url, _ := apis.ParseURL(urlName)
diff --git a/pkg/kn/commands/subscription/create_test.go b/pkg/kn/commands/subscription/create_test.go
new file mode 100644
index 00000000..3073309d
--- /dev/null
+++ b/pkg/kn/commands/subscription/create_test.go
@@ -0,0 +1,82 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"testing"
+
+	"gotest.tools/assert"
+	"knative.dev/client/pkg/messaging/v1beta1"
+
+	dynamicfake "knative.dev/client/pkg/dynamic/fake"
+	"knative.dev/client/pkg/util"
+)
+
+func TestCreateSubscriptionErrorCase(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	dynamicClient := dynamicfake.CreateFakeKnDynamicClient("default")
+
+	cRecorder := cClient.Recorder()
+	_, err := executeSubscriptionCommand(cClient, dynamicClient, "create")
+	assert.Error(t, err, "'kn subscription create' requires the subscription name given as single argument")
+	cRecorder.Validate()
+}
+
+func TestCreateSubscriptionErrorCaseRequiredChannelFlag(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	dynamicClient := dynamicfake.CreateFakeKnDynamicClient("default")
+
+	cRecorder := cClient.Recorder()
+	_, err := executeSubscriptionCommand(cClient, dynamicClient, "create", "sub0")
+	assert.Error(t, err, "'kn subscription create' requires the channel reference provided with --channel flag")
+	cRecorder.Validate()
+}
+
+func TestCreateSubscriptionErrorCaseChannelFormat(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	dynamicClient := dynamicfake.CreateFakeKnDynamicClient("default")
+
+	cRecorder := cClient.Recorder()
+	_, err := executeSubscriptionCommand(cClient, dynamicClient, "create", "sub0", "--channel", "foo::bar")
+	assert.Error(t, err, "Error: incorrect value 'foo::bar' for '--channel', must be in the format 'Group:Version:Kind:Name' or configure an alias in kn config and refer as: '--channel ALIAS:NAME'")
+	cRecorder.Validate()
+}
+
+func TestCreateSubscription(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	dynamicClient := dynamicfake.CreateFakeKnDynamicClient("default",
+		createService("ksvc0"),
+		createBroker("b0"),
+		createBroker("b1"))
+
+	cRecorder := cClient.Recorder()
+	cRecorder.CreateSubscription(createSubscription("sub0",
+		"imc0",
+		"ksvc0",
+		"b0",
+		"b1"),
+		nil)
+
+	out, err := executeSubscriptionCommand(cClient, dynamicClient, "create", "sub0",
+		"--channel", "imcv1beta1:imc0",
+		"--sink", "ksvc0",
+		"--sink-reply", "broker:b0",
+		"--sink-dead-letter", "broker:b1")
+	assert.NilError(t, err, "subscription should be created")
+	assert.Assert(t, util.ContainsAll(out, "created", "sub0", "default"))
+	cRecorder.Validate()
+}
diff --git a/pkg/kn/commands/subscription/delete_test.go b/pkg/kn/commands/subscription/delete_test.go
new file mode 100644
index 00000000..38d1014c
--- /dev/null
+++ b/pkg/kn/commands/subscription/delete_test.go
@@ -0,0 +1,54 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"errors"
+	"testing"
+
+	"gotest.tools/assert"
+
+	"knative.dev/client/pkg/messaging/v1beta1"
+	"knative.dev/client/pkg/util"
+)
+
+func TestDeleteSubscriptionErrorCase(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t, "test")
+	cRecorder := cClient.Recorder()
+	_, err := executeSubscriptionCommand(cClient, nil, "delete")
+	assert.Error(t, err, "'kn subscription delete' requires the subscription name as single argument")
+	cRecorder.Validate()
+}
+
+func TestDeleteWithError(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t, "test")
+	cRecorder := cClient.Recorder()
+	cRecorder.DeleteSubscription("sub0", errors.New("not found"))
+	_, err := executeSubscriptionCommand(cClient, nil, "delete", "sub0")
+	assert.ErrorContains(t, err, "not found")
+	cRecorder.Validate()
+}
+
+func TestSubscriptionDelete(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t, "test")
+	cRecorder := cClient.Recorder()
+	cRecorder.DeleteSubscription("sub0", nil)
+	out, err := executeSubscriptionCommand(cClient, nil, "delete", "sub0")
+	assert.NilError(t, err)
+	assert.Assert(t, util.ContainsAll(out, "deleted", "sub0", "test"))
+	cRecorder.Validate()
+}
diff --git a/pkg/kn/commands/subscription/describe_test.go b/pkg/kn/commands/subscription/describe_test.go
new file mode 100644
index 00000000..5f581d6b
--- /dev/null
+++ b/pkg/kn/commands/subscription/describe_test.go
@@ -0,0 +1,59 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"errors"
+	"testing"
+
+	"gotest.tools/assert"
+	"knative.dev/client/pkg/messaging/v1beta1"
+
+	"knative.dev/client/pkg/util"
+)
+
+func TestDescribeSubscriptionErrorCase(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	cRecorder := cClient.Recorder()
+	_, err := executeSubscriptionCommand(cClient, nil, "describe")
+	assert.Error(t, err, "'kn subscription describe' requires the subscription name given as single argument")
+	cRecorder.Validate()
+}
+
+func TestDescribeSubscriptionErrorCaseNotFound(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	cRecorder := cClient.Recorder()
+	cRecorder.GetSubscription("sub0", nil, errors.New("not found"))
+	_, err := executeSubscriptionCommand(cClient, nil, "describe", "sub0")
+	assert.Error(t, err, "not found")
+	cRecorder.Validate()
+}
+
+func TestDescribeSubscription(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	cRecorder := cClient.Recorder()
+	cRecorder.GetSubscription("sub0", createSubscription("sub0", "imc0", "ksvc0", "b0", "b1"), nil)
+	out, err := executeSubscriptionCommand(cClient, nil, "describe", "sub0")
+	assert.NilError(t, err, "subscription should be described")
+	assert.Assert(t, util.ContainsAll(out,
+		"sub0",
+		"Channel", "imc0", "messaging.knative.dev", "v1beta1", "InMemoryChannel",
+		"Subscriber", "ksvc0", "serving.knative.dev", "v1", "Service",
+		"Reply", "b0", "eventing.knative.dev", "v1beta1", "Broker",
+		"DeadLetterSink", "b1"))
+	cRecorder.Validate()
+}
diff --git a/pkg/kn/commands/subscription/list_test.go b/pkg/kn/commands/subscription/list_test.go
new file mode 100644
index 00000000..2be6581b
--- /dev/null
+++ b/pkg/kn/commands/subscription/list_test.go
@@ -0,0 +1,71 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"strings"
+	"testing"
+
+	"gotest.tools/assert"
+	messagingv1beta1 "knative.dev/eventing/pkg/apis/messaging/v1beta1"
+
+	v1beta1 "knative.dev/client/pkg/messaging/v1beta1"
+	"knative.dev/client/pkg/util"
+)
+
+func TestSubscriptionListNoSubscriptionsFound(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	cRecorder := cClient.Recorder()
+	cRecorder.ListSubscription(nil, nil)
+	out, err := executeSubscriptionCommand(cClient, nil, "list")
+	assert.NilError(t, err)
+	assert.Check(t, util.ContainsAll(out, "No subscriptions found"))
+	cRecorder.Validate()
+}
+
+func TestSubscriptionList(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	cRecorder := cClient.Recorder()
+	clist := &messagingv1beta1.SubscriptionList{}
+	clist.Items = []messagingv1beta1.Subscription{
+		*createSubscription("s0", "imc0", "ksvc0", "b00", "b01"),
+		*createSubscription("s1", "imc1", "ksvc1", "b10", "b11"),
+		*createSubscription("s2", "imc2", "ksvc2", "b20", "b21"),
+	}
+
+	t.Run("default list output", func(t *testing.T) {
+		cRecorder.ListSubscription(clist, nil)
+		out, err := executeSubscriptionCommand(cClient, nil, "list")
+		assert.NilError(t, err)
+		ol := strings.Split(out, "\n")
+		assert.Check(t, util.ContainsAll(ol[0], "NAME", "CHANNEL", "SUBSCRIBER", "REPLY", "DEAD LETTER SINK", "READY", "REASON"))
+		assert.Check(t, util.ContainsAll(ol[1], "s0", "InMemoryChannel:imc0", "ksvc:ksvc0", "broker:b00", "broker:b01"))
+		assert.Check(t, util.ContainsAll(ol[2], "s1", "imc1", "ksvc1", "b10", "b11"))
+		assert.Check(t, util.ContainsAll(ol[3], "s2", "imc2", "ksvc2", "b20", "b21"))
+	})
+
+	t.Run("no headers list output", func(t *testing.T) {
+		cRecorder.ListSubscription(clist, nil)
+		out, err := executeSubscriptionCommand(cClient, nil, "list", "--no-headers")
+		assert.NilError(t, err)
+		ol := strings.Split(out, "\n")
+		assert.Check(t, util.ContainsNone(ol[0], "NAME", "CHANNEL", "SUBSCRIBER", "REPLY", "DEAD LETTER SINK", "READY", "REASON"))
+		assert.Check(t, util.ContainsAll(ol[0], "s0", "imc0", "ksvc0", "b00", "b01"))
+	})
+
+	cRecorder.Validate()
+}
diff --git a/pkg/kn/commands/subscription/subscription_test.go b/pkg/kn/commands/subscription/subscription_test.go
new file mode 100644
index 00000000..889fa31b
--- /dev/null
+++ b/pkg/kn/commands/subscription/subscription_test.go
@@ -0,0 +1,147 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"bytes"
+
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/client-go/tools/clientcmd"
+	eventingv1beta1 "knative.dev/eventing/pkg/apis/eventing/v1beta1"
+	"knative.dev/eventing/pkg/apis/messaging/v1beta1"
+	duckv1 "knative.dev/pkg/apis/duck/v1"
+	servingv1 "knative.dev/serving/pkg/apis/serving/v1"
+
+	kndynamic "knative.dev/client/pkg/dynamic"
+	"knative.dev/client/pkg/kn/commands"
+	clientv1beta1 "knative.dev/client/pkg/messaging/v1beta1"
+)
+
+// Helper methods
+var blankConfig clientcmd.ClientConfig
+
+// TODO: Remove that blankConfig hack for tests in favor of overwriting GetConfig()
+func init() {
+	var err error
+	blankConfig, err = clientcmd.NewClientConfigFromBytes([]byte(`kind: Config
+version: v1
+users:
+- name: u
+clusters:
+- name: c
+  cluster:
+    server: example.com
+contexts:
+- name: x
+  context:
+    user: u
+    cluster: c
+current-context: x
+`))
+	if err != nil {
+		panic(err)
+	}
+}
+
+func executeSubscriptionCommand(subscriptionClient clientv1beta1.KnSubscriptionsClient, dynamicClient kndynamic.KnDynamicClient, args ...string) (string, error) {
+	knParams := &commands.KnParams{}
+	knParams.ClientConfig = blankConfig
+
+	output := new(bytes.Buffer)
+	knParams.Output = output
+	knParams.NewDynamicClient = func(namespace string) (kndynamic.KnDynamicClient, error) {
+		return dynamicClient, nil
+	}
+
+	cmd := NewSubscriptionCommand(knParams)
+	cmd.SetArgs(args)
+	cmd.SetOutput(output)
+
+	subscriptionClientFactory = func(config clientcmd.ClientConfig, namespace string) (clientv1beta1.KnSubscriptionsClient, error) {
+		return subscriptionClient, nil
+	}
+	defer cleanupSubscriptionMockClient()
+
+	err := cmd.Execute()
+
+	return output.String(), err
+}
+
+func cleanupSubscriptionMockClient() {
+	subscriptionClientFactory = nil
+}
+
+func createSubscription(name, channel, subscriber, reply, dls string) *v1beta1.Subscription {
+	return clientv1beta1.
+		NewSubscriptionBuilder(name).
+		Channel(createIMCObjectReference(channel)).
+		Subscriber(createServiceSink(subscriber)).
+		Reply(createBrokerSink(reply)).
+		DeadLetterSink(createBrokerSink(dls)).
+		Build()
+}
+
+func createIMCObjectReference(channel string) *corev1.ObjectReference {
+	return &corev1.ObjectReference{
+		APIVersion: "messaging.knative.dev/v1beta1",
+		Kind:       "InMemoryChannel",
+		Name:       channel,
+	}
+}
+
+func createServiceSink(service string) *duckv1.Destination {
+	if service == "" {
+		return nil
+	}
+	return &duckv1.Destination{
+		Ref: &duckv1.KReference{
+			Kind:       "Service",
+			APIVersion: "serving.knative.dev/v1",
+			Name:       service,
+			Namespace:  "default",
+		},
+	}
+}
+
+func createBrokerSink(broker string) *duckv1.Destination {
+	if broker == "" {
+		return nil
+	}
+	return &duckv1.Destination{
+		Ref: &duckv1.KReference{
+			Kind:       "Broker",
+			APIVersion: "eventing.knative.dev/v1beta1",
+			Name:       broker,
+			Namespace:  "default",
+		},
+	}
+}
+
+func createService(name string) *servingv1.Service {
+	return &servingv1.Service{
+		TypeMeta:   metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1"},
+		ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: "default"},
+	}
+}
+
+func createBroker(name string) *eventingv1beta1.Broker {
+	return &eventingv1beta1.Broker{
+		TypeMeta:   metav1.TypeMeta{Kind: "Broker", APIVersion: "eventing.knative.dev/v1beta1"},
+		ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: "default"},
+	}
+}
diff --git a/pkg/kn/commands/subscription/update_test.go b/pkg/kn/commands/subscription/update_test.go
new file mode 100644
index 00000000..856de466
--- /dev/null
+++ b/pkg/kn/commands/subscription/update_test.go
@@ -0,0 +1,74 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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 subscription
+
+import (
+	"testing"
+
+	"gotest.tools/assert"
+	"knative.dev/client/pkg/messaging/v1beta1"
+
+	dynamicfake "knative.dev/client/pkg/dynamic/fake"
+	"knative.dev/client/pkg/util"
+)
+
+func TestUpdateSubscriptionErrorCase(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	dynamicClient := dynamicfake.CreateFakeKnDynamicClient("default")
+
+	cRecorder := cClient.Recorder()
+	_, err := executeSubscriptionCommand(cClient, dynamicClient, "update")
+	assert.Error(t, err, "'kn subscription update' requires the subscription name given as single argument")
+	cRecorder.Validate()
+}
+
+func TestUpdateSubscriptionErrorCaseUnknownChannelFlag(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	dynamicClient := dynamicfake.CreateFakeKnDynamicClient("default")
+
+	cRecorder := cClient.Recorder()
+	_, err := executeSubscriptionCommand(cClient, dynamicClient, "update", "sub0", "--channel", "imc:i1")
+	assert.Error(t, err, "unknown flag: --channel")
+	cRecorder.Validate()
+}
+
+func TestUpdateSubscription(t *testing.T) {
+	cClient := v1beta1.NewMockKnSubscriptionsClient(t)
+	sub0 := createSubscription("sub0", "imc0", "ksvc0", "", "")
+	dynamicClient := dynamicfake.CreateFakeKnDynamicClient("default",
+		sub0,
+		createService("ksvc1"),
+		createBroker("b0"),
+		createBroker("b1"))
+
+	cRecorder := cClient.Recorder()
+	cRecorder.GetSubscription("sub0", sub0, nil)
+	cRecorder.UpdateSubscription(createSubscription("sub0",
+		"imc0",
+		"ksvc1",
+		"b0",
+		"b1"),
+		nil)
+
+	out, err := executeSubscriptionCommand(cClient, dynamicClient, "update", "sub0",
+		"--sink", "ksvc1",
+		"--sink-reply", "broker:b0",
+		"--sink-dead-letter", "broker:b1")
+	assert.NilError(t, err, "subscription should be updated")
+	assert.Assert(t, util.ContainsAll(out, "updated", "sub0", "default"))
+	cRecorder.Validate()
+}
diff --git a/pkg/kn/flags/channel_types_test.go b/pkg/kn/flags/channel_types_test.go
index 52c7c4c0..dbec563d 100644
--- a/pkg/kn/flags/channel_types_test.go
+++ b/pkg/kn/flags/channel_types_test.go
@@ -19,6 +19,7 @@ import (
 
 	"github.com/spf13/pflag"
 	"gotest.tools/assert"
+	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 )
 
@@ -29,6 +30,13 @@ type channelTypeFlagsTestCase struct {
 	expectedErrText string
 }
 
+type channelRefFlagsTestCase struct {
+	name              string
+	arg               string
+	expectedObjectRef *corev1.ObjectReference
+	expectedErrText   string
+}
+
 func TestChannelTypesFlags(t *testing.T) {
 	cases := []*channelTypeFlagsTestCase{
 		{
@@ -84,3 +92,65 @@ func TestChannelTypesFlags(t *testing.T) {
 		})
 	}
 }
+
+func TestChannelRefFlags(t *testing.T) {
+	cases := []*channelRefFlagsTestCase{
+		{
+			"inbuilt alias imcv1beta1 case",
+			"imcv1beta1:i1",
+			&corev1.ObjectReference{APIVersion: "messaging.knative.dev/v1beta1", Kind: "InMemoryChannel", Name: "i1"},
+			"",
+		},
+		{
+			"inbuilt alias 'imc' case",
+			"imc:i2",
+			&corev1.ObjectReference{APIVersion: "messaging.knative.dev/v1", Kind: "InMemoryChannel", Name: "i2"},
+			"",
+		},
+		{
+			"explicit GVK case",
+			"messaging.knative.dev:v1alpha1:KafkaChannel:k1",
+			&corev1.ObjectReference{APIVersion: "messaging.knative.dev/v1alpha1", Kind: "KafkaChannel", Name: "k1"},
+			"",
+		},
+		{
+			"default channel type prefix case",
+			"c1",
+			&corev1.ObjectReference{APIVersion: "messaging.knative.dev/v1beta1", Kind: "Channel", Name: "c1"},
+			"",
+		},
+		{
+			"error case unknown alias",
+			"natss:n1",
+			nil,
+			"Error: unknown alias 'natss' for '--channel', please configure the alias in kn config or specify in the format '--channel Group:Version:Kind:Name'",
+		},
+		{
+			"error case incorrect gvk format, missing version",
+			"foo::bar",
+			nil,
+			"Error: incorrect value 'foo::bar' for '--channel', must be in the format 'Group:Version:Kind:Name' or configure an alias in kn config and refer as: '--channel ALIAS:NAME'",
+		},
+		{
+			"error case incorrect gvk format, additional field",
+			"foo:bar::bat",
+			nil,
+			"Error: incorrect value 'foo:bar::bat' for '--channel', must be in the format 'Group:Version:Kind:Name' or configure an alias in kn config and refer as: '--channel ALIAS:NAME'",
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			f := &ChannelRef{}
+			flagset := &pflag.FlagSet{}
+			f.Add(flagset)
+			flagset.Set("channel", c.arg)
+			obj, err := f.Parse()
+			if c.expectedErrText != "" {
+				assert.Equal(t, err.Error(), c.expectedErrText)
+			} else {
+				assert.Equal(t, *obj, *c.expectedObjectRef)
+			}
+		})
+	}
+}
diff --git a/test/e2e/service_options_test.go b/test/e2e/service_options_test.go
index c0f5ffdb..617314e6 100644
--- a/test/e2e/service_options_test.go
+++ b/test/e2e/service_options_test.go
@@ -163,6 +163,21 @@ func TestServiceOptions(t *testing.T) {
 	validateServiceInitScale(r, "svc11", "2")
 	t.Log("delete service")
 	test.ServiceDelete(r, "svc11")
+
+	t.Log("create and validate service and revision annotations")
+	serviceCreateWithOptions(r, "svc12", "--annotation-service", "svc=helloworld-svc", "--annotation-revision", "rev=helloworld-rev")
+	validateServiceAndRevisionAnnotations(r, "svc12", map[string]string{"svc": "helloworld-svc"}, map[string]string{"rev": "helloworld-rev"})
+	test.ServiceDelete(r, "svc12")
+
+	t.Log("create and validate service annotations")
+	serviceCreateWithOptions(r, "svc13", "--annotation-service", "svc=helloworld-svc")
+	validateServiceAndRevisionAnnotations(r, "svc13", map[string]string{"svc": "helloworld-svc"}, nil)
+	test.ServiceDelete(r, "svc13")
+
+	t.Log("create and validate revision annotations")
+	serviceCreateWithOptions(r, "svc14", "--annotation-revision", "rev=helloworld-rev")
+	validateServiceAndRevisionAnnotations(r, "svc14", nil, map[string]string{"rev": "helloworld-rev"})
+	test.ServiceDelete(r, "svc14")
 }
 
 func serviceCreateWithOptions(r *test.KnRunResultCollector, serviceName string, options ...string) {
@@ -249,6 +264,26 @@ func validateServiceAnnotations(r *test.KnRunResultCollector, serviceName string
 	}
 }
 
+func validateServiceAndRevisionAnnotations(r *test.KnRunResultCollector, serviceName string, expectedServiceAnnotations, expectedRevisionAnnotations map[string]string) {
+
+	metadataAnnotationsJsonpathFormat := "jsonpath={.metadata.annotations.%s}"
+	templateAnnotationsJsonpathFormat := "jsonpath={.spec.template.metadata.annotations.%s}"
+
+	for k, v := range expectedServiceAnnotations {
+
+		out := r.KnTest().Kn().Run("service", "describe", serviceName, "-o", fmt.Sprintf(metadataAnnotationsJsonpathFormat, k))
+		assert.Equal(r.T(), v, out.Stdout)
+		r.AssertNoError(out)
+	}
+
+	for k, v := range expectedRevisionAnnotations {
+
+		out := r.KnTest().Kn().Run("service", "describe", serviceName, "-o", fmt.Sprintf(templateAnnotationsJsonpathFormat, k))
+		assert.Equal(r.T(), v, out.Stdout)
+		r.AssertNoError(out)
+	}
+}
+
 func validateLabels(r *test.KnRunResultCollector, serviceName string, expectedServiceLabels, expectedRevisionLabels map[string]string) {
 	out := r.KnTest().Kn().Run("service", "describe", serviceName, "-ojson")
 	data := json.NewDecoder(strings.NewReader(out.Stdout))
diff --git a/test/e2e/subscription_test.go b/test/e2e/subscription_test.go
new file mode 100644
index 00000000..bc50865d
--- /dev/null
+++ b/test/e2e/subscription_test.go
@@ -0,0 +1,67 @@
+// Copyright 2020 The Knative Authors
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or im
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// +build e2e
+// +build !serving
+
+package e2e
+
+import (
+	"testing"
+
+	"gotest.tools/assert"
+
+	"knative.dev/client/lib/test"
+	"knative.dev/client/pkg/util"
+)
+
+func TestSubscriptions(t *testing.T) {
+	t.Parallel()
+	it, err := test.NewKnTest()
+	assert.NilError(t, err)
+	defer func() {
+		assert.NilError(t, it.Teardown())
+	}()
+
+	r := test.NewKnRunResultCollector(t, it)
+	defer r.DumpIfFailed()
+
+	t.Log("Create a subscription with all the flags")
+	test.ChannelCreate(r, "c0")
+	test.ServiceCreate(r, "svc0")
+	test.ServiceCreate(r, "svc1")
+	test.ServiceCreate(r, "svc2")
+	test.SubscriptionCreate(r, "sub0", "--channel", "c0", "--sink", "ksvc:svc0", "--sink-reply", "ksvc:svc1", "--sink-dead-letter", "ksvc:svc2")
+
+	t.Log("Update a subscription")
+	test.ServiceCreate(r, "svc3")
+	test.SubscriptionUpdate(r, "sub0", "--sink", "ksvc:svc3")
+
+	t.Log("List subscriptions")
+	slist := test.SubscriptionList(r)
+	assert.Check(t, util.ContainsAll(slist, "NAME", "CHANNEL", "SUBSCRIBER", "REPLY", "DEAD LETTER SINK", "READY", "REASON"))
+	assert.Check(t, util.ContainsAll(slist, "sub0", "c0", "ksvc:svc3", "ksvc:svc1", "ksvc:svc2", "True"))
+
+	t.Log("Describe subscription")
+	sdesc := test.SubscriptionDescribe(r, "sub0")
+	assert.Check(t, util.ContainsAll(sdesc, "sub0", "Age", "Channel", "Channel", "c0", "Subscriber", "svc3", "Resource", "Service", "serving.knative.dev/v1", "Reply", "svc1", "DeadLetterSink", "svc2", "Conditions"))
+
+	t.Log("Delete subscription")
+	test.SubscriptionDelete(r, "sub0")
+	test.ServiceDelete(r, "svc0")
+	test.ServiceDelete(r, "svc1")
+	test.ServiceDelete(r, "svc2")
+	test.ServiceDelete(r, "svc3")
+	test.ChannelDelete(r, "c0")
+}
diff --git a/test/presubmit-integration-tests-latest-release.sh b/test/presubmit-integration-tests-latest-release.sh
index a756c4d6..b4d96348 100755
--- a/test/presubmit-integration-tests-latest-release.sh
+++ b/test/presubmit-integration-tests-latest-release.sh
@@ -17,7 +17,7 @@
 # This script is used in Knative/test-infra as a custom prow job to run the
 # integration tests against Knative Serving / Eventing of a specific version.
 
-export KNATIVE_SERVING_VERSION="0.17.0"
-export KNATIVE_EVENTING_VERSION="0.17.0"
+export KNATIVE_SERVING_VERSION="0.18.0"
+export KNATIVE_EVENTING_VERSION="0.18.0"
 
 $(dirname $0)/presubmit-tests.sh --integration-tests