Skip to content

Commit

Permalink
Merge pull request #2366 from SFDO-Tooling/feature/2gp-install-script
Browse files Browse the repository at this point in the history
Set post-install and uninstall script for 2gp managed packages
  • Loading branch information
David Glick authored Feb 4, 2021
2 parents 943fac8 + 0d4b386 commit a1fb7d9
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 15 deletions.
30 changes: 30 additions & 0 deletions cumulusci/tasks/package_2gp.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class PackageConfig(BaseModel):
description: str = ""
package_type: PackageTypeEnum
org_dependent: bool = False
post_install_script: Optional[str]
uninstall_script: Optional[str]
namespace: Optional[str]
version_name: str
version_base: Optional[str]
Expand All @@ -112,6 +114,18 @@ def org_dependent_must_be_unlocked(cls, v, values):
raise ValueError("Only unlocked packages can be org-dependent.")
return v

@validator("post_install_script")
def post_install_script_must_be_managed(cls, v, values):
if v and values["package_type"] != PackageTypeEnum.managed:
raise ValueError("Only managed packages can have a post-install script.")
return v

@validator("uninstall_script")
def uninstall_script_must_be_managed(cls, v, values):
if v and values["package_type"] != PackageTypeEnum.managed:
raise ValueError("Only managed packages can have an uninstall script.")
return v


