cumulusci-plus 5.0.0__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.

Potentially problematic release.


This version of cumulusci-plus might be problematic. Click here for more details.

Files changed (744) hide show
  1. cumulusci/__about__.py +1 -0
  2. cumulusci/__init__.py +22 -0
  3. cumulusci/__main__.py +3 -0
  4. cumulusci/cli/__init__.py +0 -0
  5. cumulusci/cli/cci.py +244 -0
  6. cumulusci/cli/error.py +125 -0
  7. cumulusci/cli/flow.py +185 -0
  8. cumulusci/cli/logger.py +72 -0
  9. cumulusci/cli/org.py +692 -0
  10. cumulusci/cli/plan.py +181 -0
  11. cumulusci/cli/project.py +391 -0
  12. cumulusci/cli/robot.py +116 -0
  13. cumulusci/cli/runtime.py +190 -0
  14. cumulusci/cli/service.py +521 -0
  15. cumulusci/cli/task.py +295 -0
  16. cumulusci/cli/tests/__init__.py +0 -0
  17. cumulusci/cli/tests/test_cci.py +545 -0
  18. cumulusci/cli/tests/test_error.py +170 -0
  19. cumulusci/cli/tests/test_flow.py +276 -0
  20. cumulusci/cli/tests/test_logger.py +25 -0
  21. cumulusci/cli/tests/test_org.py +1438 -0
  22. cumulusci/cli/tests/test_plan.py +245 -0
  23. cumulusci/cli/tests/test_project.py +235 -0
  24. cumulusci/cli/tests/test_robot.py +177 -0
  25. cumulusci/cli/tests/test_runtime.py +197 -0
  26. cumulusci/cli/tests/test_service.py +853 -0
  27. cumulusci/cli/tests/test_task.py +266 -0
  28. cumulusci/cli/tests/test_ui.py +310 -0
  29. cumulusci/cli/tests/test_utils.py +122 -0
  30. cumulusci/cli/tests/utils.py +52 -0
  31. cumulusci/cli/ui.py +234 -0
  32. cumulusci/cli/utils.py +150 -0
  33. cumulusci/conftest.py +181 -0
  34. cumulusci/core/__init__.py +0 -0
  35. cumulusci/core/config/BaseConfig.py +5 -0
  36. cumulusci/core/config/BaseTaskFlowConfig.py +5 -0
  37. cumulusci/core/config/OrgConfig.py +5 -0
  38. cumulusci/core/config/ScratchOrgConfig.py +5 -0
  39. cumulusci/core/config/__init__.py +125 -0
  40. cumulusci/core/config/base_config.py +111 -0
  41. cumulusci/core/config/base_task_flow_config.py +82 -0
  42. cumulusci/core/config/marketing_cloud_service_config.py +83 -0
  43. cumulusci/core/config/oauth2_service_config.py +17 -0
  44. cumulusci/core/config/org_config.py +604 -0
  45. cumulusci/core/config/project_config.py +782 -0
  46. cumulusci/core/config/scratch_org_config.py +251 -0
  47. cumulusci/core/config/sfdx_org_config.py +220 -0
  48. cumulusci/core/config/tests/_test_config_backwards_compatibility.py +33 -0
  49. cumulusci/core/config/tests/test_config.py +1895 -0
  50. cumulusci/core/config/tests/test_config_expensive.py +839 -0
  51. cumulusci/core/config/tests/test_config_util.py +91 -0
  52. cumulusci/core/config/universal_config.py +88 -0
  53. cumulusci/core/config/util.py +18 -0
  54. cumulusci/core/datasets.py +303 -0
  55. cumulusci/core/debug.py +33 -0
  56. cumulusci/core/dependencies/__init__.py +55 -0
  57. cumulusci/core/dependencies/base.py +561 -0
  58. cumulusci/core/dependencies/dependencies.py +273 -0
  59. cumulusci/core/dependencies/github.py +177 -0
  60. cumulusci/core/dependencies/github_resolvers.py +244 -0
  61. cumulusci/core/dependencies/resolvers.py +580 -0
  62. cumulusci/core/dependencies/tests/__init__.py +0 -0
  63. cumulusci/core/dependencies/tests/conftest.py +385 -0
  64. cumulusci/core/dependencies/tests/test_dependencies.py +950 -0
  65. cumulusci/core/dependencies/tests/test_github.py +83 -0
  66. cumulusci/core/dependencies/tests/test_resolvers.py +1027 -0
  67. cumulusci/core/dependencies/utils.py +13 -0
  68. cumulusci/core/enums.py +11 -0
  69. cumulusci/core/exceptions.py +311 -0
  70. cumulusci/core/flowrunner.py +888 -0
  71. cumulusci/core/github.py +665 -0
  72. cumulusci/core/keychain/__init__.py +24 -0
  73. cumulusci/core/keychain/base_project_keychain.py +441 -0
  74. cumulusci/core/keychain/encrypted_file_project_keychain.py +945 -0
  75. cumulusci/core/keychain/environment_project_keychain.py +7 -0
  76. cumulusci/core/keychain/serialization.py +152 -0
  77. cumulusci/core/keychain/subprocess_keychain.py +24 -0
  78. cumulusci/core/keychain/tests/conftest.py +50 -0
  79. cumulusci/core/keychain/tests/test_base_project_keychain.py +299 -0
  80. cumulusci/core/keychain/tests/test_encrypted_file_project_keychain.py +1228 -0
  81. cumulusci/core/metadeploy/__init__.py +0 -0
  82. cumulusci/core/metadeploy/api.py +88 -0
  83. cumulusci/core/metadeploy/plans.py +25 -0
  84. cumulusci/core/metadeploy/tests/test_api.py +276 -0
  85. cumulusci/core/runtime.py +115 -0
  86. cumulusci/core/sfdx.py +162 -0
  87. cumulusci/core/source/__init__.py +16 -0
  88. cumulusci/core/source/github.py +50 -0
  89. cumulusci/core/source/local_folder.py +35 -0
  90. cumulusci/core/source_transforms/__init__.py +0 -0
  91. cumulusci/core/source_transforms/tests/test_transforms.py +1091 -0
  92. cumulusci/core/source_transforms/transforms.py +532 -0
  93. cumulusci/core/tasks.py +404 -0
  94. cumulusci/core/template_utils.py +59 -0
  95. cumulusci/core/tests/__init__.py +0 -0
  96. cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_e2e.yaml +215 -0
  97. cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_extract_standard_objects.yaml +199 -0
  98. cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_read_explicit_extract_declaration.yaml +3 -0
  99. cumulusci/core/tests/fake_remote_repo/cumulusci.yml +32 -0
  100. cumulusci/core/tests/fake_remote_repo/tasks/directory/example_2.py +6 -0
  101. cumulusci/core/tests/fake_remote_repo/tasks/example.py +43 -0
  102. cumulusci/core/tests/fake_remote_repo_2/cumulusci.yml +11 -0
  103. cumulusci/core/tests/fake_remote_repo_2/tasks/example_3.py +6 -0
  104. cumulusci/core/tests/test_datasets_e2e.py +386 -0
  105. cumulusci/core/tests/test_exceptions.py +11 -0
  106. cumulusci/core/tests/test_flowrunner.py +836 -0
  107. cumulusci/core/tests/test_github.py +942 -0
  108. cumulusci/core/tests/test_sfdx.py +138 -0
  109. cumulusci/core/tests/test_source.py +678 -0
  110. cumulusci/core/tests/test_tasks.py +262 -0
  111. cumulusci/core/tests/test_utils.py +141 -0
  112. cumulusci/core/tests/test_utils_merge_config.py +276 -0
  113. cumulusci/core/tests/test_versions.py +76 -0
  114. cumulusci/core/tests/untrusted_repo_child/cumulusci.yml +7 -0
  115. cumulusci/core/tests/untrusted_repo_child/tasks/untrusted_child.py +6 -0
  116. cumulusci/core/tests/untrusted_repo_parent/cumulusci.yml +26 -0
  117. cumulusci/core/tests/untrusted_repo_parent/tasks/untrusted_parent.py +6 -0
  118. cumulusci/core/tests/utils.py +116 -0
  119. cumulusci/core/tests/yaml/global.yaml +0 -0
  120. cumulusci/core/utils.py +402 -0
  121. cumulusci/core/versions.py +149 -0
  122. cumulusci/cumulusci.yml +1621 -0
  123. cumulusci/files/admin_profile.xml +20 -0
  124. cumulusci/files/delete_excludes.txt +424 -0
  125. cumulusci/files/templates/project/README.md +12 -0
  126. cumulusci/files/templates/project/cumulusci.yml +63 -0
  127. cumulusci/files/templates/project/dot-gitignore +60 -0
  128. cumulusci/files/templates/project/mapping.yml +45 -0
  129. cumulusci/files/templates/project/scratch_def.json +25 -0
  130. cumulusci/oauth/__init__.py +0 -0
  131. cumulusci/oauth/client.py +400 -0
  132. cumulusci/oauth/exceptions.py +9 -0
  133. cumulusci/oauth/salesforce.py +95 -0
  134. cumulusci/oauth/tests/__init__.py +0 -0
  135. cumulusci/oauth/tests/cassettes/test_get_device_code.yaml +22 -0
  136. cumulusci/oauth/tests/cassettes/test_get_device_oauth_token.yaml +74 -0
  137. cumulusci/oauth/tests/test_client.py +308 -0
  138. cumulusci/oauth/tests/test_salesforce.py +46 -0
  139. cumulusci/plugins/__init__.py +3 -0
  140. cumulusci/plugins/plugin_base.py +93 -0
  141. cumulusci/plugins/plugin_loader.py +59 -0
  142. cumulusci/robotframework/CumulusCI.py +340 -0
  143. cumulusci/robotframework/CumulusCI.robot +7 -0
  144. cumulusci/robotframework/Performance.py +165 -0
  145. cumulusci/robotframework/Salesforce.py +936 -0
  146. cumulusci/robotframework/Salesforce.robot +192 -0
  147. cumulusci/robotframework/SalesforceAPI.py +416 -0
  148. cumulusci/robotframework/SalesforcePlaywright.py +220 -0
  149. cumulusci/robotframework/SalesforcePlaywright.robot +40 -0
  150. cumulusci/robotframework/__init__.py +2 -0
  151. cumulusci/robotframework/base_library.py +39 -0
  152. cumulusci/robotframework/faker_mixin.py +89 -0
  153. cumulusci/robotframework/form_handlers.py +222 -0
  154. cumulusci/robotframework/javascript/cci_init.js +34 -0
  155. cumulusci/robotframework/javascript/cumulusci.js +4 -0
  156. cumulusci/robotframework/locator_manager.py +197 -0
  157. cumulusci/robotframework/locators_56.py +88 -0
  158. cumulusci/robotframework/locators_57.py +5 -0
  159. cumulusci/robotframework/pageobjects/BasePageObjects.py +433 -0
  160. cumulusci/robotframework/pageobjects/ObjectManagerPageObject.py +246 -0
  161. cumulusci/robotframework/pageobjects/PageObjectLibrary.py +45 -0
  162. cumulusci/robotframework/pageobjects/PageObjects.py +351 -0
  163. cumulusci/robotframework/pageobjects/__init__.py +12 -0
  164. cumulusci/robotframework/pageobjects/baseobjects.py +120 -0
  165. cumulusci/robotframework/perftests/short/collection_perf.robot +105 -0
  166. cumulusci/robotframework/tests/CustomObjectTestPage.py +10 -0
  167. cumulusci/robotframework/tests/FooTestPage.py +8 -0
  168. cumulusci/robotframework/tests/cumulusci/base.robot +40 -0
  169. cumulusci/robotframework/tests/cumulusci/bulkdata.robot +38 -0
  170. cumulusci/robotframework/tests/cumulusci/communities.robot +57 -0
  171. cumulusci/robotframework/tests/cumulusci/datagen.robot +84 -0
  172. cumulusci/robotframework/tests/salesforce/TestLibraryA.py +24 -0
  173. cumulusci/robotframework/tests/salesforce/TestLibraryB.py +20 -0
  174. cumulusci/robotframework/tests/salesforce/TestListener.py +93 -0
  175. cumulusci/robotframework/tests/salesforce/api.robot +178 -0
  176. cumulusci/robotframework/tests/salesforce/browsers.robot +143 -0
  177. cumulusci/robotframework/tests/salesforce/classic.robot +51 -0
  178. cumulusci/robotframework/tests/salesforce/create_contact.robot +59 -0
  179. cumulusci/robotframework/tests/salesforce/faker.robot +68 -0
  180. cumulusci/robotframework/tests/salesforce/forms.robot +172 -0
  181. cumulusci/robotframework/tests/salesforce/label_locator.robot +244 -0
  182. cumulusci/robotframework/tests/salesforce/labels.html +33 -0
  183. cumulusci/robotframework/tests/salesforce/locators.robot +149 -0
  184. cumulusci/robotframework/tests/salesforce/pageobjects/base_pageobjects.robot +100 -0
  185. cumulusci/robotframework/tests/salesforce/pageobjects/example_page_object.py +25 -0
  186. cumulusci/robotframework/tests/salesforce/pageobjects/listing_page.robot +115 -0
  187. cumulusci/robotframework/tests/salesforce/pageobjects/objectmanager.robot +74 -0
  188. cumulusci/robotframework/tests/salesforce/pageobjects/pageobjects.robot +171 -0
  189. cumulusci/robotframework/tests/salesforce/performance.robot +109 -0
  190. cumulusci/robotframework/tests/salesforce/playwright/javascript_keywords.robot +33 -0
  191. cumulusci/robotframework/tests/salesforce/playwright/open_test_browser.robot +48 -0
  192. cumulusci/robotframework/tests/salesforce/playwright/playwright.robot +24 -0
  193. cumulusci/robotframework/tests/salesforce/playwright/ui.robot +32 -0
  194. cumulusci/robotframework/tests/salesforce/populate.robot +89 -0
  195. cumulusci/robotframework/tests/salesforce/test_testlistener.py +37 -0
  196. cumulusci/robotframework/tests/salesforce/ui.robot +361 -0
  197. cumulusci/robotframework/tests/test_cumulusci_library.py +304 -0
  198. cumulusci/robotframework/tests/test_locator_manager.py +158 -0
  199. cumulusci/robotframework/tests/test_pageobjects.py +291 -0
  200. cumulusci/robotframework/tests/test_performance.py +38 -0
  201. cumulusci/robotframework/tests/test_salesforce.py +79 -0
  202. cumulusci/robotframework/tests/test_salesforce_locators.py +73 -0
  203. cumulusci/robotframework/tests/test_template_util.py +53 -0
  204. cumulusci/robotframework/tests/test_utils.py +106 -0
  205. cumulusci/robotframework/utils.py +283 -0
  206. cumulusci/salesforce_api/__init__.py +0 -0
  207. cumulusci/salesforce_api/exceptions.py +23 -0
  208. cumulusci/salesforce_api/filterable_objects.py +96 -0
  209. cumulusci/salesforce_api/mc_soap_envelopes.py +89 -0
  210. cumulusci/salesforce_api/metadata.py +721 -0
  211. cumulusci/salesforce_api/org_schema.py +571 -0
  212. cumulusci/salesforce_api/org_schema_models.py +226 -0
  213. cumulusci/salesforce_api/package_install.py +265 -0
  214. cumulusci/salesforce_api/package_zip.py +301 -0
  215. cumulusci/salesforce_api/rest_deploy.py +148 -0
  216. cumulusci/salesforce_api/retrieve_profile_api.py +301 -0
  217. cumulusci/salesforce_api/soap_envelopes.py +177 -0
  218. cumulusci/salesforce_api/tests/__init__.py +0 -0
  219. cumulusci/salesforce_api/tests/metadata_test_strings.py +24 -0
  220. cumulusci/salesforce_api/tests/test_metadata.py +1015 -0
  221. cumulusci/salesforce_api/tests/test_package_install.py +219 -0
  222. cumulusci/salesforce_api/tests/test_package_zip.py +380 -0
  223. cumulusci/salesforce_api/tests/test_rest_deploy.py +264 -0
  224. cumulusci/salesforce_api/tests/test_retrieve_profile_api.py +337 -0
  225. cumulusci/salesforce_api/tests/test_utils.py +124 -0
  226. cumulusci/salesforce_api/utils.py +51 -0
  227. cumulusci/schema/cumulusci.jsonschema.json +782 -0
  228. cumulusci/tasks/__init__.py +0 -0
  229. cumulusci/tasks/apex/__init__.py +0 -0
  230. cumulusci/tasks/apex/anon.py +157 -0
  231. cumulusci/tasks/apex/batch.py +180 -0
  232. cumulusci/tasks/apex/testrunner.py +835 -0
  233. cumulusci/tasks/apex/tests/cassettes/ManualEditTestApexIntegrationTests.test_run_tests__integration_test.yaml +703 -0
  234. cumulusci/tasks/apex/tests/test_apex_tasks.py +1558 -0
  235. cumulusci/tasks/base_source_control_task.py +17 -0
  236. cumulusci/tasks/bulkdata/__init__.py +15 -0
  237. cumulusci/tasks/bulkdata/base_generate_data_task.py +96 -0
  238. cumulusci/tasks/bulkdata/dates.py +97 -0
  239. cumulusci/tasks/bulkdata/delete.py +156 -0
  240. cumulusci/tasks/bulkdata/extract.py +441 -0
  241. cumulusci/tasks/bulkdata/extract_dataset_utils/calculate_dependencies.py +117 -0
  242. cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py +123 -0
  243. cumulusci/tasks/bulkdata/extract_dataset_utils/hardcoded_default_declarations.py +49 -0
  244. cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py +283 -0
  245. cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py +142 -0
  246. cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_synthesize_extract_declarations.py +575 -0
  247. cumulusci/tasks/bulkdata/factory_utils.py +134 -0
  248. cumulusci/tasks/bulkdata/generate.py +4 -0
  249. cumulusci/tasks/bulkdata/generate_and_load_data.py +232 -0
  250. cumulusci/tasks/bulkdata/generate_and_load_data_from_yaml.py +19 -0
  251. cumulusci/tasks/bulkdata/generate_from_yaml.py +183 -0
  252. cumulusci/tasks/bulkdata/generate_mapping.py +434 -0
  253. cumulusci/tasks/bulkdata/generate_mapping_utils/dependency_map.py +169 -0
  254. cumulusci/tasks/bulkdata/generate_mapping_utils/extract_mapping_file_generator.py +45 -0
  255. cumulusci/tasks/bulkdata/generate_mapping_utils/generate_mapping_from_declarations.py +121 -0
  256. cumulusci/tasks/bulkdata/generate_mapping_utils/load_mapping_file_generator.py +127 -0
  257. cumulusci/tasks/bulkdata/generate_mapping_utils/mapping_generator_post_processes.py +53 -0
  258. cumulusci/tasks/bulkdata/generate_mapping_utils/mapping_transforms.py +139 -0
  259. cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_generate_extract_mapping_from_declarations.py +135 -0
  260. cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_generate_load_mapping_from_declarations.py +330 -0
  261. cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_mapping_generator_post_processes.py +60 -0
  262. cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_mapping_transforms.py +188 -0
  263. cumulusci/tasks/bulkdata/load.py +1196 -0
  264. cumulusci/tasks/bulkdata/mapping_parser.py +811 -0
  265. cumulusci/tasks/bulkdata/query_transformers.py +264 -0
  266. cumulusci/tasks/bulkdata/select_utils.py +792 -0
  267. cumulusci/tasks/bulkdata/snowfakery.py +753 -0
  268. cumulusci/tasks/bulkdata/snowfakery_utils/queue_manager.py +478 -0
  269. cumulusci/tasks/bulkdata/snowfakery_utils/snowfakery_run_until.py +141 -0
  270. cumulusci/tasks/bulkdata/snowfakery_utils/snowfakery_working_directory.py +53 -0
  271. cumulusci/tasks/bulkdata/snowfakery_utils/subtask_configurator.py +64 -0
  272. cumulusci/tasks/bulkdata/step.py +1242 -0
  273. cumulusci/tasks/bulkdata/tests/__init__.py +0 -0
  274. cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_random_strategy.yaml +147 -0
  275. cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_annoy_strategy.yaml +123 -0
  276. cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_select_and_insert_strategy.yaml +313 -0
  277. cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_select_and_insert_strategy_bulk.yaml +550 -0
  278. cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_strategy.yaml +175 -0
  279. cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_standard_strategy.yaml +147 -0
  280. cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__multiple_needed.yaml +69 -0
  281. cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__none_needed.yaml +22 -0
  282. cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__one_needed.yaml +24 -0
  283. cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_snowfakery_query_salesforce.yaml +25 -0
  284. cumulusci/tasks/bulkdata/tests/cassettes/TestUpdatesIntegrationTests.test_updates_task.yaml +80 -0
  285. cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_simple_upsert__rest.yaml +270 -0
  286. cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert__rest.yaml +267 -0
  287. cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_external_id_field__rest.yaml +369 -0
  288. cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_external_id_field_rest__duplicate_error.yaml +204 -0
  289. cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_fields__bulk.yaml +675 -0
  290. cumulusci/tasks/bulkdata/tests/dummy_data_factory.py +36 -0
  291. cumulusci/tasks/bulkdata/tests/integration_test_utils.py +49 -0
  292. cumulusci/tasks/bulkdata/tests/mapping-oid.yml +87 -0
  293. cumulusci/tasks/bulkdata/tests/mapping_after.yml +38 -0
  294. cumulusci/tasks/bulkdata/tests/mapping_poly.yml +34 -0
  295. cumulusci/tasks/bulkdata/tests/mapping_poly_incomplete.yml +20 -0
  296. cumulusci/tasks/bulkdata/tests/mapping_poly_wrong.yml +21 -0
  297. cumulusci/tasks/bulkdata/tests/mapping_select.yml +20 -0
  298. cumulusci/tasks/bulkdata/tests/mapping_select_invalid_strategy.yml +20 -0
  299. cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__invalid_number.yml +21 -0
  300. cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__invalid_strategy.yml +21 -0
  301. cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__non_float.yml +21 -0
  302. cumulusci/tasks/bulkdata/tests/mapping_select_missing_priority_fields.yml +22 -0
  303. cumulusci/tasks/bulkdata/tests/mapping_select_no_priority_fields.yml +18 -0
  304. cumulusci/tasks/bulkdata/tests/mapping_simple.yml +27 -0
  305. cumulusci/tasks/bulkdata/tests/mapping_v1.yml +28 -0
  306. cumulusci/tasks/bulkdata/tests/mapping_v2.yml +21 -0
  307. cumulusci/tasks/bulkdata/tests/mapping_v3.yml +32 -0
  308. cumulusci/tasks/bulkdata/tests/mapping_vanilla_sf.yml +69 -0
  309. cumulusci/tasks/bulkdata/tests/mock_data_factory_without_mapping.py +12 -0
  310. cumulusci/tasks/bulkdata/tests/person_accounts.yml +23 -0
  311. cumulusci/tasks/bulkdata/tests/person_accounts_minimal.yml +15 -0
  312. cumulusci/tasks/bulkdata/tests/recordtypes.yml +8 -0
  313. cumulusci/tasks/bulkdata/tests/recordtypes_2.yml +6 -0
  314. cumulusci/tasks/bulkdata/tests/recordtypes_with_ispersontype.yml +8 -0
  315. cumulusci/tasks/bulkdata/tests/snowfakery/child/child2.yml +3 -0
  316. cumulusci/tasks/bulkdata/tests/snowfakery/child.yml +4 -0
  317. cumulusci/tasks/bulkdata/tests/snowfakery/gen_npsp_standard_objects.recipe.yml +89 -0
  318. cumulusci/tasks/bulkdata/tests/snowfakery/include_parent.yml +3 -0
  319. cumulusci/tasks/bulkdata/tests/snowfakery/npsp_standard_objects_macros.yml +34 -0
  320. cumulusci/tasks/bulkdata/tests/snowfakery/options.recipe.yml +6 -0
  321. cumulusci/tasks/bulkdata/tests/snowfakery/query_snowfakery.recipe.yml +16 -0
  322. cumulusci/tasks/bulkdata/tests/snowfakery/sf_standard_object_macros.yml +83 -0
  323. cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery.load.yml +2 -0
  324. cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery.recipe.yml +13 -0
  325. cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_2.load.yml +5 -0
  326. cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels.load.yml +13 -0
  327. cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels.recipe.yml +12 -0
  328. cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels_2.load.yml +13 -0
  329. cumulusci/tasks/bulkdata/tests/snowfakery/unique_values.recipe.yml +4 -0
  330. cumulusci/tasks/bulkdata/tests/snowfakery/upsert.recipe.yml +23 -0
  331. cumulusci/tasks/bulkdata/tests/snowfakery/upsert_2.recipe.yml +29 -0
  332. cumulusci/tasks/bulkdata/tests/snowfakery/upsert_before.yml +10 -0
  333. cumulusci/tasks/bulkdata/tests/test_base_generate_data_tasks.py +61 -0
  334. cumulusci/tasks/bulkdata/tests/test_dates.py +99 -0
  335. cumulusci/tasks/bulkdata/tests/test_delete.py +404 -0
  336. cumulusci/tasks/bulkdata/tests/test_extract.py +1311 -0
  337. cumulusci/tasks/bulkdata/tests/test_factory_utils.py +55 -0
  338. cumulusci/tasks/bulkdata/tests/test_generate_and_load.py +252 -0
  339. cumulusci/tasks/bulkdata/tests/test_generate_from_snowfakery_task.py +343 -0
  340. cumulusci/tasks/bulkdata/tests/test_generatemapping.py +1039 -0
  341. cumulusci/tasks/bulkdata/tests/test_load.py +3175 -0
  342. cumulusci/tasks/bulkdata/tests/test_mapping_parser.py +1658 -0
  343. cumulusci/tasks/bulkdata/tests/test_query_db__joins_self_lookups.yml +12 -0
  344. cumulusci/tasks/bulkdata/tests/test_query_db_joins_lookups.yml +26 -0
  345. cumulusci/tasks/bulkdata/tests/test_query_db_joins_lookups_select.yml +48 -0
  346. cumulusci/tasks/bulkdata/tests/test_select.py +171 -0
  347. cumulusci/tasks/bulkdata/tests/test_select_utils.py +1057 -0
  348. cumulusci/tasks/bulkdata/tests/test_snowfakery.py +1153 -0
  349. cumulusci/tasks/bulkdata/tests/test_step.py +3957 -0
  350. cumulusci/tasks/bulkdata/tests/test_updates.py +513 -0
  351. cumulusci/tasks/bulkdata/tests/test_upsert.py +1015 -0
  352. cumulusci/tasks/bulkdata/tests/test_utils.py +158 -0
  353. cumulusci/tasks/bulkdata/tests/testdata.db +0 -0
  354. cumulusci/tasks/bulkdata/tests/update_describe.py +50 -0
  355. cumulusci/tasks/bulkdata/tests/update_person_accounts.yml +23 -0
  356. cumulusci/tasks/bulkdata/tests/utils.py +114 -0
  357. cumulusci/tasks/bulkdata/update_data.py +260 -0
  358. cumulusci/tasks/bulkdata/upsert_utils.py +130 -0
  359. cumulusci/tasks/bulkdata/utils.py +249 -0
  360. cumulusci/tasks/command.py +178 -0
  361. cumulusci/tasks/connectedapp.py +186 -0
  362. cumulusci/tasks/create_package_version.py +778 -0
  363. cumulusci/tasks/datadictionary.py +745 -0
  364. cumulusci/tasks/dx_convert_from.py +26 -0
  365. cumulusci/tasks/github/__init__.py +17 -0
  366. cumulusci/tasks/github/base.py +16 -0
  367. cumulusci/tasks/github/commit_status.py +13 -0
  368. cumulusci/tasks/github/merge.py +11 -0
  369. cumulusci/tasks/github/publish.py +11 -0
  370. cumulusci/tasks/github/pull_request.py +11 -0
  371. cumulusci/tasks/github/release.py +11 -0
  372. cumulusci/tasks/github/release_report.py +11 -0
  373. cumulusci/tasks/github/tag.py +11 -0
  374. cumulusci/tasks/github/tests/__init__.py +0 -0
  375. cumulusci/tasks/github/tests/test_util.py +202 -0
  376. cumulusci/tasks/github/tests/test_vcs_migration.py +44 -0
  377. cumulusci/tasks/github/tests/util_github_api.py +666 -0
  378. cumulusci/tasks/github/util.py +252 -0
  379. cumulusci/tasks/marketing_cloud/__init__.py +0 -0
  380. cumulusci/tasks/marketing_cloud/api.py +188 -0
  381. cumulusci/tasks/marketing_cloud/base.py +38 -0
  382. cumulusci/tasks/marketing_cloud/deploy.py +345 -0
  383. cumulusci/tasks/marketing_cloud/get_user_info.py +40 -0
  384. cumulusci/tasks/marketing_cloud/mc_constants.py +1 -0
  385. cumulusci/tasks/marketing_cloud/tests/__init__.py +0 -0
  386. cumulusci/tasks/marketing_cloud/tests/conftest.py +46 -0
  387. cumulusci/tasks/marketing_cloud/tests/expected-payload.json +110 -0
  388. cumulusci/tasks/marketing_cloud/tests/test_api.py +97 -0
  389. cumulusci/tasks/marketing_cloud/tests/test_api_soap_envelopes.py +145 -0
  390. cumulusci/tasks/marketing_cloud/tests/test_base.py +14 -0
  391. cumulusci/tasks/marketing_cloud/tests/test_deploy.py +400 -0
  392. cumulusci/tasks/marketing_cloud/tests/test_get_user_info.py +141 -0
  393. cumulusci/tasks/marketing_cloud/tests/validation-response.json +39 -0
  394. cumulusci/tasks/metadata/__init__.py +0 -0
  395. cumulusci/tasks/metadata/ee_src.py +94 -0
  396. cumulusci/tasks/metadata/managed_src.py +100 -0
  397. cumulusci/tasks/metadata/metadata_map.yml +868 -0
  398. cumulusci/tasks/metadata/modify.py +99 -0
  399. cumulusci/tasks/metadata/package.py +684 -0
  400. cumulusci/tasks/metadata/tests/__init__.py +0 -0
  401. cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/.hidden/.keep +0 -0
  402. cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/destructiveChanges.xml +9 -0
  403. cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/package.xml +9 -0
  404. cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/package_install_uninstall.xml +11 -0
  405. cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/reports/namespace__TestFolder/TestReport.report +3 -0
  406. cumulusci/tasks/metadata/tests/sample_package.xml +9 -0
  407. cumulusci/tasks/metadata/tests/test_ee_src.py +112 -0
  408. cumulusci/tasks/metadata/tests/test_managed_src.py +111 -0
  409. cumulusci/tasks/metadata/tests/test_modify.py +123 -0
  410. cumulusci/tasks/metadata/tests/test_package.py +476 -0
  411. cumulusci/tasks/metadata_etl/__init__.py +29 -0
  412. cumulusci/tasks/metadata_etl/base.py +436 -0
  413. cumulusci/tasks/metadata_etl/duplicate_rules.py +24 -0
  414. cumulusci/tasks/metadata_etl/field_sets.py +70 -0
  415. cumulusci/tasks/metadata_etl/help_text.py +92 -0
  416. cumulusci/tasks/metadata_etl/layouts.py +550 -0
  417. cumulusci/tasks/metadata_etl/objects.py +68 -0
  418. cumulusci/tasks/metadata_etl/permissions.py +167 -0
  419. cumulusci/tasks/metadata_etl/picklists.py +221 -0
  420. cumulusci/tasks/metadata_etl/remote_site_settings.py +99 -0
  421. cumulusci/tasks/metadata_etl/sharing.py +138 -0
  422. cumulusci/tasks/metadata_etl/tests/test_base.py +512 -0
  423. cumulusci/tasks/metadata_etl/tests/test_duplicate_rules.py +22 -0
  424. cumulusci/tasks/metadata_etl/tests/test_field_sets.py +156 -0
  425. cumulusci/tasks/metadata_etl/tests/test_help_text.py +387 -0
  426. cumulusci/tasks/metadata_etl/tests/test_ip_ranges.py +85 -0
  427. cumulusci/tasks/metadata_etl/tests/test_layouts.py +858 -0
  428. cumulusci/tasks/metadata_etl/tests/test_objects.py +236 -0
  429. cumulusci/tasks/metadata_etl/tests/test_permissions.py +223 -0
  430. cumulusci/tasks/metadata_etl/tests/test_picklists.py +547 -0
  431. cumulusci/tasks/metadata_etl/tests/test_remote_site_settings.py +46 -0
  432. cumulusci/tasks/metadata_etl/tests/test_sharing.py +333 -0
  433. cumulusci/tasks/metadata_etl/tests/test_value_sets.py +298 -0
  434. cumulusci/tasks/metadata_etl/value_sets.py +106 -0
  435. cumulusci/tasks/metadeploy.py +393 -0
  436. cumulusci/tasks/metaxml.py +88 -0
  437. cumulusci/tasks/preflight/__init__.py +0 -0
  438. cumulusci/tasks/preflight/dataset_load.py +49 -0
  439. cumulusci/tasks/preflight/licenses.py +86 -0
  440. cumulusci/tasks/preflight/packages.py +14 -0
  441. cumulusci/tasks/preflight/permsets.py +23 -0
  442. cumulusci/tasks/preflight/recordtypes.py +16 -0
  443. cumulusci/tasks/preflight/retrieve_tasks.py +30 -0
  444. cumulusci/tasks/preflight/settings.py +77 -0
  445. cumulusci/tasks/preflight/sobjects.py +202 -0
  446. cumulusci/tasks/preflight/tests/test_dataset_load.py +85 -0
  447. cumulusci/tasks/preflight/tests/test_licenses.py +174 -0
  448. cumulusci/tasks/preflight/tests/test_packages.py +14 -0
  449. cumulusci/tasks/preflight/tests/test_permset_preflights.py +51 -0
  450. cumulusci/tasks/preflight/tests/test_recordtypes.py +30 -0
  451. cumulusci/tasks/preflight/tests/test_retrieve_tasks.py +62 -0
  452. cumulusci/tasks/preflight/tests/test_settings.py +130 -0
  453. cumulusci/tasks/preflight/tests/test_sobjects.py +231 -0
  454. cumulusci/tasks/push/README.md +59 -0
  455. cumulusci/tasks/push/__init__.py +0 -0
  456. cumulusci/tasks/push/push_api.py +659 -0
  457. cumulusci/tasks/push/pushfails.py +136 -0
  458. cumulusci/tasks/push/tasks.py +476 -0
  459. cumulusci/tasks/push/tests/conftest.py +263 -0
  460. cumulusci/tasks/push/tests/test_push_api.py +951 -0
  461. cumulusci/tasks/push/tests/test_push_tasks.py +659 -0
  462. cumulusci/tasks/release_notes/README.md +63 -0
  463. cumulusci/tasks/release_notes/__init__.py +0 -0
  464. cumulusci/tasks/release_notes/exceptions.py +5 -0
  465. cumulusci/tasks/release_notes/generator.py +137 -0
  466. cumulusci/tasks/release_notes/parser.py +232 -0
  467. cumulusci/tasks/release_notes/provider.py +44 -0
  468. cumulusci/tasks/release_notes/task.py +300 -0
  469. cumulusci/tasks/release_notes/tests/__init__.py +0 -0
  470. cumulusci/tasks/release_notes/tests/change_notes/full/example1.md +17 -0
  471. cumulusci/tasks/release_notes/tests/change_notes/multi/1.txt +1 -0
  472. cumulusci/tasks/release_notes/tests/change_notes/multi/2.txt +1 -0
  473. cumulusci/tasks/release_notes/tests/change_notes/multi/3.txt +1 -0
  474. cumulusci/tasks/release_notes/tests/change_notes/single/1.txt +1 -0
  475. cumulusci/tasks/release_notes/tests/test_generator.py +582 -0
  476. cumulusci/tasks/release_notes/tests/test_parser.py +867 -0
  477. cumulusci/tasks/release_notes/tests/test_provider.py +512 -0
  478. cumulusci/tasks/release_notes/tests/test_task.py +461 -0
  479. cumulusci/tasks/release_notes/tests/utils.py +153 -0
  480. cumulusci/tasks/robotframework/__init__.py +3 -0
  481. cumulusci/tasks/robotframework/debugger/DebugListener.py +100 -0
  482. cumulusci/tasks/robotframework/debugger/__init__.py +10 -0
  483. cumulusci/tasks/robotframework/debugger/model.py +87 -0
  484. cumulusci/tasks/robotframework/debugger/ui.py +259 -0
  485. cumulusci/tasks/robotframework/libdoc.py +269 -0
  486. cumulusci/tasks/robotframework/robotframework.py +392 -0
  487. cumulusci/tasks/robotframework/stylesheet.css +130 -0
  488. cumulusci/tasks/robotframework/template.html +109 -0
  489. cumulusci/tasks/robotframework/tests/TestLibrary.py +18 -0
  490. cumulusci/tasks/robotframework/tests/TestPageObjects.py +31 -0
  491. cumulusci/tasks/robotframework/tests/TestResource.robot +8 -0
  492. cumulusci/tasks/robotframework/tests/failing_tests.robot +16 -0
  493. cumulusci/tasks/robotframework/tests/performance.robot +23 -0
  494. cumulusci/tasks/robotframework/tests/test_browser_proxies.py +137 -0
  495. cumulusci/tasks/robotframework/tests/test_debugger.py +360 -0
  496. cumulusci/tasks/robotframework/tests/test_robot_parallel.py +141 -0
  497. cumulusci/tasks/robotframework/tests/test_robotframework.py +860 -0
  498. cumulusci/tasks/salesforce/BaseRetrieveMetadata.py +58 -0
  499. cumulusci/tasks/salesforce/BaseSalesforceApiTask.py +45 -0
  500. cumulusci/tasks/salesforce/BaseSalesforceMetadataApiTask.py +18 -0
  501. cumulusci/tasks/salesforce/BaseSalesforceTask.py +4 -0
  502. cumulusci/tasks/salesforce/BaseUninstallMetadata.py +41 -0
  503. cumulusci/tasks/salesforce/CreateCommunity.py +124 -0
  504. cumulusci/tasks/salesforce/CreatePackage.py +29 -0
  505. cumulusci/tasks/salesforce/Deploy.py +240 -0
  506. cumulusci/tasks/salesforce/DeployBundles.py +88 -0
  507. cumulusci/tasks/salesforce/DescribeMetadataTypes.py +26 -0
  508. cumulusci/tasks/salesforce/EnsureRecordTypes.py +202 -0
  509. cumulusci/tasks/salesforce/GetInstalledPackages.py +8 -0
  510. cumulusci/tasks/salesforce/ListCommunities.py +40 -0
  511. cumulusci/tasks/salesforce/ListCommunityTemplates.py +19 -0
  512. cumulusci/tasks/salesforce/PublishCommunity.py +62 -0
  513. cumulusci/tasks/salesforce/RetrievePackaged.py +41 -0
  514. cumulusci/tasks/salesforce/RetrieveReportsAndDashboards.py +82 -0
  515. cumulusci/tasks/salesforce/RetrieveUnpackaged.py +36 -0
  516. cumulusci/tasks/salesforce/SOQLQuery.py +39 -0
  517. cumulusci/tasks/salesforce/UninstallLocal.py +15 -0
  518. cumulusci/tasks/salesforce/UninstallLocalBundles.py +28 -0
  519. cumulusci/tasks/salesforce/UninstallLocalNamespacedBundles.py +58 -0
  520. cumulusci/tasks/salesforce/UninstallPackage.py +32 -0
  521. cumulusci/tasks/salesforce/UninstallPackaged.py +56 -0
  522. cumulusci/tasks/salesforce/UpdateAdminProfile.py +8 -0
  523. cumulusci/tasks/salesforce/__init__.py +79 -0
  524. cumulusci/tasks/salesforce/activate_flow.py +74 -0
  525. cumulusci/tasks/salesforce/check_components.py +324 -0
  526. cumulusci/tasks/salesforce/composite.py +142 -0
  527. cumulusci/tasks/salesforce/create_permission_sets.py +35 -0
  528. cumulusci/tasks/salesforce/custom_settings.py +134 -0
  529. cumulusci/tasks/salesforce/custom_settings_wait.py +132 -0
  530. cumulusci/tasks/salesforce/enable_prediction.py +107 -0
  531. cumulusci/tasks/salesforce/insert_record.py +40 -0
  532. cumulusci/tasks/salesforce/install_package_version.py +242 -0
  533. cumulusci/tasks/salesforce/license_preflights.py +8 -0
  534. cumulusci/tasks/salesforce/network_member_group.py +178 -0
  535. cumulusci/tasks/salesforce/nonsourcetracking.py +228 -0
  536. cumulusci/tasks/salesforce/org_settings.py +193 -0
  537. cumulusci/tasks/salesforce/package_upload.py +328 -0
  538. cumulusci/tasks/salesforce/profiles.py +74 -0
  539. cumulusci/tasks/salesforce/promote_package_version.py +376 -0
  540. cumulusci/tasks/salesforce/retrieve_profile.py +195 -0
  541. cumulusci/tasks/salesforce/salesforce_files.py +244 -0
  542. cumulusci/tasks/salesforce/sourcetracking.py +507 -0
  543. cumulusci/tasks/salesforce/tests/__init__.py +3 -0
  544. cumulusci/tasks/salesforce/tests/test_CreateCommunity.py +278 -0
  545. cumulusci/tasks/salesforce/tests/test_CreatePackage.py +22 -0
  546. cumulusci/tasks/salesforce/tests/test_Deploy.py +470 -0
  547. cumulusci/tasks/salesforce/tests/test_DeployBundles.py +76 -0
  548. cumulusci/tasks/salesforce/tests/test_EnsureRecordTypes.py +345 -0
  549. cumulusci/tasks/salesforce/tests/test_ListCommunities.py +84 -0
  550. cumulusci/tasks/salesforce/tests/test_ListCommunityTemplates.py +49 -0
  551. cumulusci/tasks/salesforce/tests/test_PackageUpload.py +547 -0
  552. cumulusci/tasks/salesforce/tests/test_ProfileGrantAllAccess.py +699 -0
  553. cumulusci/tasks/salesforce/tests/test_PublishCommunity.py +181 -0
  554. cumulusci/tasks/salesforce/tests/test_RetrievePackaged.py +24 -0
  555. cumulusci/tasks/salesforce/tests/test_RetrieveReportsAndDashboards.py +56 -0
  556. cumulusci/tasks/salesforce/tests/test_RetrieveUnpackaged.py +21 -0
  557. cumulusci/tasks/salesforce/tests/test_SOQLQuery.py +30 -0
  558. cumulusci/tasks/salesforce/tests/test_UninstallLocal.py +15 -0
  559. cumulusci/tasks/salesforce/tests/test_UninstallLocalBundles.py +19 -0
  560. cumulusci/tasks/salesforce/tests/test_UninstallLocalNamespacedBundles.py +22 -0
  561. cumulusci/tasks/salesforce/tests/test_UninstallPackage.py +19 -0
  562. cumulusci/tasks/salesforce/tests/test_UninstallPackaged.py +66 -0
  563. cumulusci/tasks/salesforce/tests/test_UninstallPackagedIncremental.py +127 -0
  564. cumulusci/tasks/salesforce/tests/test_activate_flow.py +132 -0
  565. cumulusci/tasks/salesforce/tests/test_base_tasks.py +110 -0
  566. cumulusci/tasks/salesforce/tests/test_check_components.py +445 -0
  567. cumulusci/tasks/salesforce/tests/test_composite.py +250 -0
  568. cumulusci/tasks/salesforce/tests/test_create_permission_sets.py +41 -0
  569. cumulusci/tasks/salesforce/tests/test_custom_settings.py +227 -0
  570. cumulusci/tasks/salesforce/tests/test_custom_settings_wait.py +174 -0
  571. cumulusci/tasks/salesforce/tests/test_describemetadatatypes.py +18 -0
  572. cumulusci/tasks/salesforce/tests/test_enable_prediction.py +240 -0
  573. cumulusci/tasks/salesforce/tests/test_insert_record.py +110 -0
  574. cumulusci/tasks/salesforce/tests/test_install_package_version.py +464 -0
  575. cumulusci/tasks/salesforce/tests/test_network_member_group.py +444 -0
  576. cumulusci/tasks/salesforce/tests/test_nonsourcetracking.py +235 -0
  577. cumulusci/tasks/salesforce/tests/test_org_settings.py +407 -0
  578. cumulusci/tasks/salesforce/tests/test_profiles.py +202 -0
  579. cumulusci/tasks/salesforce/tests/test_retrieve_profile.py +287 -0
  580. cumulusci/tasks/salesforce/tests/test_salesforce_files.py +228 -0
  581. cumulusci/tasks/salesforce/tests/test_sourcetracking.py +350 -0
  582. cumulusci/tasks/salesforce/tests/test_trigger_handlers.py +300 -0
  583. cumulusci/tasks/salesforce/tests/test_update_dependencies.py +509 -0
  584. cumulusci/tasks/salesforce/tests/util.py +79 -0
  585. cumulusci/tasks/salesforce/trigger_handlers.py +119 -0
  586. cumulusci/tasks/salesforce/uninstall_packaged_incremental.py +136 -0
  587. cumulusci/tasks/salesforce/update_dependencies.py +290 -0
  588. cumulusci/tasks/salesforce/update_profile.py +339 -0
  589. cumulusci/tasks/salesforce/users/permsets.py +227 -0
  590. cumulusci/tasks/salesforce/users/photos.py +162 -0
  591. cumulusci/tasks/salesforce/users/tests/photo.mock.txt +1 -0
  592. cumulusci/tasks/salesforce/users/tests/test_permsets.py +950 -0
  593. cumulusci/tasks/salesforce/users/tests/test_photos.py +373 -0
  594. cumulusci/tasks/sample_data/capture_sample_data.py +77 -0
  595. cumulusci/tasks/sample_data/load_sample_data.py +85 -0
  596. cumulusci/tasks/sample_data/test_capture_sample_data.py +117 -0
  597. cumulusci/tasks/sample_data/test_load_sample_data.py +121 -0
  598. cumulusci/tasks/sfdx.py +83 -0
  599. cumulusci/tasks/tests/__init__.py +1 -0
  600. cumulusci/tasks/tests/conftest.py +30 -0
  601. cumulusci/tasks/tests/test_command.py +129 -0
  602. cumulusci/tasks/tests/test_connectedapp.py +236 -0
  603. cumulusci/tasks/tests/test_create_package_version.py +847 -0
  604. cumulusci/tasks/tests/test_datadictionary.py +1575 -0
  605. cumulusci/tasks/tests/test_dx_convert_from.py +60 -0
  606. cumulusci/tasks/tests/test_metadeploy.py +624 -0
  607. cumulusci/tasks/tests/test_metaxml.py +99 -0
  608. cumulusci/tasks/tests/test_promote_package_version.py +488 -0
  609. cumulusci/tasks/tests/test_pushfails.py +96 -0
  610. cumulusci/tasks/tests/test_salesforce.py +72 -0
  611. cumulusci/tasks/tests/test_sfdx.py +105 -0
  612. cumulusci/tasks/tests/test_util.py +207 -0
  613. cumulusci/tasks/util.py +261 -0
  614. cumulusci/tasks/vcs/__init__.py +19 -0
  615. cumulusci/tasks/vcs/commit_status.py +58 -0
  616. cumulusci/tasks/vcs/create_commit_status.py +37 -0
  617. cumulusci/tasks/vcs/download_extract.py +199 -0
  618. cumulusci/tasks/vcs/merge.py +298 -0
  619. cumulusci/tasks/vcs/publish.py +207 -0
  620. cumulusci/tasks/vcs/pull_request.py +9 -0
  621. cumulusci/tasks/vcs/release.py +134 -0
  622. cumulusci/tasks/vcs/release_report.py +105 -0
  623. cumulusci/tasks/vcs/tag.py +31 -0
  624. cumulusci/tasks/vcs/tests/github/test_commit_status.py +196 -0
  625. cumulusci/tasks/vcs/tests/github/test_download_extract.py +896 -0
  626. cumulusci/tasks/vcs/tests/github/test_merge.py +1118 -0
  627. cumulusci/tasks/vcs/tests/github/test_publish.py +823 -0
  628. cumulusci/tasks/vcs/tests/github/test_pull_request.py +29 -0
  629. cumulusci/tasks/vcs/tests/github/test_release.py +390 -0
  630. cumulusci/tasks/vcs/tests/github/test_release_report.py +109 -0
  631. cumulusci/tasks/vcs/tests/github/test_tag.py +90 -0
  632. cumulusci/tasks/vlocity/exceptions.py +2 -0
  633. cumulusci/tasks/vlocity/tests/test_vlocity.py +283 -0
  634. cumulusci/tasks/vlocity/vlocity.py +342 -0
  635. cumulusci/tests/__init__.py +1 -0
  636. cumulusci/tests/cassettes/GET_sobjects_Account_PersonAccount_describe.yaml +18 -0
  637. cumulusci/tests/cassettes/TestIntegrationInfrastructure.test_integration_tests.yaml +19 -0
  638. cumulusci/tests/pytest_plugins/pytest_sf_orgconnect.py +307 -0
  639. cumulusci/tests/pytest_plugins/pytest_sf_vcr.py +275 -0
  640. cumulusci/tests/pytest_plugins/pytest_sf_vcr_serializer.py +160 -0
  641. cumulusci/tests/pytest_plugins/pytest_typeguard.py +5 -0
  642. cumulusci/tests/pytest_plugins/test_vcr_string_compressor.py +49 -0
  643. cumulusci/tests/pytest_plugins/vcr_string_compressor.py +97 -0
  644. cumulusci/tests/shared_cassettes/GET_sobjects_Account_describe.yaml +18 -0
  645. cumulusci/tests/shared_cassettes/GET_sobjects_Case_describe.yaml +18 -0
  646. cumulusci/tests/shared_cassettes/GET_sobjects_Contact_describe.yaml +4838 -0
  647. cumulusci/tests/shared_cassettes/GET_sobjects_Custom__c_describe.yaml +242 -0
  648. cumulusci/tests/shared_cassettes/GET_sobjects_Event_describe.yaml +19 -0
  649. cumulusci/tests/shared_cassettes/GET_sobjects_Global_describe.yaml +1338 -0
  650. cumulusci/tests/shared_cassettes/GET_sobjects_Lead_describe.yaml +18 -0
  651. cumulusci/tests/shared_cassettes/GET_sobjects_OpportunityContactRole_describe.yaml +34 -0
  652. cumulusci/tests/shared_cassettes/GET_sobjects_Opportunity_describe.yaml +1261 -0
  653. cumulusci/tests/shared_cassettes/GET_sobjects_Organization.yaml +49 -0
  654. cumulusci/tests/shared_cassettes/vcr_string_templates/batchInfoList_xml.tpl +15 -0
  655. cumulusci/tests/shared_cassettes/vcr_string_templates/batchInfo_xml.tpl +13 -0
  656. cumulusci/tests/shared_cassettes/vcr_string_templates/jobInfo_insert_xml.tpl +24 -0
  657. cumulusci/tests/shared_cassettes/vcr_string_templates/jobInfo_upsert_xml.tpl +25 -0
  658. cumulusci/tests/test_entry_points.py +20 -0
  659. cumulusci/tests/test_integration_infrastructure.py +131 -0
  660. cumulusci/tests/test_main.py +9 -0
  661. cumulusci/tests/test_schema.py +32 -0
  662. cumulusci/tests/test_utils.py +657 -0
  663. cumulusci/tests/test_vcr_serializer.py +134 -0
  664. cumulusci/tests/uncompressed_cassette.yaml +83 -0
  665. cumulusci/tests/util.py +344 -0
  666. cumulusci/utils/__init__.py +731 -0
  667. cumulusci/utils/classutils.py +9 -0
  668. cumulusci/utils/collections.py +32 -0
  669. cumulusci/utils/deprecation.py +11 -0
  670. cumulusci/utils/encryption.py +31 -0
  671. cumulusci/utils/fileutils.py +295 -0
  672. cumulusci/utils/git.py +142 -0
  673. cumulusci/utils/http/multi_request.py +214 -0
  674. cumulusci/utils/http/requests_utils.py +103 -0
  675. cumulusci/utils/http/tests/cassettes/ManualEditTestCompositeParallelSalesforce.test_http_headers.yaml +32 -0
  676. cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_composite_parallel_salesforce.yaml +65 -0
  677. cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_errors.yaml +24 -0
  678. cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_reference_ids.yaml +49 -0
  679. cumulusci/utils/http/tests/test_multi_request.py +255 -0
  680. cumulusci/utils/iterators.py +21 -0
  681. cumulusci/utils/logging.py +128 -0
  682. cumulusci/utils/metaprogramming.py +10 -0
  683. cumulusci/utils/options.py +138 -0
  684. cumulusci/utils/parallel/queries_in_parallel/run_queries_in_parallel.py +29 -0
  685. cumulusci/utils/parallel/queries_in_parallel/tests/test_run_queries_in_parallel.py +50 -0
  686. cumulusci/utils/parallel/task_worker_queues/parallel_worker.py +238 -0
  687. cumulusci/utils/parallel/task_worker_queues/parallel_worker_queue.py +243 -0
  688. cumulusci/utils/parallel/task_worker_queues/tests/test_parallel_worker.py +353 -0
  689. cumulusci/utils/salesforce/count_sobjects.py +46 -0
  690. cumulusci/utils/salesforce/soql.py +17 -0
  691. cumulusci/utils/salesforce/tests/cassettes/ManualEdit_TestCountSObjects.test_count_sobjects__network_errors.yaml +23 -0
  692. cumulusci/utils/salesforce/tests/cassettes/TestCountSObjects.test_count_sobjects__errors.yaml +33 -0
  693. cumulusci/utils/salesforce/tests/cassettes/TestCountSObjects.test_count_sobjects_simple.yaml +29 -0
  694. cumulusci/utils/salesforce/tests/test_count_sobjects.py +29 -0
  695. cumulusci/utils/salesforce/tests/test_soql.py +30 -0
  696. cumulusci/utils/tests/cassettes/ManualEditTestDescribeOrg.test_minimal_schema.yaml +36 -0
  697. cumulusci/utils/tests/cassettes/ManualEdit_test_describe_to_sql.yaml +191 -0
  698. cumulusci/utils/tests/test_fileutils.py +284 -0
  699. cumulusci/utils/tests/test_git.py +85 -0
  700. cumulusci/utils/tests/test_logging.py +70 -0
  701. cumulusci/utils/tests/test_option_parsing.py +188 -0
  702. cumulusci/utils/tests/test_org_schema.py +691 -0
  703. cumulusci/utils/tests/test_org_schema_models.py +79 -0
  704. cumulusci/utils/tests/test_waiting.py +25 -0
  705. cumulusci/utils/version_strings.py +391 -0
  706. cumulusci/utils/waiting.py +42 -0
  707. cumulusci/utils/xml/__init__.py +91 -0
  708. cumulusci/utils/xml/metadata_tree.py +299 -0
  709. cumulusci/utils/xml/robot_xml.py +114 -0
  710. cumulusci/utils/xml/salesforce_encoding.py +100 -0
  711. cumulusci/utils/xml/test/test_metadata_tree.py +251 -0
  712. cumulusci/utils/xml/test/test_salesforce_encoding.py +173 -0
  713. cumulusci/utils/yaml/cumulusci_yml.py +401 -0
  714. cumulusci/utils/yaml/model_parser.py +156 -0
  715. cumulusci/utils/yaml/safer_loader.py +74 -0
  716. cumulusci/utils/yaml/tests/bad_cci.yml +5 -0
  717. cumulusci/utils/yaml/tests/cassettes/TestCumulusciYml.test_validate_url__with_errors.yaml +20 -0
  718. cumulusci/utils/yaml/tests/test_cumulusci_yml.py +286 -0
  719. cumulusci/utils/yaml/tests/test_model_parser.py +175 -0
  720. cumulusci/utils/yaml/tests/test_safer_loader.py +88 -0
  721. cumulusci/utils/ziputils.py +61 -0
  722. cumulusci/vcs/base.py +143 -0
  723. cumulusci/vcs/bootstrap.py +272 -0
  724. cumulusci/vcs/github/__init__.py +24 -0
  725. cumulusci/vcs/github/adapter.py +689 -0
  726. cumulusci/vcs/github/release_notes/generator.py +219 -0
  727. cumulusci/vcs/github/release_notes/parser.py +151 -0
  728. cumulusci/vcs/github/release_notes/provider.py +143 -0
  729. cumulusci/vcs/github/service.py +569 -0
  730. cumulusci/vcs/github/tests/test_adapter.py +138 -0
  731. cumulusci/vcs/github/tests/test_service.py +408 -0
  732. cumulusci/vcs/models.py +586 -0
  733. cumulusci/vcs/tests/conftest.py +41 -0
  734. cumulusci/vcs/tests/dummy_service.py +241 -0
  735. cumulusci/vcs/tests/test_vcs_base.py +687 -0
  736. cumulusci/vcs/tests/test_vcs_bootstrap.py +727 -0
  737. cumulusci/vcs/utils/__init__.py +31 -0
  738. cumulusci/vcs/vcs_source.py +287 -0
  739. cumulusci_plus-5.0.0.dist-info/METADATA +145 -0
  740. cumulusci_plus-5.0.0.dist-info/RECORD +744 -0
  741. cumulusci_plus-5.0.0.dist-info/WHEEL +4 -0
  742. cumulusci_plus-5.0.0.dist-info/entry_points.txt +3 -0
  743. cumulusci_plus-5.0.0.dist-info/licenses/AUTHORS.rst +41 -0
  744. cumulusci_plus-5.0.0.dist-info/licenses/LICENSE +30 -0
