cumulusci-plus 5.0.21__py3-none-any.whl → 5.0.43__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cumulusci/__about__.py +1 -1
- cumulusci/cli/logger.py +2 -2
- cumulusci/cli/service.py +20 -0
- cumulusci/cli/task.py +19 -3
- cumulusci/cli/tests/test_error.py +3 -1
- cumulusci/cli/tests/test_flow.py +279 -2
- cumulusci/cli/tests/test_org.py +5 -0
- cumulusci/cli/tests/test_service.py +15 -12
- cumulusci/cli/tests/test_task.py +122 -2
- cumulusci/cli/tests/utils.py +1 -4
- cumulusci/core/config/__init__.py +1 -0
- cumulusci/core/config/base_task_flow_config.py +26 -1
- cumulusci/core/config/org_config.py +2 -1
- cumulusci/core/config/project_config.py +14 -20
- cumulusci/core/config/scratch_org_config.py +12 -0
- cumulusci/core/config/tests/test_config.py +1 -0
- cumulusci/core/config/tests/test_config_expensive.py +9 -3
- cumulusci/core/config/universal_config.py +3 -4
- cumulusci/core/dependencies/base.py +5 -1
- cumulusci/core/dependencies/dependencies.py +1 -1
- cumulusci/core/dependencies/github.py +1 -2
- cumulusci/core/dependencies/resolvers.py +1 -1
- cumulusci/core/dependencies/tests/test_dependencies.py +1 -1
- cumulusci/core/dependencies/tests/test_resolvers.py +1 -1
- cumulusci/core/flowrunner.py +90 -6
- cumulusci/core/github.py +1 -1
- cumulusci/core/sfdx.py +3 -1
- cumulusci/core/source_transforms/tests/test_transforms.py +1 -1
- cumulusci/core/source_transforms/transforms.py +1 -1
- cumulusci/core/tasks.py +13 -2
- cumulusci/core/tests/test_flowrunner.py +100 -0
- cumulusci/core/tests/test_tasks.py +65 -0
- cumulusci/core/utils.py +3 -1
- cumulusci/core/versions.py +1 -1
- cumulusci/cumulusci.yml +73 -1
- cumulusci/oauth/client.py +1 -1
- cumulusci/plugins/plugin_base.py +5 -3
- cumulusci/robotframework/pageobjects/ObjectManagerPageObject.py +1 -1
- cumulusci/salesforce_api/rest_deploy.py +1 -1
- cumulusci/schema/cumulusci.jsonschema.json +69 -0
- cumulusci/tasks/apex/anon.py +1 -1
- cumulusci/tasks/apex/testrunner.py +421 -144
- cumulusci/tasks/apex/tests/test_apex_tasks.py +917 -1
- cumulusci/tasks/bulkdata/extract.py +0 -1
- cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py +1 -1
- cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py +1 -1
- cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py +1 -1
- cumulusci/tasks/bulkdata/generate_and_load_data.py +136 -12
- cumulusci/tasks/bulkdata/mapping_parser.py +139 -44
- cumulusci/tasks/bulkdata/select_utils.py +1 -1
- cumulusci/tasks/bulkdata/snowfakery.py +100 -25
- cumulusci/tasks/bulkdata/tests/test_generate_and_load.py +159 -0
- cumulusci/tasks/bulkdata/tests/test_load.py +0 -2
- cumulusci/tasks/bulkdata/tests/test_mapping_parser.py +763 -1
- cumulusci/tasks/bulkdata/tests/test_select_utils.py +46 -0
- cumulusci/tasks/bulkdata/tests/test_snowfakery.py +133 -0
- cumulusci/tasks/create_package_version.py +190 -16
- cumulusci/tasks/datadictionary.py +1 -1
- cumulusci/tasks/metadata_etl/__init__.py +2 -0
- cumulusci/tasks/metadata_etl/applications.py +256 -0
- cumulusci/tasks/metadata_etl/base.py +7 -3
- cumulusci/tasks/metadata_etl/layouts.py +1 -1
- cumulusci/tasks/metadata_etl/permissions.py +1 -1
- cumulusci/tasks/metadata_etl/remote_site_settings.py +2 -2
- cumulusci/tasks/metadata_etl/tests/test_applications.py +710 -0
- cumulusci/tasks/push/README.md +15 -17
- cumulusci/tasks/release_notes/README.md +13 -13
- cumulusci/tasks/release_notes/generator.py +13 -8
- cumulusci/tasks/robotframework/tests/test_robotframework.py +6 -1
- cumulusci/tasks/salesforce/Deploy.py +53 -2
- cumulusci/tasks/salesforce/SfPackageCommands.py +363 -0
- cumulusci/tasks/salesforce/__init__.py +1 -0
- cumulusci/tasks/salesforce/assign_ps_psg.py +448 -0
- cumulusci/tasks/salesforce/composite.py +1 -1
- cumulusci/tasks/salesforce/custom_settings_wait.py +1 -1
- cumulusci/tasks/salesforce/enable_prediction.py +5 -1
- cumulusci/tasks/salesforce/getPackageVersion.py +89 -0
- cumulusci/tasks/salesforce/insert_record.py +18 -19
- cumulusci/tasks/salesforce/sourcetracking.py +1 -1
- cumulusci/tasks/salesforce/tests/test_Deploy.py +316 -1
- cumulusci/tasks/salesforce/tests/test_SfPackageCommands.py +554 -0
- cumulusci/tasks/salesforce/tests/test_assign_ps_psg.py +1055 -0
- cumulusci/tasks/salesforce/tests/test_enable_prediction.py +4 -2
- cumulusci/tasks/salesforce/tests/test_getPackageVersion.py +651 -0
- cumulusci/tasks/salesforce/tests/test_update_dependencies.py +1 -1
- cumulusci/tasks/salesforce/tests/test_update_external_auth_identity_provider.py +927 -0
- cumulusci/tasks/salesforce/tests/test_update_external_credential.py +1427 -0
- cumulusci/tasks/salesforce/tests/test_update_named_credential.py +1042 -0
- cumulusci/tasks/salesforce/tests/test_update_record.py +512 -0
- cumulusci/tasks/salesforce/update_dependencies.py +2 -2
- cumulusci/tasks/salesforce/update_external_auth_identity_provider.py +551 -0
- cumulusci/tasks/salesforce/update_external_credential.py +647 -0
- cumulusci/tasks/salesforce/update_named_credential.py +441 -0
- cumulusci/tasks/salesforce/update_profile.py +17 -13
- cumulusci/tasks/salesforce/update_record.py +217 -0
- cumulusci/tasks/salesforce/users/permsets.py +62 -5
- cumulusci/tasks/salesforce/users/tests/test_permsets.py +237 -11
- cumulusci/tasks/sfdmu/__init__.py +0 -0
- cumulusci/tasks/sfdmu/sfdmu.py +376 -0
- cumulusci/tasks/sfdmu/tests/__init__.py +1 -0
- cumulusci/tasks/sfdmu/tests/test_runner.py +212 -0
- cumulusci/tasks/sfdmu/tests/test_sfdmu.py +1012 -0
- cumulusci/tasks/tests/test_create_package_version.py +716 -1
- cumulusci/tasks/tests/test_util.py +42 -0
- cumulusci/tasks/util.py +37 -1
- cumulusci/tasks/utility/copyContents.py +402 -0
- cumulusci/tasks/utility/credentialManager.py +302 -0
- cumulusci/tasks/utility/directoryRecreator.py +30 -0
- cumulusci/tasks/utility/env_management.py +1 -1
- cumulusci/tasks/utility/secretsToEnv.py +135 -0
- cumulusci/tasks/utility/tests/test_copyContents.py +1719 -0
- cumulusci/tasks/utility/tests/test_credentialManager.py +1150 -0
- cumulusci/tasks/utility/tests/test_directoryRecreator.py +439 -0
- cumulusci/tasks/utility/tests/test_secretsToEnv.py +1118 -0
- cumulusci/tests/test_integration_infrastructure.py +3 -1
- cumulusci/tests/test_utils.py +70 -6
- cumulusci/utils/__init__.py +54 -9
- cumulusci/utils/classutils.py +5 -2
- cumulusci/utils/http/tests/cassettes/ManualEditTestCompositeParallelSalesforce.test_http_headers.yaml +31 -30
- cumulusci/utils/options.py +23 -1
- cumulusci/utils/parallel/task_worker_queues/parallel_worker.py +1 -1
- cumulusci/utils/yaml/cumulusci_yml.py +8 -3
- cumulusci/utils/yaml/model_parser.py +2 -2
- cumulusci/utils/yaml/tests/test_cumulusci_yml.py +1 -1
- cumulusci/utils/yaml/tests/test_model_parser.py +3 -3
- cumulusci/vcs/base.py +23 -15
- cumulusci/vcs/bootstrap.py +5 -4
- cumulusci/vcs/utils/list_modified_files.py +189 -0
- cumulusci/vcs/utils/tests/test_list_modified_files.py +588 -0
- {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/METADATA +11 -10
- {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/RECORD +135 -104
- {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/WHEEL +1 -1
- {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/entry_points.txt +0 -0
- {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/licenses/AUTHORS.rst +0 -0
- {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/licenses/LICENSE +0 -0
|
@@ -542,6 +542,106 @@ class TestSimpleTestFlowCoordinator(AbstractFlowCoordinatorTest):
|
|
|
542
542
|
flow.run(self.org_config)
|
|
543
543
|
assert len(flow.results) == 0
|
|
544
544
|
|
|
545
|
+
def test_run__when_condition_with_env_var_true(self):
|
|
546
|
+
"""A flow step runs when env var condition evaluates to True"""
|
|
547
|
+
import os
|
|
548
|
+
|
|
549
|
+
with mock.patch.dict(os.environ, {"RUN_TASK": "true"}):
|
|
550
|
+
flow_config = FlowConfig(
|
|
551
|
+
{
|
|
552
|
+
"steps": {
|
|
553
|
+
1: {
|
|
554
|
+
"task": "pass_name",
|
|
555
|
+
"when": "env.get('RUN_TASK') == 'true'",
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
)
|
|
560
|
+
flow = FlowCoordinator(self.project_config, flow_config)
|
|
561
|
+
flow.run(self.org_config)
|
|
562
|
+
assert len(flow.results) == 1
|
|
563
|
+
|
|
564
|
+
def test_run__when_condition_with_env_var_false(self):
|
|
565
|
+
"""A flow step is skipped when env var condition evaluates to False"""
|
|
566
|
+
import os
|
|
567
|
+
|
|
568
|
+
with mock.patch.dict(os.environ, {"RUN_TASK": "false"}):
|
|
569
|
+
flow_config = FlowConfig(
|
|
570
|
+
{
|
|
571
|
+
"steps": {
|
|
572
|
+
1: {
|
|
573
|
+
"task": "pass_name",
|
|
574
|
+
"when": "env.get('RUN_TASK') == 'true'",
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
)
|
|
579
|
+
flow = FlowCoordinator(self.project_config, flow_config)
|
|
580
|
+
flow.run(self.org_config)
|
|
581
|
+
assert len(flow.results) == 0
|
|
582
|
+
|
|
583
|
+
def test_run__when_condition_with_env_var_default(self):
|
|
584
|
+
"""A flow step uses default value when env var is not set"""
|
|
585
|
+
import os
|
|
586
|
+
|
|
587
|
+
# Make sure the env var is not set
|
|
588
|
+
if "UNDEFINED_VAR" in os.environ:
|
|
589
|
+
del os.environ["UNDEFINED_VAR"]
|
|
590
|
+
flow_config = FlowConfig(
|
|
591
|
+
{
|
|
592
|
+
"steps": {
|
|
593
|
+
1: {
|
|
594
|
+
"task": "pass_name",
|
|
595
|
+
"when": "env.get('UNDEFINED_VAR', 'default') == 'default'",
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
)
|
|
600
|
+
flow = FlowCoordinator(self.project_config, flow_config)
|
|
601
|
+
flow.run(self.org_config)
|
|
602
|
+
assert len(flow.results) == 1
|
|
603
|
+
|
|
604
|
+
def test_run__when_condition_with_env_var_and_org_config(self):
|
|
605
|
+
"""A flow step can combine env vars with org_config in when condition"""
|
|
606
|
+
import os
|
|
607
|
+
|
|
608
|
+
with mock.patch.dict(os.environ, {"DEPLOY_TO_SCRATCH": "true"}):
|
|
609
|
+
flow_config = FlowConfig(
|
|
610
|
+
{
|
|
611
|
+
"steps": {
|
|
612
|
+
1: {
|
|
613
|
+
"task": "pass_name",
|
|
614
|
+
"when": "org_config.scratch and env.get('DEPLOY_TO_SCRATCH') == 'true'",
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
)
|
|
619
|
+
flow = FlowCoordinator(self.project_config, flow_config)
|
|
620
|
+
# Set org_config.scratch to True
|
|
621
|
+
self.org_config.config["scratch"] = True
|
|
622
|
+
flow.run(self.org_config)
|
|
623
|
+
assert len(flow.results) == 1
|
|
624
|
+
|
|
625
|
+
def test_run__when_condition_with_missing_env_var_is_none(self):
|
|
626
|
+
"""A flow step can check if env var exists using 'is not none'"""
|
|
627
|
+
import os
|
|
628
|
+
|
|
629
|
+
# Test when var is set
|
|
630
|
+
with mock.patch.dict(os.environ, {"MY_VAR": "value"}):
|
|
631
|
+
flow_config = FlowConfig(
|
|
632
|
+
{
|
|
633
|
+
"steps": {
|
|
634
|
+
1: {
|
|
635
|
+
"task": "pass_name",
|
|
636
|
+
"when": "env.get('MY_VAR') is not none",
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
)
|
|
641
|
+
flow = FlowCoordinator(self.project_config, flow_config)
|
|
642
|
+
flow.run(self.org_config)
|
|
643
|
+
assert len(flow.results) == 1
|
|
644
|
+
|
|
545
645
|
def test_run__task_raises_exception_fail(self):
|
|
546
646
|
"""A flow aborts when a task raises an exception"""
|
|
547
647
|
|
|
@@ -147,6 +147,71 @@ class TestBaseTaskCallable:
|
|
|
147
147
|
task = BaseTask(self.project_config, self.task_config, self.org_config)
|
|
148
148
|
assert task.options["test_option"] == "before baz after"
|
|
149
149
|
|
|
150
|
+
def test_init_options__org_config_substitution(self):
|
|
151
|
+
self.task_config.config["options"] = {"test_option": "$org_config.username"}
|
|
152
|
+
task = BaseTask(self.project_config, self.task_config, self.org_config)
|
|
153
|
+
assert task.options["test_option"] == USERNAME
|
|
154
|
+
|
|
155
|
+
def test_init_options__org_config_substitution_org_id(self):
|
|
156
|
+
self.task_config.config["options"] = {"test_option": "$org_config.org_id"}
|
|
157
|
+
task = BaseTask(self.project_config, self.task_config, self.org_config)
|
|
158
|
+
assert task.options["test_option"] == ORG_ID
|
|
159
|
+
|
|
160
|
+
def test_init_options__org_config_substitution_nested(self):
|
|
161
|
+
self.task_config.config["options"] = {
|
|
162
|
+
"test_option": "$org_config.username",
|
|
163
|
+
"nested": [
|
|
164
|
+
{"user": "$org_config.username"},
|
|
165
|
+
{"org": "$org_config.org_id"},
|
|
166
|
+
],
|
|
167
|
+
}
|
|
168
|
+
task = BaseTask(self.project_config, self.task_config, self.org_config)
|
|
169
|
+
assert task.options["test_option"] == USERNAME
|
|
170
|
+
assert task.options["nested"][0]["user"] == USERNAME
|
|
171
|
+
assert task.options["nested"][1]["org"] == ORG_ID
|
|
172
|
+
|
|
173
|
+
def test_init_options__org_config_substitution__substring(self):
|
|
174
|
+
self.task_config.config["options"] = {
|
|
175
|
+
"test_option": "User: $org_config.username, Org: $org_config.org_id"
|
|
176
|
+
}
|
|
177
|
+
task = BaseTask(self.project_config, self.task_config, self.org_config)
|
|
178
|
+
assert task.options["test_option"] == f"User: {USERNAME}, Org: {ORG_ID}"
|
|
179
|
+
|
|
180
|
+
def test_init_options__org_config_substitution__no_org(self):
|
|
181
|
+
"""Test that $org_config substitution is skipped when org_config is None"""
|
|
182
|
+
self.task_config.config["options"] = {"test_option": "$org_config.username"}
|
|
183
|
+
task = BaseTask(self.project_config, self.task_config, org_config=None)
|
|
184
|
+
# Should remain unchanged when org_config is None
|
|
185
|
+
assert task.options["test_option"] == "$org_config.username"
|
|
186
|
+
|
|
187
|
+
def test_init_options__mixed_substitution(self):
|
|
188
|
+
"""Test that both $project_config and $org_config work together"""
|
|
189
|
+
self.project_config.config["foo"] = {"bar": "baz"}
|
|
190
|
+
self.task_config.config["options"] = {
|
|
191
|
+
"test_option": "Project: $project_config.foo__bar, User: $org_config.username"
|
|
192
|
+
}
|
|
193
|
+
task = BaseTask(self.project_config, self.task_config, self.org_config)
|
|
194
|
+
assert task.options["test_option"] == f"Project: baz, User: {USERNAME}"
|
|
195
|
+
|
|
196
|
+
def test_init_options__mixed_substitution_nested(self):
|
|
197
|
+
"""Test mixed substitution in nested structures"""
|
|
198
|
+
self.project_config.config["project"] = {"name": "TestProject"}
|
|
199
|
+
self.task_config.config["options"] = {
|
|
200
|
+
"config": {
|
|
201
|
+
"project_name": "$project_config.project__name",
|
|
202
|
+
"username": "$org_config.username",
|
|
203
|
+
"items": [
|
|
204
|
+
"$project_config.project__name",
|
|
205
|
+
"$org_config.org_id",
|
|
206
|
+
],
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
task = BaseTask(self.project_config, self.task_config, self.org_config)
|
|
210
|
+
assert task.options["config"]["project_name"] == "TestProject"
|
|
211
|
+
assert task.options["config"]["username"] == USERNAME
|
|
212
|
+
assert task.options["config"]["items"][0] == "TestProject"
|
|
213
|
+
assert task.options["config"]["items"][1] == ORG_ID
|
|
214
|
+
|
|
150
215
|
def test_validates_missing_options(self):
|
|
151
216
|
class Task(BaseTask):
|
|
152
217
|
task_options = {"test_option": {"required": True}}
|
cumulusci/core/utils.py
CHANGED
|
@@ -379,7 +379,9 @@ def determine_managed_mode(options, project_config, org_config):
|
|
|
379
379
|
Note: The changes allows multiple package development under same namespace.
|
|
380
380
|
"""
|
|
381
381
|
if "managed" in options:
|
|
382
|
-
return process_bool_arg(
|
|
382
|
+
return process_bool_arg(
|
|
383
|
+
options["managed"] if options["managed"] is not None else False
|
|
384
|
+
)
|
|
383
385
|
|
|
384
386
|
# Get package and namespace information
|
|
385
387
|
package_name = getattr(project_config, "project__package__name", None)
|
cumulusci/core/versions.py
CHANGED
cumulusci/cumulusci.yml
CHANGED
|
@@ -168,6 +168,10 @@ tasks:
|
|
|
168
168
|
description: Inserts a record of any sObject using the REST API
|
|
169
169
|
class_path: cumulusci.tasks.salesforce.insert_record.InsertRecord
|
|
170
170
|
group: Data Operations
|
|
171
|
+
update_record:
|
|
172
|
+
description: Updates one or more records of any sObject using the REST API
|
|
173
|
+
class_path: cumulusci.tasks.salesforce.update_record.UpdateRecord
|
|
174
|
+
group: Data Operations
|
|
171
175
|
create_package:
|
|
172
176
|
description: Creates a package in the target org with the default package name for the project
|
|
173
177
|
class_path: cumulusci.tasks.salesforce.CreatePackage
|
|
@@ -197,6 +201,10 @@ tasks:
|
|
|
197
201
|
user_permissions:
|
|
198
202
|
- PermissionsBulkApiHardDelete
|
|
199
203
|
- PermissionsCreateAuditFields
|
|
204
|
+
assign_permission_set_to_psg:
|
|
205
|
+
group: Metadata Transformations
|
|
206
|
+
description: "Assigns specified Permission Sets to the specified Permission Set Groups using the Composite API."
|
|
207
|
+
class_path: cumulusci.tasks.salesforce.assign_ps_psg.AssignPermissionSetToPermissionSetGroup
|
|
200
208
|
create_unmanaged_ee_src:
|
|
201
209
|
description: Modifies the src directory for unmanaged deployment to an EE org
|
|
202
210
|
class_path: cumulusci.tasks.metadata.ee_src.CreateUnmanagedEESrc
|
|
@@ -228,6 +236,10 @@ tasks:
|
|
|
228
236
|
options:
|
|
229
237
|
path: src
|
|
230
238
|
group: Salesforce Metadata
|
|
239
|
+
deploy_unpackaged_metadata:
|
|
240
|
+
description: Deploys the unpackaged metadata from the project config to the target org. This is application of 2nd generation package metadata.
|
|
241
|
+
class_path: cumulusci.tasks.salesforce.DeployUnpackagedMetadata
|
|
242
|
+
group: Salesforce Metadata
|
|
231
243
|
deploy_marketing_cloud_package:
|
|
232
244
|
class_path: cumulusci.tasks.marketing_cloud.deploy.MarketingCloudDeployTask
|
|
233
245
|
description: Deploys a package zip file to a Marketing Cloud Tenant via the Marketing Cloud Package Manager API.
|
|
@@ -653,6 +665,12 @@ tasks:
|
|
|
653
665
|
class_path: cumulusci.tasks.metadata_etl.SetOrgWideDefaults
|
|
654
666
|
options:
|
|
655
667
|
namespace_inject: $project_config.project__package__namespace
|
|
668
|
+
add_applications_profile_action_overrides:
|
|
669
|
+
group: Metadata Transformations
|
|
670
|
+
description: Adds or updates profile action overrides to the Custom Applications.
|
|
671
|
+
class_path: cumulusci.tasks.metadata_etl.applications.AddProfileActionOverrides
|
|
672
|
+
options:
|
|
673
|
+
namespace_inject: $project_config.project__package__namespace
|
|
656
674
|
strip_unwanted_components:
|
|
657
675
|
description: Removes components from src folder which are not mentioned in given package.xml file
|
|
658
676
|
class_path: cumulusci.tasks.metadata.package.RemoveUnwantedComponents
|
|
@@ -749,10 +767,33 @@ tasks:
|
|
|
749
767
|
options:
|
|
750
768
|
level: info
|
|
751
769
|
group: Utilities
|
|
770
|
+
copy_file:
|
|
771
|
+
description: "Copy a file for src to dest with environment variable support, Ex: &TMPDIR&/src resolves to /tmp/src on linux or %TMPDIR%/src on windows."
|
|
772
|
+
class_path: cumulusci.tasks.util.CopyFile
|
|
773
|
+
group: Utilities
|
|
774
|
+
is_global: True
|
|
775
|
+
load_dot_env:
|
|
776
|
+
description: "Log the contents of the .env file"
|
|
777
|
+
class_path: cumulusci.tasks.util.LoadDotEnv
|
|
778
|
+
group: Utilities
|
|
779
|
+
is_global: True
|
|
752
780
|
configure_env:
|
|
753
781
|
description: Get or set environment variables.
|
|
754
782
|
class_path: cumulusci.tasks.utility.env_management.EnvManagement
|
|
755
783
|
group: Utilities
|
|
784
|
+
secrets_to_dotenv:
|
|
785
|
+
description: Get all environment variables from a target JSON file and generates a .env file that can be used to set up the environment variables for the deployment
|
|
786
|
+
class_path: cumulusci.tasks.utility.secretsToEnv.SecretsToEnv
|
|
787
|
+
group: Utilities
|
|
788
|
+
is_global: True
|
|
789
|
+
directory_recreator:
|
|
790
|
+
description: Remove and recreate a directory
|
|
791
|
+
class_path: cumulusci.tasks.utility.directoryRecreator.DirectoryRecreator
|
|
792
|
+
group: Utilities
|
|
793
|
+
consolidate_unpackaged_metadata:
|
|
794
|
+
description: Consolidate unpackaged metadata from multiple sources into a single directory
|
|
795
|
+
class_path: cumulusci.tasks.utility.copyContents.ConsolidateUnpackagedMetadata
|
|
796
|
+
group: Utilities
|
|
756
797
|
download_extract:
|
|
757
798
|
description: Downloads files and folders from a VCS repository.
|
|
758
799
|
class_path: cumulusci.tasks.vcs.download_extract.DownloadExtract
|
|
@@ -787,6 +828,10 @@ tasks:
|
|
|
787
828
|
description: Load Custom Settings specified in a YAML file to the target org
|
|
788
829
|
class_path: cumulusci.tasks.salesforce.LoadCustomSettings
|
|
789
830
|
group: "Data Operations"
|
|
831
|
+
sfdmu:
|
|
832
|
+
description: Execute SFDmu data migration with namespace injection support
|
|
833
|
+
class_path: cumulusci.tasks.sfdmu.sfdmu.SfdmuTask
|
|
834
|
+
group: "Data Operations"
|
|
790
835
|
remove_metadata_xml_elements:
|
|
791
836
|
description: Remove specified XML elements from one or more metadata files
|
|
792
837
|
class_path: cumulusci.tasks.metadata.modify.RemoveElementsXPath
|
|
@@ -823,6 +868,30 @@ tasks:
|
|
|
823
868
|
class_path: cumulusci.tasks.salesforce.SfDataCommands.DataCreateRecordTask
|
|
824
869
|
description: "Executes the `sf data create` command against an org"
|
|
825
870
|
group: SalesforceDX Data Commands
|
|
871
|
+
update_package_version:
|
|
872
|
+
class_path: cumulusci.tasks.salesforce.SfPackageCommands.PackageVersionUpdateTask
|
|
873
|
+
description: "Executes the `sf package version update` command against an org"
|
|
874
|
+
group: Salesforce Packages
|
|
875
|
+
get_package_version:
|
|
876
|
+
description: Get package version id from package name and version
|
|
877
|
+
class_path: cumulusci.tasks.salesforce.getPackageVersion.GetPackageVersion
|
|
878
|
+
group: Salesforce Packages
|
|
879
|
+
options:
|
|
880
|
+
package_name: $project_config.project__package__name
|
|
881
|
+
fail_on_error: False
|
|
882
|
+
update_named_credential:
|
|
883
|
+
class_path: cumulusci.tasks.salesforce.update_named_credential.UpdateNamedCredential
|
|
884
|
+
description: Update named credential parameters
|
|
885
|
+
group: Metadata Transformations
|
|
886
|
+
update_external_credential:
|
|
887
|
+
class_path: cumulusci.tasks.salesforce.update_external_credential.UpdateExternalCredential
|
|
888
|
+
description: Update external credential parameters
|
|
889
|
+
group: Metadata Transformations
|
|
890
|
+
update_external_auth_identity_provider:
|
|
891
|
+
class_path: cumulusci.tasks.salesforce.update_external_auth_identity_provider.UpdateExternalAuthIdentityProvider
|
|
892
|
+
description: Update external auth identity provider parameters and credentials
|
|
893
|
+
group: Metadata Transformations
|
|
894
|
+
|
|
826
895
|
flows:
|
|
827
896
|
ci_beta:
|
|
828
897
|
group: Continuous Integration
|
|
@@ -1562,7 +1631,10 @@ project:
|
|
|
1562
1631
|
namespace:
|
|
1563
1632
|
install_class:
|
|
1564
1633
|
uninstall_class:
|
|
1565
|
-
|
|
1634
|
+
apex_test_access:
|
|
1635
|
+
package_metadata_access:
|
|
1636
|
+
unpackaged_metadata_path:
|
|
1637
|
+
api_version: "64.0"
|
|
1566
1638
|
git:
|
|
1567
1639
|
default_branch: master
|
|
1568
1640
|
prefix_feature: feature/
|
cumulusci/oauth/client.py
CHANGED
|
@@ -19,7 +19,7 @@ from cryptography import x509
|
|
|
19
19
|
from cryptography.hazmat.primitives import hashes, serialization
|
|
20
20
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
21
21
|
from cryptography.x509.oid import NameOID
|
|
22
|
-
from pydantic import BaseModel
|
|
22
|
+
from pydantic.v1 import BaseModel
|
|
23
23
|
|
|
24
24
|
from cumulusci.core.exceptions import CumulusCIUsageError
|
|
25
25
|
from cumulusci.oauth.exceptions import OAuth2Error
|
cumulusci/plugins/plugin_base.py
CHANGED
|
@@ -11,7 +11,7 @@ from cumulusci.utils.yaml.cumulusci_yml import Plugin, cci_safe_load
|
|
|
11
11
|
class PluginBase(ABC):
|
|
12
12
|
plugin: Plugin
|
|
13
13
|
plugin_config_file: str = "cumulusci_plugin.yml"
|
|
14
|
-
path: str
|
|
14
|
+
path: str
|
|
15
15
|
plugin_project_config: Optional[dict] = None
|
|
16
16
|
|
|
17
17
|
def __init__(self, **kwargs) -> None:
|
|
@@ -32,12 +32,14 @@ class PluginBase(ABC):
|
|
|
32
32
|
@property
|
|
33
33
|
def name(self) -> str:
|
|
34
34
|
"""Returns the name of the plugin."""
|
|
35
|
-
return
|
|
35
|
+
return (
|
|
36
|
+
self.plugin.name if self.plugin and self.plugin.name else "Unnamed Plugin"
|
|
37
|
+
)
|
|
36
38
|
|
|
37
39
|
@property
|
|
38
40
|
def version(self) -> str:
|
|
39
41
|
"""Returns the version of the plugin."""
|
|
40
|
-
return self.plugin.version if self.plugin else "0.0.0"
|
|
42
|
+
return self.plugin.version if self.plugin and self.plugin.version else "0.0.0"
|
|
41
43
|
|
|
42
44
|
def initialize(self) -> None:
|
|
43
45
|
"""Initialize the plugin. This method is called when the plugin is loaded."""
|
|
@@ -203,7 +203,7 @@ class ObjectManagerPage(BasePage):
|
|
|
203
203
|
|
|
204
204
|
except Exception as e:
|
|
205
205
|
self.builtin.log(
|
|
206
|
-
f"on try #{tries+1} we caught this error: {e}", "DEBUG"
|
|
206
|
+
f"on try #{tries + 1} we caught this error: {e}", "DEBUG"
|
|
207
207
|
)
|
|
208
208
|
self.builtin.sleep("1 second")
|
|
209
209
|
last_error = e
|
|
@@ -138,7 +138,7 @@ class RestDeploy:
|
|
|
138
138
|
|
|
139
139
|
# Construct an error message from deployment failure details
|
|
140
140
|
def _construct_error_message(self, failure):
|
|
141
|
-
error_message = f"{str.upper(failure['problemType'])} in file {failure['fileName'][len(PARENT_DIR_NAME)+len('/'):]}: {failure['problem']}"
|
|
141
|
+
error_message = f"{str.upper(failure['problemType'])} in file {failure['fileName'][len(PARENT_DIR_NAME) + len('/'):]}: {failure['problem']}"
|
|
142
142
|
|
|
143
143
|
if failure["lineNumber"] and failure["columnNumber"]:
|
|
144
144
|
error_message += (
|
|
@@ -122,6 +122,11 @@
|
|
|
122
122
|
"name": {
|
|
123
123
|
"title": "Name",
|
|
124
124
|
"type": "string"
|
|
125
|
+
},
|
|
126
|
+
"is_global": {
|
|
127
|
+
"title": "Is Global",
|
|
128
|
+
"default": false,
|
|
129
|
+
"type": "boolean"
|
|
125
130
|
}
|
|
126
131
|
},
|
|
127
132
|
"additionalProperties": false
|
|
@@ -246,6 +251,70 @@
|
|
|
246
251
|
"metadata_package_id": {
|
|
247
252
|
"title": "Metadata Package Id",
|
|
248
253
|
"type": "string"
|
|
254
|
+
},
|
|
255
|
+
"apex_test_access": {
|
|
256
|
+
"title": "Apex Test Access",
|
|
257
|
+
"type": "object",
|
|
258
|
+
"additionalProperties": {
|
|
259
|
+
"anyOf": [
|
|
260
|
+
{
|
|
261
|
+
"type": "string"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"type": "array",
|
|
265
|
+
"items": {
|
|
266
|
+
"type": "string"
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"package_metadata_access": {
|
|
273
|
+
"title": "Package Metadata Access",
|
|
274
|
+
"type": "object",
|
|
275
|
+
"additionalProperties": {
|
|
276
|
+
"anyOf": [
|
|
277
|
+
{
|
|
278
|
+
"type": "string"
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"type": "array",
|
|
282
|
+
"items": {
|
|
283
|
+
"type": "string"
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
]
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
"unpackaged_metadata_path": {
|
|
290
|
+
"title": "Unpackaged Metadata Path",
|
|
291
|
+
"anyOf": [
|
|
292
|
+
{
|
|
293
|
+
"type": "string"
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"type": "array",
|
|
297
|
+
"items": {
|
|
298
|
+
"type": "string"
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"type": "object",
|
|
303
|
+
"additionalProperties": {
|
|
304
|
+
"anyOf": [
|
|
305
|
+
{
|
|
306
|
+
"type": "string"
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"type": "array",
|
|
310
|
+
"items": {
|
|
311
|
+
"type": "string"
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
]
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
]
|
|
249
318
|
}
|
|
250
319
|
},
|
|
251
320
|
"additionalProperties": false
|
cumulusci/tasks/apex/anon.py
CHANGED
|
@@ -4,7 +4,7 @@ from cumulusci.core.exceptions import (
|
|
|
4
4
|
SalesforceException,
|
|
5
5
|
TaskOptionsError,
|
|
6
6
|
)
|
|
7
|
-
from cumulusci.core.utils import
|
|
7
|
+
from cumulusci.core.utils import determine_managed_mode, process_bool_arg
|
|
8
8
|
from cumulusci.tasks.salesforce import BaseSalesforceApiTask
|
|
9
9
|
from cumulusci.utils import in_directory, inject_namespace
|
|
10
10
|
from cumulusci.utils.http.requests_utils import safe_json_from_response
|