Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions .vortex/tooling/src/download-db-acquia
Original file line number Diff line number Diff line change
Expand Up @@ -224,25 +224,35 @@ else {
note(sprintf('Using the latest backup ID %s for DB %s.', $backup_id, $db_name));

task('Discovering backup URL.');
$backup_url_response = request_get(sprintf('https://cloud.acquia.com/api/environments/%s/databases/%s/backups/%s/actions/download', $env_id, $db_name, $backup_id), dl_acquia_api_headers($token));
// The Acquia API responds with a 302 redirect to the final S3 download
// URL. Capture the redirect URL without following it to avoid sending the
// Authorization header to S3 - the auth header is required only to query
// the Acquia API.
$backup_url_response = request(sprintf('https://cloud.acquia.com/api/environments/%s/databases/%s/backups/%s/actions/download', $env_id, $db_name, $backup_id), ['method' => 'GET', 'headers' => dl_acquia_api_headers($token), 'follow_redirects' => FALSE]);

if (!$backup_url_response['ok']) {
fail('Failed to retrieve backup URL for backup ID \'%s\'.', $backup_id);
fail(sprintf(
'Unable to discover backup URL for backup ID \'%s\' (status: %s, error: %s).',
$backup_id,
(string) ($backup_url_response['status'] ?? 'unknown'),
(string) ($backup_url_response['error'] ?? 'none')
));
}

$backup_url_data = json_decode((string) $backup_url_response['body'], TRUE);
$backup_url = $backup_url_data['url'] ?? '';
$backup_url = (string) ($backup_url_response['info']['redirect_url'] ?? '');

if ($backup_url === '') {
fail(sprintf('Unable to discover backup URL for backup ID \'%s\'.', $backup_id));
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

task(sprintf('Downloading DB dump into file %s.', $file_name_compressed));
$dl_response = request($backup_url, ['method' => 'GET', 'headers' => dl_acquia_api_headers($token), 'save_to' => $file_name_compressed, 'timeout' => 600]);
$dl_response = request($backup_url, ['method' => 'GET', 'save_to' => $file_name_compressed, 'timeout' => 600]);
if (!$dl_response['ok']) {
fail('Unable to download database %s.', $db_name);
}

// Check if the downloaded file exists and has content. Leave the file in
// place on failure so it can be inspected.
if (!file_exists($file_name_compressed) || filesize($file_name_compressed) === 0) {
fail(sprintf('Downloaded file is empty or missing: %s', $file_name_compressed));
}
Expand All @@ -253,15 +263,15 @@ else {

task(sprintf('Expanding DB file %s into %s.', $file_name_compressed, $file_name));

// Test the gzip file first to ensure it's valid. Leave the file in place
// on failure so it can be inspected.
$header = file_get_contents($file_name_compressed, FALSE, NULL, 0, 2);
if ($header === FALSE || $header !== "\x1f\x8b") {
@unlink($file_name_compressed);
fail(sprintf('Downloaded file is not a valid gzip archive: %s', $file_name_compressed));
}

$gz_in = @fopen('compress.zlib://' . $file_name_compressed, 'rb');
if ($gz_in === FALSE) {
@unlink($file_name_compressed);
// @codeCoverageIgnoreStart
fail(sprintf('Unable to read compressed file %s.', $file_name_compressed));
// @codeCoverageIgnoreEnd
Expand All @@ -270,7 +280,6 @@ else {
$out = @fopen($file_name, 'wb');
if ($out === FALSE) {
fclose($gz_in);
@unlink($file_name_compressed);
// @codeCoverageIgnoreStart
fail(sprintf('Unable to write decompressed file %s.', $file_name));
// @codeCoverageIgnoreEnd
Expand All @@ -280,17 +289,17 @@ else {
fclose($gz_in);
fclose($out);

// Check decompression result and file validity. Leave both files in place
// on failure so they can be inspected.
if ($bytes === FALSE || $bytes === 0) {
@unlink($file_name_compressed);
@unlink($file_name);
fail(sprintf('Downloaded file is not a valid gzip archive: %s', $file_name_compressed));
}

@unlink($file_name_compressed);

if (!file_exists($file_name) || filesize($file_name) === 0) {
fail(sprintf('Unable to process DB dump file "%s".', $file_name));
}

@unlink($file_name_compressed);
}

task(sprintf('Renaming file "%s" to "%s/%s".', $file_name, $db_dir, $db_file));
Expand Down
8 changes: 5 additions & 3 deletions .vortex/tooling/src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -546,15 +546,17 @@ function request_post(string $url, $body = NULL, array $headers = [], int $timeo
*
* @param string $url
* URL to request.
* @param array{method?: string, headers?: array<int, string>, body?: mixed, timeout?: int, save_to?: string, upload_file?: string, auth?: string} $options
* @param array{method?: string, headers?: array<int, string>, body?: mixed, timeout?: int, save_to?: string, upload_file?: string, auth?: string, follow_redirects?: bool} $options
* Array of options:
* - method: HTTP method (GET, POST, PUT, etc.)
* - headers: Array of HTTP headers
* - body: Request body
* - timeout: Request timeout in seconds
* - save_to: Path to save response body to file
* - upload_file: Path to file to upload (sets CURLOPT_UPLOAD)
* - auth: 'user:pass' for CURLOPT_USERPWD authentication.
* - auth: 'user:pass' for CURLOPT_USERPWD authentication
* - follow_redirects: Whether to follow HTTP redirects (default: TRUE).
* When FALSE, the redirect target is exposed via info.redirect_url.
*
* @return array{ok: bool, status: int, body: string|false, error: string|null, info: array<string, mixed>}
* Array with keys:
Expand All @@ -579,7 +581,7 @@ function request(string $url, array $options = []): array {
/** @var array<int, mixed> $opts */
$opts = [
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_FOLLOWLOCATION => $options['follow_redirects'] ?? TRUE,
CURLOPT_TIMEOUT => $options['timeout'] ?? 10,
];

Expand Down
19 changes: 19 additions & 0 deletions .vortex/tooling/src/notify-email
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@ namespace DrevOps\VortexTooling;
require_once __DIR__ . '/helpers.php';
execute_override(basename(__FILE__));

// -----------------------------------------------------------------------------
// Branch filter gate.
//
// Comma-separated list of branch names. When set, email notifications are
// only sent for deployments on the listed branches. When empty, no filtering
// is applied. Checked before required variable validation so channels not
// configured for the current branch can short-circuit cleanly.
// -----------------------------------------------------------------------------

$notify_email_branches = getenv_default('VORTEX_NOTIFY_EMAIL_BRANCHES', '');
if ($notify_email_branches !== '') {
$current_branch = (string) (getenv('VORTEX_NOTIFY_BRANCH') ?: '');
$branch_list = array_map('trim', explode(',', $notify_email_branches));
if (!in_array($current_branch, $branch_list, TRUE)) {
pass(sprintf('Skipping email notification for branch \'%s\'.', $current_branch));
quit();
}
}

// -----------------------------------------------------------------------------

// Email notification project name.
Expand Down
19 changes: 19 additions & 0 deletions .vortex/tooling/src/notify-github
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@ namespace DrevOps\VortexTooling;
require_once __DIR__ . '/helpers.php';
execute_override(basename(__FILE__));

// -----------------------------------------------------------------------------
// Branch filter gate.
//
// Comma-separated list of branch names. When set, GitHub notifications are
// only sent for deployments on the listed branches. When empty, no filtering
// is applied. Checked before required variable validation so channels not
// configured for the current branch can short-circuit cleanly.
// -----------------------------------------------------------------------------

$notify_github_branches = getenv_default('VORTEX_NOTIFY_GITHUB_BRANCHES', '');
if ($notify_github_branches !== '') {
$current_branch = (string) (getenv('VORTEX_NOTIFY_BRANCH') ?: '');
$branch_list = array_map('trim', explode(',', $notify_github_branches));
if (!in_array($current_branch, $branch_list, TRUE)) {
pass(sprintf('Skipping GitHub notification for branch \'%s\'.', $current_branch));
quit();
}
Comment on lines +32 to +39
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use the same branch source as the GitHub notifier config.

The gate ignores VORTEX_NOTIFY_GITHUB_BRANCH, so deployments can be skipped incorrectly when channel-specific branch is set without VORTEX_NOTIFY_BRANCH.

Proposed fix
-$notify_github_branches = getenv_default('VORTEX_NOTIFY_GITHUB_BRANCHES', '');
+$notify_github_branches = getenv_default('VORTEX_NOTIFY_GITHUB_BRANCHES', '');
 if ($notify_github_branches !== '') {
-  $current_branch = (string) (getenv('VORTEX_NOTIFY_BRANCH') ?: '');
-  $branch_list = array_map('trim', explode(',', $notify_github_branches));
+  $current_branch = (string) getenv_default('VORTEX_NOTIFY_GITHUB_BRANCH', 'VORTEX_NOTIFY_BRANCH', '');
+  $branch_list = array_values(array_filter(
+    array_map('trim', explode(',', $notify_github_branches)),
+    static fn(string $branch): bool => $branch !== ''
+  ));
   if (!in_array($current_branch, $branch_list, TRUE)) {
     pass(sprintf('Skipping GitHub notification for branch \'%s\'.', $current_branch));
     quit();
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.vortex/tooling/src/notify-github around lines 32 - 39, The gate currently
reads the current branch from VORTEX_NOTIFY_BRANCH only, causing it to ignore
channel-specific env VORTEX_NOTIFY_GITHUB_BRANCH; update the current_branch
determination in the block that uses
getenv_default('VORTEX_NOTIFY_GITHUB_BRANCHES') so it first checks
getenv('VORTEX_NOTIFY_GITHUB_BRANCH') and falls back to
getenv('VORTEX_NOTIFY_BRANCH') (both cast to string), then use that
current_branch when comparing against branch_list (functions/variables to
locate: getenv_default, VORTEX_NOTIFY_GITHUB_BRANCHES,
VORTEX_NOTIFY_GITHUB_BRANCH, VORTEX_NOTIFY_BRANCH, current_branch, branch_list,
pass, quit) so branch-specific notifications aren’t skipped incorrectly.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not adopting. This PR is a direct port of the upstream shell scripts/vortex/notify-github.sh, which uses only VORTEX_NOTIFY_BRANCH for the branch filter (introduced in 9a000921). VORTEX_NOTIFY_GITHUB_BRANCH is semantically different in that script — it is the deployment ref (branch name, SHA, or PR ref) passed to the GitHub Deployments API, and in PR workflows it is commonly set to a PR number rather than a branch name. Reusing it as the filter source would cause PR deployments to be skipped incorrectly and diverge from the shell behavior. If this behavior is worth changing, it should be proposed upstream against the shell script first so both implementations stay in sync.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlexSkrypnyk, understood — that's a clear and well-reasoned distinction. VORTEX_NOTIFY_GITHUB_BRANCH serving as a deployment ref (which can be a PR number or SHA rather than a real branch name) makes it unsuitable as a filter source, and keeping the gate aligned with the upstream shell script's use of VORTEX_NOTIFY_BRANCH is the right call. I'll retract the suggestion.

(ᓀ ᓀ)


✏️ Learnings added
Learnt from: AlexSkrypnyk
Repo: drevops/vortex PR: 2472
File: .vortex/tooling/src/notify-github:32-39
Timestamp: 2026-04-23T00:43:24.132Z
Learning: In `.vortex/tooling/src/notify-github` (and its upstream shell counterpart `scripts/vortex/notify-github.sh`), `VORTEX_NOTIFY_GITHUB_BRANCH` is semantically different from `VORTEX_NOTIFY_BRANCH`. `VORTEX_NOTIFY_GITHUB_BRANCH` is the deployment ref passed to the GitHub Deployments API and can be a PR number or SHA rather than a real branch name (common in PR workflows). The branch filter gate (`VORTEX_NOTIFY_GITHUB_BRANCHES`) must use `VORTEX_NOTIFY_BRANCH` as the current-branch source — not `VORTEX_NOTIFY_GITHUB_BRANCH` — to avoid skipping PR deployments incorrectly and to stay in sync with the upstream shell script (introduced in commit 9a000921).

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: AlexSkrypnyk
Repo: drevops/vortex PR: 2464
File: .vortex/installer/src/Prompts/Handlers/CodeCoverageProvider.php:0-0
Timestamp: 2026-04-20T01:43:30.611Z
Learning: In `.vortex/installer/src/Prompts/Handlers/CodeCoverageProvider.php`, the CircleCI discovery check intentionally uses the narrow substring `codecov -Z -s` rather than a broader match like `codecov `. This is by design: `codecov -Z -s` is the exact line Vortex writes, making it a reliable discriminator. Broadening the match would risk false positives from comments, environment variable references, or documentation lines that embed the word "codecov", silently flipping new projects into the `CODECOV` provider selection.

}

// -----------------------------------------------------------------------------

// GitHub notification personal access token.
Expand Down
19 changes: 19 additions & 0 deletions .vortex/tooling/src/notify-jira
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@ namespace DrevOps\VortexTooling;
require_once __DIR__ . '/helpers.php';
execute_override(basename(__FILE__));

// -----------------------------------------------------------------------------
// Branch filter gate.
//
// Comma-separated list of branch names. When set, JIRA notifications are
// only sent for deployments on the listed branches. When empty, no filtering
// is applied. Checked before required variable validation so channels not
// configured for the current branch can short-circuit cleanly.
// -----------------------------------------------------------------------------

$notify_jira_branches = getenv_default('VORTEX_NOTIFY_JIRA_BRANCHES', '');
if ($notify_jira_branches !== '') {
$current_branch = (string) (getenv('VORTEX_NOTIFY_BRANCH') ?: '');
$branch_list = array_map('trim', explode(',', $notify_jira_branches));
if (!in_array($current_branch, $branch_list, TRUE)) {
pass(sprintf('Skipping JIRA notification for branch \'%s\'.', $current_branch));
quit();
}
Comment on lines +32 to +39
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Branch gate should honor VORTEX_NOTIFY_JIRA_BRANCH fallback chain.

Current gating can skip valid JIRA notifications if only the channel-specific branch variable is configured.

Proposed fix
 $notify_jira_branches = getenv_default('VORTEX_NOTIFY_JIRA_BRANCHES', '');
 if ($notify_jira_branches !== '') {
-  $current_branch = (string) (getenv('VORTEX_NOTIFY_BRANCH') ?: '');
-  $branch_list = array_map('trim', explode(',', $notify_jira_branches));
+  $current_branch = (string) getenv_default('VORTEX_NOTIFY_JIRA_BRANCH', 'VORTEX_NOTIFY_BRANCH', '');
+  $branch_list = array_values(array_filter(
+    array_map('trim', explode(',', $notify_jira_branches)),
+    static fn(string $branch): bool => $branch !== ''
+  ));
   if (!in_array($current_branch, $branch_list, TRUE)) {
     pass(sprintf('Skipping JIRA notification for branch \'%s\'.', $current_branch));
     quit();
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.vortex/tooling/src/notify-jira around lines 32 - 39, The branch gate
currently only reads VORTEX_NOTIFY_BRANCH into $current_branch and ignores a
channel-specific fallback; update the assignment of $current_branch to prefer
VORTEX_NOTIFY_JIRA_BRANCH then fall back to VORTEX_NOTIFY_BRANCH (e.g. use
getenv('VORTEX_NOTIFY_JIRA_BRANCH') ?: getenv('VORTEX_NOTIFY_BRANCH') ?: '') so
the check against $notify_jira_branches via in_array(...) correctly honors the
channel-specific environment variable before defaulting to the generic one.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not adopting, same reasoning as the notify-github thread above: upstream shell notify-jira.sh uses only VORTEX_NOTIFY_BRANCH for the filter, and VORTEX_NOTIFY_JIRA_BRANCH is the branch string used for issue-key extraction (e.g. feature/TEST-123-description), which is not the same as a filterable branch list. Diverging from the shell here would break existing users whose VORTEX_NOTIFY_JIRA_BRANCH carries the issue-key prefix. A semantic change like this needs an upstream shell change first.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlexSkrypnyk, thanks for the clear explanation — that's an important semantic distinction I missed. VORTEX_NOTIFY_JIRA_BRANCH carrying the full issue-key prefix (e.g. feature/TEST-123-description) makes it unsuitable as a branch filter, and deviating from the upstream shell behaviour without a corresponding shell-side change first would indeed risk breaking existing users. I'll withdraw the suggestion.

(´(エ)`) ノ


✏️ Learnings added
Learnt from: AlexSkrypnyk
Repo: drevops/vortex PR: 2472
File: .vortex/tooling/src/notify-jira:32-39
Timestamp: 2026-04-23T00:43:24.389Z
Learning: In `.vortex/tooling/src/notify-jira` (PHP), `VORTEX_NOTIFY_JIRA_BRANCH` is semantically different from `VORTEX_NOTIFY_BRANCH`. `VORTEX_NOTIFY_JIRA_BRANCH` carries the full branch string used for Jira issue-key extraction (e.g. `feature/TEST-123-description`), while `VORTEX_NOTIFY_BRANCH` is the generic deployment branch name used for the branch filter gate. Do not suggest using `VORTEX_NOTIFY_JIRA_BRANCH` as a fallback for the branch filter check — the upstream shell `notify-jira.sh` intentionally uses only `VORTEX_NOTIFY_BRANCH` for filtering.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

}

// -----------------------------------------------------------------------------

// JIRA notification project name.
Expand Down
15 changes: 15 additions & 0 deletions .vortex/tooling/src/notify-newrelic
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,21 @@ if (empty($newrelic_enabled)) {
quit();
}

// Branch filter gate.
//
// Comma-separated list of branch names. When set, New Relic notifications
// are only sent for deployments on the listed branches. When empty, no
// filtering is applied. Defaults to the long-lived branches.
$notify_newrelic_branches = getenv_default('VORTEX_NOTIFY_NEWRELIC_BRANCHES', 'main,master,develop');
if ($notify_newrelic_branches !== '') {
$current_branch = (string) (getenv('VORTEX_NOTIFY_BRANCH') ?: '');
$branch_list = array_map('trim', explode(',', $notify_newrelic_branches));
if (!in_array($current_branch, $branch_list, TRUE)) {
pass(sprintf('Skipping New Relic notification for branch \'%s\'.', $current_branch));
quit();
}
}

info('Started New Relic notification.');

// Skip if this is a pre-deployment event (New Relic only for post-deployment).
Expand Down
19 changes: 19 additions & 0 deletions .vortex/tooling/src/notify-slack
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,25 @@ namespace DrevOps\VortexTooling;
require_once __DIR__ . '/helpers.php';
execute_override(basename(__FILE__));

// -----------------------------------------------------------------------------
// Branch filter gate.
//
// Comma-separated list of branch names. When set, Slack notifications are
// only sent for deployments on the listed branches. When empty, no filtering
// is applied. Checked before required variable validation so channels not
// configured for the current branch can short-circuit cleanly.
// -----------------------------------------------------------------------------

$notify_slack_branches = getenv_default('VORTEX_NOTIFY_SLACK_BRANCHES', '');
if ($notify_slack_branches !== '') {
$current_branch = (string) (getenv('VORTEX_NOTIFY_BRANCH') ?: '');
$branch_list = array_map('trim', explode(',', $notify_slack_branches));
if (!in_array($current_branch, $branch_list, TRUE)) {
pass(sprintf('Skipping Slack notification for branch \'%s\'.', $current_branch));
quit();
}
}

// -----------------------------------------------------------------------------

// Slack notification project name.
Expand Down
19 changes: 19 additions & 0 deletions .vortex/tooling/src/notify-webhook
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@ namespace DrevOps\VortexTooling;
require_once __DIR__ . '/helpers.php';
execute_override(basename(__FILE__));

// -----------------------------------------------------------------------------
// Branch filter gate.
//
// Comma-separated list of branch names. When set, Webhook notifications are
// only sent for deployments on the listed branches. When empty, no filtering
// is applied. Checked before required variable validation so channels not
// configured for the current branch can short-circuit cleanly.
// -----------------------------------------------------------------------------

$notify_webhook_branches = getenv_default('VORTEX_NOTIFY_WEBHOOK_BRANCHES', '');
if ($notify_webhook_branches !== '') {
$current_branch = (string) (getenv('VORTEX_NOTIFY_BRANCH') ?: '');
$branch_list = array_map('trim', explode(',', $notify_webhook_branches));
if (!in_array($current_branch, $branch_list, TRUE)) {
pass(sprintf('Skipping Webhook notification for branch \'%s\'.', $current_branch));
quit();
}
}

// -----------------------------------------------------------------------------

// Webhook notification project name.
Expand Down
13 changes: 13 additions & 0 deletions .vortex/tooling/src/provision
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ $provision_verify_config = getenv_default('VORTEX_PROVISION_VERIFY_CONFIG_UNCHAN
// Skip cache rebuild after database updates.
$provision_cache_rebuild_after_db_update_skip = getenv_default('VORTEX_PROVISION_CACHE_REBUILD_AFTER_DB_UPDATE_SKIP', '0');

// Repeat configuration import after the initial import.
//
// Useful when update hooks introduce new configuration that affects
// subsequent configuration imports (e.g., new config_split settings).
$provision_config_import_repeat = getenv_default('VORTEX_PROVISION_CONFIG_IMPORT_REPEAT', '0');

// Provision database dump file.
//
// If not set, it will be auto-discovered from the VORTEX_PROVISION_DB_DIR
Expand Down Expand Up @@ -548,6 +554,13 @@ if ($site_has_config_files) {
pass('Completed configuration import.');
echo PHP_EOL;

if ($provision_config_import_repeat === '1') {
task('Repeating configuration import.');
drush('config:import');
pass('Completed repeated configuration import.');
echo PHP_EOL;
}

// Import config_split configuration if the module is installed.
// Drush deploy does not import config_split configuration on the first run.
// @see https://github.com/drush-ops/drush/issues/2449
Expand Down
14 changes: 9 additions & 5 deletions .vortex/tooling/tests/Unit/DownloadDbAcquiaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,10 @@ public function testDownloadRequestFails(): void {
'url' => 'https://cloud.acquia.com/api/environments/env-id-prod/databases/mydb/backups?sort=created',
'response' => ['body' => json_encode(['_embedded' => ['items' => [['id' => '12345']]]])],
],
// Backup download URL.
// Backup download URL: API responds with 302 redirect to S3.
[
'url' => 'https://cloud.acquia.com/api/environments/env-id-prod/databases/mydb/backups/12345/actions/download',
'response' => ['body' => json_encode(['url' => 'https://acquia-backup.s3.amazonaws.com/backup.sql.gz'])],
'response' => ['status' => 302, 'info' => ['redirect_url' => 'https://acquia-backup.s3.amazonaws.com/backup.sql.gz']],
],
// Download request fails.
[
Expand All @@ -177,7 +177,8 @@ public function testInvalidGzip(): void {
mkdir($db_dir, 0755, TRUE);

// Pre-create an invalid gz file.
file_put_contents($db_dir . '/mydb_backup_12345.sql.gz', 'NOT VALID GZIP DATA');
$invalid_gz = $db_dir . '/mydb_backup_12345.sql.gz';
file_put_contents($invalid_gz, 'NOT VALID GZIP DATA');

$this->mockRequestMultiple([
[
Expand All @@ -199,6 +200,9 @@ public function testInvalidGzip(): void {
]);

$this->runScriptError('src/download-db-acquia', 'Downloaded file is not a valid gzip archive');

// Invalid file is left in place for inspection.
$this->assertFileExists($invalid_gz);
}

public function testNoBackups(): void {
Expand Down Expand Up @@ -246,10 +250,10 @@ public function testBackupUrlEmpty(): void {
'url' => 'https://cloud.acquia.com/api/environments/env-id-prod/databases/mydb/backups?sort=created',
'response' => ['body' => json_encode(['_embedded' => ['items' => [['id' => '12345']]]])],
],
// Backup download URL returns empty.
// Backup download URL returns no redirect (empty redirect_url).
[
'url' => 'https://cloud.acquia.com/api/environments/env-id-prod/databases/mydb/backups/12345/actions/download',
'response' => ['body' => json_encode([])],
'response' => ['info' => ['redirect_url' => '']],
],
]);

Expand Down
23 changes: 23 additions & 0 deletions .vortex/tooling/tests/Unit/NotifyEmailTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,29 @@ public function testPreDeploymentEventSkipped(): void {
$this->runScriptEarlyPass('src/notify-email', 'Skipping email notification for pre_deployment event');
}

public function testNotificationSkippedWhenBranchNotInFilter(): void {
$this->envSet('VORTEX_NOTIFY_EMAIL_BRANCHES', 'main,master');
$this->envSet('VORTEX_NOTIFY_BRANCH', 'develop');

$this->runScriptEarlyPass('src/notify-email', "Skipping email notification for branch 'develop'.");
}

public function testNotificationProceedsWhenBranchInFilter(): void {
$this->envSet('VORTEX_NOTIFY_EMAIL_BRANCHES', 'main,develop');
$this->envSet('VORTEX_NOTIFY_BRANCH', 'develop');

$this->mockMail([
'to' => 'to@example.com',
'subject' => 'test-project deployment notification of main',
'message' => $this->defaultMessageMatcher(),
'result' => TRUE,
]);

$output = $this->runScript('src/notify-email');

$this->assertStringContainsString('Finished email notification', $output);
}

#[DataProvider('dataProviderMissingRequiredVariables')]
public function testMissingRequiredVariables(string $var_name): void {
$this->envUnset($var_name);
Expand Down
Loading
Loading