From 54edc1fe6c41770aa4c301e55d7fecc8ecb47508 Mon Sep 17 00:00:00 2001 From: Rick van de Loo Date: Wed, 24 Dec 2025 09:58:34 +0100 Subject: [PATCH 1/6] more robust waitForAvailability If the DNS change has not propagated yet to all nameservers, then it may be that the first reachability success goes through but a second one falis. in that case we are better off first trying for 'consecutive success' before we proceed with the deploy can be used in deploy.php like: ``` $testingStage->addBrancherServer("$APP_NAME") ->setLabels(['autodestroy=false', 'stage=acceptance', 'ci_ref=' . (\getenv('GITHUB_HEAD_REF') ?: 'none')]) ->setBrancherReachabilityCheckCount(6) // Amount of consecutive checks required ->setBrancherReachabilityCheckInterval(10); // Amount of seconds between checks ``` --- src/Brancher/BrancherHypernodeManager.php | 43 +++++++++++++++++++---- src/DeployRunner.php | 9 ++++- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/Brancher/BrancherHypernodeManager.php b/src/Brancher/BrancherHypernodeManager.php index cb82ef2..9f96175 100644 --- a/src/Brancher/BrancherHypernodeManager.php +++ b/src/Brancher/BrancherHypernodeManager.php @@ -107,14 +107,20 @@ public function createForHypernode(string $hypernode, array $data = []): string * * @param string $brancherHypernode Name of the brancher Hypernode * @param int $timeout Maximum time to wait for availability + * @param int $reachabilityCheckCount Number of consecutive successful checks required + * @param int $reachabilityCheckInterval Seconds between reachability checks * @return void * @throws CreateBrancherHypernodeFailedException * @throws HypernodeApiClientException * @throws HypernodeApiServerException * @throws TimeoutException */ - public function waitForAvailability(string $brancherHypernode, int $timeout = 1500): void - { + public function waitForAvailability( + string $brancherHypernode, + int $timeout = 1500, + int $reachabilityCheckCount = 6, + int $reachabilityCheckInterval = 10 + ): void { $latest = microtime(true); $timeElapsed = 0; $resolved = false; @@ -175,7 +181,7 @@ public function waitForAvailability(string $brancherHypernode, int $timeout = 15 ); } - $resolved = false; + $consecutiveSuccesses = 0; while ($timeElapsed < $timeout) { $now = microtime(true); $timeElapsed += $now - $latest; @@ -184,12 +190,37 @@ public function waitForAvailability(string $brancherHypernode, int $timeout = 15 $connection = @fsockopen(sprintf("%s.hypernode.io", $brancherHypernode), 22); if ($connection) { fclose($connection); - $resolved = true; - break; + $consecutiveSuccesses++; + $this->log->info( + sprintf( + 'Brancher Hypernode %s reachability check %d/%d succeeded.', + $brancherHypernode, + $consecutiveSuccesses, + $reachabilityCheckCount + ) + ); + + if ($consecutiveSuccesses >= $reachabilityCheckCount) { + break; + } + sleep($reachabilityCheckInterval); + } else { + if ($consecutiveSuccesses > 0) { + $this->log->info( + sprintf( + 'Brancher Hypernode %s reachability check failed, resetting counter (was at %d/%d).', + $brancherHypernode, + $consecutiveSuccesses, + $reachabilityCheckCount + ) + ); + } + $consecutiveSuccesses = 0; + sleep($reachabilityCheckInterval); } } - if (!$resolved) { + if ($consecutiveSuccesses < $reachabilityCheckCount) { throw new TimeoutException( sprintf('Timed out waiting for brancher Hypernode %s to become reachable', $brancherHypernode) ); diff --git a/src/DeployRunner.php b/src/DeployRunner.php index 3688ae8..294d8d0 100644 --- a/src/DeployRunner.php +++ b/src/DeployRunner.php @@ -274,6 +274,8 @@ private function maybeConfigureBrancherServer(Server $server, bool $reuseBranche if ($isBrancher && $parentApp) { $settings = $serverOptions[Server::OPTION_HN_BRANCHER_SETTINGS] ?? []; $labels = $serverOptions[Server::OPTION_HN_BRANCHER_LABELS] ?? []; + $reachabilityCheckCount = $serverOptions[Server::OPTION_HN_BRANCHER_REACHABILITY_CHECK_COUNT] ?? 6; + $reachabilityCheckInterval = $serverOptions[Server::OPTION_HN_BRANCHER_REACHABILITY_CHECK_INTERVAL] ?? 10; $this->log->info(sprintf('Creating an brancher Hypernode based on %s.', $parentApp)); if ($settings) { @@ -299,7 +301,12 @@ private function maybeConfigureBrancherServer(Server $server, bool $reuseBranche try { $this->log->info('Waiting for brancher Hypernode to become available...'); - $this->brancherHypernodeManager->waitForAvailability($brancherApp); + $this->brancherHypernodeManager->waitForAvailability( + $brancherApp, + 1500, + $reachabilityCheckCount, + $reachabilityCheckInterval + ); $this->log->info('Brancher Hypernode has become available!'); } catch (CreateBrancherHypernodeFailedException | TimeoutException $e) { if (in_array($brancherApp, $this->brancherHypernodesRegistered)) { From f06be7ff427d37daabd8f422a644a0ee118c324e Mon Sep 17 00:00:00 2001 From: Rick van de Loo Date: Wed, 24 Dec 2025 10:11:08 +0100 Subject: [PATCH 2/6] temp use hypernode-deploy-configuration branch so we can test both PRs without merging both: https://github.com/ByteInternet/hypernode-deploy-configuration/pull/55 https://github.com/ByteInternet/hypernode-deploy/pull/184 --- composer.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 87c18cb..0d83e3d 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "doctrine/annotations": "^1.6", "guzzlehttp/guzzle": "^7.5", "hypernode/api-client": "^0.5", - "hypernode/deploy-configuration": "^3.5", + "hypernode/deploy-configuration": "dev-more-robust-dns-check as 3.5.99", "php-di/php-di": "^7.0", "psr/log": "^1.0", "symfony/console": "^5.4", @@ -55,6 +55,10 @@ "deployer-fork": { "type": "vcs", "url": "https://github.com/ByteInternet/deployer" + }, + "deploy-configuration": { + "type": "vcs", + "url": "https://github.com/ByteInternet/hypernode-deploy-configuration" } } } From 439dd2fbc8639c2bc291cf86245a643b117f2f28 Mon Sep 17 00:00:00 2001 From: Rick van de Loo Date: Wed, 24 Dec 2025 10:21:44 +0100 Subject: [PATCH 3/6] add DEFAULT_BRANCHER_TIMEOUT --- src/DeployRunner.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/DeployRunner.php b/src/DeployRunner.php index 294d8d0..4bb2b15 100644 --- a/src/DeployRunner.php +++ b/src/DeployRunner.php @@ -35,6 +35,10 @@ class DeployRunner public const TASK_BUILD = 'build'; public const TASK_DEPLOY = 'deploy'; + public const DEFAULT_BRANCHER_TIMEOUT = 1500; + public const DEFAULT_BRANCHER_REACHABILITY_CHECK_COUNT = 6; + public const DEFAULT_BRANCHER_REACHABILITY_CHECK_INTERVAL = 10; + private TaskFactory $taskFactory; private InputInterface $input; private LoggerInterface $log; @@ -274,8 +278,9 @@ private function maybeConfigureBrancherServer(Server $server, bool $reuseBranche if ($isBrancher && $parentApp) { $settings = $serverOptions[Server::OPTION_HN_BRANCHER_SETTINGS] ?? []; $labels = $serverOptions[Server::OPTION_HN_BRANCHER_LABELS] ?? []; - $reachabilityCheckCount = $serverOptions[Server::OPTION_HN_BRANCHER_REACHABILITY_CHECK_COUNT] ?? 6; - $reachabilityCheckInterval = $serverOptions[Server::OPTION_HN_BRANCHER_REACHABILITY_CHECK_INTERVAL] ?? 10; + $timeout = $serverOptions[Server::OPTION_HN_BRANCHER_TIMEOUT] ?? self::DEFAULT_BRANCHER_TIMEOUT; + $reachabilityCheckCount = $serverOptions[Server::OPTION_HN_BRANCHER_REACHABILITY_CHECK_COUNT] ?? self::DEFAULT_BRANCHER_REACHABILITY_CHECK_COUNT; + $reachabilityCheckInterval = $serverOptions[Server::OPTION_HN_BRANCHER_REACHABILITY_CHECK_INTERVAL] ?? self::DEFAULT_BRANCHER_REACHABILITY_CHECK_INTERVAL; $this->log->info(sprintf('Creating an brancher Hypernode based on %s.', $parentApp)); if ($settings) { @@ -303,7 +308,7 @@ private function maybeConfigureBrancherServer(Server $server, bool $reuseBranche $this->log->info('Waiting for brancher Hypernode to become available...'); $this->brancherHypernodeManager->waitForAvailability( $brancherApp, - 1500, + $timeout, $reachabilityCheckCount, $reachabilityCheckInterval ); From 49ab333c34eb06c06aad92f0b93b8bd4e79423f2 Mon Sep 17 00:00:00 2001 From: Rick van de Loo Date: Wed, 24 Dec 2025 10:47:29 +0100 Subject: [PATCH 4/6] Revert "temp use hypernode-deploy-configuration branch" This reverts commit f06be7ff427d37daabd8f422a644a0ee118c324e. --- composer.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 0d83e3d..87c18cb 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "doctrine/annotations": "^1.6", "guzzlehttp/guzzle": "^7.5", "hypernode/api-client": "^0.5", - "hypernode/deploy-configuration": "dev-more-robust-dns-check as 3.5.99", + "hypernode/deploy-configuration": "^3.5", "php-di/php-di": "^7.0", "psr/log": "^1.0", "symfony/console": "^5.4", @@ -55,10 +55,6 @@ "deployer-fork": { "type": "vcs", "url": "https://github.com/ByteInternet/deployer" - }, - "deploy-configuration": { - "type": "vcs", - "url": "https://github.com/ByteInternet/hypernode-deploy-configuration" } } } From af93a8ed808a77619b60639f916becf4d41f21f6 Mon Sep 17 00:00:00 2001 From: Rick van de Loo Date: Wed, 24 Dec 2025 10:55:37 +0100 Subject: [PATCH 5/6] use deploy-configuration 3.6 --- composer.json | 2 +- composer.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 87c18cb..48bb58f 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "doctrine/annotations": "^1.6", "guzzlehttp/guzzle": "^7.5", "hypernode/api-client": "^0.5", - "hypernode/deploy-configuration": "^3.5", + "hypernode/deploy-configuration": "^3.6", "php-di/php-di": "^7.0", "psr/log": "^1.0", "symfony/console": "^5.4", diff --git a/composer.lock b/composer.lock index 63e817f..17c2d5d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ac062b2d98f523024b86eb9b650ed881", + "content-hash": "060108911b9a3452b54a2d0704c7c549", "packages": [ { "name": "carbonphp/carbon-doctrine-types", @@ -917,16 +917,16 @@ }, { "name": "hypernode/deploy-configuration", - "version": "3.5.0", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/ByteInternet/hypernode-deploy-configuration.git", - "reference": "c42b0e35237888b2a0afa2ed66a3e6ae49cdf3c9" + "reference": "7abbb530e95add7d64dd4312e12643f6fe7aeb0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ByteInternet/hypernode-deploy-configuration/zipball/c42b0e35237888b2a0afa2ed66a3e6ae49cdf3c9", - "reference": "c42b0e35237888b2a0afa2ed66a3e6ae49cdf3c9", + "url": "https://api.github.com/repos/ByteInternet/hypernode-deploy-configuration/zipball/7abbb530e95add7d64dd4312e12643f6fe7aeb0c", + "reference": "7abbb530e95add7d64dd4312e12643f6fe7aeb0c", "shasum": "" }, "require": { @@ -954,9 +954,9 @@ "description": "Hypernode deploy configuration files", "support": { "issues": "https://github.com/ByteInternet/hypernode-deploy-configuration/issues", - "source": "https://github.com/ByteInternet/hypernode-deploy-configuration/tree/3.5.0" + "source": "https://github.com/ByteInternet/hypernode-deploy-configuration/tree/3.6.0" }, - "time": "2025-12-15T11:56:28+00:00" + "time": "2025-12-24T09:41:44+00:00" }, { "name": "justinrainbow/json-schema", @@ -7722,7 +7722,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -7732,6 +7732,6 @@ "ext-zlib": "*", "composer-runtime-api": "^2" }, - "platform-dev": [], - "plugin-api-version": "2.6.0" + "platform-dev": {}, + "plugin-api-version": "2.9.0" } From a05e355497684f6eb73ac4545e56d7b42be8575a Mon Sep 17 00:00:00 2001 From: Rick van de Loo Date: Wed, 24 Dec 2025 11:55:19 +0100 Subject: [PATCH 6/6] double brancher timeout in integration test --- ci/test/magento/deploy_brancher.php | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/test/magento/deploy_brancher.php b/ci/test/magento/deploy_brancher.php index 4399a7d..5d9d3bd 100644 --- a/ci/test/magento/deploy_brancher.php +++ b/ci/test/magento/deploy_brancher.php @@ -19,6 +19,7 @@ $productionStage = $configuration->addStage('test', 'banaan.store'); $productionStage->addBrancherServer('hndeployintegr8') + ->setBrancherTimeout(3000) ->setLabels(['gitref='. (\getenv('GITHUB_SHA') ?: 'unknown')]); return $configuration;