Skip to content

Commit

Permalink
Merge pull request #3296 from SFDO-Tooling/omnistudio-retrieve-deploy
Browse files Browse the repository at this point in the history
Omnistudio Retrieve/Deploy Tasks
  • Loading branch information
TheBitShepherd committed Jul 20, 2022
2 parents 0dc786f + f155c91 commit 5813e6f
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 0 deletions.
8 changes: 8 additions & 0 deletions cumulusci/cumulusci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,14 @@ tasks:
group: NPSP/EDA
options:
restore: True
vlocity_pack_export:
class_path: cumulusci.tasks.vlocity.vlocity.VlocityRetrieveTask
description: "Executes the `vlocity packExport` command against an org"
group: Vlocity
vlocity_pack_deploy:
class_path: cumulusci.tasks.vlocity.vlocity.VlocityDeployTask
description: "Executes the `vlocity packDeploy` command against an org"
group: Vlocity
flows:
ci_beta:
group: Continuous Integration
Expand Down
2 changes: 2 additions & 0 deletions cumulusci/tasks/vlocity/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class BuildToolMissingError(Exception):
pass
103 changes: 103 additions & 0 deletions cumulusci/tasks/vlocity/tests/test_vlocity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from unittest import mock

import pytest

from cumulusci.core.config import TaskConfig
from cumulusci.core.config.org_config import OrgConfig
from cumulusci.core.config.scratch_org_config import ScratchOrgConfig
from cumulusci.tasks.vlocity.exceptions import BuildToolMissingError
from cumulusci.tasks.vlocity.vlocity import (
BUILD_TOOL_MISSING_ERROR,
VlocityDeployTask,
VlocityRetrieveTask,
)

username = "foo"
org_name = "dev"
access_token = "foo.bar.baz"
instance_url = "https://something.custom.salesforce.com"
scratch_org_config = ScratchOrgConfig(
{
"instance_url": "https://test.salesforce.com",
"username": username,
"org_id": "00Dxxxxxxxxxxxx",
"password": "test",
},
org_name,
keychain=mock.Mock(),
)
persistent_org_config = OrgConfig(
{
"instance_url": instance_url,
"username": username,
"org_id": "00Dxxxxxxxxxxxx",
"access_token": access_token,
},
org_name,
keychain=mock.Mock(),
)


vlocity_test_cases = [
(
scratch_org_config,
VlocityRetrieveTask,
None,
f"vlocity packExport -job vlocity.yaml --json -sfdx.username '{username}'",
),
(
persistent_org_config,
VlocityRetrieveTask,
None,
f"vlocity packExport -job vlocity.yaml --json -sf.accessToken '{access_token}' -sf.instanceUrl '{instance_url}'",
),
(
scratch_org_config,
VlocityDeployTask,
None,
f"vlocity packDeploy -job vlocity.yaml --json -sfdx.username '{username}'",
),
(
persistent_org_config,
VlocityDeployTask,
None,
f"vlocity packDeploy -job vlocity.yaml --json -sf.accessToken '{access_token}' -sf.instanceUrl '{instance_url}'",
),
(
persistent_org_config,
VlocityDeployTask,
"foo=bar",
f"vlocity packDeploy -job vlocity.yaml --json -sf.accessToken '{access_token}' -sf.instanceUrl '{instance_url}' foo=bar",
),
]


@pytest.mark.parametrize(
"org_config,task_class,extra,expected_command", vlocity_test_cases
)
def test_vlocity_simple_job(
project_config, org_config, task_class, extra, expected_command
):

task_config = TaskConfig(
config={
"options": {"job_file": "vlocity.yaml", "org": org_name, "extra": extra}
}
)
task = task_class(project_config, task_config, org_config)

assert task._get_command() == expected_command


def test_vlocity_build_tool_missing(project_config):
task_config = TaskConfig(
config={"options": {"job_file": "vlocity.yaml", "org": org_name}}
)
task = VlocityRetrieveTask(project_config, task_config, scratch_org_config)

with mock.patch(
"cumulusci.tasks.vlocity.vlocity.sarge.Command",
mock.Mock(side_effect=ValueError),
):
with pytest.raises(BuildToolMissingError, match=BUILD_TOOL_MISSING_ERROR):
task._init_task()
86 changes: 86 additions & 0 deletions cumulusci/tasks/vlocity/vlocity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from abc import ABC
from typing import Final

import sarge

from cumulusci.core.config.scratch_org_config import ScratchOrgConfig
from cumulusci.core.tasks import BaseSalesforceTask
from cumulusci.tasks.command import Command
from cumulusci.tasks.vlocity.exceptions import BuildToolMissingError

CLI_KEYWORD = "vlocity"
BUILD_TOOL_MISSING_ERROR = (
"This task requires the Vlocity Build CLI tool which is not currently installed on this system. "
"For information on installing this tool visit: https://github.com/vlocityinc/vlocity_build#vlocity-build"
)


class VlocityBaseTask(Command, BaseSalesforceTask):
"""Call the vlocity build tool cli with params"""

task_options: dict = {
"command": {
"description": "The full command to run with the sfdx cli.",
"required": True,
},
"extra": {"description": "Any extra arguments to pass to the vlocity CLI"},
}

def _init_task(self):
tool_exists = self._vlocity_build_tool_exists()
if not tool_exists:
raise BuildToolMissingError(BUILD_TOOL_MISSING_ERROR)

def _vlocity_build_tool_exists(self) -> bool:
try:
p = sarge.Command("vlocity", stdout=sarge.Capture(buffer_size=-1))
p.run(async_=True)
p.wait()
except ValueError:
return False
else:
return True

def _get_command(self) -> str:
command: str = f"{CLI_KEYWORD} {self.options['command']}"

if extra_options := self.options.get("extra"):
command += f" {extra_options}"
return command


class VlocitySimpleJobTask(VlocityBaseTask, ABC):
"""Abstract class for working with the `vlocity` CLI tool"""

task_options: dict = {
"job_file": {"description": "Filepath to the jobfile", "required": True},
"extra": {"description": "Any extra arguments to pass to the vlocity CLI"},
}

def _get_command(self) -> str:
username: str = self.org_config.username
job_file: str = self.options.get("job_file")

command: str = f"{self.command_keyword} -job {job_file} --json"

if isinstance(self.org_config, ScratchOrgConfig):
command = f"{command} -sfdx.username '{username}'"
else:
access_token: str = f"-sf.accessToken '{self.org_config.access_token}'"
instance_url: str = f"-sf.instanceUrl '{self.org_config.instance_url}'"
command = f"{command} {access_token} {instance_url}"

self.options["command"] = command
return super()._get_command()


class VlocityRetrieveTask(VlocitySimpleJobTask):
"""Runs a `vlocity packExport` command with a given user and job file"""

command_keyword: Final[str] = "packExport"


class VlocityDeployTask(VlocitySimpleJobTask):
"""Runs a `vlocity packDeploy` command with a given user and job file"""

command_keyword: Final[str] = "packDeploy"

0 comments on commit 5813e6f

Please sign in to comment.