Repository: PrefectHQ/prefect

Issue:
Expose versionGroupId in flow deployment
Currently, when deploying Flows from Core using the standard documented method you are forced to use the versioning mechanism of Cloud (which is by name / project).  Cloud actually has a built-in versioning mechanism which is much more flexible, allowing users to provide a `versionGroupId` with each flow deploy.  

We should expose this input in `flow.deploy` and `client.deploy` and document it accordingly.


Discussion:

Resolving patch:
diff --git a/src/prefect/client/client.py b/src/prefect/client/client.py
--- a/src/prefect/client/client.py
+++ b/src/prefect/client/client.py
@@ -491,6 +491,7 @@ def deploy(
         project_name: str,
         build: bool = True,
         set_schedule_active: bool = True,
+        version_group_id: str = None,
         compressed: bool = True,
     ) -> str:
         """
@@ -504,6 +505,9 @@ def deploy(
             - set_schedule_active (bool, optional): if `False`, will set the
                 schedule to inactive in the database to prevent auto-scheduling runs (if the Flow has a schedule).
                 Defaults to `True`. This can be changed later.
+            - version_group_id (str, optional): the UUID version group ID to use for versioning this Flow
+                in Cloud; if not provided, the version group ID associated with this Flow's project and name
+                will be used.
             - compressed (bool, optional): if `True`, the serialized flow will be; defaults to `True`
                 compressed
 
@@ -569,6 +573,7 @@ def deploy(
                     projectId=project[0].id,
                     serializedFlow=serialized_flow,
                     setScheduleActive=set_schedule_active,
+                    versionGroupId=version_group_id,
                 )
             ),
         )  # type: Any
diff --git a/src/prefect/core/flow.py b/src/prefect/core/flow.py
--- a/src/prefect/core/flow.py
+++ b/src/prefect/core/flow.py
@@ -1227,6 +1227,7 @@ def deploy(
         project_name: str,
         build: bool = True,
         set_schedule_active: bool = True,
+        version_group_id: str = None,
         **kwargs: Any
     ) -> str:
         """
@@ -1240,6 +1241,9 @@ def deploy(
             - set_schedule_active (bool, optional): if `False`, will set the
                 schedule to inactive in the database to prevent auto-scheduling runs (if the Flow has a schedule).
                 Defaults to `True`. This can be changed later.
+            - version_group_id (str, optional): the UUID version group ID to use for versioning this Flow
+                in Cloud; if not provided, the version group ID associated with this Flow's project and name
+                will be used.
             - **kwargs (Any): if instantiating a Storage object from default settings, these keyword arguments
                 will be passed to the initialization method of the default Storage class
 
@@ -1259,6 +1263,7 @@ def deploy(
             build=build,
             project_name=project_name,
             set_schedule_active=set_schedule_active,
+            version_group_id=version_group_id,
         )
         return deployed_flow
 


Test patch:
diff --git a/tests/client/test_client.py b/tests/client/test_client.py
--- a/tests/client/test_client.py
+++ b/tests/client/test_client.py
@@ -2,6 +2,7 @@
 import json
 import os
 import tempfile
+import uuid
 from unittest.mock import MagicMock, mock_open
 
 import marshmallow
@@ -107,7 +108,10 @@ def test_client_deploy(patch_post, compressed):
         client = Client()
     flow = prefect.Flow(name="test", storage=prefect.environments.storage.Memory())
     flow_id = client.deploy(
-        flow, project_name="my-default-project", compressed=compressed
+        flow,
+        project_name="my-default-project",
+        compressed=compressed,
+        version_group_id=str(uuid.uuid4()),
     )
     assert flow_id == "long-id"