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.
Files changed (135) hide show
  1. cumulusci/__about__.py +1 -1
  2. cumulusci/cli/logger.py +2 -2
  3. cumulusci/cli/service.py +20 -0
  4. cumulusci/cli/task.py +19 -3
  5. cumulusci/cli/tests/test_error.py +3 -1
  6. cumulusci/cli/tests/test_flow.py +279 -2
  7. cumulusci/cli/tests/test_org.py +5 -0
  8. cumulusci/cli/tests/test_service.py +15 -12
  9. cumulusci/cli/tests/test_task.py +122 -2
  10. cumulusci/cli/tests/utils.py +1 -4
  11. cumulusci/core/config/__init__.py +1 -0
  12. cumulusci/core/config/base_task_flow_config.py +26 -1
  13. cumulusci/core/config/org_config.py +2 -1
  14. cumulusci/core/config/project_config.py +14 -20
  15. cumulusci/core/config/scratch_org_config.py +12 -0
  16. cumulusci/core/config/tests/test_config.py +1 -0
  17. cumulusci/core/config/tests/test_config_expensive.py +9 -3
  18. cumulusci/core/config/universal_config.py +3 -4
  19. cumulusci/core/dependencies/base.py +5 -1
  20. cumulusci/core/dependencies/dependencies.py +1 -1
  21. cumulusci/core/dependencies/github.py +1 -2
  22. cumulusci/core/dependencies/resolvers.py +1 -1
  23. cumulusci/core/dependencies/tests/test_dependencies.py +1 -1
  24. cumulusci/core/dependencies/tests/test_resolvers.py +1 -1
  25. cumulusci/core/flowrunner.py +90 -6
  26. cumulusci/core/github.py +1 -1
  27. cumulusci/core/sfdx.py +3 -1
  28. cumulusci/core/source_transforms/tests/test_transforms.py +1 -1
  29. cumulusci/core/source_transforms/transforms.py +1 -1
  30. cumulusci/core/tasks.py +13 -2
  31. cumulusci/core/tests/test_flowrunner.py +100 -0
  32. cumulusci/core/tests/test_tasks.py +65 -0
  33. cumulusci/core/utils.py +3 -1
  34. cumulusci/core/versions.py +1 -1
  35. cumulusci/cumulusci.yml +73 -1
  36. cumulusci/oauth/client.py +1 -1
  37. cumulusci/plugins/plugin_base.py +5 -3
  38. cumulusci/robotframework/pageobjects/ObjectManagerPageObject.py +1 -1
  39. cumulusci/salesforce_api/rest_deploy.py +1 -1
  40. cumulusci/schema/cumulusci.jsonschema.json +69 -0
  41. cumulusci/tasks/apex/anon.py +1 -1
  42. cumulusci/tasks/apex/testrunner.py +421 -144
  43. cumulusci/tasks/apex/tests/test_apex_tasks.py +917 -1
  44. cumulusci/tasks/bulkdata/extract.py +0 -1
  45. cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py +1 -1
  46. cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py +1 -1
  47. cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py +1 -1
  48. cumulusci/tasks/bulkdata/generate_and_load_data.py +136 -12
  49. cumulusci/tasks/bulkdata/mapping_parser.py +139 -44
  50. cumulusci/tasks/bulkdata/select_utils.py +1 -1
  51. cumulusci/tasks/bulkdata/snowfakery.py +100 -25
  52. cumulusci/tasks/bulkdata/tests/test_generate_and_load.py +159 -0
  53. cumulusci/tasks/bulkdata/tests/test_load.py +0 -2
  54. cumulusci/tasks/bulkdata/tests/test_mapping_parser.py +763 -1
  55. cumulusci/tasks/bulkdata/tests/test_select_utils.py +46 -0
  56. cumulusci/tasks/bulkdata/tests/test_snowfakery.py +133 -0
  57. cumulusci/tasks/create_package_version.py +190 -16
  58. cumulusci/tasks/datadictionary.py +1 -1
  59. cumulusci/tasks/metadata_etl/__init__.py +2 -0
  60. cumulusci/tasks/metadata_etl/applications.py +256 -0
  61. cumulusci/tasks/metadata_etl/base.py +7 -3
  62. cumulusci/tasks/metadata_etl/layouts.py +1 -1
  63. cumulusci/tasks/metadata_etl/permissions.py +1 -1
  64. cumulusci/tasks/metadata_etl/remote_site_settings.py +2 -2
  65. cumulusci/tasks/metadata_etl/tests/test_applications.py +710 -0
  66. cumulusci/tasks/push/README.md +15 -17
  67. cumulusci/tasks/release_notes/README.md +13 -13
  68. cumulusci/tasks/release_notes/generator.py +13 -8
  69. cumulusci/tasks/robotframework/tests/test_robotframework.py +6 -1
  70. cumulusci/tasks/salesforce/Deploy.py +53 -2
  71. cumulusci/tasks/salesforce/SfPackageCommands.py +363 -0
  72. cumulusci/tasks/salesforce/__init__.py +1 -0
  73. cumulusci/tasks/salesforce/assign_ps_psg.py +448 -0
  74. cumulusci/tasks/salesforce/composite.py +1 -1
  75. cumulusci/tasks/salesforce/custom_settings_wait.py +1 -1
  76. cumulusci/tasks/salesforce/enable_prediction.py +5 -1
  77. cumulusci/tasks/salesforce/getPackageVersion.py +89 -0
  78. cumulusci/tasks/salesforce/insert_record.py +18 -19
  79. cumulusci/tasks/salesforce/sourcetracking.py +1 -1
  80. cumulusci/tasks/salesforce/tests/test_Deploy.py +316 -1
  81. cumulusci/tasks/salesforce/tests/test_SfPackageCommands.py +554 -0
  82. cumulusci/tasks/salesforce/tests/test_assign_ps_psg.py +1055 -0
  83. cumulusci/tasks/salesforce/tests/test_enable_prediction.py +4 -2
  84. cumulusci/tasks/salesforce/tests/test_getPackageVersion.py +651 -0
  85. cumulusci/tasks/salesforce/tests/test_update_dependencies.py +1 -1
  86. cumulusci/tasks/salesforce/tests/test_update_external_auth_identity_provider.py +927 -0
  87. cumulusci/tasks/salesforce/tests/test_update_external_credential.py +1427 -0
  88. cumulusci/tasks/salesforce/tests/test_update_named_credential.py +1042 -0
  89. cumulusci/tasks/salesforce/tests/test_update_record.py +512 -0
  90. cumulusci/tasks/salesforce/update_dependencies.py +2 -2
  91. cumulusci/tasks/salesforce/update_external_auth_identity_provider.py +551 -0
  92. cumulusci/tasks/salesforce/update_external_credential.py +647 -0
  93. cumulusci/tasks/salesforce/update_named_credential.py +441 -0
  94. cumulusci/tasks/salesforce/update_profile.py +17 -13
  95. cumulusci/tasks/salesforce/update_record.py +217 -0
  96. cumulusci/tasks/salesforce/users/permsets.py +62 -5
  97. cumulusci/tasks/salesforce/users/tests/test_permsets.py +237 -11
  98. cumulusci/tasks/sfdmu/__init__.py +0 -0
  99. cumulusci/tasks/sfdmu/sfdmu.py +376 -0
  100. cumulusci/tasks/sfdmu/tests/__init__.py +1 -0
  101. cumulusci/tasks/sfdmu/tests/test_runner.py +212 -0
  102. cumulusci/tasks/sfdmu/tests/test_sfdmu.py +1012 -0
  103. cumulusci/tasks/tests/test_create_package_version.py +716 -1
  104. cumulusci/tasks/tests/test_util.py +42 -0
  105. cumulusci/tasks/util.py +37 -1
  106. cumulusci/tasks/utility/copyContents.py +402 -0
  107. cumulusci/tasks/utility/credentialManager.py +302 -0
  108. cumulusci/tasks/utility/directoryRecreator.py +30 -0
  109. cumulusci/tasks/utility/env_management.py +1 -1
  110. cumulusci/tasks/utility/secretsToEnv.py +135 -0
  111. cumulusci/tasks/utility/tests/test_copyContents.py +1719 -0
  112. cumulusci/tasks/utility/tests/test_credentialManager.py +1150 -0
  113. cumulusci/tasks/utility/tests/test_directoryRecreator.py +439 -0
  114. cumulusci/tasks/utility/tests/test_secretsToEnv.py +1118 -0
  115. cumulusci/tests/test_integration_infrastructure.py +3 -1
  116. cumulusci/tests/test_utils.py +70 -6
  117. cumulusci/utils/__init__.py +54 -9
  118. cumulusci/utils/classutils.py +5 -2
  119. cumulusci/utils/http/tests/cassettes/ManualEditTestCompositeParallelSalesforce.test_http_headers.yaml +31 -30
  120. cumulusci/utils/options.py +23 -1
  121. cumulusci/utils/parallel/task_worker_queues/parallel_worker.py +1 -1
  122. cumulusci/utils/yaml/cumulusci_yml.py +8 -3
  123. cumulusci/utils/yaml/model_parser.py +2 -2
  124. cumulusci/utils/yaml/tests/test_cumulusci_yml.py +1 -1
  125. cumulusci/utils/yaml/tests/test_model_parser.py +3 -3
  126. cumulusci/vcs/base.py +23 -15
  127. cumulusci/vcs/bootstrap.py +5 -4
  128. cumulusci/vcs/utils/list_modified_files.py +189 -0
  129. cumulusci/vcs/utils/tests/test_list_modified_files.py +588 -0
  130. {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/METADATA +11 -10
  131. {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/RECORD +135 -104
  132. {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/WHEEL +1 -1
  133. {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/entry_points.txt +0 -0
  134. {cumulusci_plus-5.0.21.dist-info → cumulusci_plus-5.0.43.dist-info}/licenses/AUTHORS.rst +0 -0
  135. {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(options["managed"])
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)
@@ -1,7 +1,7 @@
1
1
  import re
2
2
  from typing import Optional, Union
3
3
 
4
- from pydantic import BaseModel
4
+ from pydantic.v1 import BaseModel
5
5
 
6
6
  from cumulusci.core.enums import StrEnum
7
7
 
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
- api_version: "63.0"
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
@@ -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 = None
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 self.plugin.name if self.plugin else "Unnamed Plugin"
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
@@ -4,7 +4,7 @@ from cumulusci.core.exceptions import (
4
4
  SalesforceException,
5
5
  TaskOptionsError,
6
6
  )
7
- from cumulusci.core.utils import process_bool_arg, determine_managed_mode
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