Repository: kubeflow/pipelines

Issue:
Upload Pipeline Version If already exists
It's not a bug or issue.
**In case it doesn't exists, then it's a suggestion**

Is there any way I can upload pipeline to kubeflow via sdk, and it just uploads a version if the main pipeline already exists. 

Versions:
```
kfp                      0.4.0
kfp-server-api           0.3.0
```


Discussion:

Resolving patch:
diff --git a/sdk/python/kfp/_client.py b/sdk/python/kfp/_client.py
--- a/sdk/python/kfp/_client.py
+++ b/sdk/python/kfp/_client.py
@@ -39,7 +39,15 @@
 # initialized with host=<inverse proxy endpoint>.
 # Set to 55 mins to provide some safe margin.
 _GCP_ACCESS_TOKEN_TIMEOUT = datetime.timedelta(minutes=55)
-
+# Operators on scalar values. Only applies to one of |int_value|,
+# |long_value|, |string_value| or |timestamp_value|.
+_FILTER_OPERATIONS = {"UNKNOWN": 0,
+    "EQUALS" : 1,
+    "NOT_EQUALS" : 2,
+    "GREATER_THAN": 3,
+    "GREATER_THAN_EQUALS": 5,
+    "LESS_THAN": 6,
+    "LESS_THAN_EQUALS": 7}
 
 def _add_generated_apis(target_struct, api_module, api_client):
   '''Initializes a hierarchical API object based on the generated API module.
@@ -304,6 +312,29 @@ def create_experiment(self, name, description=None, namespace=None):
       IPython.display.display(IPython.display.HTML(html))
     return experiment
 
+  def get_pipeline_id(self, name):
+    """Returns the pipeline id if a pipeline with the name exsists.
+    Args:
+      name: pipeline name
+    Returns:
+      A response object including a list of experiments and next page token.
+    """
+    pipeline_filter = json.dumps({
+      "predicates": [
+        {
+          "op":  _FILTER_OPERATIONS["EQUALS"],
+          "key": "name",
+          "stringValue": name,
+        }
+      ]
+    })
+    result = self._pipelines_api.list_pipelines(filter=pipeline_filter)
+    if len(result.pipelines)==1:
+      return result.pipelines[0].id
+    elif len(result.pipelines)>1:
+      raise ValueError("Multiple pipelines with the name: {} found, the name needs to be unique".format(name))
+    return None
+
   def list_experiments(self, page_token='', page_size=10, sort_by='', namespace=None):
     """List experiments.
     Args:
diff --git a/sdk/python/kfp/cli/pipeline.py b/sdk/python/kfp/cli/pipeline.py
--- a/sdk/python/kfp/cli/pipeline.py
+++ b/sdk/python/kfp/cli/pipeline.py
@@ -47,7 +47,13 @@ def upload(ctx, pipeline_name, package_file):
     "-p",
     "--pipeline-id",
     help="ID of the pipeline",
-    required=True
+    required=False
+)
+@click.option(
+    "-n",
+    "--pipeline-name",
+    help="Name of pipeline",
+    required=False
 )
 @click.option(
     "-v",
@@ -57,15 +63,21 @@ def upload(ctx, pipeline_name, package_file):
 )
 @click.argument("package-file")
 @click.pass_context
-def upload_version(ctx, package_file, pipeline_version, pipeline_id):
+def upload_version(ctx, package_file, pipeline_version, pipeline_id=None, pipeline_name=None):
     """Upload a version of the KFP pipeline"""
     client = ctx.obj["client"]
-
+    if bool(pipeline_id) == bool(pipeline_name):
+        raise ValueError("Need to suppy 'pipeline-name' or 'pipeline-id'")
+    if pipeline_name!=None: 
+        pipeline_id = client.get_pipeline_id(name=pipeline_name)
+        if pipeline_id==None: 
+            raise ValueError("Can't find a pipeline with name: %s" % pipeline_name)
+    logging.info("The pipeline id is: %s" % pipeline_id)
     version = client.pipeline_uploads.upload_pipeline_version(
         package_file, name=pipeline_version, pipelineid=pipeline_id)
     logging.info(
-        "The {} version of the pipeline {} has been submitted\n".format(
-            pipeline_version, pipeline_id))
+        "The %s version of the pipeline %s has been submitted\n" %
+            (pipeline_version, pipeline_id))
     _display_pipeline_version(version)
 
 


Test patch: