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.
- cumulusci/__about__.py +1 -0
- cumulusci/__init__.py +22 -0
- cumulusci/__main__.py +3 -0
- cumulusci/cli/__init__.py +0 -0
- cumulusci/cli/cci.py +244 -0
- cumulusci/cli/error.py +125 -0
- cumulusci/cli/flow.py +185 -0
- cumulusci/cli/logger.py +72 -0
- cumulusci/cli/org.py +692 -0
- cumulusci/cli/plan.py +181 -0
- cumulusci/cli/project.py +391 -0
- cumulusci/cli/robot.py +116 -0
- cumulusci/cli/runtime.py +190 -0
- cumulusci/cli/service.py +521 -0
- cumulusci/cli/task.py +295 -0
- cumulusci/cli/tests/__init__.py +0 -0
- cumulusci/cli/tests/test_cci.py +545 -0
- cumulusci/cli/tests/test_error.py +170 -0
- cumulusci/cli/tests/test_flow.py +276 -0
- cumulusci/cli/tests/test_logger.py +25 -0
- cumulusci/cli/tests/test_org.py +1438 -0
- cumulusci/cli/tests/test_plan.py +245 -0
- cumulusci/cli/tests/test_project.py +235 -0
- cumulusci/cli/tests/test_robot.py +177 -0
- cumulusci/cli/tests/test_runtime.py +197 -0
- cumulusci/cli/tests/test_service.py +853 -0
- cumulusci/cli/tests/test_task.py +266 -0
- cumulusci/cli/tests/test_ui.py +310 -0
- cumulusci/cli/tests/test_utils.py +122 -0
- cumulusci/cli/tests/utils.py +52 -0
- cumulusci/cli/ui.py +234 -0
- cumulusci/cli/utils.py +150 -0
- cumulusci/conftest.py +181 -0
- cumulusci/core/__init__.py +0 -0
- cumulusci/core/config/BaseConfig.py +5 -0
- cumulusci/core/config/BaseTaskFlowConfig.py +5 -0
- cumulusci/core/config/OrgConfig.py +5 -0
- cumulusci/core/config/ScratchOrgConfig.py +5 -0
- cumulusci/core/config/__init__.py +125 -0
- cumulusci/core/config/base_config.py +111 -0
- cumulusci/core/config/base_task_flow_config.py +82 -0
- cumulusci/core/config/marketing_cloud_service_config.py +83 -0
- cumulusci/core/config/oauth2_service_config.py +17 -0
- cumulusci/core/config/org_config.py +604 -0
- cumulusci/core/config/project_config.py +782 -0
- cumulusci/core/config/scratch_org_config.py +251 -0
- cumulusci/core/config/sfdx_org_config.py +220 -0
- cumulusci/core/config/tests/_test_config_backwards_compatibility.py +33 -0
- cumulusci/core/config/tests/test_config.py +1895 -0
- cumulusci/core/config/tests/test_config_expensive.py +839 -0
- cumulusci/core/config/tests/test_config_util.py +91 -0
- cumulusci/core/config/universal_config.py +88 -0
- cumulusci/core/config/util.py +18 -0
- cumulusci/core/datasets.py +303 -0
- cumulusci/core/debug.py +33 -0
- cumulusci/core/dependencies/__init__.py +55 -0
- cumulusci/core/dependencies/base.py +561 -0
- cumulusci/core/dependencies/dependencies.py +273 -0
- cumulusci/core/dependencies/github.py +177 -0
- cumulusci/core/dependencies/github_resolvers.py +244 -0
- cumulusci/core/dependencies/resolvers.py +580 -0
- cumulusci/core/dependencies/tests/__init__.py +0 -0
- cumulusci/core/dependencies/tests/conftest.py +385 -0
- cumulusci/core/dependencies/tests/test_dependencies.py +950 -0
- cumulusci/core/dependencies/tests/test_github.py +83 -0
- cumulusci/core/dependencies/tests/test_resolvers.py +1027 -0
- cumulusci/core/dependencies/utils.py +13 -0
- cumulusci/core/enums.py +11 -0
- cumulusci/core/exceptions.py +311 -0
- cumulusci/core/flowrunner.py +888 -0
- cumulusci/core/github.py +665 -0
- cumulusci/core/keychain/__init__.py +24 -0
- cumulusci/core/keychain/base_project_keychain.py +441 -0
- cumulusci/core/keychain/encrypted_file_project_keychain.py +945 -0
- cumulusci/core/keychain/environment_project_keychain.py +7 -0
- cumulusci/core/keychain/serialization.py +152 -0
- cumulusci/core/keychain/subprocess_keychain.py +24 -0
- cumulusci/core/keychain/tests/conftest.py +50 -0
- cumulusci/core/keychain/tests/test_base_project_keychain.py +299 -0
- cumulusci/core/keychain/tests/test_encrypted_file_project_keychain.py +1228 -0
- cumulusci/core/metadeploy/__init__.py +0 -0
- cumulusci/core/metadeploy/api.py +88 -0
- cumulusci/core/metadeploy/plans.py +25 -0
- cumulusci/core/metadeploy/tests/test_api.py +276 -0
- cumulusci/core/runtime.py +115 -0
- cumulusci/core/sfdx.py +162 -0
- cumulusci/core/source/__init__.py +16 -0
- cumulusci/core/source/github.py +50 -0
- cumulusci/core/source/local_folder.py +35 -0
- cumulusci/core/source_transforms/__init__.py +0 -0
- cumulusci/core/source_transforms/tests/test_transforms.py +1091 -0
- cumulusci/core/source_transforms/transforms.py +532 -0
- cumulusci/core/tasks.py +404 -0
- cumulusci/core/template_utils.py +59 -0
- cumulusci/core/tests/__init__.py +0 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_e2e.yaml +215 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_extract_standard_objects.yaml +199 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_read_explicit_extract_declaration.yaml +3 -0
- cumulusci/core/tests/fake_remote_repo/cumulusci.yml +32 -0
- cumulusci/core/tests/fake_remote_repo/tasks/directory/example_2.py +6 -0
- cumulusci/core/tests/fake_remote_repo/tasks/example.py +43 -0
- cumulusci/core/tests/fake_remote_repo_2/cumulusci.yml +11 -0
- cumulusci/core/tests/fake_remote_repo_2/tasks/example_3.py +6 -0
- cumulusci/core/tests/test_datasets_e2e.py +386 -0
- cumulusci/core/tests/test_exceptions.py +11 -0
- cumulusci/core/tests/test_flowrunner.py +836 -0
- cumulusci/core/tests/test_github.py +942 -0
- cumulusci/core/tests/test_sfdx.py +138 -0
- cumulusci/core/tests/test_source.py +678 -0
- cumulusci/core/tests/test_tasks.py +262 -0
- cumulusci/core/tests/test_utils.py +141 -0
- cumulusci/core/tests/test_utils_merge_config.py +276 -0
- cumulusci/core/tests/test_versions.py +76 -0
- cumulusci/core/tests/untrusted_repo_child/cumulusci.yml +7 -0
- cumulusci/core/tests/untrusted_repo_child/tasks/untrusted_child.py +6 -0
- cumulusci/core/tests/untrusted_repo_parent/cumulusci.yml +26 -0
- cumulusci/core/tests/untrusted_repo_parent/tasks/untrusted_parent.py +6 -0
- cumulusci/core/tests/utils.py +116 -0
- cumulusci/core/tests/yaml/global.yaml +0 -0
- cumulusci/core/utils.py +402 -0
- cumulusci/core/versions.py +149 -0
- cumulusci/cumulusci.yml +1621 -0
- cumulusci/files/admin_profile.xml +20 -0
- cumulusci/files/delete_excludes.txt +424 -0
- cumulusci/files/templates/project/README.md +12 -0
- cumulusci/files/templates/project/cumulusci.yml +63 -0
- cumulusci/files/templates/project/dot-gitignore +60 -0
- cumulusci/files/templates/project/mapping.yml +45 -0
- cumulusci/files/templates/project/scratch_def.json +25 -0
- cumulusci/oauth/__init__.py +0 -0
- cumulusci/oauth/client.py +400 -0
- cumulusci/oauth/exceptions.py +9 -0
- cumulusci/oauth/salesforce.py +95 -0
- cumulusci/oauth/tests/__init__.py +0 -0
- cumulusci/oauth/tests/cassettes/test_get_device_code.yaml +22 -0
- cumulusci/oauth/tests/cassettes/test_get_device_oauth_token.yaml +74 -0
- cumulusci/oauth/tests/test_client.py +308 -0
- cumulusci/oauth/tests/test_salesforce.py +46 -0
- cumulusci/plugins/__init__.py +3 -0
- cumulusci/plugins/plugin_base.py +93 -0
- cumulusci/plugins/plugin_loader.py +59 -0
- cumulusci/robotframework/CumulusCI.py +340 -0
- cumulusci/robotframework/CumulusCI.robot +7 -0
- cumulusci/robotframework/Performance.py +165 -0
- cumulusci/robotframework/Salesforce.py +936 -0
- cumulusci/robotframework/Salesforce.robot +192 -0
- cumulusci/robotframework/SalesforceAPI.py +416 -0
- cumulusci/robotframework/SalesforcePlaywright.py +220 -0
- cumulusci/robotframework/SalesforcePlaywright.robot +40 -0
- cumulusci/robotframework/__init__.py +2 -0
- cumulusci/robotframework/base_library.py +39 -0
- cumulusci/robotframework/faker_mixin.py +89 -0
- cumulusci/robotframework/form_handlers.py +222 -0
- cumulusci/robotframework/javascript/cci_init.js +34 -0
- cumulusci/robotframework/javascript/cumulusci.js +4 -0
- cumulusci/robotframework/locator_manager.py +197 -0
- cumulusci/robotframework/locators_56.py +88 -0
- cumulusci/robotframework/locators_57.py +5 -0
- cumulusci/robotframework/pageobjects/BasePageObjects.py +433 -0
- cumulusci/robotframework/pageobjects/ObjectManagerPageObject.py +246 -0
- cumulusci/robotframework/pageobjects/PageObjectLibrary.py +45 -0
- cumulusci/robotframework/pageobjects/PageObjects.py +351 -0
- cumulusci/robotframework/pageobjects/__init__.py +12 -0
- cumulusci/robotframework/pageobjects/baseobjects.py +120 -0
- cumulusci/robotframework/perftests/short/collection_perf.robot +105 -0
- cumulusci/robotframework/tests/CustomObjectTestPage.py +10 -0
- cumulusci/robotframework/tests/FooTestPage.py +8 -0
- cumulusci/robotframework/tests/cumulusci/base.robot +40 -0
- cumulusci/robotframework/tests/cumulusci/bulkdata.robot +38 -0
- cumulusci/robotframework/tests/cumulusci/communities.robot +57 -0
- cumulusci/robotframework/tests/cumulusci/datagen.robot +84 -0
- cumulusci/robotframework/tests/salesforce/TestLibraryA.py +24 -0
- cumulusci/robotframework/tests/salesforce/TestLibraryB.py +20 -0
- cumulusci/robotframework/tests/salesforce/TestListener.py +93 -0
- cumulusci/robotframework/tests/salesforce/api.robot +178 -0
- cumulusci/robotframework/tests/salesforce/browsers.robot +143 -0
- cumulusci/robotframework/tests/salesforce/classic.robot +51 -0
- cumulusci/robotframework/tests/salesforce/create_contact.robot +59 -0
- cumulusci/robotframework/tests/salesforce/faker.robot +68 -0
- cumulusci/robotframework/tests/salesforce/forms.robot +172 -0
- cumulusci/robotframework/tests/salesforce/label_locator.robot +244 -0
- cumulusci/robotframework/tests/salesforce/labels.html +33 -0
- cumulusci/robotframework/tests/salesforce/locators.robot +149 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/base_pageobjects.robot +100 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/example_page_object.py +25 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/listing_page.robot +115 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/objectmanager.robot +74 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/pageobjects.robot +171 -0
- cumulusci/robotframework/tests/salesforce/performance.robot +109 -0
- cumulusci/robotframework/tests/salesforce/playwright/javascript_keywords.robot +33 -0
- cumulusci/robotframework/tests/salesforce/playwright/open_test_browser.robot +48 -0
- cumulusci/robotframework/tests/salesforce/playwright/playwright.robot +24 -0
- cumulusci/robotframework/tests/salesforce/playwright/ui.robot +32 -0
- cumulusci/robotframework/tests/salesforce/populate.robot +89 -0
- cumulusci/robotframework/tests/salesforce/test_testlistener.py +37 -0
- cumulusci/robotframework/tests/salesforce/ui.robot +361 -0
- cumulusci/robotframework/tests/test_cumulusci_library.py +304 -0
- cumulusci/robotframework/tests/test_locator_manager.py +158 -0
- cumulusci/robotframework/tests/test_pageobjects.py +291 -0
- cumulusci/robotframework/tests/test_performance.py +38 -0
- cumulusci/robotframework/tests/test_salesforce.py +79 -0
- cumulusci/robotframework/tests/test_salesforce_locators.py +73 -0
- cumulusci/robotframework/tests/test_template_util.py +53 -0
- cumulusci/robotframework/tests/test_utils.py +106 -0
- cumulusci/robotframework/utils.py +283 -0
- cumulusci/salesforce_api/__init__.py +0 -0
- cumulusci/salesforce_api/exceptions.py +23 -0
- cumulusci/salesforce_api/filterable_objects.py +96 -0
- cumulusci/salesforce_api/mc_soap_envelopes.py +89 -0
- cumulusci/salesforce_api/metadata.py +721 -0
- cumulusci/salesforce_api/org_schema.py +571 -0
- cumulusci/salesforce_api/org_schema_models.py +226 -0
- cumulusci/salesforce_api/package_install.py +265 -0
- cumulusci/salesforce_api/package_zip.py +301 -0
- cumulusci/salesforce_api/rest_deploy.py +148 -0
- cumulusci/salesforce_api/retrieve_profile_api.py +301 -0
- cumulusci/salesforce_api/soap_envelopes.py +177 -0
- cumulusci/salesforce_api/tests/__init__.py +0 -0
- cumulusci/salesforce_api/tests/metadata_test_strings.py +24 -0
- cumulusci/salesforce_api/tests/test_metadata.py +1015 -0
- cumulusci/salesforce_api/tests/test_package_install.py +219 -0
- cumulusci/salesforce_api/tests/test_package_zip.py +380 -0
- cumulusci/salesforce_api/tests/test_rest_deploy.py +264 -0
- cumulusci/salesforce_api/tests/test_retrieve_profile_api.py +337 -0
- cumulusci/salesforce_api/tests/test_utils.py +124 -0
- cumulusci/salesforce_api/utils.py +51 -0
- cumulusci/schema/cumulusci.jsonschema.json +782 -0
- cumulusci/tasks/__init__.py +0 -0
- cumulusci/tasks/apex/__init__.py +0 -0
- cumulusci/tasks/apex/anon.py +157 -0
- cumulusci/tasks/apex/batch.py +180 -0
- cumulusci/tasks/apex/testrunner.py +835 -0
- cumulusci/tasks/apex/tests/cassettes/ManualEditTestApexIntegrationTests.test_run_tests__integration_test.yaml +703 -0
- cumulusci/tasks/apex/tests/test_apex_tasks.py +1558 -0
- cumulusci/tasks/base_source_control_task.py +17 -0
- cumulusci/tasks/bulkdata/__init__.py +15 -0
- cumulusci/tasks/bulkdata/base_generate_data_task.py +96 -0
- cumulusci/tasks/bulkdata/dates.py +97 -0
- cumulusci/tasks/bulkdata/delete.py +156 -0
- cumulusci/tasks/bulkdata/extract.py +441 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/calculate_dependencies.py +117 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py +123 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/hardcoded_default_declarations.py +49 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py +283 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py +142 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_synthesize_extract_declarations.py +575 -0
- cumulusci/tasks/bulkdata/factory_utils.py +134 -0
- cumulusci/tasks/bulkdata/generate.py +4 -0
- cumulusci/tasks/bulkdata/generate_and_load_data.py +232 -0
- cumulusci/tasks/bulkdata/generate_and_load_data_from_yaml.py +19 -0
- cumulusci/tasks/bulkdata/generate_from_yaml.py +183 -0
- cumulusci/tasks/bulkdata/generate_mapping.py +434 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/dependency_map.py +169 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/extract_mapping_file_generator.py +45 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/generate_mapping_from_declarations.py +121 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/load_mapping_file_generator.py +127 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/mapping_generator_post_processes.py +53 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/mapping_transforms.py +139 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_generate_extract_mapping_from_declarations.py +135 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_generate_load_mapping_from_declarations.py +330 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_mapping_generator_post_processes.py +60 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_mapping_transforms.py +188 -0
- cumulusci/tasks/bulkdata/load.py +1196 -0
- cumulusci/tasks/bulkdata/mapping_parser.py +811 -0
- cumulusci/tasks/bulkdata/query_transformers.py +264 -0
- cumulusci/tasks/bulkdata/select_utils.py +792 -0
- cumulusci/tasks/bulkdata/snowfakery.py +753 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/queue_manager.py +478 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/snowfakery_run_until.py +141 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/snowfakery_working_directory.py +53 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/subtask_configurator.py +64 -0
- cumulusci/tasks/bulkdata/step.py +1242 -0
- cumulusci/tasks/bulkdata/tests/__init__.py +0 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_random_strategy.yaml +147 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_annoy_strategy.yaml +123 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_select_and_insert_strategy.yaml +313 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_select_and_insert_strategy_bulk.yaml +550 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_strategy.yaml +175 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_standard_strategy.yaml +147 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__multiple_needed.yaml +69 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__none_needed.yaml +22 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__one_needed.yaml +24 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_snowfakery_query_salesforce.yaml +25 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpdatesIntegrationTests.test_updates_task.yaml +80 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_simple_upsert__rest.yaml +270 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert__rest.yaml +267 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_external_id_field__rest.yaml +369 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_external_id_field_rest__duplicate_error.yaml +204 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_fields__bulk.yaml +675 -0
- cumulusci/tasks/bulkdata/tests/dummy_data_factory.py +36 -0
- cumulusci/tasks/bulkdata/tests/integration_test_utils.py +49 -0
- cumulusci/tasks/bulkdata/tests/mapping-oid.yml +87 -0
- cumulusci/tasks/bulkdata/tests/mapping_after.yml +38 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly.yml +34 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly_incomplete.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly_wrong.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_strategy.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__invalid_number.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__invalid_strategy.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__non_float.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_missing_priority_fields.yml +22 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_no_priority_fields.yml +18 -0
- cumulusci/tasks/bulkdata/tests/mapping_simple.yml +27 -0
- cumulusci/tasks/bulkdata/tests/mapping_v1.yml +28 -0
- cumulusci/tasks/bulkdata/tests/mapping_v2.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_v3.yml +32 -0
- cumulusci/tasks/bulkdata/tests/mapping_vanilla_sf.yml +69 -0
- cumulusci/tasks/bulkdata/tests/mock_data_factory_without_mapping.py +12 -0
- cumulusci/tasks/bulkdata/tests/person_accounts.yml +23 -0
- cumulusci/tasks/bulkdata/tests/person_accounts_minimal.yml +15 -0
- cumulusci/tasks/bulkdata/tests/recordtypes.yml +8 -0
- cumulusci/tasks/bulkdata/tests/recordtypes_2.yml +6 -0
- cumulusci/tasks/bulkdata/tests/recordtypes_with_ispersontype.yml +8 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/child/child2.yml +3 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/child.yml +4 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/gen_npsp_standard_objects.recipe.yml +89 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/include_parent.yml +3 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/npsp_standard_objects_macros.yml +34 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/options.recipe.yml +6 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/query_snowfakery.recipe.yml +16 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/sf_standard_object_macros.yml +83 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery.load.yml +2 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery.recipe.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_2.load.yml +5 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels.load.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels.recipe.yml +12 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels_2.load.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/unique_values.recipe.yml +4 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert.recipe.yml +23 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert_2.recipe.yml +29 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert_before.yml +10 -0
- cumulusci/tasks/bulkdata/tests/test_base_generate_data_tasks.py +61 -0
- cumulusci/tasks/bulkdata/tests/test_dates.py +99 -0
- cumulusci/tasks/bulkdata/tests/test_delete.py +404 -0
- cumulusci/tasks/bulkdata/tests/test_extract.py +1311 -0
- cumulusci/tasks/bulkdata/tests/test_factory_utils.py +55 -0
- cumulusci/tasks/bulkdata/tests/test_generate_and_load.py +252 -0
- cumulusci/tasks/bulkdata/tests/test_generate_from_snowfakery_task.py +343 -0
- cumulusci/tasks/bulkdata/tests/test_generatemapping.py +1039 -0
- cumulusci/tasks/bulkdata/tests/test_load.py +3175 -0
- cumulusci/tasks/bulkdata/tests/test_mapping_parser.py +1658 -0
- cumulusci/tasks/bulkdata/tests/test_query_db__joins_self_lookups.yml +12 -0
- cumulusci/tasks/bulkdata/tests/test_query_db_joins_lookups.yml +26 -0
- cumulusci/tasks/bulkdata/tests/test_query_db_joins_lookups_select.yml +48 -0
- cumulusci/tasks/bulkdata/tests/test_select.py +171 -0
- cumulusci/tasks/bulkdata/tests/test_select_utils.py +1057 -0
- cumulusci/tasks/bulkdata/tests/test_snowfakery.py +1153 -0
- cumulusci/tasks/bulkdata/tests/test_step.py +3957 -0
- cumulusci/tasks/bulkdata/tests/test_updates.py +513 -0
- cumulusci/tasks/bulkdata/tests/test_upsert.py +1015 -0
- cumulusci/tasks/bulkdata/tests/test_utils.py +158 -0
- cumulusci/tasks/bulkdata/tests/testdata.db +0 -0
- cumulusci/tasks/bulkdata/tests/update_describe.py +50 -0
- cumulusci/tasks/bulkdata/tests/update_person_accounts.yml +23 -0
- cumulusci/tasks/bulkdata/tests/utils.py +114 -0
- cumulusci/tasks/bulkdata/update_data.py +260 -0
- cumulusci/tasks/bulkdata/upsert_utils.py +130 -0
- cumulusci/tasks/bulkdata/utils.py +249 -0
- cumulusci/tasks/command.py +178 -0
- cumulusci/tasks/connectedapp.py +186 -0
- cumulusci/tasks/create_package_version.py +778 -0
- cumulusci/tasks/datadictionary.py +745 -0
- cumulusci/tasks/dx_convert_from.py +26 -0
- cumulusci/tasks/github/__init__.py +17 -0
- cumulusci/tasks/github/base.py +16 -0
- cumulusci/tasks/github/commit_status.py +13 -0
- cumulusci/tasks/github/merge.py +11 -0
- cumulusci/tasks/github/publish.py +11 -0
- cumulusci/tasks/github/pull_request.py +11 -0
- cumulusci/tasks/github/release.py +11 -0
- cumulusci/tasks/github/release_report.py +11 -0
- cumulusci/tasks/github/tag.py +11 -0
- cumulusci/tasks/github/tests/__init__.py +0 -0
- cumulusci/tasks/github/tests/test_util.py +202 -0
- cumulusci/tasks/github/tests/test_vcs_migration.py +44 -0
- cumulusci/tasks/github/tests/util_github_api.py +666 -0
- cumulusci/tasks/github/util.py +252 -0
- cumulusci/tasks/marketing_cloud/__init__.py +0 -0
- cumulusci/tasks/marketing_cloud/api.py +188 -0
- cumulusci/tasks/marketing_cloud/base.py +38 -0
- cumulusci/tasks/marketing_cloud/deploy.py +345 -0
- cumulusci/tasks/marketing_cloud/get_user_info.py +40 -0
- cumulusci/tasks/marketing_cloud/mc_constants.py +1 -0
- cumulusci/tasks/marketing_cloud/tests/__init__.py +0 -0
- cumulusci/tasks/marketing_cloud/tests/conftest.py +46 -0
- cumulusci/tasks/marketing_cloud/tests/expected-payload.json +110 -0
- cumulusci/tasks/marketing_cloud/tests/test_api.py +97 -0
- cumulusci/tasks/marketing_cloud/tests/test_api_soap_envelopes.py +145 -0
- cumulusci/tasks/marketing_cloud/tests/test_base.py +14 -0
- cumulusci/tasks/marketing_cloud/tests/test_deploy.py +400 -0
- cumulusci/tasks/marketing_cloud/tests/test_get_user_info.py +141 -0
- cumulusci/tasks/marketing_cloud/tests/validation-response.json +39 -0
- cumulusci/tasks/metadata/__init__.py +0 -0
- cumulusci/tasks/metadata/ee_src.py +94 -0
- cumulusci/tasks/metadata/managed_src.py +100 -0
- cumulusci/tasks/metadata/metadata_map.yml +868 -0
- cumulusci/tasks/metadata/modify.py +99 -0
- cumulusci/tasks/metadata/package.py +684 -0
- cumulusci/tasks/metadata/tests/__init__.py +0 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/.hidden/.keep +0 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/destructiveChanges.xml +9 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/package.xml +9 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/package_install_uninstall.xml +11 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/reports/namespace__TestFolder/TestReport.report +3 -0
- cumulusci/tasks/metadata/tests/sample_package.xml +9 -0
- cumulusci/tasks/metadata/tests/test_ee_src.py +112 -0
- cumulusci/tasks/metadata/tests/test_managed_src.py +111 -0
- cumulusci/tasks/metadata/tests/test_modify.py +123 -0
- cumulusci/tasks/metadata/tests/test_package.py +476 -0
- cumulusci/tasks/metadata_etl/__init__.py +29 -0
- cumulusci/tasks/metadata_etl/base.py +436 -0
- cumulusci/tasks/metadata_etl/duplicate_rules.py +24 -0
- cumulusci/tasks/metadata_etl/field_sets.py +70 -0
- cumulusci/tasks/metadata_etl/help_text.py +92 -0
- cumulusci/tasks/metadata_etl/layouts.py +550 -0
- cumulusci/tasks/metadata_etl/objects.py +68 -0
- cumulusci/tasks/metadata_etl/permissions.py +167 -0
- cumulusci/tasks/metadata_etl/picklists.py +221 -0
- cumulusci/tasks/metadata_etl/remote_site_settings.py +99 -0
- cumulusci/tasks/metadata_etl/sharing.py +138 -0
- cumulusci/tasks/metadata_etl/tests/test_base.py +512 -0
- cumulusci/tasks/metadata_etl/tests/test_duplicate_rules.py +22 -0
- cumulusci/tasks/metadata_etl/tests/test_field_sets.py +156 -0
- cumulusci/tasks/metadata_etl/tests/test_help_text.py +387 -0
- cumulusci/tasks/metadata_etl/tests/test_ip_ranges.py +85 -0
- cumulusci/tasks/metadata_etl/tests/test_layouts.py +858 -0
- cumulusci/tasks/metadata_etl/tests/test_objects.py +236 -0
- cumulusci/tasks/metadata_etl/tests/test_permissions.py +223 -0
- cumulusci/tasks/metadata_etl/tests/test_picklists.py +547 -0
- cumulusci/tasks/metadata_etl/tests/test_remote_site_settings.py +46 -0
- cumulusci/tasks/metadata_etl/tests/test_sharing.py +333 -0
- cumulusci/tasks/metadata_etl/tests/test_value_sets.py +298 -0
- cumulusci/tasks/metadata_etl/value_sets.py +106 -0
- cumulusci/tasks/metadeploy.py +393 -0
- cumulusci/tasks/metaxml.py +88 -0
- cumulusci/tasks/preflight/__init__.py +0 -0
- cumulusci/tasks/preflight/dataset_load.py +49 -0
- cumulusci/tasks/preflight/licenses.py +86 -0
- cumulusci/tasks/preflight/packages.py +14 -0
- cumulusci/tasks/preflight/permsets.py +23 -0
- cumulusci/tasks/preflight/recordtypes.py +16 -0
- cumulusci/tasks/preflight/retrieve_tasks.py +30 -0
- cumulusci/tasks/preflight/settings.py +77 -0
- cumulusci/tasks/preflight/sobjects.py +202 -0
- cumulusci/tasks/preflight/tests/test_dataset_load.py +85 -0
- cumulusci/tasks/preflight/tests/test_licenses.py +174 -0
- cumulusci/tasks/preflight/tests/test_packages.py +14 -0
- cumulusci/tasks/preflight/tests/test_permset_preflights.py +51 -0
- cumulusci/tasks/preflight/tests/test_recordtypes.py +30 -0
- cumulusci/tasks/preflight/tests/test_retrieve_tasks.py +62 -0
- cumulusci/tasks/preflight/tests/test_settings.py +130 -0
- cumulusci/tasks/preflight/tests/test_sobjects.py +231 -0
- cumulusci/tasks/push/README.md +59 -0
- cumulusci/tasks/push/__init__.py +0 -0
- cumulusci/tasks/push/push_api.py +659 -0
- cumulusci/tasks/push/pushfails.py +136 -0
- cumulusci/tasks/push/tasks.py +476 -0
- cumulusci/tasks/push/tests/conftest.py +263 -0
- cumulusci/tasks/push/tests/test_push_api.py +951 -0
- cumulusci/tasks/push/tests/test_push_tasks.py +659 -0
- cumulusci/tasks/release_notes/README.md +63 -0
- cumulusci/tasks/release_notes/__init__.py +0 -0
- cumulusci/tasks/release_notes/exceptions.py +5 -0
- cumulusci/tasks/release_notes/generator.py +137 -0
- cumulusci/tasks/release_notes/parser.py +232 -0
- cumulusci/tasks/release_notes/provider.py +44 -0
- cumulusci/tasks/release_notes/task.py +300 -0
- cumulusci/tasks/release_notes/tests/__init__.py +0 -0
- cumulusci/tasks/release_notes/tests/change_notes/full/example1.md +17 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/1.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/2.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/3.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/single/1.txt +1 -0
- cumulusci/tasks/release_notes/tests/test_generator.py +582 -0
- cumulusci/tasks/release_notes/tests/test_parser.py +867 -0
- cumulusci/tasks/release_notes/tests/test_provider.py +512 -0
- cumulusci/tasks/release_notes/tests/test_task.py +461 -0
- cumulusci/tasks/release_notes/tests/utils.py +153 -0
- cumulusci/tasks/robotframework/__init__.py +3 -0
- cumulusci/tasks/robotframework/debugger/DebugListener.py +100 -0
- cumulusci/tasks/robotframework/debugger/__init__.py +10 -0
- cumulusci/tasks/robotframework/debugger/model.py +87 -0
- cumulusci/tasks/robotframework/debugger/ui.py +259 -0
- cumulusci/tasks/robotframework/libdoc.py +269 -0
- cumulusci/tasks/robotframework/robotframework.py +392 -0
- cumulusci/tasks/robotframework/stylesheet.css +130 -0
- cumulusci/tasks/robotframework/template.html +109 -0
- cumulusci/tasks/robotframework/tests/TestLibrary.py +18 -0
- cumulusci/tasks/robotframework/tests/TestPageObjects.py +31 -0
- cumulusci/tasks/robotframework/tests/TestResource.robot +8 -0
- cumulusci/tasks/robotframework/tests/failing_tests.robot +16 -0
- cumulusci/tasks/robotframework/tests/performance.robot +23 -0
- cumulusci/tasks/robotframework/tests/test_browser_proxies.py +137 -0
- cumulusci/tasks/robotframework/tests/test_debugger.py +360 -0
- cumulusci/tasks/robotframework/tests/test_robot_parallel.py +141 -0
- cumulusci/tasks/robotframework/tests/test_robotframework.py +860 -0
- cumulusci/tasks/salesforce/BaseRetrieveMetadata.py +58 -0
- cumulusci/tasks/salesforce/BaseSalesforceApiTask.py +45 -0
- cumulusci/tasks/salesforce/BaseSalesforceMetadataApiTask.py +18 -0
- cumulusci/tasks/salesforce/BaseSalesforceTask.py +4 -0
- cumulusci/tasks/salesforce/BaseUninstallMetadata.py +41 -0
- cumulusci/tasks/salesforce/CreateCommunity.py +124 -0
- cumulusci/tasks/salesforce/CreatePackage.py +29 -0
- cumulusci/tasks/salesforce/Deploy.py +240 -0
- cumulusci/tasks/salesforce/DeployBundles.py +88 -0
- cumulusci/tasks/salesforce/DescribeMetadataTypes.py +26 -0
- cumulusci/tasks/salesforce/EnsureRecordTypes.py +202 -0
- cumulusci/tasks/salesforce/GetInstalledPackages.py +8 -0
- cumulusci/tasks/salesforce/ListCommunities.py +40 -0
- cumulusci/tasks/salesforce/ListCommunityTemplates.py +19 -0
- cumulusci/tasks/salesforce/PublishCommunity.py +62 -0
- cumulusci/tasks/salesforce/RetrievePackaged.py +41 -0
- cumulusci/tasks/salesforce/RetrieveReportsAndDashboards.py +82 -0
- cumulusci/tasks/salesforce/RetrieveUnpackaged.py +36 -0
- cumulusci/tasks/salesforce/SOQLQuery.py +39 -0
- cumulusci/tasks/salesforce/UninstallLocal.py +15 -0
- cumulusci/tasks/salesforce/UninstallLocalBundles.py +28 -0
- cumulusci/tasks/salesforce/UninstallLocalNamespacedBundles.py +58 -0
- cumulusci/tasks/salesforce/UninstallPackage.py +32 -0
- cumulusci/tasks/salesforce/UninstallPackaged.py +56 -0
- cumulusci/tasks/salesforce/UpdateAdminProfile.py +8 -0
- cumulusci/tasks/salesforce/__init__.py +79 -0
- cumulusci/tasks/salesforce/activate_flow.py +74 -0
- cumulusci/tasks/salesforce/check_components.py +324 -0
- cumulusci/tasks/salesforce/composite.py +142 -0
- cumulusci/tasks/salesforce/create_permission_sets.py +35 -0
- cumulusci/tasks/salesforce/custom_settings.py +134 -0
- cumulusci/tasks/salesforce/custom_settings_wait.py +132 -0
- cumulusci/tasks/salesforce/enable_prediction.py +107 -0
- cumulusci/tasks/salesforce/insert_record.py +40 -0
- cumulusci/tasks/salesforce/install_package_version.py +242 -0
- cumulusci/tasks/salesforce/license_preflights.py +8 -0
- cumulusci/tasks/salesforce/network_member_group.py +178 -0
- cumulusci/tasks/salesforce/nonsourcetracking.py +228 -0
- cumulusci/tasks/salesforce/org_settings.py +193 -0
- cumulusci/tasks/salesforce/package_upload.py +328 -0
- cumulusci/tasks/salesforce/profiles.py +74 -0
- cumulusci/tasks/salesforce/promote_package_version.py +376 -0
- cumulusci/tasks/salesforce/retrieve_profile.py +195 -0
- cumulusci/tasks/salesforce/salesforce_files.py +244 -0
- cumulusci/tasks/salesforce/sourcetracking.py +507 -0
- cumulusci/tasks/salesforce/tests/__init__.py +3 -0
- cumulusci/tasks/salesforce/tests/test_CreateCommunity.py +278 -0
- cumulusci/tasks/salesforce/tests/test_CreatePackage.py +22 -0
- cumulusci/tasks/salesforce/tests/test_Deploy.py +470 -0
- cumulusci/tasks/salesforce/tests/test_DeployBundles.py +76 -0
- cumulusci/tasks/salesforce/tests/test_EnsureRecordTypes.py +345 -0
- cumulusci/tasks/salesforce/tests/test_ListCommunities.py +84 -0
- cumulusci/tasks/salesforce/tests/test_ListCommunityTemplates.py +49 -0
- cumulusci/tasks/salesforce/tests/test_PackageUpload.py +547 -0
- cumulusci/tasks/salesforce/tests/test_ProfileGrantAllAccess.py +699 -0
- cumulusci/tasks/salesforce/tests/test_PublishCommunity.py +181 -0
- cumulusci/tasks/salesforce/tests/test_RetrievePackaged.py +24 -0
- cumulusci/tasks/salesforce/tests/test_RetrieveReportsAndDashboards.py +56 -0
- cumulusci/tasks/salesforce/tests/test_RetrieveUnpackaged.py +21 -0
- cumulusci/tasks/salesforce/tests/test_SOQLQuery.py +30 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocal.py +15 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocalBundles.py +19 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocalNamespacedBundles.py +22 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackage.py +19 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackaged.py +66 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackagedIncremental.py +127 -0
- cumulusci/tasks/salesforce/tests/test_activate_flow.py +132 -0
- cumulusci/tasks/salesforce/tests/test_base_tasks.py +110 -0
- cumulusci/tasks/salesforce/tests/test_check_components.py +445 -0
- cumulusci/tasks/salesforce/tests/test_composite.py +250 -0
- cumulusci/tasks/salesforce/tests/test_create_permission_sets.py +41 -0
- cumulusci/tasks/salesforce/tests/test_custom_settings.py +227 -0
- cumulusci/tasks/salesforce/tests/test_custom_settings_wait.py +174 -0
- cumulusci/tasks/salesforce/tests/test_describemetadatatypes.py +18 -0
- cumulusci/tasks/salesforce/tests/test_enable_prediction.py +240 -0
- cumulusci/tasks/salesforce/tests/test_insert_record.py +110 -0
- cumulusci/tasks/salesforce/tests/test_install_package_version.py +464 -0
- cumulusci/tasks/salesforce/tests/test_network_member_group.py +444 -0
- cumulusci/tasks/salesforce/tests/test_nonsourcetracking.py +235 -0
- cumulusci/tasks/salesforce/tests/test_org_settings.py +407 -0
- cumulusci/tasks/salesforce/tests/test_profiles.py +202 -0
- cumulusci/tasks/salesforce/tests/test_retrieve_profile.py +287 -0
- cumulusci/tasks/salesforce/tests/test_salesforce_files.py +228 -0
- cumulusci/tasks/salesforce/tests/test_sourcetracking.py +350 -0
- cumulusci/tasks/salesforce/tests/test_trigger_handlers.py +300 -0
- cumulusci/tasks/salesforce/tests/test_update_dependencies.py +509 -0
- cumulusci/tasks/salesforce/tests/util.py +79 -0
- cumulusci/tasks/salesforce/trigger_handlers.py +119 -0
- cumulusci/tasks/salesforce/uninstall_packaged_incremental.py +136 -0
- cumulusci/tasks/salesforce/update_dependencies.py +290 -0
- cumulusci/tasks/salesforce/update_profile.py +339 -0
- cumulusci/tasks/salesforce/users/permsets.py +227 -0
- cumulusci/tasks/salesforce/users/photos.py +162 -0
- cumulusci/tasks/salesforce/users/tests/photo.mock.txt +1 -0
- cumulusci/tasks/salesforce/users/tests/test_permsets.py +950 -0
- cumulusci/tasks/salesforce/users/tests/test_photos.py +373 -0
- cumulusci/tasks/sample_data/capture_sample_data.py +77 -0
- cumulusci/tasks/sample_data/load_sample_data.py +85 -0
- cumulusci/tasks/sample_data/test_capture_sample_data.py +117 -0
- cumulusci/tasks/sample_data/test_load_sample_data.py +121 -0
- cumulusci/tasks/sfdx.py +83 -0
- cumulusci/tasks/tests/__init__.py +1 -0
- cumulusci/tasks/tests/conftest.py +30 -0
- cumulusci/tasks/tests/test_command.py +129 -0
- cumulusci/tasks/tests/test_connectedapp.py +236 -0
- cumulusci/tasks/tests/test_create_package_version.py +847 -0
- cumulusci/tasks/tests/test_datadictionary.py +1575 -0
- cumulusci/tasks/tests/test_dx_convert_from.py +60 -0
- cumulusci/tasks/tests/test_metadeploy.py +624 -0
- cumulusci/tasks/tests/test_metaxml.py +99 -0
- cumulusci/tasks/tests/test_promote_package_version.py +488 -0
- cumulusci/tasks/tests/test_pushfails.py +96 -0
- cumulusci/tasks/tests/test_salesforce.py +72 -0
- cumulusci/tasks/tests/test_sfdx.py +105 -0
- cumulusci/tasks/tests/test_util.py +207 -0
- cumulusci/tasks/util.py +261 -0
- cumulusci/tasks/vcs/__init__.py +19 -0
- cumulusci/tasks/vcs/commit_status.py +58 -0
- cumulusci/tasks/vcs/create_commit_status.py +37 -0
- cumulusci/tasks/vcs/download_extract.py +199 -0
- cumulusci/tasks/vcs/merge.py +298 -0
- cumulusci/tasks/vcs/publish.py +207 -0
- cumulusci/tasks/vcs/pull_request.py +9 -0
- cumulusci/tasks/vcs/release.py +134 -0
- cumulusci/tasks/vcs/release_report.py +105 -0
- cumulusci/tasks/vcs/tag.py +31 -0
- cumulusci/tasks/vcs/tests/github/test_commit_status.py +196 -0
- cumulusci/tasks/vcs/tests/github/test_download_extract.py +896 -0
- cumulusci/tasks/vcs/tests/github/test_merge.py +1118 -0
- cumulusci/tasks/vcs/tests/github/test_publish.py +823 -0
- cumulusci/tasks/vcs/tests/github/test_pull_request.py +29 -0
- cumulusci/tasks/vcs/tests/github/test_release.py +390 -0
- cumulusci/tasks/vcs/tests/github/test_release_report.py +109 -0
- cumulusci/tasks/vcs/tests/github/test_tag.py +90 -0
- cumulusci/tasks/vlocity/exceptions.py +2 -0
- cumulusci/tasks/vlocity/tests/test_vlocity.py +283 -0
- cumulusci/tasks/vlocity/vlocity.py +342 -0
- cumulusci/tests/__init__.py +1 -0
- cumulusci/tests/cassettes/GET_sobjects_Account_PersonAccount_describe.yaml +18 -0
- cumulusci/tests/cassettes/TestIntegrationInfrastructure.test_integration_tests.yaml +19 -0
- cumulusci/tests/pytest_plugins/pytest_sf_orgconnect.py +307 -0
- cumulusci/tests/pytest_plugins/pytest_sf_vcr.py +275 -0
- cumulusci/tests/pytest_plugins/pytest_sf_vcr_serializer.py +160 -0
- cumulusci/tests/pytest_plugins/pytest_typeguard.py +5 -0
- cumulusci/tests/pytest_plugins/test_vcr_string_compressor.py +49 -0
- cumulusci/tests/pytest_plugins/vcr_string_compressor.py +97 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Account_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Case_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Contact_describe.yaml +4838 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Custom__c_describe.yaml +242 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Event_describe.yaml +19 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Global_describe.yaml +1338 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Lead_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_OpportunityContactRole_describe.yaml +34 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Opportunity_describe.yaml +1261 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Organization.yaml +49 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/batchInfoList_xml.tpl +15 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/batchInfo_xml.tpl +13 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/jobInfo_insert_xml.tpl +24 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/jobInfo_upsert_xml.tpl +25 -0
- cumulusci/tests/test_entry_points.py +20 -0
- cumulusci/tests/test_integration_infrastructure.py +131 -0
- cumulusci/tests/test_main.py +9 -0
- cumulusci/tests/test_schema.py +32 -0
- cumulusci/tests/test_utils.py +657 -0
- cumulusci/tests/test_vcr_serializer.py +134 -0
- cumulusci/tests/uncompressed_cassette.yaml +83 -0
- cumulusci/tests/util.py +344 -0
- cumulusci/utils/__init__.py +731 -0
- cumulusci/utils/classutils.py +9 -0
- cumulusci/utils/collections.py +32 -0
- cumulusci/utils/deprecation.py +11 -0
- cumulusci/utils/encryption.py +31 -0
- cumulusci/utils/fileutils.py +295 -0
- cumulusci/utils/git.py +142 -0
- cumulusci/utils/http/multi_request.py +214 -0
- cumulusci/utils/http/requests_utils.py +103 -0
- cumulusci/utils/http/tests/cassettes/ManualEditTestCompositeParallelSalesforce.test_http_headers.yaml +32 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_composite_parallel_salesforce.yaml +65 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_errors.yaml +24 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_reference_ids.yaml +49 -0
- cumulusci/utils/http/tests/test_multi_request.py +255 -0
- cumulusci/utils/iterators.py +21 -0
- cumulusci/utils/logging.py +128 -0
- cumulusci/utils/metaprogramming.py +10 -0
- cumulusci/utils/options.py +138 -0
- cumulusci/utils/parallel/queries_in_parallel/run_queries_in_parallel.py +29 -0
- cumulusci/utils/parallel/queries_in_parallel/tests/test_run_queries_in_parallel.py +50 -0
- cumulusci/utils/parallel/task_worker_queues/parallel_worker.py +238 -0
- cumulusci/utils/parallel/task_worker_queues/parallel_worker_queue.py +243 -0
- cumulusci/utils/parallel/task_worker_queues/tests/test_parallel_worker.py +353 -0
- cumulusci/utils/salesforce/count_sobjects.py +46 -0
- cumulusci/utils/salesforce/soql.py +17 -0
- cumulusci/utils/salesforce/tests/cassettes/ManualEdit_TestCountSObjects.test_count_sobjects__network_errors.yaml +23 -0
- cumulusci/utils/salesforce/tests/cassettes/TestCountSObjects.test_count_sobjects__errors.yaml +33 -0
- cumulusci/utils/salesforce/tests/cassettes/TestCountSObjects.test_count_sobjects_simple.yaml +29 -0
- cumulusci/utils/salesforce/tests/test_count_sobjects.py +29 -0
- cumulusci/utils/salesforce/tests/test_soql.py +30 -0
- cumulusci/utils/tests/cassettes/ManualEditTestDescribeOrg.test_minimal_schema.yaml +36 -0
- cumulusci/utils/tests/cassettes/ManualEdit_test_describe_to_sql.yaml +191 -0
- cumulusci/utils/tests/test_fileutils.py +284 -0
- cumulusci/utils/tests/test_git.py +85 -0
- cumulusci/utils/tests/test_logging.py +70 -0
- cumulusci/utils/tests/test_option_parsing.py +188 -0
- cumulusci/utils/tests/test_org_schema.py +691 -0
- cumulusci/utils/tests/test_org_schema_models.py +79 -0
- cumulusci/utils/tests/test_waiting.py +25 -0
- cumulusci/utils/version_strings.py +391 -0
- cumulusci/utils/waiting.py +42 -0
- cumulusci/utils/xml/__init__.py +91 -0
- cumulusci/utils/xml/metadata_tree.py +299 -0
- cumulusci/utils/xml/robot_xml.py +114 -0
- cumulusci/utils/xml/salesforce_encoding.py +100 -0
- cumulusci/utils/xml/test/test_metadata_tree.py +251 -0
- cumulusci/utils/xml/test/test_salesforce_encoding.py +173 -0
- cumulusci/utils/yaml/cumulusci_yml.py +401 -0
- cumulusci/utils/yaml/model_parser.py +156 -0
- cumulusci/utils/yaml/safer_loader.py +74 -0
- cumulusci/utils/yaml/tests/bad_cci.yml +5 -0
- cumulusci/utils/yaml/tests/cassettes/TestCumulusciYml.test_validate_url__with_errors.yaml +20 -0
- cumulusci/utils/yaml/tests/test_cumulusci_yml.py +286 -0
- cumulusci/utils/yaml/tests/test_model_parser.py +175 -0
- cumulusci/utils/yaml/tests/test_safer_loader.py +88 -0
- cumulusci/utils/ziputils.py +61 -0
- cumulusci/vcs/base.py +143 -0
- cumulusci/vcs/bootstrap.py +272 -0
- cumulusci/vcs/github/__init__.py +24 -0
- cumulusci/vcs/github/adapter.py +689 -0
- cumulusci/vcs/github/release_notes/generator.py +219 -0
- cumulusci/vcs/github/release_notes/parser.py +151 -0
- cumulusci/vcs/github/release_notes/provider.py +143 -0
- cumulusci/vcs/github/service.py +569 -0
- cumulusci/vcs/github/tests/test_adapter.py +138 -0
- cumulusci/vcs/github/tests/test_service.py +408 -0
- cumulusci/vcs/models.py +586 -0
- cumulusci/vcs/tests/conftest.py +41 -0
- cumulusci/vcs/tests/dummy_service.py +241 -0
- cumulusci/vcs/tests/test_vcs_base.py +687 -0
- cumulusci/vcs/tests/test_vcs_bootstrap.py +727 -0
- cumulusci/vcs/utils/__init__.py +31 -0
- cumulusci/vcs/vcs_source.py +287 -0
- cumulusci_plus-5.0.0.dist-info/METADATA +145 -0
- cumulusci_plus-5.0.0.dist-info/RECORD +744 -0
- cumulusci_plus-5.0.0.dist-info/WHEEL +4 -0
- cumulusci_plus-5.0.0.dist-info/entry_points.txt +3 -0
- cumulusci_plus-5.0.0.dist-info/licenses/AUTHORS.rst +41 -0
- cumulusci_plus-5.0.0.dist-info/licenses/LICENSE +30 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from typing import List, Optional, Type
|
|
5
|
+
|
|
6
|
+
from pydantic import AnyUrl, ValidationError
|
|
7
|
+
|
|
8
|
+
import cumulusci.core.dependencies.base as base_dependency
|
|
9
|
+
from cumulusci.core.config import OrgConfig
|
|
10
|
+
from cumulusci.core.config.project_config import BaseProjectConfig
|
|
11
|
+
from cumulusci.core.exceptions import DependencyParseError
|
|
12
|
+
from cumulusci.salesforce_api.package_install import (
|
|
13
|
+
DEFAULT_PACKAGE_RETRY_OPTIONS,
|
|
14
|
+
PackageInstallOptions,
|
|
15
|
+
install_package_by_namespace_version,
|
|
16
|
+
install_package_by_version_id,
|
|
17
|
+
)
|
|
18
|
+
from cumulusci.utils import download_extract_zip
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class PackageNamespaceVersionDependency(base_dependency.StaticDependency):
|
|
24
|
+
"""Static dependency on a package identified by namespace and version number."""
|
|
25
|
+
|
|
26
|
+
namespace: str
|
|
27
|
+
version: str
|
|
28
|
+
package_name: Optional[str] = None
|
|
29
|
+
version_id: Optional[str] = None
|
|
30
|
+
|
|
31
|
+
password_env_name: Optional[str] = None
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def package(self):
|
|
35
|
+
return self.package_name or self.namespace or "Unknown Package"
|
|
36
|
+
|
|
37
|
+
def install(
|
|
38
|
+
self,
|
|
39
|
+
context: BaseProjectConfig,
|
|
40
|
+
org: OrgConfig,
|
|
41
|
+
options: Optional[PackageInstallOptions] = None,
|
|
42
|
+
retry_options=None,
|
|
43
|
+
):
|
|
44
|
+
if not options:
|
|
45
|
+
options = PackageInstallOptions()
|
|
46
|
+
if self.password_env_name:
|
|
47
|
+
options.password = os.environ.get(self.password_env_name)
|
|
48
|
+
if not retry_options:
|
|
49
|
+
retry_options = DEFAULT_PACKAGE_RETRY_OPTIONS
|
|
50
|
+
|
|
51
|
+
if "Beta" in self.version:
|
|
52
|
+
version_string = self.version.split(" ")[0]
|
|
53
|
+
beta = self.version.split(" ")[-1].strip(")")
|
|
54
|
+
version = f"{version_string}b{beta}"
|
|
55
|
+
else:
|
|
56
|
+
version = self.version
|
|
57
|
+
|
|
58
|
+
if org.has_minimum_package_version(
|
|
59
|
+
self.namespace,
|
|
60
|
+
version,
|
|
61
|
+
):
|
|
62
|
+
context.logger.info(
|
|
63
|
+
f"{self} or a newer version is already installed; skipping."
|
|
64
|
+
)
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
context.logger.info(f"Installing {self.description}")
|
|
68
|
+
install_package_by_namespace_version(
|
|
69
|
+
context,
|
|
70
|
+
org,
|
|
71
|
+
self.namespace,
|
|
72
|
+
self.version,
|
|
73
|
+
options,
|
|
74
|
+
retry_options=retry_options,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def name(self):
|
|
79
|
+
return f"Install {self.package} {self.version}"
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def description(self):
|
|
83
|
+
return f"{self.package} {self.version}"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class PackageVersionIdDependency(base_dependency.StaticDependency):
|
|
87
|
+
"""Static dependency on a package identified by 04t version id."""
|
|
88
|
+
|
|
89
|
+
version_id: str
|
|
90
|
+
package_name: Optional[str] = None
|
|
91
|
+
version_number: Optional[str] = None
|
|
92
|
+
|
|
93
|
+
password_env_name: Optional[str] = None
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def package(self):
|
|
97
|
+
return self.package_name or "Unknown Package"
|
|
98
|
+
|
|
99
|
+
def install(
|
|
100
|
+
self,
|
|
101
|
+
context: BaseProjectConfig,
|
|
102
|
+
org: OrgConfig,
|
|
103
|
+
options: Optional[PackageInstallOptions] = None,
|
|
104
|
+
retry_options=None,
|
|
105
|
+
):
|
|
106
|
+
if not options:
|
|
107
|
+
options = PackageInstallOptions()
|
|
108
|
+
if self.password_env_name:
|
|
109
|
+
options.password = os.environ.get(self.password_env_name)
|
|
110
|
+
if not retry_options:
|
|
111
|
+
retry_options = DEFAULT_PACKAGE_RETRY_OPTIONS
|
|
112
|
+
|
|
113
|
+
if any(
|
|
114
|
+
self.version_id == v.id
|
|
115
|
+
for v in itertools.chain(*org.installed_packages.values())
|
|
116
|
+
):
|
|
117
|
+
context.logger.info(
|
|
118
|
+
f"{self} or a newer version is already installed; skipping."
|
|
119
|
+
)
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
context.logger.info(f"Installing {self.description}")
|
|
123
|
+
install_package_by_version_id(
|
|
124
|
+
context,
|
|
125
|
+
org,
|
|
126
|
+
self.version_id,
|
|
127
|
+
options,
|
|
128
|
+
retry_options=retry_options,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def name(self):
|
|
133
|
+
return f"Install {self.description}"
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def description(self):
|
|
137
|
+
return f"{self.package} {self.version_number or self.version_id}"
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class UnmanagedZipURLDependency(base_dependency.UnmanagedDependency):
|
|
141
|
+
"""Static dependency on unmanaged metadata downloaded as a zip file from a URL."""
|
|
142
|
+
|
|
143
|
+
zip_url: AnyUrl
|
|
144
|
+
|
|
145
|
+
def _get_zip_src(self, context: BaseProjectConfig):
|
|
146
|
+
# We don't pass `subfolder` to download_extract_github_from_repo()
|
|
147
|
+
# because we need to get the whole ref in order to
|
|
148
|
+
# correctly handle any permutation of MDAPI/SFDX format,
|
|
149
|
+
# with or without a subfolder specified.
|
|
150
|
+
|
|
151
|
+
# install() will take care of that for us.
|
|
152
|
+
|
|
153
|
+
return download_extract_zip(self.zip_url)
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def name(self):
|
|
157
|
+
subfolder = f"/{self.subfolder}" if self.subfolder else ""
|
|
158
|
+
return f"Deploy {self.zip_url} {subfolder}"
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def description(self):
|
|
162
|
+
subfolder = f"/{self.subfolder}" if self.subfolder else ""
|
|
163
|
+
return f"{self.zip_url} {subfolder}"
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
#### Definition of dependency classes ####
|
|
167
|
+
|
|
168
|
+
AVAILABLE_DEPENDENCY_CLASSES = [
|
|
169
|
+
PackageVersionIdDependency,
|
|
170
|
+
PackageNamespaceVersionDependency,
|
|
171
|
+
UnmanagedZipURLDependency,
|
|
172
|
+
]
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def add_dependency_class(new_class: Type[base_dependency.Dependency]) -> None:
|
|
176
|
+
"""
|
|
177
|
+
Adds a new dependency class to the global list if it's not already present.
|
|
178
|
+
Args:
|
|
179
|
+
new_class: The dependency class to add.
|
|
180
|
+
"""
|
|
181
|
+
if new_class not in AVAILABLE_DEPENDENCY_CLASSES:
|
|
182
|
+
AVAILABLE_DEPENDENCY_CLASSES.append(new_class)
|
|
183
|
+
logger.debug(f"dependency_config: Added '{new_class}'.")
|
|
184
|
+
else:
|
|
185
|
+
logger.debug(f"dependency_config: '{new_class}' already exists.")
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def parse_dependency(dep_dict: dict[str, str]) -> Optional[base_dependency.Dependency]:
|
|
189
|
+
"""Parse a single dependency specification in the form of a dict
|
|
190
|
+
into a concrete Dependency subclass.
|
|
191
|
+
|
|
192
|
+
Returns None if the given dict cannot be parsed."""
|
|
193
|
+
|
|
194
|
+
# The order in which we attempt parsing is significant.
|
|
195
|
+
# GitHubDynamicDependency has an optional `ref` field, but we want
|
|
196
|
+
# any dependencies with a populated `ref` to be parsed as static deps.
|
|
197
|
+
|
|
198
|
+
# We also want PackageVersionIdDependency to match before
|
|
199
|
+
# PackageNamespaceVersionDependency, which can also accept a `version_id`.
|
|
200
|
+
|
|
201
|
+
for dependency_class in AVAILABLE_DEPENDENCY_CLASSES:
|
|
202
|
+
try:
|
|
203
|
+
dep = dependency_class.parse_obj(dep_dict)
|
|
204
|
+
if dep:
|
|
205
|
+
return dep
|
|
206
|
+
except ValidationError:
|
|
207
|
+
pass
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def parse_dependencies(
|
|
211
|
+
deps: Optional[List[dict[str, str]]]
|
|
212
|
+
) -> List[base_dependency.Dependency]:
|
|
213
|
+
"""Convert a list of dependency specifications in the form of dicts
|
|
214
|
+
(as defined in `cumulusci.yml`) and parse each into a concrete Dependency subclass.
|
|
215
|
+
|
|
216
|
+
Throws DependencyParseError if a dict cannot be parsed."""
|
|
217
|
+
parsed_deps = []
|
|
218
|
+
for dep in deps or []:
|
|
219
|
+
parsed = parse_dependency(dep)
|
|
220
|
+
if parsed is None:
|
|
221
|
+
raise DependencyParseError(f"Unable to parse dependency: {dep}")
|
|
222
|
+
parsed_deps.append(parsed)
|
|
223
|
+
return parsed_deps
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
#### Definition of dependency pins classes ####
|
|
227
|
+
|
|
228
|
+
AVAILABLE_DEPENDENCY_PIN_CLASSES = []
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def parse_pins(pins: Optional[List[dict]]) -> List[base_dependency.DependencyPin]:
|
|
232
|
+
"""Convert a list of dependency pin specifications in the form of dicts
|
|
233
|
+
(as defined in `cumulusci.yml`) and parse each into a concrete DependencyPin subclass.
|
|
234
|
+
|
|
235
|
+
Throws DependencyParseError if a dict cannot be parsed."""
|
|
236
|
+
parsed_pins = []
|
|
237
|
+
for pin in pins or []:
|
|
238
|
+
parsed = parse_dependency_pin(pin)
|
|
239
|
+
if parsed is None:
|
|
240
|
+
raise DependencyParseError(f"Unable to parse dependency pin: {pin}")
|
|
241
|
+
parsed_pins.append(parsed)
|
|
242
|
+
|
|
243
|
+
return parsed_pins
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def add_dependency_pin_class(new_class: Type[base_dependency.DependencyPin]) -> None:
|
|
247
|
+
"""
|
|
248
|
+
Adds a new dependency pin class to the global list if it's not already present.
|
|
249
|
+
Args:
|
|
250
|
+
new_class: The dependency pin class to add.
|
|
251
|
+
"""
|
|
252
|
+
if new_class not in AVAILABLE_DEPENDENCY_PIN_CLASSES:
|
|
253
|
+
AVAILABLE_DEPENDENCY_PIN_CLASSES.append(new_class)
|
|
254
|
+
logger.info(f"dependency_pin_config: Added '{new_class}'.")
|
|
255
|
+
else:
|
|
256
|
+
logger.warning(f"dependency_pin_config: '{new_class}' already exists.")
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def parse_dependency_pin(
|
|
260
|
+
pin_dict: dict[str, str]
|
|
261
|
+
) -> Optional[base_dependency.DependencyPin]:
|
|
262
|
+
"""Parse a single dependency pin specification in the form of a dict
|
|
263
|
+
into a concrete DependencyPin subclass.
|
|
264
|
+
|
|
265
|
+
Returns None if the given dict cannot be parsed."""
|
|
266
|
+
|
|
267
|
+
for dependency_pin_class in AVAILABLE_DEPENDENCY_PIN_CLASSES:
|
|
268
|
+
try:
|
|
269
|
+
pin = dependency_pin_class.parse_obj(pin_dict)
|
|
270
|
+
if pin:
|
|
271
|
+
return pin
|
|
272
|
+
except ValidationError:
|
|
273
|
+
pass
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from abc import ABC
|
|
3
|
+
from functools import lru_cache
|
|
4
|
+
from typing import Optional, Type
|
|
5
|
+
|
|
6
|
+
from pydantic import root_validator
|
|
7
|
+
from pydantic.networks import AnyUrl
|
|
8
|
+
|
|
9
|
+
import cumulusci.core.dependencies.base as base_dependency
|
|
10
|
+
from cumulusci.core.exceptions import DependencyResolutionError, GithubApiNotFoundError
|
|
11
|
+
from cumulusci.utils.git import split_repo_url
|
|
12
|
+
from cumulusci.vcs.github.adapter import GitHubRepository
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
VCS_GITHUB = "github"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@lru_cache(50)
|
|
20
|
+
def get_github_repo(project_config, url) -> GitHubRepository:
|
|
21
|
+
from cumulusci.vcs.github.service import VCSService, get_github_service_for_url
|
|
22
|
+
|
|
23
|
+
vcs_service: Optional[VCSService] = get_github_service_for_url(project_config, url)
|
|
24
|
+
|
|
25
|
+
if vcs_service is None:
|
|
26
|
+
raise DependencyResolutionError(
|
|
27
|
+
f"Could not find a GitHub service for URL: {url}"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
repo = vcs_service.get_repository(options={"repository_url": url})
|
|
32
|
+
if repo is None:
|
|
33
|
+
raise GithubApiNotFoundError(f"Get GitHub Repository found None. {url}")
|
|
34
|
+
return repo
|
|
35
|
+
except GithubApiNotFoundError as e:
|
|
36
|
+
raise DependencyResolutionError(
|
|
37
|
+
f"Could not find a GitHub repository at {url}: {e}"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _validate_github_parameters(values):
|
|
42
|
+
if values.get("repo_owner") or values.get("repo_name"):
|
|
43
|
+
logger.warning(
|
|
44
|
+
"The repo_name and repo_owner keys are deprecated. Please use the github key."
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
assert (
|
|
48
|
+
values.get("url")
|
|
49
|
+
or values.get("github")
|
|
50
|
+
or (values.get("repo_owner") and values.get("repo_name"))
|
|
51
|
+
), "Must specify `github` or `repo_owner` and `repo_name`"
|
|
52
|
+
|
|
53
|
+
# Populate the `github` property if not already populated.
|
|
54
|
+
if not values.get("github") and values.get("repo_name"):
|
|
55
|
+
values["github"] = values[
|
|
56
|
+
"url"
|
|
57
|
+
] = f"https://github.com/{values['repo_owner']}/{values['repo_name']}"
|
|
58
|
+
values.pop("repo_owner")
|
|
59
|
+
values.pop("repo_name")
|
|
60
|
+
|
|
61
|
+
return values
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _sync_github_and_url(values):
|
|
65
|
+
# If only github is provided, set url to github
|
|
66
|
+
if values.get("github") and not values.get("url"):
|
|
67
|
+
values["url"] = values["github"]
|
|
68
|
+
# If only url is provided, set github to url
|
|
69
|
+
elif values.get("url") and not values.get("github"):
|
|
70
|
+
values["github"] = values["url"]
|
|
71
|
+
return values
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class GitHubDependencyPin(base_dependency.VcsDependencyPin):
|
|
75
|
+
"""Model representing a request to pin a GitHub dependency to a specific tag"""
|
|
76
|
+
|
|
77
|
+
github: str
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def vcsTagResolver(self): # -> Type["AbstractTagResolver"]:
|
|
81
|
+
from cumulusci.core.dependencies.github_resolvers import ( # Circular imports
|
|
82
|
+
GitHubTagResolver,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
return GitHubTagResolver
|
|
86
|
+
|
|
87
|
+
@root_validator(pre=True)
|
|
88
|
+
def sync_vcs_and_url(cls, values):
|
|
89
|
+
"""Defined vcs should be assigned to url"""
|
|
90
|
+
return _sync_github_and_url(values)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
GitHubDependencyPin.update_forward_refs()
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class BaseGitHubDependency(base_dependency.BaseVcsDynamicDependency, ABC):
|
|
97
|
+
"""Base class for dynamic dependencies that reference a GitHub repo."""
|
|
98
|
+
|
|
99
|
+
github: Optional[AnyUrl] = None
|
|
100
|
+
vcs: str = VCS_GITHUB
|
|
101
|
+
pin_class = GitHubDependencyPin
|
|
102
|
+
|
|
103
|
+
repo_owner: Optional[str] = None # Deprecated - use full URL
|
|
104
|
+
repo_name: Optional[str] = None # Deprecated - use full URL
|
|
105
|
+
|
|
106
|
+
@root_validator
|
|
107
|
+
def check_deprecated_fields(cls, values):
|
|
108
|
+
if values.get("repo_owner") or values.get("repo_name"):
|
|
109
|
+
logger.warning(
|
|
110
|
+
"The dependency keys `repo_owner` and `repo_name` are deprecated. Use the full repo URL with the `github` key instead."
|
|
111
|
+
)
|
|
112
|
+
return values
|
|
113
|
+
|
|
114
|
+
@root_validator
|
|
115
|
+
def validate_github_parameters(cls, values):
|
|
116
|
+
return _validate_github_parameters(values)
|
|
117
|
+
|
|
118
|
+
@root_validator(pre=True)
|
|
119
|
+
def sync_vcs_and_url(cls, values):
|
|
120
|
+
"""Defined vcs should be assigned to url"""
|
|
121
|
+
return _sync_github_and_url(values)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class GitHubDynamicSubfolderDependency(
|
|
125
|
+
BaseGitHubDependency, base_dependency.VcsDynamicSubfolderDependency
|
|
126
|
+
):
|
|
127
|
+
"""A dependency expressed by a reference to a subfolder of a GitHub repo, which needs
|
|
128
|
+
to be resolved to a specific ref. This is always an unmanaged dependency."""
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def unmanagedVcsDependency(self) -> Type["UnmanagedGitHubRefDependency"]:
|
|
132
|
+
"""A human-readable description of the dependency."""
|
|
133
|
+
return UnmanagedGitHubRefDependency
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class GitHubDynamicDependency(
|
|
137
|
+
BaseGitHubDependency, base_dependency.VcsDynamicDependency
|
|
138
|
+
):
|
|
139
|
+
"""A dependency expressed by a reference to a GitHub repo, which needs
|
|
140
|
+
to be resolved to a specific ref and/or package version."""
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def unmanagedVcsDependency(self) -> Type["UnmanagedGitHubRefDependency"]:
|
|
144
|
+
"""A human-readable description of the dependency."""
|
|
145
|
+
return UnmanagedGitHubRefDependency
|
|
146
|
+
|
|
147
|
+
def get_repo(self, context, url) -> "GitHubRepository":
|
|
148
|
+
return get_github_repo(context, url)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class UnmanagedGitHubRefDependency(base_dependency.UnmanagedVcsDependency):
|
|
152
|
+
"""Static dependency on unmanaged metadata in a specific GitHub ref and subfolder."""
|
|
153
|
+
|
|
154
|
+
repo_owner: Optional[str] = None
|
|
155
|
+
repo_name: Optional[str] = None
|
|
156
|
+
|
|
157
|
+
# or
|
|
158
|
+
github: Optional[AnyUrl] = None
|
|
159
|
+
|
|
160
|
+
def get_repo(self, context, url) -> "GitHubRepository":
|
|
161
|
+
return get_github_repo(context, url)
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def package_name(self) -> str:
|
|
165
|
+
repo_owner, repo_name = split_repo_url((str(self.github)))
|
|
166
|
+
package_name = f"{repo_owner}/{repo_name} {self.subfolder}"
|
|
167
|
+
return package_name
|
|
168
|
+
|
|
169
|
+
@root_validator
|
|
170
|
+
def validate(cls, values):
|
|
171
|
+
return _validate_github_parameters(values)
|
|
172
|
+
|
|
173
|
+
@root_validator(pre=True)
|
|
174
|
+
def sync_vcs_and_url(cls, values):
|
|
175
|
+
"""Defined vcs should be assigned to url"""
|
|
176
|
+
|
|
177
|
+
return _sync_github_and_url(values)
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
from typing import Any, List, Optional
|
|
3
|
+
|
|
4
|
+
from cumulusci.core.config.project_config import BaseProjectConfig
|
|
5
|
+
from cumulusci.core.dependencies.github import (
|
|
6
|
+
VCS_GITHUB,
|
|
7
|
+
BaseGitHubDependency,
|
|
8
|
+
get_github_repo,
|
|
9
|
+
)
|
|
10
|
+
from cumulusci.core.dependencies.resolvers import (
|
|
11
|
+
AbstractReleaseTagResolver,
|
|
12
|
+
AbstractTagResolver,
|
|
13
|
+
AbstractUnmanagedHeadResolver,
|
|
14
|
+
AbstractVcsCommitStatusPackageResolver,
|
|
15
|
+
AbstractVcsReleaseBranchResolver,
|
|
16
|
+
DependencyResolutionStrategy,
|
|
17
|
+
)
|
|
18
|
+
from cumulusci.core.exceptions import DependencyResolutionError
|
|
19
|
+
from cumulusci.utils.git import get_feature_branch_name
|
|
20
|
+
from cumulusci.vcs.bootstrap import find_repo_feature_prefix
|
|
21
|
+
from cumulusci.vcs.github.adapter import GitHubBranch, GitHubRepository
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class GitHubTagResolver(AbstractTagResolver):
|
|
25
|
+
"""Resolver that identifies a ref by a specific GitHub tag."""
|
|
26
|
+
|
|
27
|
+
name = "GitHub Tag Resolver"
|
|
28
|
+
vcs = VCS_GITHUB
|
|
29
|
+
|
|
30
|
+
def get_repo(
|
|
31
|
+
self, context: BaseProjectConfig, url: Optional[str]
|
|
32
|
+
) -> GitHubRepository:
|
|
33
|
+
return get_github_repo(context, url)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class GitHubReleaseTagResolver(AbstractReleaseTagResolver):
|
|
37
|
+
"""Resolver that identifies a ref by finding the latest GitHub release."""
|
|
38
|
+
|
|
39
|
+
name = "GitHub Release Resolver"
|
|
40
|
+
vcs = VCS_GITHUB
|
|
41
|
+
|
|
42
|
+
def get_repo(
|
|
43
|
+
self, context: BaseProjectConfig, url: Optional[str]
|
|
44
|
+
) -> GitHubRepository:
|
|
45
|
+
return get_github_repo(context, url)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class GitHubBetaReleaseTagResolver(GitHubReleaseTagResolver):
|
|
49
|
+
"""Resolver that identifies a ref by finding the latest GitHub release, including betas."""
|
|
50
|
+
|
|
51
|
+
name = "GitHub Release Resolver (Betas)"
|
|
52
|
+
include_beta = True
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class GitHubUnmanagedHeadResolver(AbstractUnmanagedHeadResolver):
|
|
56
|
+
"""Resolver that identifies a ref by finding the latest commit on the main branch."""
|
|
57
|
+
|
|
58
|
+
name = "GitHub Unmanaged Resolver"
|
|
59
|
+
vcs = VCS_GITHUB
|
|
60
|
+
|
|
61
|
+
def get_repo(
|
|
62
|
+
self, context: BaseProjectConfig, url: Optional[str]
|
|
63
|
+
) -> GitHubRepository:
|
|
64
|
+
return get_github_repo(context, url)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class GitHubReleaseBranchCommitStatusResolver(AbstractVcsReleaseBranchResolver):
|
|
68
|
+
"""Resolver that identifies a ref by finding a beta 2GP package version
|
|
69
|
+
in a commit status on a `feature/NNN` release branch."""
|
|
70
|
+
|
|
71
|
+
name = "GitHub Release Branch Commit Status Resolver"
|
|
72
|
+
commit_status_context = "2gp_context"
|
|
73
|
+
commit_status_default = "Build Feature Test Package"
|
|
74
|
+
branch_offset_start = 0
|
|
75
|
+
branch_offset_end = 1
|
|
76
|
+
|
|
77
|
+
def get_repo(
|
|
78
|
+
self, context: BaseProjectConfig, url: Optional[str]
|
|
79
|
+
) -> GitHubRepository:
|
|
80
|
+
return get_github_repo(context, url)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class GitHubReleaseBranchUnlockedResolver(AbstractVcsReleaseBranchResolver):
|
|
84
|
+
"""Resolver that identifies a ref by finding an unlocked package version
|
|
85
|
+
in a commit status on a `feature/NNN` release branch."""
|
|
86
|
+
|
|
87
|
+
name = "GitHub Release Branch Unlocked Commit Status Resolver"
|
|
88
|
+
commit_status_context = "unlocked_context"
|
|
89
|
+
commit_status_default = "Build Unlocked Test Package"
|
|
90
|
+
branch_offset_start = 0
|
|
91
|
+
branch_offset_end = 1
|
|
92
|
+
|
|
93
|
+
def get_repo(
|
|
94
|
+
self, context: BaseProjectConfig, url: Optional[str]
|
|
95
|
+
) -> GitHubRepository:
|
|
96
|
+
return get_github_repo(context, url)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class GitHubPreviousReleaseBranchCommitStatusResolver(AbstractVcsReleaseBranchResolver):
|
|
100
|
+
"""Resolver that identifies a ref by finding a beta 2GP package version
|
|
101
|
+
in a commit status on a `feature/NNN` release branch that is earlier
|
|
102
|
+
than the matching local release branch."""
|
|
103
|
+
|
|
104
|
+
name = "GitHub Previous Release Branch Commit Status Resolver"
|
|
105
|
+
commit_status_context = "2gp_context"
|
|
106
|
+
commit_status_default = "Build Feature Test Package"
|
|
107
|
+
branch_offset_start = 1
|
|
108
|
+
branch_offset_end = 3
|
|
109
|
+
|
|
110
|
+
def get_repo(
|
|
111
|
+
self, context: BaseProjectConfig, url: Optional[str]
|
|
112
|
+
) -> GitHubRepository:
|
|
113
|
+
return get_github_repo(context, url)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class GitHubPreviousReleaseBranchUnlockedResolver(AbstractVcsReleaseBranchResolver):
|
|
117
|
+
"""Resolver that identifies a ref by finding an unlocked package version
|
|
118
|
+
in a commit status on a `feature/NNN` release branch that is earlier
|
|
119
|
+
than the matching local release branch."""
|
|
120
|
+
|
|
121
|
+
name = "GitHub Previous Release Branch Unlocked Commit Status Resolver"
|
|
122
|
+
commit_status_context = "unlocked_context"
|
|
123
|
+
commit_status_default = "Build Unlocked Test Package"
|
|
124
|
+
branch_offset_start = 1
|
|
125
|
+
branch_offset_end = 3
|
|
126
|
+
|
|
127
|
+
def get_repo(
|
|
128
|
+
self, context: BaseProjectConfig, url: Optional[str]
|
|
129
|
+
) -> GitHubRepository:
|
|
130
|
+
return get_github_repo(context, url)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class AbstractGitHubExactMatchCommitStatusResolver(
|
|
134
|
+
AbstractVcsCommitStatusPackageResolver, abc.ABC
|
|
135
|
+
):
|
|
136
|
+
"""Abstract base class for resolvers that identify a ref by finding a package version
|
|
137
|
+
in a commit status on a branch whose name matches the local branch."""
|
|
138
|
+
|
|
139
|
+
def get_repo(
|
|
140
|
+
self, context: BaseProjectConfig, url: Optional[str]
|
|
141
|
+
) -> GitHubRepository:
|
|
142
|
+
return get_github_repo(context, url)
|
|
143
|
+
|
|
144
|
+
def get_branches(
|
|
145
|
+
self,
|
|
146
|
+
dep: BaseGitHubDependency,
|
|
147
|
+
context: BaseProjectConfig,
|
|
148
|
+
) -> List[GitHubBranch]:
|
|
149
|
+
repo = self.get_repo(context, dep.url)
|
|
150
|
+
if not repo:
|
|
151
|
+
raise DependencyResolutionError(
|
|
152
|
+
f"Unable to access GitHub repository for {dep.url}"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
try:
|
|
156
|
+
remote_branch_prefix = find_repo_feature_prefix(repo)
|
|
157
|
+
except Exception:
|
|
158
|
+
context.logger.info(
|
|
159
|
+
f"Could not find feature branch prefix or commit-status context for {repo.clone_url}. Unable to resolve package."
|
|
160
|
+
)
|
|
161
|
+
return []
|
|
162
|
+
|
|
163
|
+
# Attempt exact match
|
|
164
|
+
try:
|
|
165
|
+
branch = get_feature_branch_name(
|
|
166
|
+
context.repo_branch, context.project__git__prefix_feature
|
|
167
|
+
)
|
|
168
|
+
release_branch = repo.branch(f"{remote_branch_prefix}{branch}")
|
|
169
|
+
except Exception:
|
|
170
|
+
context.logger.info(f"Exact-match branch not found for {repo.clone_url}.")
|
|
171
|
+
return []
|
|
172
|
+
|
|
173
|
+
return [release_branch]
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class GitHubExactMatch2GPResolver(AbstractGitHubExactMatchCommitStatusResolver):
|
|
177
|
+
"""Resolver that identifies a ref by finding a 2GP package version
|
|
178
|
+
in a commit status on a branch whose name matches the local branch."""
|
|
179
|
+
|
|
180
|
+
name = "GitHub Exact-Match Commit Status Resolver"
|
|
181
|
+
commit_status_context = "2gp_context"
|
|
182
|
+
commit_status_default = "Build Feature Test Package"
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class GitHubExactMatchUnlockedCommitStatusResolver(
|
|
186
|
+
AbstractGitHubExactMatchCommitStatusResolver
|
|
187
|
+
):
|
|
188
|
+
"""Resolver that identifies a ref by finding an unlocked package version
|
|
189
|
+
in a commit status on a branch whose name matches the local branch."""
|
|
190
|
+
|
|
191
|
+
name = "GitHub Exact-Match Unlocked Commit Status Resolver"
|
|
192
|
+
commit_status_context = "unlocked_context"
|
|
193
|
+
commit_status_default = "Build Unlocked Test Package"
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
class AbstractGitHubDefaultBranchCommitStatusResolver(
|
|
197
|
+
AbstractVcsCommitStatusPackageResolver, abc.ABC
|
|
198
|
+
):
|
|
199
|
+
"""Abstract base class for resolvers that identify a ref by finding a beta package version
|
|
200
|
+
in a commit status on the repo's default branch."""
|
|
201
|
+
|
|
202
|
+
def get_repo(
|
|
203
|
+
self, context: BaseProjectConfig, url: Optional[str]
|
|
204
|
+
) -> GitHubRepository:
|
|
205
|
+
return get_github_repo(context, url)
|
|
206
|
+
|
|
207
|
+
def get_branches(
|
|
208
|
+
self,
|
|
209
|
+
dep: BaseGitHubDependency,
|
|
210
|
+
context: BaseProjectConfig,
|
|
211
|
+
) -> List[GitHubBranch]:
|
|
212
|
+
repo = self.get_repo(context, dep.url)
|
|
213
|
+
|
|
214
|
+
return [repo.branch(repo.default_branch)]
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class GitHubDefaultBranch2GPResolver(AbstractGitHubDefaultBranchCommitStatusResolver):
|
|
218
|
+
name = "GitHub Default Branch Commit Status Resolver"
|
|
219
|
+
commit_status_context = "2gp_context"
|
|
220
|
+
commit_status_default = "Build Feature Test Package"
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
class GitHubDefaultBranchUnlockedCommitStatusResolver(
|
|
224
|
+
AbstractGitHubDefaultBranchCommitStatusResolver
|
|
225
|
+
):
|
|
226
|
+
name = "GitHub Default Branch Unlocked Commit Status Resolver"
|
|
227
|
+
commit_status_context = "unlocked_context"
|
|
228
|
+
commit_status_default = "Build Unlocked Test Package"
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
GITHUB_RESOLVER_CLASSES: dict[str, type[Any]] = {
|
|
232
|
+
DependencyResolutionStrategy.STATIC_TAG_REFERENCE: GitHubTagResolver,
|
|
233
|
+
DependencyResolutionStrategy.COMMIT_STATUS_EXACT_BRANCH: GitHubExactMatch2GPResolver,
|
|
234
|
+
DependencyResolutionStrategy.COMMIT_STATUS_RELEASE_BRANCH: GitHubReleaseBranchCommitStatusResolver,
|
|
235
|
+
DependencyResolutionStrategy.COMMIT_STATUS_PREVIOUS_RELEASE_BRANCH: GitHubPreviousReleaseBranchCommitStatusResolver,
|
|
236
|
+
DependencyResolutionStrategy.COMMIT_STATUS_DEFAULT_BRANCH: GitHubDefaultBranch2GPResolver,
|
|
237
|
+
DependencyResolutionStrategy.BETA_RELEASE_TAG: GitHubBetaReleaseTagResolver,
|
|
238
|
+
DependencyResolutionStrategy.RELEASE_TAG: GitHubReleaseTagResolver,
|
|
239
|
+
DependencyResolutionStrategy.UNMANAGED_HEAD: GitHubUnmanagedHeadResolver,
|
|
240
|
+
DependencyResolutionStrategy.UNLOCKED_EXACT_BRANCH: GitHubExactMatchUnlockedCommitStatusResolver,
|
|
241
|
+
DependencyResolutionStrategy.UNLOCKED_RELEASE_BRANCH: GitHubReleaseBranchUnlockedResolver,
|
|
242
|
+
DependencyResolutionStrategy.UNLOCKED_PREVIOUS_RELEASE_BRANCH: GitHubPreviousReleaseBranchUnlockedResolver,
|
|
243
|
+
DependencyResolutionStrategy.UNLOCKED_DEFAULT_BRANCH: GitHubDefaultBranchUnlockedCommitStatusResolver,
|
|
244
|
+
}
|