diff --git a/cumulusci/core/config/org_config.py b/cumulusci/core/config/org_config.py index b3f191d172..0783ba3df9 100644 --- a/cumulusci/core/config/org_config.py +++ b/cumulusci/core/config/org_config.py @@ -308,6 +308,28 @@ def has_minimum_package_version(self, package_identifier, version_identifier): return installed_version[0].number >= version_identifier + def get_package_from_version(self, package_version_id, installationkey=None): + """Fetch and return the package details based on a provided package version ID. + Find the SubscriberPackageVersion for the 04t Id provided in package_version_id + If no package is found return None. If a package is found return the first record + (assuming that the query will only return one record for a specific Id).""" + + query = ( + "tooling/query/?q=SELECT Id, SubscriberPackageId, MajorVersion, " + "MinorVersion, PatchVersion, BuildNumber from SubscriberPackageVersion " + f"WHERE Id = '{package_version_id}'" + ) + if installationkey: + query += f" AND InstallationKey = '{installationkey}'" + + response = self.salesforce_client.restful(query) + + if not response or "records" not in response or not response["records"]: + return None + + package = response["records"][0] + return package + @property def installed_packages(self): """installed_packages is a dict mapping a namespace or package Id (033*) to the installed package diff --git a/cumulusci/core/dependencies/dependencies.py b/cumulusci/core/dependencies/dependencies.py index 3301cdb8a5..c987eb0ad7 100644 --- a/cumulusci/core/dependencies/dependencies.py +++ b/cumulusci/core/dependencies/dependencies.py @@ -519,6 +519,20 @@ def install( ) return + package = org.get_package_from_version(self.version_id, options.password) + + if package: + package_id = package["SubscriberPackageId"] + package_version_number = f"{package['MajorVersion']}.{package['MinorVersion']}.{package['PatchVersion']}" + + if org.has_minimum_package_version( + package_id, + package_version_number, + ): + context.logger.info( + f"{self} or a newer version is already installed; skipping." + ) + return context.logger.info(f"Installing {self.description}") install_package_by_version_id( context,