From 43bad59bbc3b14853d6a69def4363d3330a78eb4 Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Tue, 28 Feb 2023 16:33:46 -0600 Subject: [PATCH 01/22] WIP, Move Acquia DB backups to cloud v2. --- composer.json | 6 +- defaults.yml | 14 - docs/tasks.md | 5 +- src/TheBuild/Acquia/AcquiaTask.php | 126 --------- src/TheBuild/Acquia/GetLatestBackupTask.php | 290 ++++---------------- targets/acquia.xml | 3 +- 6 files changed, 54 insertions(+), 390 deletions(-) delete mode 100644 src/TheBuild/Acquia/AcquiaTask.php diff --git a/composer.json b/composer.json index aeaa392c..c8432a77 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "pear/versioncontrol_git": "@dev", "phing/phing": "^2.14", "phpmd/phpmd": "^2.4", - "phpspec/prophecy-phpunit": "^2" + "phpspec/prophecy-phpunit": "^2", + "typhonius/acquia-php-sdk-v2": "^2.0" }, "autoload": { "psr-0": { @@ -34,7 +35,8 @@ "sort-packages": true, "allow-plugins": { "cweagans/composer-patches": true, - "dealerdirect/phpcodesniffer-composer-installer": true + "dealerdirect/phpcodesniffer-composer-installer": true, + "phing/phing-composer-configurator": true } }, "extra": { diff --git a/defaults.yml b/defaults.yml index 507c204c..8bdd3552 100644 --- a/defaults.yml +++ b/defaults.yml @@ -187,14 +187,6 @@ acquia: # Directory for storing downloaded database backups. backups: artifacts/backups - # Max age of the downloaded backup database, in hours. - backup_age_hours: 24 - - # The Acquia Cloud hosting "realm" where the site is running. - # - Acquia Cloud Enterprise: 'prod' - # - Acquia Cloud Professional: 'devcloud' - realm: "" - # Acquia site/application name. site: "" @@ -205,12 +197,6 @@ acquia: # Acquia environment to download backups from. env: "prod" - # Acquia Cloud API credentials file, downloaded from your Acquia account. Do not check - # this file into your codebase. - cloud: - conf: "${env.HOME}/.acquia/cloudapi.conf" - - # Configuration to use the PHP interpreter's built in linter to check for syntax errors # and deprecated code. This property is used by the task in the # defaults/build.xml template. diff --git a/docs/tasks.md b/docs/tasks.md index 6daa6afd..6634946f 100644 --- a/docs/tasks.md +++ b/docs/tasks.md @@ -103,13 +103,10 @@ Download a recent backup from Acquia Cloud. | Name | Type | Description | Default | Required | |---|---|---|---|---| | dir | directory path | Local backups directory. | | Yes | -| realm | string | Acquia hosting realm, either "devcloud" or "prod". | | Yes | | site | string | Acquia site name. | | Yes | | env | string | Acquia environment, generally "dev", "test", or "prod". | | Yes | | database | string | Acquia database name. | The site name. | No | -| maxAge | int | Maximum age of the backup, in hours. | 24 | No | -| propertyName | string | Name of a property to set to the backup file. | | No | -| credentialsFile | file path | Path to your Acquia Cloud API credentials. (Do not check this file in to your repository) | `~/.acquia/cloudapi.conf` | No | +| credentialsFile | file path | Path to your Acquia Cloud API credentials. (Do not check this file in to your repository) | `~/.acquia/cloudapiv2.conf` | No | ### Example diff --git a/src/TheBuild/Acquia/AcquiaTask.php b/src/TheBuild/Acquia/AcquiaTask.php deleted file mode 100644 index dc53c1c0..00000000 --- a/src/TheBuild/Acquia/AcquiaTask.php +++ /dev/null @@ -1,126 +0,0 @@ -mail) || empty($this->key)) { - if (empty($this->credentialsFile)) { - $this->credentialsFile = new \PhingFile($_SERVER['HOME'] . '/.acquia/cloudapi.conf'); - } - - if (!file_exists($this->credentialsFile) || !is_readable($this->credentialsFile)) { - throw new \BuildException("Acquia Cloud credentials file '{$this->credentialsFile}' is not available."); - } - - $contents = file_get_contents($this->credentialsFile); - $creds = json_decode($contents, TRUE); - - $this->mail = $creds['mail']; - $this->key = $creds['key']; - } - - if (empty($this->mail) || empty($this->key)) { - throw new \BuildException('Missing Acquia Cloud API credentials.'); - } - } - - /** - * Build an HTTP request object against the Acquia Cloud API. - * - * @param string $path - * Acquia Cloud API path. - * - * @return \HTTP_Request2 - * Request object. - */ - protected function createRequest(string $path) : \HTTP_Request2 { - $this->loadCredentials(); - - $uri = $this->endpoint . '/' . ltrim($path, '/'); - - $request = new \HTTP_Request2($uri); - $request->setConfig('follow_redirects', TRUE); - $request->setAuth($this->mail, $this->key); - - return $request; - } - - /** - * Example of how to query the Acquia Cloud API. - * - * @param string $path - * Acquia Cloud API path. - * - * @return string - * API response. - */ - protected function getApiResponseBody(string $path) : string { - $request = $this->createRequest($path); - - $this->log('GET ' . $request->getUrl()); - $response = $request->send(); - return $response->getBody(); - } - - /** - * Set the Acquia credentials file. - * - * @param \PhingFile $file - * Acquia credentials file. - * - * @throws \IOException - * @throws \NullPointerException - */ - public function setCredentialsFile(\PhingFile $file) { - $this->credentialsFile = new \PhingFile($file); - } - -} diff --git a/src/TheBuild/Acquia/GetLatestBackupTask.php b/src/TheBuild/Acquia/GetLatestBackupTask.php index 3f11cf13..0e745e93 100644 --- a/src/TheBuild/Acquia/GetLatestBackupTask.php +++ b/src/TheBuild/Acquia/GetLatestBackupTask.php @@ -2,10 +2,16 @@ namespace TheBuild\Acquia; +use AcquiaCloudApi\Connector\Client; +use AcquiaCloudApi\Connector\Connector; +use AcquiaCloudApi\Endpoints\Applications; +use AcquiaCloudApi\Endpoints\Environments; +use AcquiaCloudApi\Endpoints\DatabaseBackups; + /** * Fetch a recent backup from Acquia. */ -class GetLatestBackupTask extends AcquiaTask { +class GetLatestBackupTask extends \Task { /** * Required. Directory for storing downloaded database backups. @@ -14,18 +20,6 @@ class GetLatestBackupTask extends AcquiaTask { */ protected $dir; - /** - * Required. The Acquia Cloud hosting realm where the site is running. - * - * This also appears in a site's server names, as - * 'sitename.REALM.hosting.acquia.com'. - * - Acquia Cloud Enterprise: 'prod' - * - Acquia Cloud Professional: 'devcloud' - * - * @var string - */ - protected $realm; - /** * Required. The Acquia Cloud site account name. * @@ -53,35 +47,6 @@ class GetLatestBackupTask extends AcquiaTask { */ protected $database; - /** - * Optional. Maximum age of the database backup in hours. - * - * If there is no backup matching this age in the current backups.json, the - * backups.json will be refreshed and the newest backup will be downloaded. - * - * @var int - */ - protected $maxAge = 24; - - /** - * Name of a property to populate with the path to the latest database backup. - * - * Optional parameter. - * - * @var string - */ - protected $propertyName; - - /** - * Where to store the JSON list of database backups. - * - * This info is downloaded from the Acquia Cloud API. The file is set to - * 'backups.json' in the directory specified by $dir. - * - * @var \PhingFile - */ - protected $backupsFile; - /** * {@inheritdoc} * @@ -90,207 +55,66 @@ class GetLatestBackupTask extends AcquiaTask { */ public function main() { $this->validate(); - - // Store the Acquia Cloud API JSON database backup records in our backups - // directory.. - $this->backupsFile = new \PhingFile($this->dir, "backups-{$this->site}-{$this->database}-{$this->env}.json"); - - // Check the database backup records for entries within our time window. - $backups = $this->getCurrentBackupRecords(); - - // Have we already downloaded any of the entries in our time window? - $downloaded_backups = []; - foreach ($backups as $backup) { - $filename = basename($backup['path']); - $file = new \PhingFile($this->dir, $filename); - - if ($file->exists()) { - $downloaded_backups[] = $backup; - } - } - - // Pick out the newest current backup record, preferring already downloaded - // backups. - $newest_backup = FALSE; - if (!empty($downloaded_backups)) { - $newest_backup = end($downloaded_backups); - $this->log("Using previously downloaded backup from " . $this->formatBackupTime($newest_backup) . " ({$newest_backup['id']})"); - } - elseif (!empty($backups)) { - $newest_backup = end($backups); - $this->log("Using backup from " . $this->formatBackupTime($newest_backup) . " ({$newest_backup['id']})"); - } - - // If we don't have a current enough backup record, check the API directly. - if (!$newest_backup) { - $this->downloadBackupRecords($this->backupsFile); - // Always return something, regardless of the time window. - $backups = $this->getBackupRecords($this->backupsFile); - $newest_backup = end($backups); - - $this->log("Using backup from " . $this->formatBackupTime($newest_backup) . " ({$newest_backup['id']})"); - } - - // This means that we didn't have a current record in our backups json, and - // the Acquia Cloud API returned empty or malformed JSON. - if (empty($newest_backup)) { - throw new \BuildException('Failed to find a backup record.'); - } - - // Download the backup if it does not yet exist on the filesystem. - $filename = basename($newest_backup['path']); - $file = new \PhingFile($this->dir, $filename); - if (!$file->exists()) { - $this->log("Downloading the backup to " . $file->getAbsolutePath()); - $this->downloadBackup($newest_backup, $file); - } - else { - $this->log("Existing backup found at " . $file->getAbsolutePath()); - } - - // Set the property value if a propertyName was provided. - if ($this->propertyName) { - $project = $this->getProject(); - $project->setNewProperty($this->propertyName, $file->getAbsolutePath()); - } - } - - /** - * Download a backup from Acquia Cloud. - * - * @param array $backup - * Acquia backup info array. - * @param \PhingFile $destination - * Destination file for the downloaded backup. - */ - protected function downloadBackup(array $backup, \PhingFile $destination) { - $stream = fopen($destination->getAbsolutePath(), 'wb'); - if (!$stream) { - throw new \BuildException('Can not write to ' . $destination->getAbsolutePath()); - } - - // Use an HTTP_Request2 with the Observer pattern in order to download large - // backups. - // @see HTTP/Request2/Observer/UncompressingDownload.php - // @see https://cloudapi.acquia.com/#GET__sites__site_envs__env_dbs__db_backups-instance_route - $request = $this->createRequest("/sites/{$this->realm}:{$this->site}/envs/{$this->env}/dbs/{$this->database}/backups/{$backup['id']}/download.json"); - $request->setConfig('store_body', FALSE); - - $observer = new \HTTP_Request2_Observer_UncompressingDownload($stream, 5000000000); - $request->attach($observer); - - $response = $request->send(); - fclose($stream); - - $this->log("Downloaded " . intval($response->getHeader('content-length')) / 1000000 . "MB to " . $destination->getAbsolutePath()); + $credentials = $this->getAcquiaCloudCredentials(); + $client = $this->connectAcquiaCloud($credentials); + $application_uuid = $this->getApplicationUuid($client); + $env_uuid = $this->getEnvironmentsUuid($client, $application_uuid); + dump($env_uuid); } /** - * Get backup records that are within the desired time window. + * Get acquia cloud credentials stored in the environments variables. * * @return array - * Array of available backups within the specified timeframe. + * The array structure require to instantiate the cloud api client. */ - protected function getCurrentBackupRecords() { - try { - $backups = $this->getBackupRecords($this->backupsFile); + private function getAcquiaCloudCredentials() { + if (!$api_key = getenv('ACQUIA_CLOUD_API_KEY')) { + $this->log("Couldn't find ACQUIA_CLOUD_API_KEY env variable."); } - catch (\BuildException $e) { - $backups = []; - } - - $current_backups = []; - - $threshold_time = new \DateTime("-{$this->maxAge} hours"); - $backup_time = new \DateTime(); - foreach ($backups as $backup) { - $backup_time->setTimestamp($backup['started']); - if ($backup_time > $threshold_time) { - $current_backups[] = $backup; - } + if (!$api_secret = getenv('ACQUIA_CLOUD_API_SECRET')) { + $this->log("Couldn't find ACQUIA_CLOUD_API_SECRET env variable."); } - return $current_backups; + return [ + 'key' => $api_key, + 'secret' => $api_secret, + ]; } /** - * Get the array of backup records from the Acquia Cloud API JSON output. - * - * Sorts records from oldest to newest. - * - * @param \PhingFile $file - * Temp file containing the Acquia Cloud API response. - * - * @return array - * Acquia backup info array. - * - * @throws \BuildException - * - * @SuppressWarnings(PHPMD.ShortVariable) + * Set Connection to Acquia Cloud using env variables. */ - protected function getBackupRecords(\PhingFile $file) { - if ($file->exists()) { - $backups = json_decode($file->contents(), TRUE); - - // If the backup records have loaded as an array, and the first record - // has the property that we're using, then it is *probably* valid data. - if (isset($backups[0]['started'])) { - - // Sort the backups by start time so that the newest is always last. - usort($backups, function ($a, $b) { - if ($a['started'] == $b['started']) { - return 0; - } - return ($a['started'] < $b['started']) ? -1 : 1; - }); - - return $backups; - } - elseif (count($backups) === 0) { - // The site might not have been backed up yet. - throw new \BuildException('No Acquia Cloud backups found: ' . $file->getCanonicalPath()); - } - } - throw new \BuildException('Acquia Cloud backup records could not be loaded from JSON: ' . $file->getCanonicalPath()); + private function connectAcquiaCloud($credentials) { + $connector = new Connector($credentials); + return Client::factory($connector); } /** - * Download the latest list of backup records from the Acquia Cloud API. - * - * @param \PhingFile $backups_file - * The file where the downloaded backup should be stored. + * Get all apps and return the one that belong to the specific project. */ - protected function downloadBackupRecords(\PhingFile $backups_file) { - $json = $this->getApiResponseBody("/sites/{$this->realm}:{$this->site}/envs/{$this->env}/dbs/{$this->database}/backups.json"); - - $writer = new \FileWriter($backups_file); - $writer->write($json); - } - - /** - * Format the backup time to display in log messages. - * - * @param array $backup - * Acquia backup info array. - * - * @return string - * A human-readable date. - */ - protected function formatBackupTime(array $backup) { - $time = new \DateTime('now'); - $time->setTimestamp($backup['started']); - return $time->format(DATE_RFC850); + protected function getApplicationUuid($client) { + $apps = new Applications($client); + $applications = $apps->getAll(); + foreach ($applications as $application) { + if ($application->name == $this->site) { + return $application->uuid; + } + } } /** - * Set the Acquia realm. - * - * @param string $value - * Acquia realm. + * Get all environments uuids from the project. */ - public function setRealm(string $value) { - $this->realm = $value; + protected function getEnvironmentsUuid($client, $appUuid) { + $environment = new Environments($client); + $environments = $environment->getAll($appUuid); + foreach ($environments as $env) { + if ($env->name == $this->env) { + return $env->uuid; + } + } } /** @@ -333,26 +157,6 @@ public function setDir(string $value) { $this->dir = new \PhingFile($value); } - /** - * Set the max age. - * - * @param int|string $value - * Max age in hours. - */ - public function setMaxAge(int|string $value) { - $this->maxAge = (int) $value; - } - - /** - * Set the property name. - * - * @param string $value - * Property name to use for the result. - */ - public function setPropertyName(string $value) { - $this->propertyName = $value; - } - /** * Verify that the required parameters are available. */ @@ -362,9 +166,9 @@ protected function validate() { $this->database = $this->site; } // Check the build attributes. - foreach (['dir', 'realm', 'site', 'env'] as $attribute) { + foreach (['dir', 'site', 'env'] as $attribute) { if (empty($this->$attribute)) { - throw new \BuildException("$attribute attribute is required.", $this->location); + throw new \BuildException("$attribute attribute is required."); } } } diff --git a/targets/acquia.xml b/targets/acquia.xml index 6cd52d95..7ea64316 100644 --- a/targets/acquia.xml +++ b/targets/acquia.xml @@ -25,8 +25,9 @@ + - + From 395c45ab2d4555b492092a380f5cb39668e4fd3b Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Wed, 1 Mar 2023 10:18:12 -0600 Subject: [PATCH 02/22] Adding Download Methods and removing dump messages. --- src/TheBuild/Acquia/GetLatestBackupTask.php | 31 ++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/TheBuild/Acquia/GetLatestBackupTask.php b/src/TheBuild/Acquia/GetLatestBackupTask.php index 0e745e93..146d842d 100644 --- a/src/TheBuild/Acquia/GetLatestBackupTask.php +++ b/src/TheBuild/Acquia/GetLatestBackupTask.php @@ -59,7 +59,7 @@ public function main() { $client = $this->connectAcquiaCloud($credentials); $application_uuid = $this->getApplicationUuid($client); $env_uuid = $this->getEnvironmentsUuid($client, $application_uuid); - dump($env_uuid); + $this->getLatestBackup($client, $env_uuid); } /** @@ -91,6 +91,35 @@ private function connectAcquiaCloud($credentials) { return Client::factory($connector); } + /** + * Get latest backup from specified environment. + */ + protected function getLatestBackup($client, $environment_uuid) { + $backup = new DatabaseBackups($client); + $backups = $backup->getAll($environment_uuid, $this->database); + $filepath = $this->dir . '/' . $this->env . '_' . $this->database . '_' . 'sql.gz'; + if (!empty($backups)) { + // file_put_contents loads the response into memory. + // This is okay for small things like Drush aliases. + // But not for database backups. + // Use curl.options to stream data to disk and minimize memory usage. + $client->addOption('sink', $filepath); + $client->addOption('curl.options', [ + 'CURLOPT_RETURNTRANSFER' => TRUE, + 'CURLOPT_FILE' => $filepath, + ]); + // Get latest backup. + $backupId = $backups[0]->id; + $this->log("Downloading backup id $backupId of database $this->database from $this->env environment"); + // Downloading the latest backup. + if ($backup->download($environment_uuid, $this->database, $backupId)) { + $this->log("Database was downloaded successfully in $filepath"); + return TRUE; + } + return FALSE; + } + } + /** * Get all apps and return the one that belong to the specific project. */ From 6fc0dd1c83e85a65f92e9f85cf91cff9490718ba Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Wed, 1 Mar 2023 10:36:51 -0600 Subject: [PATCH 03/22] Removing wrong return FALSE. --- src/TheBuild/Acquia/GetLatestBackupTask.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/TheBuild/Acquia/GetLatestBackupTask.php b/src/TheBuild/Acquia/GetLatestBackupTask.php index 146d842d..5211d821 100644 --- a/src/TheBuild/Acquia/GetLatestBackupTask.php +++ b/src/TheBuild/Acquia/GetLatestBackupTask.php @@ -110,13 +110,12 @@ protected function getLatestBackup($client, $environment_uuid) { ]); // Get latest backup. $backupId = $backups[0]->id; - $this->log("Downloading backup id $backupId of database $this->database from $this->env environment"); + $this->log("Downloading backup id $backupId of database $this->database from $this->env environment $this->env"); // Downloading the latest backup. if ($backup->download($environment_uuid, $this->database, $backupId)) { $this->log("Database was downloaded successfully in $filepath"); return TRUE; } - return FALSE; } } From fa54ae91fec42ebf3db720b78d4da9e6e34f787e Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Wed, 1 Mar 2023 12:22:55 -0600 Subject: [PATCH 04/22] Adding Exeptions and cleaning code. --- docs/tasks.md | 5 +---- src/TheBuild/Acquia/GetLatestBackupTask.php | 10 +++++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/tasks.md b/docs/tasks.md index 6634946f..95cb6e8c 100644 --- a/docs/tasks.md +++ b/docs/tasks.md @@ -106,7 +106,6 @@ Download a recent backup from Acquia Cloud. | site | string | Acquia site name. | | Yes | | env | string | Acquia environment, generally "dev", "test", or "prod". | | Yes | | database | string | Acquia database name. | The site name. | No | -| credentialsFile | file path | Path to your Acquia Cloud API credentials. (Do not check this file in to your repository) | `~/.acquia/cloudapiv2.conf` | No | ### Example @@ -115,8 +114,6 @@ Download a recent backup from Acquia Cloud. - + - - ``` diff --git a/src/TheBuild/Acquia/GetLatestBackupTask.php b/src/TheBuild/Acquia/GetLatestBackupTask.php index 5211d821..1d6fb445 100644 --- a/src/TheBuild/Acquia/GetLatestBackupTask.php +++ b/src/TheBuild/Acquia/GetLatestBackupTask.php @@ -76,6 +76,9 @@ private function getAcquiaCloudCredentials() { if (!$api_secret = getenv('ACQUIA_CLOUD_API_SECRET')) { $this->log("Couldn't find ACQUIA_CLOUD_API_SECRET env variable."); } + if (!$api_key || !$api_secret) { + throw new \BuildException("Credentials are required."); + } return [ 'key' => $api_key, @@ -98,7 +101,7 @@ protected function getLatestBackup($client, $environment_uuid) { $backup = new DatabaseBackups($client); $backups = $backup->getAll($environment_uuid, $this->database); $filepath = $this->dir . '/' . $this->env . '_' . $this->database . '_' . 'sql.gz'; - if (!empty($backups)) { + if ($backups) { // file_put_contents loads the response into memory. // This is okay for small things like Drush aliases. // But not for database backups. @@ -193,6 +196,11 @@ protected function validate() { if (empty($this->database)) { $this->database = $this->site; } + // Check .env file exists. + if (!file_exists(".env")) { + throw new \BuildException(".env file is needed in the root of project with credentials see .env.example."); + } + // Check the build attributes. foreach (['dir', 'site', 'env'] as $attribute) { if (empty($this->$attribute)) { From 5ae6bc5801403aa69b627fd0201ed78838bed7bd Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Mon, 6 Mar 2023 23:06:55 -0600 Subject: [PATCH 05/22] Moving acquia package to suggested and ensure this is going to be added if acquia is selected as hosting during the project setup. --- composer.json | 6 ++++-- targets/install.xml | 7 ++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index c8432a77..4473520b 100644 --- a/composer.json +++ b/composer.json @@ -23,8 +23,10 @@ "pear/versioncontrol_git": "@dev", "phing/phing": "^2.14", "phpmd/phpmd": "^2.4", - "phpspec/prophecy-phpunit": "^2", - "typhonius/acquia-php-sdk-v2": "^2.0" + "phpspec/prophecy-phpunit": "^2" + }, + "suggest": { + "typhonius/acquia-php-sdk-v2": "Adding Cloud Acquia SDK API V2. Mainly used to trait backups." }, "autoload": { "psr-0": { diff --git a/targets/install.xml b/targets/install.xml index 3636b0f1..12aeec1f 100644 --- a/targets/install.xml +++ b/targets/install.xml @@ -281,8 +281,13 @@ + + + + + + - From 5f87378e0e0b98edeaeef10122db4e6401e3b6bf Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Mon, 6 Mar 2023 23:25:16 -0600 Subject: [PATCH 06/22] Adding task to copy .env.example file if acquia is selected. --- defaults/install/.env.example | 9 +++++++++ targets/install.xml | 2 ++ 2 files changed, 11 insertions(+) create mode 100644 defaults/install/.env.example diff --git a/defaults/install/.env.example b/defaults/install/.env.example new file mode 100644 index 00000000..164630ff --- /dev/null +++ b/defaults/install/.env.example @@ -0,0 +1,9 @@ +# ddev docker env file. +# See: https://ddev.readthedocs.io/en/stable/users/extend/customization-extendibility/#providing-custom-environment-variables-to-a-container + +# Copy this file into .env (ie. remove .example) + +# Set Acquia Cloud API keys. +# See DevOps secure note in 1Password. +export ACQUIA_CLOUD_API_KEY='REPLACE_ME' +export ACQUIA_CLOUD_API_SECRET='REPLACE_ME' diff --git a/targets/install.xml b/targets/install.xml index 12aeec1f..d40c9286 100644 --- a/targets/install.xml +++ b/targets/install.xml @@ -287,6 +287,8 @@ + + From 3ec3f03619a13d842e8d5acec69867fc42908b1e Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Tue, 7 Mar 2023 17:38:37 -0600 Subject: [PATCH 07/22] Moving suggest package and add it as a normal require if acquia is selected as hosting provider and remove copy of the .env.example to move it some more globally. --- composer.json | 3 --- targets/install.xml | 9 +++------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 4473520b..9ee035ed 100644 --- a/composer.json +++ b/composer.json @@ -25,9 +25,6 @@ "phpmd/phpmd": "^2.4", "phpspec/prophecy-phpunit": "^2" }, - "suggest": { - "typhonius/acquia-php-sdk-v2": "Adding Cloud Acquia SDK API V2. Mainly used to trait backups." - }, "autoload": { "psr-0": { "TheBuild\\": "src/" diff --git a/targets/install.xml b/targets/install.xml index d40c9286..b0287058 100644 --- a/targets/install.xml +++ b/targets/install.xml @@ -282,13 +282,10 @@ - - - - + + + - - From 768f54a679cab4e43a7d926cf04fb171ad7afe4b Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Wed, 8 Mar 2023 19:26:50 -0600 Subject: [PATCH 08/22] Fixing the extension of the backups. --- src/TheBuild/Acquia/GetLatestBackupTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TheBuild/Acquia/GetLatestBackupTask.php b/src/TheBuild/Acquia/GetLatestBackupTask.php index 1d6fb445..5ca4cc68 100644 --- a/src/TheBuild/Acquia/GetLatestBackupTask.php +++ b/src/TheBuild/Acquia/GetLatestBackupTask.php @@ -100,7 +100,7 @@ private function connectAcquiaCloud($credentials) { protected function getLatestBackup($client, $environment_uuid) { $backup = new DatabaseBackups($client); $backups = $backup->getAll($environment_uuid, $this->database); - $filepath = $this->dir . '/' . $this->env . '_' . $this->database . '_' . 'sql.gz'; + $filepath = $this->dir . '/' . $this->env . '_' . $this->database . '.sql.gz'; if ($backups) { // file_put_contents loads the response into memory. // This is okay for small things like Drush aliases. From 47f96262e6e72980f3c30720f13aea7230b507c9 Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Wed, 8 Mar 2023 19:33:59 -0600 Subject: [PATCH 09/22] Fixing the command to decompress file and importing it without drush to improve performance by 93% --- defaults.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/defaults.yml b/defaults.yml index 8bdd3552..a871fb14 100644 --- a/defaults.yml +++ b/defaults.yml @@ -110,7 +110,7 @@ drupal: # Database connection for Drupal. database: # This value is required, but a default is set in the-build.xml. - # database: drupal + database: db username: db password: db host: db @@ -134,9 +134,9 @@ drupal: # $> gunzip -c FILENAME.sql.gz | drush sqlc # # Command to extract text contents of the backup file. - contents_command: gunzip -c + contents_command: gzip -dc # Command to load database contents into Drupal. - mysql_command: drush sqlc + mysql_command: mysql --host=${drupal.site.database.host} --user=${drupal.site.database.username} --password=${drupal.site.database.password} --database=${drupal.site.database.database} # Load a specific file rather than one matching the `export_pattern`. This can be used # if your build relies on a seed database that is checked in to the repository. From 4466d7f39e6e6a2f9cfd11cabe32c2429d4ffc7c Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Wed, 8 Mar 2023 21:24:30 -0600 Subject: [PATCH 10/22] Adding hosting packages as new phing task. --- defaults.yml | 3 +++ targets/install.xml | 38 +++++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/defaults.yml b/defaults.yml index a871fb14..e52a86a4 100644 --- a/defaults.yml +++ b/defaults.yml @@ -15,6 +15,9 @@ build: # The destination host, either 'acquia', 'pantheon', 'platformsh', or 'other'. This is # currently only used when setting up the settings.php file for a Drupal site. host: acquia + # Adding specific packages for specific host. One per line. + host_packages: + - "typhonius/acquia-php-sdk-v2:^2.0" # Drupal configuration used by targets/drupal.xml drupal: diff --git a/targets/install.xml b/targets/install.xml index b0287058..fa9b4c45 100644 --- a/targets/install.xml +++ b/targets/install.xml @@ -281,16 +281,10 @@ - - - - - - @@ -304,15 +298,37 @@ - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + From 4e1beeba34046c93421bdd5c4a19daf8fb8c1535 Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Wed, 15 Mar 2023 11:44:04 -0600 Subject: [PATCH 11/22] Adding PHPStan.neo file to exclude Acquia refeences to be scanned first time. --- .circleci/config.yml | 2 +- phpstan.neon | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 phpstan.neon diff --git a/.circleci/config.yml b/.circleci/config.yml index 5ac76ad2..28f63044 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,7 +49,7 @@ jobs: echo "phpmd for tasks" vendor/bin/phpmd src text defaults/standard/phpmd.xml "php,inc,module,theme,profile,install,test" echo "phpstan for tasks" - vendor/bin/phpstan analyse src --level=2 + vendor/bin/phpstan analyse -c phpstan.neon # Install a drupal test project. - run: diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..c119e483 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,7 @@ +parameters: + level: 2 + paths: + - src + excludePaths: + analyse: + - src/TheBuild/Acquia From 8472626abd625c1b2eb17dff99812e4871abad46 Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Wed, 15 Mar 2023 11:56:02 -0600 Subject: [PATCH 12/22] Removing the check if we are in CIrcleCI to add composer dependencies, we don't need this. --- targets/install.xml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/targets/install.xml b/targets/install.xml index fa9b4c45..4ad449c0 100644 --- a/targets/install.xml +++ b/targets/install.xml @@ -314,16 +314,7 @@ - - - - - - - - - - + From 1364c34335e6527bcfc20d1dfa11ede09726b738 Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Wed, 15 Mar 2023 20:30:24 -0600 Subject: [PATCH 13/22] Fixing foreach typo in clossing tag. --- targets/install.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/install.xml b/targets/install.xml index 4ad449c0..88da679d 100644 --- a/targets/install.xml +++ b/targets/install.xml @@ -312,7 +312,7 @@ - + From 4fc7395c94d13e3880438478786af18df7a6cd29 Mon Sep 17 00:00:00 2001 From: Daniel Serna Date: Wed, 15 Mar 2023 21:14:31 -0600 Subject: [PATCH 14/22] Installing specific packages per hosting default task tag. --- targets/install.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/targets/install.xml b/targets/install.xml index 88da679d..54e4c8ba 100644 --- a/targets/install.xml +++ b/targets/install.xml @@ -282,6 +282,7 @@ + @@ -301,9 +302,11 @@ + + - + From 3e11faf09fd500c9c823bd76198a8326f6637434 Mon Sep 17 00:00:00 2001 From: byrond Date: Fri, 17 Nov 2023 13:30:26 -0500 Subject: [PATCH 15/22] allow newer versions of phpmd --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 7ca39bae..3f025514 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "pear/http_request2": "^2.3", "pear/versioncontrol_git": "@dev", "phing/phing": "^2.14", - "phpmd/phpmd": "2.13", + "phpmd/phpmd": "^2.13", "phpspec/prophecy-phpunit": "^2" }, "autoload": { From 564b04cb9b53b93e853de01b40bef0ffae2e91f1 Mon Sep 17 00:00:00 2001 From: byrond Date: Fri, 17 Nov 2023 13:45:38 -0500 Subject: [PATCH 16/22] revert change to version constraint so we can fix it elsewhere --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3f025514..7ca39bae 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "pear/http_request2": "^2.3", "pear/versioncontrol_git": "@dev", "phing/phing": "^2.14", - "phpmd/phpmd": "^2.13", + "phpmd/phpmd": "2.13", "phpspec/prophecy-phpunit": "^2" }, "autoload": { From 90cee16801ad1589637d108a87acf8814231bdb9 Mon Sep 17 00:00:00 2001 From: Byron Duvall Date: Fri, 12 Jan 2024 10:21:32 -0500 Subject: [PATCH 17/22] sort use statements in GetLatestBackupTask.php --- src/TheBuild/Acquia/GetLatestBackupTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TheBuild/Acquia/GetLatestBackupTask.php b/src/TheBuild/Acquia/GetLatestBackupTask.php index 5ca4cc68..7ea8a975 100644 --- a/src/TheBuild/Acquia/GetLatestBackupTask.php +++ b/src/TheBuild/Acquia/GetLatestBackupTask.php @@ -5,8 +5,8 @@ use AcquiaCloudApi\Connector\Client; use AcquiaCloudApi\Connector\Connector; use AcquiaCloudApi\Endpoints\Applications; -use AcquiaCloudApi\Endpoints\Environments; use AcquiaCloudApi\Endpoints\DatabaseBackups; +use AcquiaCloudApi\Endpoints\Environments; /** * Fetch a recent backup from Acquia. From eb12d5cfcf55acb0c83596882e3f4d5073ab8074 Mon Sep 17 00:00:00 2001 From: Byron Duvall Date: Wed, 13 Mar 2024 14:37:57 -0400 Subject: [PATCH 18/22] fix the-build installer for host packages --- defaults.yml | 3 ++- targets/install.xml | 29 +++++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/defaults.yml b/defaults.yml index cde6b801..71e83fe3 100644 --- a/defaults.yml +++ b/defaults.yml @@ -16,7 +16,8 @@ build: # currently only used when setting up the settings.php file for a Drupal site. host: acquia # Adding specific packages for specific host. One per line. - host_packages: + host_packages: + acquia: - "typhonius/acquia-php-sdk-v2:^2.0" # Drupal configuration used by targets/drupal.xml diff --git a/targets/install.xml b/targets/install.xml index 13b61e63..f6402eed 100644 --- a/targets/install.xml +++ b/targets/install.xml @@ -306,26 +306,31 @@ - - - - + + + + - + - + - - - - - - + + + + + + + + + + + From d9d5cea9e5f465b015cdfe4ec882465e6b0fc383 Mon Sep 17 00:00:00 2001 From: Byron Duvall Date: Wed, 13 Mar 2024 14:43:57 -0400 Subject: [PATCH 19/22] remove inheritall from foreach in install.xml --- targets/install.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/install.xml b/targets/install.xml index f6402eed..67c27d2f 100644 --- a/targets/install.xml +++ b/targets/install.xml @@ -318,7 +318,7 @@ - + From 4a4f630727d21657d2f52d3ec546f3d6ed498695 Mon Sep 17 00:00:00 2001 From: Byron Duvall Date: Wed, 13 Mar 2024 17:12:07 -0400 Subject: [PATCH 20/22] remove check for .env since there is already a check for the env vars --- src/TheBuild/Acquia/GetLatestBackupTask.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/TheBuild/Acquia/GetLatestBackupTask.php b/src/TheBuild/Acquia/GetLatestBackupTask.php index 7ea8a975..03b2589f 100644 --- a/src/TheBuild/Acquia/GetLatestBackupTask.php +++ b/src/TheBuild/Acquia/GetLatestBackupTask.php @@ -196,10 +196,6 @@ protected function validate() { if (empty($this->database)) { $this->database = $this->site; } - // Check .env file exists. - if (!file_exists(".env")) { - throw new \BuildException(".env file is needed in the root of project with credentials see .env.example."); - } // Check the build attributes. foreach (['dir', 'site', 'env'] as $attribute) { From be6fe1150252a75f11776918c91ddabffddfc173 Mon Sep 17 00:00:00 2001 From: Byron Duvall Date: Mon, 14 Oct 2024 10:08:40 -0400 Subject: [PATCH 21/22] revert change to default database name --- defaults.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults.yml b/defaults.yml index 2ba059c4..b3eafb9a 100644 --- a/defaults.yml +++ b/defaults.yml @@ -114,7 +114,7 @@ drupal: # Database connection for Drupal. database: # This value is required, but a default is set in the-build.xml. - database: db + # database: drupal username: db password: db host: db From 90b7d7db6829c0a127fd9cdada31b9f0de9ed1a9 Mon Sep 17 00:00:00 2001 From: Byron Duvall Date: Mon, 14 Oct 2024 10:14:56 -0400 Subject: [PATCH 22/22] default first database name in ddev is "db" --- defaults/install/the-build/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults/install/the-build/build.yml b/defaults/install/the-build/build.yml index b8aeda31..8cb420d6 100644 --- a/defaults/install/the-build/build.yml +++ b/defaults/install/the-build/build.yml @@ -35,7 +35,7 @@ drupal: # OPTIONAL: The Drupal database name defaults to the site's "dir" value. database: - database: "drupal" + database: "db" # Multisites created by `phing drupal-add-multisite` will be automatically added here. # @multisite_placeholder@