class CreatePackageVersion(BaseSalesforceApiTask):
"""Creates a new second-generation package version.
Expand Down Expand Up @@ -145,6 +159,12 @@ class CreatePackageVersion(BaseSalesforceApiTask):
"org_dependent": {
"description": "If true, create an org-dependent unlocked package. Default: false."
},
"post_install_script": {
"description": "Post-install script (for managed packages)",
},
"uninstall_script": {
"description": "Uninstall script (for managed packages)",
},
"force_upload": {
"description": "If true, force creating a new package version even if one with the same contents already exists"
},
Expand All @@ -162,6 +182,10 @@ def _init_options(self, kwargs):
package_type=self.options.get("package_type")
or self.project_config.project__package__type,
org_dependent=self.options.get("org_dependent", False),
post_install_script=self.options.get("post_install_script")
or self.project_config.project__package__install_class,
uninstall_script=self.options.get("uninstall_script")
or self.project_config.project__package__uninstall_class,
namespace=self.options.get("namespace")
or self.project_config.project__package__namespace,
version_name=self.options.get("version_name") or "Release",
Expand Down Expand Up @@ -365,6 +389,12 @@ def _create_version_request(
"versionName": package_config.version_name,
"versionNumber": version_number.format(),
}
if package_config.post_install_script:
package_descriptor[
"postInstallScript"
] = package_config.post_install_script
if package_config.uninstall_script:
package_descriptor["uninstallScript"] = package_config.uninstall_script

# Add org shape
with open(self.org_config.config_file, "r") as f:
Expand Down
49 changes: 37 additions & 12 deletions cumulusci/tasks/tests/test_package_2gp.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import shutil
import zipfile

from pydantic import ValidationError
import pytest
import responses
import yaml
Expand All @@ -21,9 +22,13 @@
from cumulusci.core.exceptions import PackageUploadFailure
from cumulusci.core.exceptions import TaskOptionsError
from cumulusci.salesforce_api.package_zip import BasePackageZipBuilder
from cumulusci.tasks.package_2gp import CreatePackageVersion
from cumulusci.tasks.package_2gp import PackageVersionNumber
from cumulusci.tasks.package_2gp import VersionTypeEnum
from cumulusci.tasks.package_2gp import (
CreatePackageVersion,
PackageConfig,
PackageTypeEnum,
PackageVersionNumber,
VersionTypeEnum,
)
from cumulusci.utils import temporary_dir
from cumulusci.utils import touch

Expand Down Expand Up @@ -67,9 +72,11 @@ def repo_root():
@pytest.fixture
def project_config(repo_root):
project_config = BaseProjectConfig(
UniversalConfig(), repo_info={"root": repo_root, "branch": "main"}
UniversalConfig(),
repo_info={"root": repo_root, "branch": "main"},
)

project_config.config["project"]["package"]["install_class"] = "Install"
project_config.config["project"]["package"]["uninstall_class"] = "Uninstall"
project_config.keychain = BaseProjectKeychain(project_config, key=None)
pathlib.Path(repo_root, "orgs").mkdir()
pathlib.Path(repo_root, "orgs", "scratch_def.json").write_text(
Expand Down Expand Up @@ -117,7 +124,7 @@ def task(project_config, devhub_config, org_config):
TaskConfig(
{
"options": {
"package_type": "Unlocked",
"package_type": "Managed",
"org_dependent": False,
"package_name": "Test Package",
"static_resource_path": "static-resources",
Expand Down Expand Up @@ -162,6 +169,24 @@ def test_increment(self):
)


class TestPackageConfig:
def test_validate_org_dependent(self):
with pytest.raises(ValidationError, match="Only unlocked packages"):
PackageConfig(package_type=PackageTypeEnum.managed, org_dependent=True)

def test_validate_post_install_script(self):
with pytest.raises(ValidationError, match="Only managed packages"):
PackageConfig(
package_type=PackageTypeEnum.unlocked, post_install_script="Install"
)

def test_validate_uninstall_script(self):
with pytest.raises(ValidationError, match="Only managed packages"):
PackageConfig(
package_type=PackageTypeEnum.unlocked, uninstall_script="Uninstall"
)


class TestCreatePackageVersion:
devhub_base_url = "https://devhub.my.salesforce.com/services/data/v50.0"
scratch_base_url = "https://scratch.my.salesforce.com/services/data/v50.0"
Expand Down Expand Up @@ -407,7 +432,7 @@ def test_get_or_create_package__namespaced_existing(
json={
"size": 1,
"records": [
{"Id": "0Ho6g000000fy4ZCAQ", "ContainerOptions": "Unlocked"}
{"Id": "0Ho6g000000fy4ZCAQ", "ContainerOptions": "Managed"}
],
},
)
Expand All @@ -417,7 +442,7 @@ def test_get_or_create_package__namespaced_existing(
TaskConfig(
{
"options": {
"package_type": "Unlocked",
"package_type": "Managed",
"package_name": "Test Package",
"namespace": "ns",
}
Expand All @@ -440,7 +465,7 @@ def test_get_or_create_package__exists_but_wrong_type(
json={
"size": 1,
"records": [
{"Id": "0Ho6g000000fy4ZCAQ", "ContainerOptions": "Managed"}
{"Id": "0Ho6g000000fy4ZCAQ", "ContainerOptions": "Unlocked"}
],
},
)
Expand All @@ -450,7 +475,7 @@ def test_get_or_create_package__exists_but_wrong_type(
TaskConfig(
{
"options": {
"package_type": "Unlocked",
"package_type": "Managed",
"package_name": "Test Package",
"namespace": "ns",
}
Expand Down Expand Up @@ -558,7 +583,7 @@ def test_init_devhub__from_sfdx(self, project_config, org_config):
TaskConfig(
{
"options": {
"package_type": "Unlocked",
"package_type": "Managed",
"package_name": "Test Package",
}
}
Expand All @@ -582,7 +607,7 @@ def test_init_devhub__from_service(self, project_config, org_config):
TaskConfig(
{
"options": {
"package_type": "Unlocked",
"package_type": "Managed",
"package_name": "Test Package",
}
}
Expand Down
19 changes: 16 additions & 3 deletions docs/tasks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,6 @@ Options

If set, the namespace tokens in files and filenames are replaced with the namespace's prefix

Default: $project_config.project__package__namespace

``--api_version APIVERSION``
*Optional*

Expand Down Expand Up @@ -1171,10 +1169,15 @@ Options

Version name

``--version_base VERSIONBASE``
*Optional*

The version number to use as a base before incrementing. Optional; defaults to the highest existing version number of this package. Can be set to ``latest_github_release`` to use the version of the most recent release published to GitHub.

``--version_type VERSIONTYPE``
*Optional*

The part of the version number to increment. Options are major, minor, patch. Defaults to minor
The part of the version number to increment. Options are major, minor, patch, build. Defaults to build

``--skip_validation SKIPVALIDATION``
*Optional*
Expand All @@ -1186,6 +1189,16 @@ Options

If true, create an org-dependent unlocked package. Default: false.

``--post_install_script POSTINSTALLSCRIPT``
*Optional*

Post-install script (for managed packages)

``--uninstall_script UNINSTALLSCRIPT``
*Optional*

Uninstall script (for managed packages)

``--force_upload FORCEUPLOAD``
*Optional*

Expand Down

0 comments on commit a1fb7d9

Please sign in to comment.