@@ -0,0 +1,778 @@
1
+ import base64
2
+ import io
3
+ import json
4
+ import pathlib
5
+ import zipfile
6
+ from typing import List, Optional
7
+
8
+ from pydantic import BaseModel, validator
9
+ from simple_salesforce.exceptions import SalesforceMalformedRequest
10
+
11
+ from cumulusci.core.config.util import get_devhub_config
12
+ from cumulusci.core.dependencies.base import UnmanagedDependency, UnmanagedVcsDependency
13
+ from cumulusci.core.dependencies.dependencies import (
14
+ PackageNamespaceVersionDependency,
15
+ PackageVersionIdDependency,
16
+ )
17
+ from cumulusci.core.dependencies.resolvers import get_static_dependencies
18
+ from cumulusci.core.dependencies.utils import TaskContext
19
+ from cumulusci.core.enums import StrEnum
20
+ from cumulusci.core.exceptions import (
21
+ CumulusCIUsageError,
22
+ DependencyLookupError,
23
+ PackageUploadFailure,
24
+ TaskOptionsError,
25
+ VcsException,
26
+ )
27
+ from cumulusci.core.sfdx import convert_sfdx_source
28
+ from cumulusci.core.utils import process_bool_arg
29
+ from cumulusci.core.versions import PackageType, PackageVersionNumber, VersionTypeEnum
30
+ from cumulusci.salesforce_api.package_zip import (
31
+ BasePackageZipBuilder,
32
+ MetadataPackageZipBuilder,
33
+ )
34
+ from cumulusci.salesforce_api.utils import get_simple_salesforce_connection
35
+ from cumulusci.tasks.salesforce.BaseSalesforceApiTask import BaseSalesforceApiTask
36
+ from cumulusci.tasks.salesforce.org_settings import build_settings_package
37
+ from cumulusci.utils.salesforce.soql import (
38
+ format_subscriber_package_version_where_clause,
39
+ )
40
+ from cumulusci.vcs.bootstrap import (
41
+ get_latest_tag,
42
+ get_repo_from_config,
43
+ get_version_id_from_tag,
44
+ )
45
+
46
+ PERSISTENT_ORG_ERROR = """
47
+ Target org scratch org definition file missing. Persistent orgs like a Dev Hub can't be used for 2GP package uploads.
48
+ """
49
+
50
+
51
+ class PackageTypeEnum(StrEnum):
52
+ managed = "Managed"
53
+ unlocked = "Unlocked"
54
+
55
+
56
+ class PackageConfig(BaseModel):
57
+ package_name: str
58
+ description: str = ""
59
+ package_type: PackageTypeEnum
60
+ org_dependent: bool = False
61
+ post_install_script: Optional[str] = None
62
+ uninstall_script: Optional[str] = None
63
+ namespace: Optional[str] = None
64
+ version_name: str
65
+ version_base: Optional[str] = None
66
+ version_type: VersionTypeEnum = VersionTypeEnum.minor
67
+
68
+ @validator("org_dependent")
69
+ def org_dependent_must_be_unlocked(cls, v, values):
70
+ if v and values["package_type"] != PackageTypeEnum.unlocked:
71
+ raise ValueError("Only unlocked packages can be org-dependent.")
72
+ return v
73
+
74
+ @validator("post_install_script")
75
+ def post_install_script_must_be_managed(cls, v, values):
76
+ if v and values["package_type"] != PackageTypeEnum.managed:
77
+ raise ValueError("Only managed packages can have a post-install script.")
78
+ return v
79
+
80
+ @validator("uninstall_script")
81
+ def uninstall_script_must_be_managed(cls, v, values):
82
+ if v and values["package_type"] != PackageTypeEnum.managed:
83
+ raise ValueError("Only managed packages can have an uninstall script.")
84
+ return v
85
+
86
+
87
+ class CreatePackageVersion(BaseSalesforceApiTask):
88
+ """Creates a new second-generation package version.
89
+
90
+ If a package named ``package_name`` does not yet exist in the Dev Hub, it will be created.
91
+ """
92
+
93
+ task_docs = """
94
+ Facilitates the upload of 2GP (second-generation packaging)
95
+ package versions using CumulusCI.
96
+
97
+ The target org is used both for looking up dependency package IDs and
98
+ configuring the build org during the package upload. Ensure the specified
99
+ org is a scratch org with the correct configuration for these purposes.
100
+ """
101
+
102
+ task_options = {
103
+ "package_name": {"description": "Name of package"},
104
+ "package_type": {
105
+ "description": "Package type (Unlocked or Managed)",
106
+ "required": True,
107
+ },
108
+ "namespace": {"description": "Package namespace"},
109
+ "version_name": {"description": "Version name"},
110
+ "version_base": {
111
+ "description": "The version number to use as a base before incrementing. "
112
+ "Optional; defaults to the highest existing version number of this package. "
113
+ "Can be set to ``latest_vcs_release`` to use the version of the most recent release published to GitHub."
114
+ },
115
+ "version_type": {
116
+ "description": "The part of the version number to increment. "
117
+ "Options are major, minor, patch, build. Defaults to build"
118
+ },
119
+ "skip_validation": {
120
+ "description": "If true, skip validation of the package version. Default: false. "
121
+ "Skipping validation creates packages more quickly, but they cannot be promoted for release."
122
+ },
123
+ "org_dependent": {
124
+ "description": "If true, create an org-dependent unlocked package. Default: false."
125
+ },
126
+ "post_install_script": {
127
+ "description": "Post-install script (for managed packages)",
128
+ },
129
+ "uninstall_script": {
130
+ "description": "Uninstall script (for managed packages)",
131
+ },
132
+ "install_key": {
133
+ "description": "Install key for package. Default is no install key."
134
+ },
135
+ "force_upload": {
136
+ "description": "If true, force creating a new package version even if one with the same contents already exists"
137
+ },
138
+ "static_resource_path": {
139
+ "description": "The path where decompressed static resources are stored. "
140
+ "Any subdirectories found will be zipped and added to the staticresources directory of the build."
141
+ },
142
+ "ancestor_id": {
143
+ "description": "The 04t Id to use for the ancestor of this package. "
144
+ "Optional; defaults to no ancestor specified. "
145
+ "Can be set to ``latest_vcs_release`` to use the most recent production version published to GitHub."
146
+ },
147
+ "resolution_strategy": {
148
+ "description": "The name of a sequence of resolution_strategy "
149
+ "(from project__dependency_resolutions) to apply to dynamic dependencies. Defaults to 'production'."
150
+ },
151
+ "create_unlocked_dependency_packages": {
152
+ "description": "If True, create unlocked packages for unpackaged metadata in this project and dependencies. "
153
+ "Defaults to False."
154
+ },
155
+ }
156
+
157
+ def _init_options(self, kwargs):
158
+ super()._init_options(kwargs)
159
+
160
+ if not self.org_config.config_file:
161
+ raise TaskOptionsError(PERSISTENT_ORG_ERROR)
162
+
163
+ # Allow these fields to be explicitly set to blanks
164
+ # so that unlocked builds can override an otherwise-configured
165
+ # postinstall script
166
+ if "post_install_script" in self.options:
167
+ post_install_script = self.options["post_install_script"]
168
+ else:
169
+ post_install_script = self.project_config.project__package__install_class
170
+
171
+ if "uninstall_script" in self.options:
172
+ uninstall_script = self.options["uninstall_script"]
173
+ else:
174
+ uninstall_script = self.project_config.project__package__uninstall_class
175
+
176
+ self.package_config = PackageConfig(
177
+ package_name=self.options.get("package_name")
178
+ or self.project_config.project__package__name,
179
+ package_type=self.options.get("package_type")
180
+ or self.project_config.project__package__type,
181
+ org_dependent=self.options.get("org_dependent", False),
182
+ post_install_script=post_install_script,
183
+ uninstall_script=uninstall_script,
184
+ namespace=self.options.get("namespace")
185
+ or self.project_config.project__package__namespace,
186
+ version_name=self.options.get("version_name") or "Release",
187
+ version_base=self.options.get("version_base"),
188
+ version_type=self.options.get("version_type") or VersionTypeEnum("build"),
189
+ )
190
+ self.options["skip_validation"] = process_bool_arg(
191
+ self.options.get("skip_validation") or False
192
+ )
193
+ self.options["force_upload"] = process_bool_arg(
194
+ self.options.get("force_upload") or False
195
+ )
196
+ self.options["create_unlocked_dependency_packages"] = process_bool_arg(
197
+ self.options.get("create_unlocked_dependency_packages") or False
198
+ )
199
+
200
+ def _init_task(self):
201
+ self.tooling = get_simple_salesforce_connection(
202
+ self.project_config,
203
+ get_devhub_config(self.project_config),
204
+ api_version=self.project_config.project__package__api_version,
205
+ base_url="tooling",
206
+ )
207
+ self.context = TaskContext(self.org_config, self.project_config, self.logger)
208
+
209
+ def _run_task(self):
210
+ """Creates a new 2GP package version.
211
+
212
+ 1. Create package if not found in Dev Hub.
213
+ 2. Request creation of package version.
214
+ 3. Wait for completion.
215
+ 4. Collect package information as return values.
216
+ """
217
+ # find existing package in Dev Hub, or create one if necessary
218
+ self.package_id = self._get_or_create_package(self.package_config)
219
+ self.return_values["package_id"] = self.package_id
220
+
221
+ # submit request to create package version
222
+ options = {
223
+ "package_type": self.package_config.package_type.value,
224
+ "namespace_inject": self.package_config.namespace,
225
+ "namespaced_org": self.package_config.namespace is not None,
226
+ }
227
+ if "static_resource_path" in self.options:
228
+ options["static_resource_path"] = self.options["static_resource_path"]
229
+
230
+ package_zip_builder = None
231
+ with convert_sfdx_source(
232
+ self.project_config.default_package_path,
233
+ None,
234
+ self.logger,
235
+ ) as path:
236
+ package_zip_builder = MetadataPackageZipBuilder(
237
+ path=path,
238
+ name=self.package_config.package_name,
239
+ options=options,
240
+ context=self.context,
241
+ )
242
+
243
+ ancestor_id = self._resolve_ancestor_id(self.options.get("ancestor_id"))
244
+
245
+ self.request_id = self._create_version_request(
246
+ self.package_id,
247
+ self.package_config,
248
+ package_zip_builder,
249
+ ancestor_id,
250
+ self.options["skip_validation"],
251
+ )
252
+ self.return_values["request_id"] = self.request_id
253
+
254
+ # wait for request to complete
255
+ self._poll()
256
+ self.return_values["package2_version_id"] = self.package_version_id
257
+
258
+ # get the new version number from Package2Version
259
+ res = self.tooling.query(
260
+ f"SELECT MajorVersion, MinorVersion, PatchVersion, BuildNumber, SubscriberPackageVersionId FROM Package2Version WHERE Id='{self.package_version_id}'"
261
+ )
262
+ package2_version = res["records"][0]
263
+ self.return_values["subscriber_package_version_id"] = package2_version[
264
+ "SubscriberPackageVersionId"
265
+ ]
266
+ self.return_values["version_number"] = PackageVersionNumber(
267
+ **package2_version
268
+ ).format()
269
+
270
+ # get the new version's dependencies from SubscriberPackageVersion
271
+ where_clause = format_subscriber_package_version_where_clause(
272
+ package2_version["SubscriberPackageVersionId"],
273
+ self.options.get("install_key"),
274
+ )
275
+ res = self.tooling.query(
276
+ "SELECT Dependencies FROM SubscriberPackageVersion " f"WHERE {where_clause}"
277
+ )
278
+ self.return_values["dependencies"] = self._prepare_cci_dependencies(
279
+ res["records"][0]["Dependencies"]
280
+ )
281
+
282
+ self.logger.info("Created package version:")
283
+ self.logger.info(f" Package2 Id: {self.package_id}")
284
+ self.logger.info(f" Package2Version Id: {self.package_version_id}")
285
+ self.logger.info(
286
+ f" SubscriberPackageVersion Id: {self.return_values['subscriber_package_version_id']}"
287
+ )
288
+ self.logger.info(f" Version Number: {self.return_values['version_number']}")
289
+ self.logger.info(f" Dependencies: {self.return_values['dependencies']}")
290
+
291
+ def _get_or_create_package(self, package_config: PackageConfig):
292
+ """Find or create the Package2
293
+
294
+ Checks the Dev Hub for an existing, non-deprecated 2GP package
295
+ with matching name, type, and namespace.
296
+ """
297
+ message = f"Checking for existing {package_config.package_type} Package named {package_config.package_name}"
298
+ query = (
299
+ f"SELECT Id, ContainerOptions FROM Package2 WHERE IsDeprecated = FALSE "
300
+ f"AND ContainerOptions='{package_config.package_type}' "
301
+ f"AND IsOrgDependent={package_config.org_dependent} "
302
+ f"AND Name='{package_config.package_name}'"
303
+ )
304
+ if package_config.namespace:
305
+ query += f" AND NamespacePrefix='{package_config.namespace}'"
306
+ message += f" with namespace {package_config.namespace}"
307
+ else:
308
+ query += " AND NamespacePrefix=null"
309
+ self.logger.info(message)
310
+ try:
311
+ res = self.tooling.query(query)
312
+ except SalesforceMalformedRequest as err:
313
+ if "Object type 'Package2' is not supported" in err.content[0]["message"]:
314
+ raise TaskOptionsError(
315
+ "This org does not have a Dev Hub with 2nd-generation packaging enabled. "
316
+ "Make sure you are using the correct org and/or check the Dev Hub settings in Setup."
317
+ )
318
+ raise # pragma: no cover
319
+ if res["size"] > 1:
320
+ raise TaskOptionsError(
321
+ f"Found {res['size']} packages with the same name, namespace, and package_type"
322
+ )
323
+ if res["size"] == 1:
324
+ existing_package = res["records"][0]
325
+ if existing_package["ContainerOptions"] != package_config.package_type:
326
+ raise PackageUploadFailure(
327
+ f"Duplicate Package: {existing_package['ContainerOptions']} package with id "
328
+ f"{existing_package['Id']} has the same name ({package_config.package_name}) "
329
+ "for this namespace but has a different package type"
330
+ )
331
+ package_id = existing_package["Id"]
332
+ self.logger.info(f"Found {package_id}")
333
+ return package_id
334
+
335
+ self.logger.info("No existing package found, creating the package")
336
+ Package2 = self._get_tooling_object("Package2")
337
+ package = Package2.create(
338
+ {
339
+ "ContainerOptions": package_config.package_type,
340
+ "IsOrgDependent": package_config.org_dependent,
341
+ "Name": package_config.package_name,
342
+ "Description": package_config.description,
343
+ "NamespacePrefix": package_config.namespace,
344
+ }
345
+ )
346
+ return package["id"]
347
+
348
+ def _create_version_request(
349
+ self,
350
+ package_id: str,
351
+ package_config: PackageConfig,
352
+ package_zip_builder: BasePackageZipBuilder,
353
+ ancestor_id: str = "",
354
+ skip_validation: bool = False,
355
+ dependencies: list = None,
356
+ ):
357
+ # Prepare the VersionInfo file
358
+ version_bytes = io.BytesIO()
359
+ version_info = zipfile.ZipFile(version_bytes, "w", zipfile.ZIP_DEFLATED)
360
+ try:
361
+ # Add the package.zip
362
+ package_hash = package_zip_builder.as_hash()
363
+ version_info.writestr("package.zip", package_zip_builder.as_bytes())
364
+
365
+ if not self.options["force_upload"]:
366
+ # Check for an existing package with the same contents
367
+ res = self.tooling.query(
368
+ "SELECT Id "
369
+ "FROM Package2VersionCreateRequest "
370
+ f"WHERE Package2Id = '{package_id}' "
371
+ "AND Status != 'Error' "
372
+ f"AND SkipValidation = {str(skip_validation)} "
373
+ f"AND Tag = 'hash:{package_hash}' "
374
+ "ORDER BY CreatedDate DESC"
375
+ )
376
+ if res["size"] > 0:
377
+ self.logger.info(
378
+ "Found existing request for package with the same metadata. Using existing package."
379
+ )
380
+ return res["records"][0]["Id"]
381
+
382
+ # Create the package descriptor
383
+ version_number = self._get_base_version_number(
384
+ package_config.version_base, package_id
385
+ ).increment(package_config.version_type)
386
+
387
+ package_descriptor = {
388
+ "id": package_id,
389
+ "path": "",
390
+ "versionName": package_config.version_name,
391
+ "versionNumber": version_number.format(),
392
+ "ancestorId": ancestor_id,
393
+ }
394
+
395
+ if package_config.post_install_script:
396
+ package_descriptor[
397
+ "postInstallScript"
398
+ ] = package_config.post_install_script
399
+ if package_config.uninstall_script:
400
+ package_descriptor["uninstallScript"] = package_config.uninstall_script
401
+
402
+ # Add org shape
403
+ with open(self.org_config.config_file, "r") as f:
404
+ scratch_org_def = json.load(f)
405
+ # See https://github.com/forcedotcom/packaging/blob/main/src/package/packageVersionCreate.ts#L358
406
+ # Note that we handle orgPreferences below by converting to settings,
407
+ # in build_settings_package()
408
+ for key in (
409
+ "country",
410
+ "edition",
411
+ "language",
412
+ "features",
413
+ "snapshot",
414
+ "release",
415
+ "sourceOrg",
416
+ ):
417
+ if key in scratch_org_def:
418
+ package_descriptor[key] = scratch_org_def[key]
419
+
420
+ # Add settings
421
+ if "settings" in scratch_org_def or "objectSettings" in scratch_org_def:
422
+ with build_settings_package(
423
+ scratch_org_def.get("settings"),
424
+ scratch_org_def.get("objectSettings"),
425
+ self.project_config.project__package__api_version,
426
+ ) as path:
427
+ settings_zip_builder = MetadataPackageZipBuilder(
428
+ path=path, context=self.context
429
+ )
430
+ version_info.writestr(
431
+ "settings.zip", settings_zip_builder.as_bytes()
432
+ )
433
+
434
+ # Add the dependencies for the package
435
+ is_dependency = package_config is not self.package_config
436
+ if (
437
+ not (package_config.org_dependent or skip_validation)
438
+ and not is_dependency
439
+ ):
440
+ self.logger.info("Determining dependencies for package")
441
+ dependencies = self._get_dependencies()
442
+ if dependencies:
443
+ package_descriptor["dependencies"] = dependencies
444
+
445
+ # Add package descriptor to version info
446
+ version_info.writestr(
447
+ "package2-descriptor.json", json.dumps(package_descriptor)
448
+ )
449
+ finally:
450
+ version_info.close()
451
+ version_info = base64.b64encode(version_bytes.getvalue()).decode("utf-8")
452
+ Package2CreateVersionRequest = self._get_tooling_object(
453
+ "Package2VersionCreateRequest"
454
+ )
455
+ request = {
456
+ "Package2Id": package_id,
457
+ "SkipValidation": skip_validation,
458
+ "Tag": f"hash:{package_hash}",
459
+ "VersionInfo": version_info,
460
+ "CalculateCodeCoverage": not skip_validation,
461
+ }
462
+
463
+ install_key = self.options.get("install_key")
464
+ if install_key:
465
+ request["InstallKey"] = install_key
466
+ self.return_values["install_key"] = install_key
467
+
468
+ self.logger.info(
469
+ f"Requesting creation of package version {version_number.format()} "
470
+ f"for package {package_config.package_name} ({package_id})"
471
+ )
472
+ response = Package2CreateVersionRequest.create(request)
473
+ self.logger.info(
474
+ f"Package2VersionCreateRequest created with id {response['id']}"
475
+ )
476
+ return response["id"]
477
+
478
+ def _resolve_ancestor_id(self, spv_id: Optional[str] = None) -> str:
479
+ """
480
+ If an ancestor_id (04t) is not specified, get it
481
+ from the latest production release.
482
+
483
+ @param spv_id The SubscriberPackageVersionId (04t) that is the ancestor
484
+ to the version being created.
485
+ """
486
+ if not spv_id:
487
+ return ""
488
+ elif self.package_config.package_type == PackageTypeEnum.unlocked:
489
+ raise CumulusCIUsageError(
490
+ "Cannot specify an ancestor for Unlocked packages."
491
+ )
492
+ elif spv_id.startswith("04t"):
493
+ return self._convert_ancestor_id(spv_id)
494
+ elif spv_id == "latest_github_release" or spv_id == "latest_vcs_release":
495
+ self.repo = get_repo_from_config(self.project_config, self.options)
496
+
497
+ try:
498
+ tag_name = get_latest_tag(self.repo, beta=False)
499
+ except VcsException:
500
+ # No release found
501
+ return ""
502
+
503
+ spv_id = get_version_id_from_tag(self.repo, tag_name)
504
+ self.logger.info(f"Resolved ancestor to version: {spv_id}")
505
+ self.logger.info("")
506
+
507
+ return self._convert_ancestor_id(spv_id)
508
+ else:
509
+ raise TaskOptionsError(f"Unrecognized value for ancestor_id: {spv_id}")
510
+
511
+ def _convert_ancestor_id(self, ancestor_id: str) -> str:
512
+ """Given a SubscriberPackageVersionId (04t) find
513
+ the corresponding Package2VersionId (05i).
514
+ See: https://github.com/forcedotcom/salesforce-alm/blob/83745351670a701762c6ecc926885564b8853357/src/lib/package/packageUtils.ts#L517
515
+
516
+ @param ancestor_id A SubscriberPackageVersionId (04t)
517
+ @returns the corresponding Package2VersionId (05i) or an empty string
518
+ if no Package2Version is found.
519
+ """
520
+ package_2_version_id = ""
521
+ res = self.tooling.query(
522
+ f"SELECT Id FROM Package2Version WHERE SubscriberPackageVersionId='{ancestor_id}'"
523
+ )
524
+ if res["size"] > 0:
525
+ package_2_version_id = res["records"][0]["Id"]
526
+ self.logger.info(
527
+ f"Converted ancestor_id to corresponding Package2Version: {package_2_version_id}"
528
+ )
529
+ self.logger.info("")
530
+
531
+ return package_2_version_id
532
+
533
+ def _get_base_version_number(
534
+ self, version_base: Optional[str], package_id: str
535
+ ) -> PackageVersionNumber:
536
+ """Determine the "base version" of the package (existing version to be incremented)"""
537
+ if version_base is None:
538
+ # Default: Get the highest existing version of the package
539
+ res = self.tooling.query(
540
+ "SELECT MajorVersion, MinorVersion, PatchVersion, BuildNumber, IsReleased "
541
+ "FROM Package2Version "
542
+ f"WHERE Package2Id='{package_id}' "
543
+ "ORDER BY MajorVersion DESC, MinorVersion DESC, PatchVersion DESC, BuildNumber DESC "
544
+ "LIMIT 1"
545
+ )
546
+ if res["size"]:
547
+ return PackageVersionNumber(
548
+ **res["records"][0], package_type=PackageType.SECOND_GEN
549
+ )
550
+ elif (
551
+ version_base == "latest_github_release"
552
+ or version_base == "latest_vcs_release"
553
+ ):
554
+ # Get the version of the latest github release
555
+ try:
556
+ # Because we are building a 2GP (which has an incrementable version number)
557
+ # but the latest package version may in fact be a 1GP, force this version number
558
+ # to be treated as a 2GP so we can increment it.
559
+ return PackageVersionNumber.parse(
560
+ str(self.project_config.get_latest_version()),
561
+ package_type=PackageType.SECOND_GEN,
562
+ )
563
+ except VcsException:
564
+ # handle case where there isn't a release yet
565
+ pass
566
+ else:
567
+ return PackageVersionNumber.parse(
568
+ version_base, package_type=PackageType.SECOND_GEN
569
+ )
570
+ return PackageVersionNumber(package_type=PackageType.SECOND_GEN)
571
+
572
+ def _get_dependencies(self):
573
+ """Resolve dependencies into SubscriberPackageVersionIds (04t prefix)"""
574
+ dependencies = get_static_dependencies(
575
+ self.project_config,
576
+ resolution_strategy=self.options.get("resolution_strategy") or "production",
577
+ )
578
+
579
+ # If any dependencies are expressed as a 1gp namespace + version,
580
+ # we need to convert those to 04t package version ids,
581
+ # for which we need an org with the packages installed.
582
+ if self._has_1gp_namespace_dependency(dependencies):
583
+ dependencies = self.org_config.resolve_04t_dependencies(dependencies)
584
+
585
+ # Convert dependencies to correct format for Package2VersionCreateRequest
586
+ dependencies = self._convert_project_dependencies(dependencies)
587
+
588
+ # Build additional packages for local unpackaged/pre
589
+ dependencies = self._get_unpackaged_pre_dependencies(dependencies)
590
+
591
+ return dependencies
592
+
593
+ def _has_1gp_namespace_dependency(self, project_dependencies):
594
+ """Returns true if any dependencies are specified using a namespace rather than 04t"""
595
+ return any(
596
+ isinstance(dependency, PackageNamespaceVersionDependency)
597
+ and not dependency.version_id
598
+ for dependency in project_dependencies
599
+ )
600
+
601
+ def _convert_project_dependencies(self, dependencies):
602
+ """Convert dependencies into the format expected by Package2VersionCreateRequest.
603
+
604
+ For dependencies expressed as a VCS repo subfolder, build an unlocked package from that.
605
+ """
606
+ new_dependencies = []
607
+ for dependency in dependencies:
608
+ new_dependency = {}
609
+ if isinstance(dependency, PackageVersionIdDependency) or (
610
+ isinstance(dependency, PackageNamespaceVersionDependency)
611
+ and dependency.version_id
612
+ ):
613
+ self.logger.info(
614
+ f"Adding dependency {dependency.package_name} with id {dependency.version_id}"
615
+ )
616
+ new_dependency["subscriberPackageVersionId"] = dependency.version_id
617
+ elif isinstance(dependency, UnmanagedDependency):
618
+ if self.options["create_unlocked_dependency_packages"]:
619
+ version_id = self._create_unlocked_package_from_unmanaged_dep(
620
+ dependency, new_dependencies
621
+ )
622
+ self.logger.info(
623
+ f"Adding dependency {dependency} with id {version_id}"
624
+ )
625
+ new_dependency["subscriberPackageVersionId"] = version_id
626
+ else:
627
+ self.logger.info(
628
+ f"Skipping dependency {dependency} because create_unlocked_dependency_packages is False."
629
+ )
630
+ continue
631
+ else:
632
+ raise DependencyLookupError(
633
+ f"Unable to convert dependency: {dependency}"
634
+ )
635
+
636
+ new_dependencies.append(new_dependency)
637
+
638
+ return new_dependencies
639
+
640
+ def _get_unpackaged_pre_dependencies(self, dependencies):
641
+ """Create package for unpackaged/pre metadata, if necessary"""
642
+ path = pathlib.Path("unpackaged", "pre")
643
+ if not path.exists():
644
+ return dependencies
645
+
646
+ if not self.options["create_unlocked_dependency_packages"]:
647
+ self.logger.info(
648
+ "Skipping unpackaged/pre dependencies because create_unlocked_dependency_packages is False."
649
+ )
650
+ return dependencies
651
+
652
+ for item_path in sorted(path.iterdir(), key=str):
653
+ if item_path.is_dir():
654
+ version_id = self._create_unlocked_package_from_local(
655
+ item_path, dependencies
656
+ )
657
+ self.logger.info(
658
+ "Adding dependency {}/{} {} with id {}".format(
659
+ self.project_config.repo_owner,
660
+ self.project_config.repo_name,
661
+ item_path,
662
+ version_id,
663
+ )
664
+ )
665
+ dependencies.append({"subscriberPackageVersionId": version_id})
666
+
667
+ return dependencies
668
+
669
+ def _create_unlocked_package_from_unmanaged_dep(
670
+ self, dependency: UnmanagedVcsDependency, dependencies
671
+ ) -> str:
672
+ if isinstance(dependency, UnmanagedVcsDependency):
673
+ package_name = dependency.package_name
674
+ else:
675
+ package_name = dependency.description
676
+
677
+ package_zip_builder = dependency.get_metadata_package_zip_builder(
678
+ self.project_config, self.org_config
679
+ )
680
+
681
+ package_config = PackageConfig(
682
+ package_name=package_name,
683
+ version_name="Auto",
684
+ package_type="Unlocked",
685
+ # Ideally we'd do this without a namespace,
686
+ # but it needs to match the dependent package
687
+ namespace=self.package_config.namespace,
688
+ )
689
+ package_id = self._get_or_create_package(package_config)
690
+ self.request_id = self._create_version_request(
691
+ package_id,
692
+ package_config,
693
+ package_zip_builder,
694
+ dependencies=dependencies,
695
+ )
696
+
697
+ self._poll()
698
+ self._reset_poll()
699
+ res = self.tooling.query(
700
+ "SELECT SubscriberPackageVersionId FROM Package2Version "
701
+ f"WHERE Id='{self.package_version_id}'"
702
+ )
703
+ package2_version = res["records"][0]
704
+ return package2_version["SubscriberPackageVersionId"]
705
+
706
+ def _create_unlocked_package_from_local(self, path, dependencies):
707
+ """Create an unlocked package version from a local directory."""
708
+ self.logger.info(f"Creating package for dependencies in {path}")
709
+ package_name = (
710
+ f"{self.project_config.repo_owner}/{self.project_config.repo_name} {path}"
711
+ )
712
+ with convert_sfdx_source(path, package_name, self.logger) as src_path:
713
+ package_zip_builder = MetadataPackageZipBuilder(
714
+ path=src_path, name=package_name, context=self.context
715
+ )
716
+ package_config = PackageConfig(
717
+ package_name=package_name,
718
+ version_name="Auto",
719
+ package_type="Unlocked",
720
+ # Ideally we'd do this without a namespace,
721
+ # but it needs to match the dependent package
722
+ namespace=self.package_config.namespace,
723
+ )
724
+ package_id = self._get_or_create_package(package_config)
725
+ self.request_id = self._create_version_request(
726
+ package_id,
727
+ package_config,
728
+ package_zip_builder,
729
+ dependencies=dependencies,
730
+ )
731
+ self._poll()
732
+ self._reset_poll()
733
+ res = self.tooling.query(
734
+ "SELECT SubscriberPackageVersionId FROM Package2Version "
735
+ f"WHERE Id='{self.package_version_id}'"
736
+ )
737
+ package2_version = res["records"][0]
738
+ return package2_version["SubscriberPackageVersionId"]
739
+
740
+ def _poll_action(self):
741
+ """Check if Package2VersionCreateRequest has completed."""
742
+ res = self.tooling.query(
743
+ f"SELECT Id, Status, Package2VersionId FROM Package2VersionCreateRequest WHERE Id = '{self.request_id}'"
744
+ )
745
+ request = res["records"][0]
746
+ if request["Status"] == "Success":
747
+ self.logger.info("[Success]: Package creation successful")
748
+ self.poll_complete = True
749
+ self.package_version_id = request["Package2VersionId"]
750
+ elif request["Status"] == "Error":
751
+ self.logger.error("[Error]: Package creation failed with error:")
752
+ res = self.tooling.query(
753
+ "SELECT Message FROM Package2VersionCreateRequestError "
754
+ f"WHERE ParentRequestId = '{request['Id']}'"
755
+ )
756
+ errors = []
757
+ if res["size"] > 0:
758
+ for error in res["records"]:
759
+ errors.append(error["Message"])
760
+ self.logger.error(error["Message"])
761
+ raise PackageUploadFailure("\n".join(errors))
762
+ else:
763
+ self.logger.info(f"[{request['Status']}]")
764
+
765
+ def _prepare_cci_dependencies(self, deps) -> List[dict]:
766
+ # Convert the dependencies returned by the Tooling API
767
+ # for the new package back into `update_dependencies`-compatible
768
+ # format for persistence into the GitHub release.
769
+
770
+ if deps:
771
+ return [
772
+ PackageVersionIdDependency(
773
+ version_id=v["subscriberPackageVersionId"]
774
+ ).dict(exclude_none=True)
775
+ for v in deps["ids"]
776
+ ]
777
+
778
+ return []