From 08dce880be6d7277542b52683e3d7e4236b12b76 Mon Sep 17 00:00:00 2001 From: Yanick Witschi Date: Fri, 26 Jan 2018 16:39:31 +0100 Subject: [PATCH 01/20] Added sleep task to allow delaying execution of other tasks --- src/Task/BuiltIn/SleepTask.php | 68 ++++++++++++++++++++++++++++ tests/Task/BuiltIn/SleepTaskTest.php | 31 +++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 src/Task/BuiltIn/SleepTask.php create mode 100644 tests/Task/BuiltIn/SleepTaskTest.php diff --git a/src/Task/BuiltIn/SleepTask.php b/src/Task/BuiltIn/SleepTask.php new file mode 100644 index 00000000..24c60512 --- /dev/null +++ b/src/Task/BuiltIn/SleepTask.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Mage\Task\BuiltIn; + +use Mage\Task\Exception\ErrorException; +use Mage\Task\AbstractTask; + +/** + * Sleep task. Sleeps for a given number of seconds so you can delay task + * execution. + * + * @author Yanick Witschi + */ +class SleepTask extends AbstractTask +{ + /** + * @return string + */ + public function getName() + { + return 'sleep'; + } + + /** + * @return string + */ + public function getDescription() + { + $options = $this->getOptions(); + + return sprintf('[Sleep] Sleeping for %s second(s)', (int) $options['seconds']); + } + + /** + * @return bool + * + * @throws ErrorException + */ + public function execute() + { + $options = $this->getOptions(); + + sleep((int) $options['seconds']); + + return true; + } + + /** + * @return array + */ + protected function getOptions() + { + $options = array_merge( + ['seconds' => 1], + $this->options + ); + + return $options; + } +} diff --git a/tests/Task/BuiltIn/SleepTaskTest.php b/tests/Task/BuiltIn/SleepTaskTest.php new file mode 100644 index 00000000..26f1756f --- /dev/null +++ b/tests/Task/BuiltIn/SleepTaskTest.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Mage\Tests\Task\BuiltIn; + +use Mage\Task\BuiltIn\SleepTask; +use Mage\Tests\Runtime\RuntimeMockup; +use PHPUnit_Framework_TestCase as TestCase; + +class SleepTaskTest extends TestCase +{ + public function testCommand() + { + $runtime = new RuntimeMockup(); + $runtime->setConfiguration(['environments' => ['test' => []]]); + $runtime->setEnvironment('test'); + + $task = new SleepTask(); + $task->setRuntime($runtime); + + $this->assertSame('[Sleep] Sleeping for 1 second(s)', $task->getDescription()); + $task->execute(); + } +} From 3f22cc6288fab1d6886d5640d418ec42743d68d5 Mon Sep 17 00:00:00 2001 From: Ante Galic Date: Tue, 12 Jun 2018 15:20:37 +0200 Subject: [PATCH 02/20] Add optional symlink --- src/Task/BuiltIn/Deploy/ReleaseTask.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Task/BuiltIn/Deploy/ReleaseTask.php b/src/Task/BuiltIn/Deploy/ReleaseTask.php index ab767f01..231dd2a1 100644 --- a/src/Task/BuiltIn/Deploy/ReleaseTask.php +++ b/src/Task/BuiltIn/Deploy/ReleaseTask.php @@ -40,8 +40,10 @@ public function execute() $hostPath = rtrim($this->runtime->getEnvOption('host_path'), '/'); $releaseId = $this->runtime->getReleaseId(); + + $symlink = $this->runtime->getEnvOption('symlink', 'current'); - $cmdLinkRelease = sprintf('cd %s && ln -snf releases/%s current', $hostPath, $releaseId); + $cmdLinkRelease = sprintf('cd %s && ln -snf releases/%s %s', $hostPath, $releaseId, $symlink); /** @var Process $process */ $process = $this->runtime->runRemoteCommand($cmdLinkRelease, false, null); From df248dd1b00f759e017793c0b576e97f5e024afe Mon Sep 17 00:00:00 2001 From: Fritz Michael Gschwantner Date: Mon, 10 Sep 2018 18:27:56 +0200 Subject: [PATCH 03/20] use fallback for posix_getpwuid on Windows --- src/Runtime/Runtime.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Runtime/Runtime.php b/src/Runtime/Runtime.php index 5b7368df..006282ef 100644 --- a/src/Runtime/Runtime.php +++ b/src/Runtime/Runtime.php @@ -517,6 +517,11 @@ public function getTempFile() */ public function getCurrentUser() { + // Windows fallback + if (!function_exists('posix_getpwuid')) { + return getenv('USERNAME') ?: ''; + } + $userData = posix_getpwuid(posix_geteuid()); return $userData['name']; } From 9a46f89266616911d24cf192fc1cdd956aedf6a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 01:20:03 -0300 Subject: [PATCH 04/20] [Galactica] V5 initial scope --- .github/workflows/linters.yml | 32 +++ .github/workflows/tests.yml | 60 +++++ .gitignore | 2 +- .travis.yml | 3 +- CHANGELOG.md | 28 +-- CONTRIBUTING.md | 25 +- LICENSE | 2 +- README.md | 4 +- composer.json | 26 +- docs/dockers/docker-compose.yml | 6 +- docs/dockers/{php7.4 => php8.0}/Dockerfile | 4 +- docs/example-config.yml | 8 +- phpcs.xml.dist | 14 ++ phpstan.neon | 4 + phpunit.xml.dist | 61 ++--- src/Command/AbstractCommand.php | 29 +-- src/Command/BuiltIn/Config/DumpCommand.php | 14 +- .../BuiltIn/Config/EnvironmentsCommand.php | 14 +- src/Command/BuiltIn/DeployCommand.php | 108 +++++--- src/Command/BuiltIn/Releases/ListCommand.php | 31 ++- .../BuiltIn/Releases/RollbackCommand.php | 35 +-- src/Command/BuiltIn/VersionCommand.php | 14 +- src/Deploy/Strategy/ReleasesStrategy.php | 27 +- src/Deploy/Strategy/RsyncStrategy.php | 27 +- src/Deploy/Strategy/StrategyInterface.php | 42 +++- src/Mage.php | 5 +- src/MageApplication.php | 43 ++-- src/Runtime/Exception/RuntimeException.php | 5 +- src/Runtime/Runtime.php | 231 +++++++----------- src/Task/AbstractTask.php | 43 +--- .../BuiltIn/Composer/AbstractComposerTask.php | 11 +- .../BuiltIn/Composer/DumpAutoloadTask.php | 9 +- src/Task/BuiltIn/Composer/InstallTask.php | 11 +- src/Task/BuiltIn/Composer/SelfUpdateTask.php | 86 ------- .../BuiltIn/Deploy/Release/CleanupTask.php | 7 +- .../BuiltIn/Deploy/Release/PrepareTask.php | 7 +- src/Task/BuiltIn/Deploy/ReleaseTask.php | 9 +- src/Task/BuiltIn/Deploy/RsyncTask.php | 23 +- src/Task/BuiltIn/Deploy/Tar/CleanupTask.php | 7 +- src/Task/BuiltIn/Deploy/Tar/CopyTask.php | 20 +- src/Task/BuiltIn/Deploy/Tar/PrepareTask.php | 14 +- src/Task/BuiltIn/ExecTask.php | 13 +- src/Task/BuiltIn/FS/AbstractFileTask.php | 15 +- src/Task/BuiltIn/FS/ChangeModeTask.php | 14 +- src/Task/BuiltIn/FS/CopyTask.php | 14 +- src/Task/BuiltIn/FS/LinkTask.php | 14 +- src/Task/BuiltIn/FS/MoveTask.php | 11 +- src/Task/BuiltIn/FS/RemoveTask.php | 14 +- src/Task/BuiltIn/Git/ChangeBranchTask.php | 19 +- src/Task/BuiltIn/Git/UpdateTask.php | 13 +- .../BuiltIn/Symfony/AbstractSymfonyTask.php | 11 +- .../BuiltIn/Symfony/AssetsInstallTask.php | 18 +- src/Task/BuiltIn/Symfony/CacheClearTask.php | 7 +- .../BuiltIn/Symfony/CachePoolClearTask.php | 17 +- .../BuiltIn/Symfony/CachePoolPruneTask.php | 7 +- src/Task/BuiltIn/Symfony/CacheWarmupTask.php | 7 +- src/Task/Exception/ErrorException.php | 7 +- src/Task/Exception/SkipException.php | 5 +- src/Task/ExecuteOnRollbackInterface.php | 1 + src/Task/TaskFactory.php | 42 ++-- src/Utils.php | 47 ++-- .../BuiltIn/DeployCommandWithReleasesTest.php | 49 ++++ tests/MageApplicationMockup.php | 2 +- tests/MageApplicationWindowsMockup.php | 3 +- tests/Runtime/ProcessMockup.php | 9 +- tests/Runtime/RuntimeMockup.php | 18 +- tests/Runtime/RuntimeWindowsMockup.php | 2 +- tests/Task/AbstractTaskTest.php | 8 - .../BuiltIn/Composer/BasicComposerTask.php | 6 +- .../BuiltIn/Composer/SelfUpdateTaskTest.php | 174 ------------- tests/Task/Custom/NotInstantiableTask.php | 6 +- tests/Task/Custom/ValidTask.php | 6 +- tests/Task/CustomTask.php | 6 +- tests/Task/TestCaseFailTask.php | 6 +- tests/Task/TestCaseTask.php | 6 +- 75 files changed, 811 insertions(+), 937 deletions(-) create mode 100644 .github/workflows/linters.yml create mode 100644 .github/workflows/tests.yml rename docs/dockers/{php7.4 => php8.0}/Dockerfile (68%) create mode 100644 phpcs.xml.dist create mode 100644 phpstan.neon delete mode 100644 src/Task/BuiltIn/Composer/SelfUpdateTask.php delete mode 100644 tests/Task/BuiltIn/Composer/SelfUpdateTaskTest.php diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml new file mode 100644 index 00000000..83ccf61d --- /dev/null +++ b/.github/workflows/linters.yml @@ -0,0 +1,32 @@ +name: Linters + +on: + push: + branches: + - master + - galactica + pull_request: + release: + types: + - created + +jobs: + linters: + name: Linters + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Composer install + uses: php-actions/composer@v5 + with: + command: install + args: --ignore-platform-reqs --no-scripts + version: 2 + php_version: 8.0 + - name: PHPStan + run: ./vendor/bin/phpstan analyse + - name: PHP Code Sniffer + run: ./vendor/bin/phpcs diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..e3c563a8 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,60 @@ +name: PHPUnit + +on: + push: + branches: + - master + - galactica + pull_request: + release: + types: + - created + +jobs: + unit_tests_80: + name: Unit tests with PHP 8.0 + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Composer install + uses: php-actions/composer@v5 + with: + command: install + args: --ignore-platform-reqs --no-scripts + version: 2 + php_version: 8.0 + - name: Run tests + env: + XDEBUG_MODE: coverage + run: ./vendor/bin/phpunit --testsuite=unit + - name: Run Coveralls + env: + XDEBUG_MODE: coverage + run: ./vendor/bin/php-coveralls -v --coverage_clover build/logs/coverage.xml + + unit_tests_81: + name: Unit tests with PHP 8.1 + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Composer install + uses: php-actions/composer@v5 + with: + command: install + args: --ignore-platform-reqs --no-scripts + version: 2 + php_version: 8.1 + - name: Run tests + env: + XDEBUG_MODE: coverage + run: ./vendor/bin/phpunit --testsuite=unit + - name: Run Coveralls + env: + XDEBUG_MODE: coverage + run: ./vendor/bin/php-coveralls -v --coverage_clover build/logs/coverage.xml diff --git a/.gitignore b/.gitignore index 34fa4e77..f8cb51bf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ composer.lock .mage.yml .phpunit.result.cache - +.phpcs-cache diff --git a/.travis.yml b/.travis.yml index 96cce3eb..3a15c801 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,7 @@ language: php php: - - '7.2' - - '7.4' - '8.0' + - '8.1' install: - composer install diff --git a/CHANGELOG.md b/CHANGELOG.md index 704d0483..8d3fcfb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,24 +1,8 @@ -CHANGELOG for 4.X +CHANGELOG for 5.X ================= -* 4.1.1 (2021-02-20) - * Add `copyDirectory` option - * Bug fixes - * Improve testing and coverage - - -* 4.1.0 (2021-02-19) - * PHP 8 and Symfony 5 compatibility [PR#448] - * Timeout option for SSH [PR#436] - * Improve compatibility with Windows [PR#434] [PR#429] - * Improve config load [PR#422] - * Bug fixes [PR#448] [PR#424] - * Readme Update [PR#438] - - -* 4.0.0 (2018-04-02) - * v4 series release - * Refactored for Symfony 4 and PHP 7.1 - * Symfony Pool Clear task added - * Symfony Pool Prune task added - * Symfony Assetic task removed +* 5.0.0 (2022-04-15) + * v5 series release + * Refactored for Symfony 6 and PHP 8 + * Added strong types + * Removed task `composer/self-update` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cc1ed8ee..d262e045 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ Please read the following guidelines to make your and our work easier and cleane 1. Write clean code with no mess left 2. Contribute the docs when adding configurable new feature -3. Create your pull request from `nostromo` branch +3. Create your pull request from `galactica` branch 4. Ensure your code is fully covered by tests ---------- @@ -28,39 +28,36 @@ In order to have the PRs prioritized name them with the following tags. [FEATURE] Create new PermissionsTask [HOTFIX] Exception not caught on deployment ``` -All Pull Requests must be done to the `nostromo` branch, only exception are Hotfixes. +All Pull Requests must be done to the `galactica` branch, only exception are Hotfixes. Remember of square brackets when adding issue number. If you'd forget adding them, your whole message will be a comment! # Developing Magallanes ## Branches The flow is pretty simple. -In most common cases we work on the `nostromo` branch. It's the branch with the main development for the current major version. All Pull Requests must merge with that branch. The `master` branch is used to move the validated code and generate the releases in an orderly fashion, also we could use it for hotfixes. +In most common cases we work on the `galactica` branch. It's the branch with the main development for the current major version. All Pull Requests must merge with that branch. The `master` branch is used to move the validated code and generate the releases in an orderly fashion, also we could use it for hotfixes. -If you want to use developing branch in your code, simple pass `dev-nostromo` to dependency version in your `composer.json` file: +If you want to use developing branch in your code, simple pass `dev-galactica` to dependency version in your `composer.json` file: ```json { "require": { - "andres-montanez/magallanes": "dev-nostromo" + "andres-montanez/magallanes": "dev-galactica" } } ``` ## Organization and code quality -We use [PSR2](http://www.php-fig.org/psr/psr-2/) as PHP coding standard. +We use [PSR-12](http://www.php-fig.org/psr/psr-12/) as PHP coding standard. ### Tools you can use to ensure your code quality -1. PHP-CodeSniffer -2. [PHP Mess Detector](https://phpmd.org/) -3. PHP Copy/Paste Detector -4. PHP Dead Code Detector -5. [PHP Coding Standards Fixer](http://cs.sensiolabs.org) with --level=psr2 +1. PHPStan `./vendor/bin/phpstan analyse` +2. PHP Code Sniffer `./vendor/bin/phpcs` ## Testing and quality We use PHPUnit to test our code. Most of the project is covered with tests, so if you want your code to be merged push it with proper testing and coverage (at least 95%). To execute the tests with code coverage report: -``` -vendor/bin/phpunit --coverage-clover build/logs/coverage.xml -vendor/bin/coveralls -v --coverage_clover build/logs/coverage.xml +```bash +./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml --coverage-text +./vendor/bin/php-coveralls -v --coverage_clover build/logs/coverage.xml ``` Tests structure follow almost the same structure as production code with `Test` suffix in class and file name. Follow the tests already made as guidelines. diff --git a/LICENSE b/LICENSE index 2130481b..f5d91f06 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011 - 2017 Andrés Montañez +Copyright (c) 2011 - 2022 Andrés Montañez Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/README.md b/README.md index 5a6bc407..e20260ad 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Simply add the following dependency to your project’s composer.json file: ```json "require-dev": { - "andres-montanez/magallanes": "^4.0" + "andres-montanez/magallanes": "^5.0" } ``` Finally you can use **Magallanes** from the vendor's bin: @@ -26,4 +26,4 @@ vendor/bin/mage version ``` ### Codename Discovery One -Each new mayor version of **Magallanes** will have a codename (like Ubuntu), version 3 was _Nostromo_, and in the current version it is **_Discovery One_**, in homage to the spaceship from the ground breaking film *2001: A Space Odyssey (1968)*. +Each new mayor version of **Magallanes** will have a codename (like Ubuntu), version 3 was _Nostromo_, version 4 was _Discovery One_, and in the current version it is **_Galactica_**, in homage to the space battleship from the TV series Battlestar Galactica, both the '70s and the mind blowing revision of 2005. diff --git a/composer.json b/composer.json index 45fe0732..903ae36c 100644 --- a/composer.json +++ b/composer.json @@ -12,18 +12,20 @@ } ], "require": { - "php": "^7.2 | ^8.0", - "monolog/monolog": "~1.11 | ^2.0", - "symfony/console": "^4.0 | ^5.0", - "symfony/filesystem": "^4.0 | ^5.0", - "symfony/event-dispatcher": "^4.0 | ^5.0", - "symfony/finder": "^4.0 | ^5.0", - "symfony/yaml": "^4.0 | ^5.0", - "symfony/process": "^4.0 | ^5.0" + "php": "^8.0", + "monolog/monolog": "^2.5", + "symfony/console": "^6.0", + "symfony/filesystem": "^6.0", + "symfony/event-dispatcher": "^6.0", + "symfony/finder": "^6.0", + "symfony/yaml": "^6.0", + "symfony/process": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^8.0", - "php-coveralls/php-coveralls": "~2.0" + "phpunit/phpunit": "^9.5", + "phpstan/phpstan": "^1.5", + "squizlabs/php_codesniffer": "^3.6", + "php-coveralls/php-coveralls": "^2.5" }, "suggest": { "ext-posix": "*" @@ -41,8 +43,8 @@ "bin": ["bin/mage"], "extra": { "branch-alias": { - "dev-master": "4.0.x-dev", - "dev-discovery-one": "4.x-dev" + "dev-master": "5.0.x-dev", + "dev-discovery-one": "5.x-dev" } } } diff --git a/docs/dockers/docker-compose.yml b/docs/dockers/docker-compose.yml index 6ba830ce..ad04dc54 100644 --- a/docs/dockers/docker-compose.yml +++ b/docs/dockers/docker-compose.yml @@ -1,7 +1,7 @@ version: '2' services: - php7.4: - container_name: mage-php7.4 - build: ./php7.4 + php8.0: + container_name: mage-php8.0 + build: ./php8.0 volumes: - ../../:/home/magephp diff --git a/docs/dockers/php7.4/Dockerfile b/docs/dockers/php8.0/Dockerfile similarity index 68% rename from docs/dockers/php7.4/Dockerfile rename to docs/dockers/php8.0/Dockerfile index abafc3b2..a2492d57 100644 --- a/docs/dockers/php7.4/Dockerfile +++ b/docs/dockers/php8.0/Dockerfile @@ -1,11 +1,11 @@ -FROM ubuntu:20.04 +FROM ubuntu:21.10 ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC RUN apt-get update && apt-get upgrade -y RUN apt-get install -y vim curl git unzip -RUN apt-get install -y php7.4-cli php-zip php7.4-curl php7.4-xml php7.4-mbstring php7.4-xdebug +RUN apt-get install -y php8.0-cli php8.0-zip php8.0-curl php8.0-xml php8.0-mbstring php8.0-xdebug RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer diff --git a/docs/example-config.yml b/docs/example-config.yml index a59e97a4..e27f4e45 100644 --- a/docs/example-config.yml +++ b/docs/example-config.yml @@ -7,10 +7,8 @@ magephp: host_path: /var/www/test releases: 4 exclude: - - vendor - - app/cache - - app/log - - web/app_dev.php + - var/cache + - var/log hosts: - webserver1 - webserver2 @@ -18,7 +16,7 @@ magephp: pre-deploy: - git/update - composer/install - - composer/generate-autoload + - composer/dump-autoload on-deploy: - symfony/cache-warmup: { env: 'prod' } - symfony/assets-install: { env: 'prod' } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 00000000..38f2f106 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,14 @@ + + + + + + + + + + + + src/ + diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..6e451faa --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,4 @@ +parameters: + level: 6 + paths: + - src diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f8680dbe..686da15e 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,37 +1,28 @@ - - - - - - - - - - - - ./tests/ - - - - - - benchmark - intl-data - - - - - - ./src/ - - ./tests/ - - - + + + + ./src/ + + + ./tests/ + + + + + + + + + + + ./tests/ + + + + + benchmark + intl-data + + diff --git a/src/Command/AbstractCommand.php b/src/Command/AbstractCommand.php index ba941647..cc1712e0 100644 --- a/src/Command/AbstractCommand.php +++ b/src/Command/AbstractCommand.php @@ -1,4 +1,5 @@ runtime = $runtime; - return $this; } /** * Logs a message - * - * @param string $message - * @param string $level */ - public function log($message, $level = LogLevel::DEBUG) + public function log(string $message, string $level = LogLevel::DEBUG): void { $this->runtime->log($message, $level); } /** * Get the Human friendly Stage name - * - * @return string */ - protected function getStageName() + protected function getStageName(): string { $utils = new Utils(); return $utils->getStageName($this->runtime->getStage()); @@ -71,7 +56,7 @@ protected function getStageName() /** * Requires the configuration to be loaded */ - protected function requireConfig() + protected function requireConfig(): void { $app = $this->getApplication(); if ($app instanceof MageApplication) { diff --git a/src/Command/BuiltIn/Config/DumpCommand.php b/src/Command/BuiltIn/Config/DumpCommand.php index 8b7a1851..181fd23c 100644 --- a/src/Command/BuiltIn/Config/DumpCommand.php +++ b/src/Command/BuiltIn/Config/DumpCommand.php @@ -1,4 +1,5 @@ setName('config:dump') - ->setDescription('Dumps the Magallanes configuration') - ; + ->setDescription('Dumps the Magallanes configuration'); } /** * Execute the Command - * - * @param InputInterface $input - * @param OutputInterface $output - * @return int|mixed */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->requireConfig(); @@ -51,6 +47,6 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln(''); $output->writeln('Finished Magallanes'); - return 0; + return self::SUCCESS; } } diff --git a/src/Command/BuiltIn/Config/EnvironmentsCommand.php b/src/Command/BuiltIn/Config/EnvironmentsCommand.php index b66616b9..65e74eba 100644 --- a/src/Command/BuiltIn/Config/EnvironmentsCommand.php +++ b/src/Command/BuiltIn/Config/EnvironmentsCommand.php @@ -1,4 +1,5 @@ setName('config:environments') - ->setDescription('List all Magallanes configured Environments') - ; + ->setDescription('List all Magallanes configured Environments'); } /** * Execute the Command - * - * @param InputInterface $input - * @param OutputInterface $output - * @return int|mixed */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->requireConfig(); @@ -66,6 +62,6 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln(''); $output->writeln('Finished Magallanes'); - return 0; + return self::SUCCESS; } } diff --git a/src/Command/BuiltIn/DeployCommand.php b/src/Command/BuiltIn/DeployCommand.php index bb2cb5c4..684c57a5 100644 --- a/src/Command/BuiltIn/DeployCommand.php +++ b/src/Command/BuiltIn/DeployCommand.php @@ -1,4 +1,5 @@ setName('deploy') ->setDescription('Deploy code to hosts') ->addArgument('environment', InputArgument::REQUIRED, 'Name of the environment to deploy to') - ->addOption('branch', null, InputOption::VALUE_REQUIRED, 'Force to switch to a branch other than the one defined', false) - ; + ->addOption( + 'branch', + null, + InputOption::VALUE_REQUIRED, + 'Force to switch to a branch other than the one defined', + false + ); } /** * Execute the Command - * - * @param InputInterface $input - * @param OutputInterface $output - * @return integer */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->requireConfig(); @@ -103,17 +102,15 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln('Finished Magallanes'); - return $this->statusCode; + return intval($this->statusCode); } /** * Run the Deployment Process * - * @param OutputInterface $output - * @param StrategyInterface $strategy * @throws RuntimeException */ - protected function runDeployment(OutputInterface $output, StrategyInterface $strategy) + protected function runDeployment(OutputInterface $output, StrategyInterface $strategy): void { // Run "Pre Deploy" Tasks $this->runtime->setStage(Runtime::PRE_DEPLOY); @@ -140,16 +137,20 @@ protected function runDeployment(OutputInterface $output, StrategyInterface $str } } - protected function runOnHosts(OutputInterface $output, $tasks) + /** + * @param string[] $tasks + */ + protected function runOnHosts(OutputInterface $output, array $tasks): void { $hosts = $this->runtime->getEnvOption('hosts'); if (!is_array($hosts) && !$hosts instanceof \Countable) { $hosts = []; } - if (count($hosts) == 0) { + + if (count($hosts) === 0) { $output->writeln(sprintf(' No hosts defined, skipping %s tasks', $this->getStageName())); $output->writeln(''); - return true; + return; } foreach ($hosts as $host) { @@ -165,21 +166,27 @@ protected function runOnHosts(OutputInterface $output, $tasks) /** * Runs all the tasks * - * @param OutputInterface $output - * @param $tasks - * @return bool + * @param string[] $tasks * @throws RuntimeException */ - protected function runTasks(OutputInterface $output, $tasks) + protected function runTasks(OutputInterface $output, array $tasks): bool { if (count($tasks) == 0) { - $output->writeln(sprintf(' No tasks defined for %s stage', $this->getStageName())); + $output->writeln( + sprintf(' No tasks defined for %s stage', $this->getStageName()) + ); $output->writeln(''); return true; } if ($this->runtime->getHostName() !== null) { - $output->writeln(sprintf(' Starting %s tasks on host %s:', $this->getStageName(), $this->runtime->getHostName())); + $output->writeln( + sprintf( + ' Starting %s tasks on host %s:', + $this->getStageName(), + $this->runtime->getHostName() + ) + ); } else { $output->writeln(sprintf(' Starting %s tasks:', $this->getStageName())); } @@ -188,7 +195,6 @@ protected function runTasks(OutputInterface $output, $tasks) $succeededTasks = 0; foreach ($tasks as $taskName) { - /** @var AbstractTask $task */ $task = $this->taskFactory->get($taskName); $output->write(sprintf(' Running %s ... ', $task->getDescription())); $this->log(sprintf('Running task %s (%s)', $task->getDescription(), $task->getName())); @@ -196,25 +202,48 @@ protected function runTasks(OutputInterface $output, $tasks) if ($this->runtime->inRollback() && !$task instanceof ExecuteOnRollbackInterface) { $succeededTasks++; $output->writeln('SKIPPED'); - $this->log(sprintf('Task %s (%s) finished with SKIPPED, it was in a Rollback', $task->getDescription(), $task->getName())); + $this->log( + sprintf( + 'Task %s (%s) finished with SKIPPED, it was in a Rollback', + $task->getDescription(), + $task->getName() + ) + ); } else { try { if ($task->execute()) { $succeededTasks++; $output->writeln('OK'); - $this->log(sprintf('Task %s (%s) finished with OK', $task->getDescription(), $task->getName())); + $this->log( + sprintf('Task %s (%s) finished with OK', $task->getDescription(), $task->getName()) + ); } else { $output->writeln('FAIL'); $this->statusCode = 180; - $this->log(sprintf('Task %s (%s) finished with FAIL', $task->getDescription(), $task->getName())); + $this->log( + sprintf('Task %s (%s) finished with FAIL', $task->getDescription(), $task->getName()) + ); } } catch (SkipException $exception) { $succeededTasks++; $output->writeln('SKIPPED'); - $this->log(sprintf('Task %s (%s) finished with SKIPPED, thrown SkipException', $task->getDescription(), $task->getName())); + $this->log( + sprintf( + 'Task %s (%s) finished with SKIPPED, thrown SkipException', + $task->getDescription(), + $task->getName() + ) + ); } catch (ErrorException $exception) { $output->writeln(sprintf('ERROR [%s]', $exception->getTrimmedMessage())); - $this->log(sprintf('Task %s (%s) finished with FAIL, with Error "%s"', $task->getDescription(), $task->getName(), $exception->getMessage())); + $this->log( + sprintf( + 'Task %s (%s) finished with FAIL, with Error "%s"', + $task->getDescription(), + $task->getName(), + $exception->getMessage() + ) + ); $this->statusCode = 190; } } @@ -229,7 +258,15 @@ protected function runTasks(OutputInterface $output, $tasks) $alertColor = 'green'; } - $output->writeln(sprintf(' Finished %d/%d tasks for %s.', $alertColor, $succeededTasks, $totalTasks, $this->getStageName())); + $output->writeln( + sprintf( + ' Finished %d/%d tasks for %s.', + $alertColor, + $succeededTasks, + $totalTasks, + $this->getStageName() + ) + ); $output->writeln(''); return ($succeededTasks == $totalTasks); @@ -238,8 +275,11 @@ protected function runTasks(OutputInterface $output, $tasks) /** * Exception for halting the the current process */ - protected function getException() + protected function getException(): RuntimeException { - return new RuntimeException(sprintf('Stage "%s" did not finished successfully, halting command.', $this->getStageName()), 50); + return new RuntimeException( + sprintf('Stage "%s" did not finished successfully, halting command.', $this->getStageName()), + 50 + ); } } diff --git a/src/Command/BuiltIn/Releases/ListCommand.php b/src/Command/BuiltIn/Releases/ListCommand.php index 3b5b7805..294afffb 100644 --- a/src/Command/BuiltIn/Releases/ListCommand.php +++ b/src/Command/BuiltIn/Releases/ListCommand.php @@ -1,4 +1,5 @@ setName('releases:list') ->setDescription('List the releases on an environment') - ->addArgument('environment', InputArgument::REQUIRED, 'Name of the environment to deploy to') - ; + ->addArgument('environment', InputArgument::REQUIRED, 'Name of the environment to deploy to'); } /** * Execute the Command - * - * @param InputInterface $input - * @param OutputInterface $output - * @return int|mixed */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->requireConfig(); @@ -102,7 +93,9 @@ protected function execute(InputInterface $input, OutputInterface $output) } if (count($releases) == 0) { - $output->writeln(sprintf(' No releases available on host %s:', $host)); + $output->writeln( + sprintf(' No releases available on host %s:', $host) + ); } else { // Get Current Release $cmdCurrentRelease = sprintf('readlink -f %s/current', $hostPath); @@ -110,7 +103,10 @@ protected function execute(InputInterface $input, OutputInterface $output) /** @var Process $process */ $process = $this->runtime->runRemoteCommand($cmdCurrentRelease, false); if (!$process->isSuccessful()) { - throw new RuntimeException(sprintf('Unable to retrieve current release from host "%s"', $host), 85); + throw new RuntimeException( + sprintf('Unable to retrieve current release from host "%s"', $host), + 85 + ); } $currentReleaseId = explode('/', trim($process->getOutput())); @@ -121,7 +117,8 @@ protected function execute(InputInterface $input, OutputInterface $output) foreach ($releases as $releaseId) { $releaseDate = $utils->getReleaseDate($releaseId); - $output->write(sprintf(' Release ID: %s - Date: %s [%s]', + $output->write(sprintf( + ' Release ID: %s - Date: %s [%s]', $releaseId, $releaseDate->format('Y-m-d H:i:s'), $utils->getTimeDiff($releaseDate) @@ -146,6 +143,6 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln('Finished Magallanes'); - return $this->statusCode; + return intval($this->statusCode); } } diff --git a/src/Command/BuiltIn/Releases/RollbackCommand.php b/src/Command/BuiltIn/Releases/RollbackCommand.php index 4837aa41..c27fe968 100644 --- a/src/Command/BuiltIn/Releases/RollbackCommand.php +++ b/src/Command/BuiltIn/Releases/RollbackCommand.php @@ -1,4 +1,5 @@ setName('releases:rollback') ->setDescription('Rollback to a release on an environment') ->addArgument('environment', InputArgument::REQUIRED, 'Name of the environment to deploy to') - ->addArgument('release', InputArgument::REQUIRED, 'The ID or the Index of the release to rollback to') - ; + ->addArgument('release', InputArgument::REQUIRED, 'The ID or the Index of the release to rollback to'); } /** * Execute the Command - * - * @param InputInterface $input - * @param OutputInterface $output - * @return int|mixed */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $this->requireConfig(); @@ -68,11 +59,14 @@ protected function execute(InputInterface $input, OutputInterface $output) } $releaseToRollback = $input->getArgument('release'); - if (($releaseId = $this->checkReleaseAvailability($releaseToRollback)) === false) { - throw new RuntimeException(sprintf('Release "%s" is not available on all hosts', $releaseToRollback), 72); + if ($this->checkReleaseAvailability($releaseToRollback) === false) { + throw new RuntimeException( + sprintf('Release "%s" is not available on all hosts', $releaseToRollback), + 72 + ); } - $this->runtime->setReleaseId($releaseId)->setRollback(true); + $this->runtime->setReleaseId($releaseToRollback)->setRollback(true); $output->writeln(sprintf(' Environment: %s', $this->runtime->getEnvironment())); $this->log(sprintf('Environment: %s', $this->runtime->getEnvironment())); @@ -95,16 +89,13 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln('Finished Magallanes'); - return $this->statusCode; + return intval($this->statusCode); } /** * Check if the provided Release ID is available in all hosts - * - * @param string $releaseToRollback Release ID - * @return bool */ - protected function checkReleaseAvailability($releaseToRollback) + protected function checkReleaseAvailability(string $releaseToRollback): bool { $hosts = $this->runtime->getEnvOption('hosts'); $hostPath = rtrim($this->runtime->getEnvOption('host_path'), '/'); @@ -132,7 +123,7 @@ protected function checkReleaseAvailability($releaseToRollback) } if ($availableInHosts === count($hosts)) { - return $releaseToRollback; + return (bool) $releaseToRollback; } return false; diff --git a/src/Command/BuiltIn/VersionCommand.php b/src/Command/BuiltIn/VersionCommand.php index f5a1a0f4..df65e44b 100644 --- a/src/Command/BuiltIn/VersionCommand.php +++ b/src/Command/BuiltIn/VersionCommand.php @@ -1,4 +1,5 @@ setName('version') - ->setDescription('Get the version of Magallanes') - ; + ->setDescription('Get the version of Magallanes'); } /** * Executes the Command - * - * @param InputInterface $input - * @param OutputInterface $output - * @return int */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $output->writeln(sprintf('Magallanes v%s [%s]', Mage::VERSION, Mage::CODENAME)); - return 0; + return self::SUCCESS; } } diff --git a/src/Deploy/Strategy/ReleasesStrategy.php b/src/Deploy/Strategy/ReleasesStrategy.php index 132fdd05..800ab551 100644 --- a/src/Deploy/Strategy/ReleasesStrategy.php +++ b/src/Deploy/Strategy/ReleasesStrategy.php @@ -1,4 +1,5 @@ runtime = $runtime; } - public function getPreDeployTasks() + public function getPreDeployTasks(): array { $this->checkStage(Runtime::PRE_DEPLOY); $tasks = $this->runtime->getTasks(); @@ -51,7 +49,7 @@ public function getPreDeployTasks() return $tasks; } - public function getOnDeployTasks() + public function getOnDeployTasks(): array { $this->checkStage(Runtime::ON_DEPLOY); $tasks = $this->runtime->getTasks(); @@ -67,7 +65,7 @@ public function getOnDeployTasks() return $tasks; } - public function getOnReleaseTasks() + public function getOnReleaseTasks(): array { $this->checkStage(Runtime::ON_RELEASE); $tasks = $this->runtime->getTasks(); @@ -79,7 +77,7 @@ public function getOnReleaseTasks() return $tasks; } - public function getPostReleaseTasks() + public function getPostReleaseTasks(): array { $this->checkStage(Runtime::POST_RELEASE); $tasks = $this->runtime->getTasks(); @@ -91,7 +89,7 @@ public function getPostReleaseTasks() return $tasks; } - public function getPostDeployTasks() + public function getPostDeployTasks(): array { $this->checkStage(Runtime::POST_DEPLOY); $tasks = $this->runtime->getTasks(); @@ -110,13 +108,14 @@ public function getPostDeployTasks() /** * Check the runtime stage is correct * - * @param string $stage * @throws RuntimeException */ - private function checkStage($stage) + private function checkStage(string $stage): void { if ($this->runtime->getStage() !== $stage) { - throw new RuntimeException(sprintf('Invalid stage, got "%s" but expected "%s"', $this->runtime->getStage(), $stage)); + throw new RuntimeException( + sprintf('Invalid stage, got "%s" but expected "%s"', $this->runtime->getStage(), $stage) + ); } } } diff --git a/src/Deploy/Strategy/RsyncStrategy.php b/src/Deploy/Strategy/RsyncStrategy.php index 2be748e3..c7b5f1a1 100644 --- a/src/Deploy/Strategy/RsyncStrategy.php +++ b/src/Deploy/Strategy/RsyncStrategy.php @@ -1,4 +1,5 @@ runtime = $runtime; } - public function getPreDeployTasks() + public function getPreDeployTasks(): array { $this->checkStage(Runtime::PRE_DEPLOY); $tasks = $this->runtime->getTasks(); @@ -47,7 +45,7 @@ public function getPreDeployTasks() return $tasks; } - public function getOnDeployTasks() + public function getOnDeployTasks(): array { $this->checkStage(Runtime::ON_DEPLOY); $tasks = $this->runtime->getTasks(); @@ -59,17 +57,17 @@ public function getOnDeployTasks() return $tasks; } - public function getOnReleaseTasks() + public function getOnReleaseTasks(): array { return []; } - public function getPostReleaseTasks() + public function getPostReleaseTasks(): array { return []; } - public function getPostDeployTasks() + public function getPostDeployTasks(): array { $this->checkStage(Runtime::POST_DEPLOY); $tasks = $this->runtime->getTasks(); @@ -84,13 +82,14 @@ public function getPostDeployTasks() /** * Check the runtime stage is correct * - * @param $stage * @throws RuntimeException */ - private function checkStage($stage) + private function checkStage(string $stage): void { if ($this->runtime->getStage() !== $stage) { - throw new RuntimeException(sprintf('Invalid stage, got "%s" but expected "%s"', $this->runtime->getStage(), $stage)); + throw new RuntimeException( + sprintf('Invalid stage, got "%s" but expected "%s"', $this->runtime->getStage(), $stage) + ); } } } diff --git a/src/Deploy/Strategy/StrategyInterface.php b/src/Deploy/Strategy/StrategyInterface.php index 6bd9c77b..9da78dfc 100644 --- a/src/Deploy/Strategy/StrategyInterface.php +++ b/src/Deploy/Strategy/StrategyInterface.php @@ -1,4 +1,5 @@ addListener(ConsoleEvents::ERROR, function (ConsoleErrorEvent $event) { $output = $event->getOutput(); $command = $event->getCommand(); - $output->writeln(sprintf('Oops, exception thrown while running command %s', $command->getName())); + $output->writeln( + sprintf('Oops, exception thrown while running command %s', $command->getName()) + ); $exitCode = $event->getExitCode(); $event->setError(new \LogicException('Caught exception', $exitCode, $event->getError())); }); @@ -63,7 +65,7 @@ public function __construct($file) * * @throws RuntimeException */ - public function configure() + public function configure(): void { if (!file_exists($this->file) || !is_readable($this->file)) { throw new RuntimeException(sprintf('The file "%s" does not exists or is not readable.', $this->file)); @@ -78,15 +80,22 @@ public function configure() if (array_key_exists('magephp', $config) && is_array($config['magephp'])) { $logger = null; - if (array_key_exists('log_dir', $config['magephp']) && file_exists($config['magephp']['log_dir']) && is_dir($config['magephp']['log_dir'])) { + if ( + array_key_exists('log_dir', $config['magephp']) && + file_exists($config['magephp']['log_dir']) && is_dir($config['magephp']['log_dir']) + ) { $logfile = sprintf('%s/%s.log', $config['magephp']['log_dir'], date('Ymd_His')); $config['magephp']['log_file'] = $logfile; $logger = new Logger('magephp'); $logger->pushHandler(new StreamHandler($logfile)); - } elseif (array_key_exists('log_dir', $config['magephp']) && !is_dir($config['magephp']['log_dir'])) { - throw new RuntimeException(sprintf('The configured log_dir "%s" does not exists or is not a directory.', $config['magephp']['log_dir'])); + throw new RuntimeException( + sprintf( + 'The configured log_dir "%s" does not exists or is not a directory.', + $config['magephp']['log_dir'] + ) + ); } $this->runtime->setConfiguration($config['magephp']); @@ -94,13 +103,15 @@ public function configure() return; } - throw new RuntimeException(sprintf('The file "%s" does not have a valid Magallanes configuration.', $this->file)); + throw new RuntimeException( + sprintf('The file "%s" does not have a valid Magallanes configuration.', $this->file) + ); } /** * Loads the BuiltIn Commands */ - protected function loadBuiltInCommands() + protected function loadBuiltInCommands(): void { $finder = new Finder(); $finder->files()->in(__DIR__ . '/Command/BuiltIn')->name('*Command.php'); @@ -109,7 +120,7 @@ protected function loadBuiltInCommands() foreach ($finder as $file) { $class = substr('\\Mage\\Command\\BuiltIn\\' . str_replace('/', '\\', $file->getRelativePathname()), 0, -4); if (class_exists($class)) { - $reflex = new ReflectionClass($class); + $reflex = new \ReflectionClass($class); if ($reflex->isInstantiable()) { $command = new $class(); if ($command instanceof AbstractCommand) { @@ -123,20 +134,16 @@ protected function loadBuiltInCommands() /** * Gets the Runtime instance to use - * - * @return Runtime */ - protected function instantiateRuntime() + protected function instantiateRuntime(): Runtime { return new Runtime(); } /** * Get the Runtime instance - * - * @return Runtime */ - public function getRuntime() + public function getRuntime(): Runtime { return $this->runtime; } diff --git a/src/Runtime/Exception/RuntimeException.php b/src/Runtime/Exception/RuntimeException.php index 5b0fc75f..a7dd09f4 100644 --- a/src/Runtime/Exception/RuntimeException.php +++ b/src/Runtime/Exception/RuntimeException.php @@ -1,4 +1,5 @@ */ -class RuntimeException extends Exception +class RuntimeException extends \Exception { } diff --git a/src/Runtime/Runtime.php b/src/Runtime/Runtime.php index e1f026a7..ba483f54 100644 --- a/src/Runtime/Runtime.php +++ b/src/Runtime/Runtime.php @@ -1,4 +1,5 @@ Magallanes configuration */ - protected $configuration = []; + protected array $configuration = []; /** * @var string|null Environment being deployed */ - protected $environment; + protected ?string $environment = null; /** - * @var string Stage of Deployment + * @var string|null Stage of Deployment */ - protected $stage; + protected ?string $stage = null; /** * @var string|null The host being deployed to */ - protected $workingHost = null; + protected ?string $workingHost = null; /** * @var string|null The Release ID */ - protected $releaseId = null; + protected ?string $releaseId = null; /** - * @var array Hold a bag of variables for sharing information between tasks, if needed + * @var array Hold a bag of variables for sharing information between tasks, if needed */ protected $vars = []; - /** - * @var LoggerInterface|null The logger instance - */ - protected $logger; + protected ?LoggerInterface $logger = null; /** * @var bool Indicates if a Rollback operation is in progress */ - protected $rollback = false; + protected bool $rollback = false; - public function isWindows() + public function isWindows(): bool { return stripos(PHP_OS, 'WIN') === 0; } /** * Generate the Release ID - * - * @return Runtime */ - public function generateReleaseId() + public function generateReleaseId(): self { $this->setReleaseId(date('YmdHis')); return $this; @@ -89,11 +86,8 @@ public function generateReleaseId() /** * Sets the Release ID - * - * @param string $releaseId Release ID - * @return Runtime */ - public function setReleaseId($releaseId) + public function setReleaseId(string $releaseId): self { $this->releaseId = $releaseId; return $this; @@ -101,21 +95,16 @@ public function setReleaseId($releaseId) /** * Retrieve the current Release ID - * - * @return null|string Release ID */ - public function getReleaseId() + public function getReleaseId(): ?string { return $this->releaseId; } /** * Sets the Runtime in Rollback mode On or Off - * - * @param bool $inRollback - * @return Runtime */ - public function setRollback($inRollback) + public function setRollback(bool $inRollback): self { $this->rollback = $inRollback; return $this; @@ -123,35 +112,25 @@ public function setRollback($inRollback) /** * Indicates if Runtime is in rollback - * - * @return bool */ - public function inRollback() + public function inRollback(): bool { return $this->rollback; } /** * Sets a value in the Vars bag - * - * @param string $key Variable name - * @param string $value Variable value - * @return Runtime */ - public function setVar($key, $value) + public function setVar(string $key, string $value): self { $this->vars[$key] = $value; return $this; } /** - * Retrieve a value from the Vars bag - * - * @param string $key Variable name - * @param mixed $default Variable default value, returned if not found - * @return string + * Retrieve a value from the Vars bag, or a default (null) if not set */ - public function getVar($key, $default = null) + public function getVar(string $key, mixed $default = null): ?string { if (array_key_exists($key, $this->vars)) { return $this->vars[$key]; @@ -162,11 +141,8 @@ public function getVar($key, $default = null) /** * Sets the Logger instance - * - * @param LoggerInterface $logger Logger instance - * @return Runtime */ - public function setLogger(LoggerInterface $logger = null) + public function setLogger(?LoggerInterface $logger = null): self { $this->logger = $logger; return $this; @@ -175,10 +151,9 @@ public function setLogger(LoggerInterface $logger = null) /** * Sets the Magallanes Configuration to the Runtime * - * @param array $configuration Configuration - * @return Runtime + * @param array $configuration */ - public function setConfiguration($configuration) + public function setConfiguration(array $configuration): self { $this->configuration = $configuration; return $this; @@ -187,21 +162,17 @@ public function setConfiguration($configuration) /** * Retrieve the Configuration * - * @return array + * @return array $configuration */ - public function getConfiguration() + public function getConfiguration(): array { return $this->configuration; } /** * Retrieves the Configuration Option for a specific section in the configuration - * - * @param string $key Section name - * @param mixed $default Default value - * @return mixed */ - public function getConfigOption($key, $default = null) + public function getConfigOption(string $key, mixed $default = null): mixed { if (array_key_exists($key, $this->configuration)) { return $this->configuration[$key]; @@ -212,14 +183,13 @@ public function getConfigOption($key, $default = null) /** * Returns the Configuration Option for a specific section the current Environment - * - * @param string $key Section/Parameter name - * @param mixed $default Default value - * @return mixed */ - public function getEnvOption($key, $default = null) + public function getEnvOption(string $key, mixed $default = null): mixed { - if (!array_key_exists('environments', $this->configuration) || !is_array($this->configuration['environments'])) { + if ( + !array_key_exists('environments', $this->configuration) || + !is_array($this->configuration['environments']) + ) { return $default; } @@ -238,12 +208,10 @@ public function getEnvOption($key, $default = null) * Shortcut to get the the configuration option for a specific environment and merge it with * the global one (environment specific overrides the global one if present). * - * @param $key - * @param array $defaultEnv - * - * @return array + * @param array $defaultEnv + * @return array */ - public function getMergedOption($key, $defaultEnv = []) + public function getMergedOption(string $key, array $defaultEnv = []): array { $userGlobalOptions = $this->getConfigOption($key, $defaultEnv); $userEnvOptions = $this->getEnvOption($key, $defaultEnv); @@ -256,12 +224,8 @@ public function getMergedOption($key, $defaultEnv = []) /** * Overwrites an Environment Configuration Option - * - * @param string $key - * @param mixed $value - * @return Runtime */ - public function setEnvOption($key, $value) + public function setEnvOption(string $key, mixed $value): self { if (array_key_exists('environments', $this->configuration) && is_array($this->configuration['environments'])) { if (array_key_exists($this->environment, $this->configuration['environments'])) { @@ -275,13 +239,14 @@ public function setEnvOption($key, $value) /** * Sets the working Environment * - * @param string $environment Environment name - * @return Runtime * @throws RuntimeException */ - public function setEnvironment($environment) + public function setEnvironment(string $environment): self { - if (array_key_exists('environments', $this->configuration) && array_key_exists($environment, $this->configuration['environments'])) { + if ( + array_key_exists('environments', $this->configuration) && + array_key_exists($environment, $this->configuration['environments']) + ) { $this->environment = $environment; return $this; } @@ -291,21 +256,16 @@ public function setEnvironment($environment) /** * Returns the current working Environment - * - * @return null|string */ - public function getEnvironment() + public function getEnvironment(): ?string { return $this->environment; } /** * Sets the working stage - * - * @param string $stage Stage code - * @return Runtime */ - public function setStage($stage) + public function setStage(string $stage): self { $this->stage = $stage; return $this; @@ -313,10 +273,8 @@ public function setStage($stage) /** * Retrieve the current working Stage - * - * @return string */ - public function getStage() + public function getStage(): ?string { return $this->stage; } @@ -324,11 +282,14 @@ public function getStage() /** * Retrieve the defined Tasks for the current Environment and Stage * - * @return array + * @return string[] */ - public function getTasks() + public function getTasks(): array { - if (!array_key_exists('environments', $this->configuration) || !is_array($this->configuration['environments'])) { + if ( + !array_key_exists('environments', $this->configuration) || + !is_array($this->configuration['environments']) + ) { return []; } @@ -347,11 +308,8 @@ public function getTasks() /** * Sets the working Host - * - * @param string $host Host name - * @return Runtime */ - public function setWorkingHost($host) + public function setWorkingHost(?string $host): self { $this->workingHost = $host; return $this; @@ -359,21 +317,16 @@ public function setWorkingHost($host) /** * Retrieve the working Host - * - * @return null|string */ - public function getWorkingHost() + public function getWorkingHost(): ?string { return $this->workingHost; } /** * Logs a Message into the Logger - * - * @param string $message Log message - * @param string $level Log Level */ - public function log($message, $level = LogLevel::DEBUG) + public function log(string $message, string $level = LogLevel::DEBUG): void { if ($this->logger instanceof LoggerInterface) { $this->logger->log($level, $message); @@ -382,12 +335,8 @@ public function log($message, $level = LogLevel::DEBUG) /** * Executes a command, it will be run Locally or Remotely based on the working Stage - * - * @param string $cmd Command to execute - * @param int $timeout Seconds to wait - * @return Process */ - public function runCommand($cmd, $timeout = 120) + public function runCommand(string $cmd, int $timeout = 120): Process { switch ($this->getStage()) { case self::ON_DEPLOY: @@ -401,12 +350,8 @@ public function runCommand($cmd, $timeout = 120) /** * Execute a command locally - * - * @param string $cmd Command to execute - * @param int $timeout Seconds to wait - * @return Process */ - public function runLocalCommand($cmd, $timeout = 120) + public function runLocalCommand(string $cmd, int $timeout = 120): Process { $this->log($cmd, LogLevel::INFO); @@ -424,13 +369,8 @@ public function runLocalCommand($cmd, $timeout = 120) /** * Executes a command remotely, if jail is true, it will run inside the Host Path and the Release (if available) - * - * @param string $cmd Command to execute - * @param bool $jail Jail the command - * @param int $timeout Seconds to wait - * @return Process */ - public function runRemoteCommand($cmd, $jail, $timeout = 120) + public function runRemoteCommand(string $cmd, bool $jail, int $timeout = 120): Process { $user = $this->getEnvOption('user', $this->getCurrentUser()); $sudo = $this->getEnvOption('sudo', false); @@ -450,7 +390,14 @@ public function runRemoteCommand($cmd, $jail, $timeout = 120) } $cmdRemote = str_replace('"', '\"', $cmdDelegate); - $cmdLocal = sprintf('ssh -p %d %s %s@%s "%s"', $sshConfig['port'], $sshConfig['flags'], $user, $host, $cmdRemote); + $cmdLocal = sprintf( + 'ssh -p %d %s %s@%s "%s"', + $sshConfig['port'], + $sshConfig['flags'], + $user, + $host, + $cmdRemote + ); return $this->runLocalCommand($cmdLocal, $timeout); } @@ -458,11 +405,17 @@ public function runRemoteCommand($cmd, $jail, $timeout = 120) /** * Get the SSH configuration based on the environment * - * @return array + * @return array */ - public function getSSHConfig() + public function getSSHConfig(): array { - $sshConfig = $this->getEnvOption('ssh', ['port' => 22, 'flags' => '-q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no']); + $sshConfig = $this->getEnvOption( + 'ssh', + [ + 'port' => 22, + 'flags' => '-q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' + ] + ); if ($this->getHostPort() !== null) { $sshConfig['port'] = $this->getHostPort(); @@ -485,46 +438,38 @@ public function getSSHConfig() /** * Get the current Host Port or default ssh port - * - * @return integer */ - public function getHostPort() + public function getHostPort(): ?int { $info = explode(':', $this->getWorkingHost()); - return isset($info[1]) ? $info[1] : null; + return isset($info[1]) ? intval($info[1]) : null; } /** * Get the current Host Name - * - * @return string */ - public function getHostName() + public function getHostName(): ?string { if (strpos($this->getWorkingHost(), ':') === false) { return $this->getWorkingHost(); } $info = explode(':', $this->getWorkingHost()); - return $info[0]; + return strval($info[0]); } /** * Gets a Temporal File name - * - * @return string */ - public function getTempFile() + public function getTempFile(): string { return tempnam(sys_get_temp_dir(), 'mage'); } /** * Get the current user - * - * @return string */ - public function getCurrentUser() + public function getCurrentUser(): string { $userData = posix_getpwuid(posix_geteuid()); return $userData['name']; @@ -533,19 +478,17 @@ public function getCurrentUser() /** * Shortcut for getting Branch information * - * @return boolean|string + * @return bool|string */ - public function getBranch() + public function getBranch(): mixed { return $this->getEnvOption('branch', false); } /** * Guesses the Deploy Strategy to use - * - * @return StrategyInterface */ - public function guessStrategy() + public function guessStrategy(): StrategyInterface { $strategy = new RsyncStrategy(); diff --git a/src/Task/AbstractTask.php b/src/Task/AbstractTask.php index ee031347..af22a505 100644 --- a/src/Task/AbstractTask.php +++ b/src/Task/AbstractTask.php @@ -1,4 +1,5 @@ */ + protected array $options = []; - /** - * @var Runtime - */ - protected $runtime; + protected Runtime $runtime; /** * Get the Name/Code of the Task - * - * @return string */ - abstract public function getName(); + abstract public function getName(): string; /** * Get a short Description of the Task - * - * @return string */ - abstract public function getDescription(); + abstract public function getDescription(): string; /** * Executes the Command - * - * @return bool */ - abstract public function execute(); + abstract public function execute(): bool; /** * Set additional Options for the Task * - * @param array $options Options - * @return AbstractTask + * @param array $options */ - public function setOptions($options = []) + public function setOptions(array $options = []): self { - if (!is_array($options)) { - $options = []; - } - $this->options = array_merge($this->getDefaults(), $options); return $this; } /** * Set the Runtime instance - * - * @param Runtime $runtime - * @return AbstractTask */ - public function setRuntime(Runtime $runtime) + public function setRuntime(Runtime $runtime): self { $this->runtime = $runtime; return $this; @@ -80,9 +62,10 @@ public function setRuntime(Runtime $runtime) /** * Return Default options - * @return array + * + * @return array */ - public function getDefaults() + public function getDefaults(): array { return []; } diff --git a/src/Task/BuiltIn/Composer/AbstractComposerTask.php b/src/Task/BuiltIn/Composer/AbstractComposerTask.php index bce2234c..2e986871 100644 --- a/src/Task/BuiltIn/Composer/AbstractComposerTask.php +++ b/src/Task/BuiltIn/Composer/AbstractComposerTask.php @@ -1,4 +1,5 @@ 'composer'], @@ -31,7 +35,10 @@ protected function getOptions() return $options; } - protected function getComposerOptions() + /** + * @return array + */ + protected function getComposerOptions(): array { return []; } diff --git a/src/Task/BuiltIn/Composer/DumpAutoloadTask.php b/src/Task/BuiltIn/Composer/DumpAutoloadTask.php index 4e09bce5..87dbfd54 100644 --- a/src/Task/BuiltIn/Composer/DumpAutoloadTask.php +++ b/src/Task/BuiltIn/Composer/DumpAutoloadTask.php @@ -1,4 +1,5 @@ getOptions(); $cmd = sprintf('%s dump-autoload %s', $options['path'], $options['flags']); @@ -40,7 +41,7 @@ public function execute() return $process->isSuccessful(); } - protected function getComposerOptions() + protected function getComposerOptions(): array { return ['flags' => '--optimize']; } diff --git a/src/Task/BuiltIn/Composer/InstallTask.php b/src/Task/BuiltIn/Composer/InstallTask.php index 55a6a8d5..a03f7928 100644 --- a/src/Task/BuiltIn/Composer/InstallTask.php +++ b/src/Task/BuiltIn/Composer/InstallTask.php @@ -1,4 +1,5 @@ getOptions(); $cmd = sprintf('%s install %s', $options['path'], $options['flags']); /** @var Process $process */ - $process = $this->runtime->runCommand(trim($cmd), $options['timeout']); + $process = $this->runtime->runCommand(trim($cmd), intval($options['timeout'])); return $process->isSuccessful(); } - protected function getComposerOptions() + protected function getComposerOptions(): array { return ['flags' => '--optimize-autoloader', 'timeout' => 120]; } diff --git a/src/Task/BuiltIn/Composer/SelfUpdateTask.php b/src/Task/BuiltIn/Composer/SelfUpdateTask.php deleted file mode 100644 index a151d958..00000000 --- a/src/Task/BuiltIn/Composer/SelfUpdateTask.php +++ /dev/null @@ -1,86 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Mage\Task\BuiltIn\Composer; - -use Mage\Task\Exception\SkipException; -use Symfony\Component\Process\Process; -use DateTime; - -/** - * Composer Task - Self update - * - * @author Yanick Witschi - */ -class SelfUpdateTask extends AbstractComposerTask -{ - public function getName() - { - return 'composer/self-update'; - } - - public function getDescription() - { - return '[Composer] Self Update'; - } - - public function execute() - { - $options = $this->getOptions(); - $cmdVersion = sprintf('%s --version', $options['path']); - /** @var Process $process */ - $process = $this->runtime->runCommand(trim($cmdVersion)); - if (!$process->isSuccessful()) { - return false; - } - - $buildDate = $this->getBuildDate($process->getOutput()); - if (!$buildDate instanceof DateTime) { - return false; - } - - $compareDate = $this->getCompareDate(); - if ($buildDate >= $compareDate) { - throw new SkipException(); - } - - $cmdUpdate = sprintf('%s self-update', $options['path']); - /** @var Process $process */ - $process = $this->runtime->runCommand(trim($cmdUpdate)); - - return $process->isSuccessful(); - } - - protected function getBuildDate($output) - { - $buildDate = null; - $output = explode("\n", $output); - foreach ($output as $row) { - if (strpos($row, 'Composer version ') === 0) { - $buildDate = DateTime::createFromFormat('Y-m-d H:i:s', substr(trim($row), -19)); - } - } - - return $buildDate; - } - - protected function getCompareDate() - { - $options = $this->getOptions(); - $compareDate = new DateTime(); - $compareDate->modify(sprintf('now -%d days', $options['days'])); - return $compareDate; - } - - protected function getComposerOptions() - { - return ['days' => 60]; - } -} diff --git a/src/Task/BuiltIn/Deploy/Release/CleanupTask.php b/src/Task/BuiltIn/Deploy/Release/CleanupTask.php index 30039e15..9abcaf67 100644 --- a/src/Task/BuiltIn/Deploy/Release/CleanupTask.php +++ b/src/Task/BuiltIn/Deploy/Release/CleanupTask.php @@ -1,4 +1,5 @@ runtime->getEnvOption('host_path'), '/'); $currentReleaseId = $this->runtime->getReleaseId(); diff --git a/src/Task/BuiltIn/Deploy/Release/PrepareTask.php b/src/Task/BuiltIn/Deploy/Release/PrepareTask.php index 74117b59..edf81e88 100644 --- a/src/Task/BuiltIn/Deploy/Release/PrepareTask.php +++ b/src/Task/BuiltIn/Deploy/Release/PrepareTask.php @@ -1,4 +1,5 @@ runtime->getEnvOption('host_path'), '/'); diff --git a/src/Task/BuiltIn/Deploy/ReleaseTask.php b/src/Task/BuiltIn/Deploy/ReleaseTask.php index ab767f01..fdc404ae 100644 --- a/src/Task/BuiltIn/Deploy/ReleaseTask.php +++ b/src/Task/BuiltIn/Deploy/ReleaseTask.php @@ -1,4 +1,5 @@ runtime->getEnvOption('releases', false)) { throw new ErrorException('This task is only available with releases enabled', 40); @@ -44,7 +45,7 @@ public function execute() $cmdLinkRelease = sprintf('cd %s && ln -snf releases/%s current', $hostPath, $releaseId); /** @var Process $process */ - $process = $this->runtime->runRemoteCommand($cmdLinkRelease, false, null); + $process = $this->runtime->runRemoteCommand($cmdLinkRelease, false, 0); return $process->isSuccessful(); } } diff --git a/src/Task/BuiltIn/Deploy/RsyncTask.php b/src/Task/BuiltIn/Deploy/RsyncTask.php index 1310a5a8..c4598b6b 100644 --- a/src/Task/BuiltIn/Deploy/RsyncTask.php +++ b/src/Task/BuiltIn/Deploy/RsyncTask.php @@ -1,4 +1,5 @@ runtime->getEnvOption('rsync', '-avz'); $sshConfig = $this->runtime->getSSHConfig(); @@ -46,14 +47,24 @@ public function execute() $excludes = $this->getExcludes(); $from = $this->runtime->getEnvOption('from', './'); - $cmdRsync = sprintf('rsync -e "ssh -p %d %s" %s %s %s %s@%s:%s', $sshConfig['port'], $sshConfig['flags'], $flags, $excludes, $from, $user, $host, $targetDir); + $cmdRsync = sprintf( + 'rsync -e "ssh -p %d %s" %s %s %s %s@%s:%s', + $sshConfig['port'], + $sshConfig['flags'], + $flags, + $excludes, + $from, + $user, + $host, + $targetDir + ); /** @var Process $process */ - $process = $this->runtime->runLocalCommand($cmdRsync, null); + $process = $this->runtime->runLocalCommand($cmdRsync, 0); return $process->isSuccessful(); } - protected function getExcludes() + protected function getExcludes(): string { $excludes = $this->runtime->getMergedOption('exclude', []); $excludes = array_merge(['.git'], array_filter($excludes)); diff --git a/src/Task/BuiltIn/Deploy/Tar/CleanupTask.php b/src/Task/BuiltIn/Deploy/Tar/CleanupTask.php index f5382711..4355232a 100644 --- a/src/Task/BuiltIn/Deploy/Tar/CleanupTask.php +++ b/src/Task/BuiltIn/Deploy/Tar/CleanupTask.php @@ -1,4 +1,5 @@ runtime->getEnvOption('releases', false)) { throw new ErrorException('This task is only available with releases enabled', 40); diff --git a/src/Task/BuiltIn/Deploy/Tar/CopyTask.php b/src/Task/BuiltIn/Deploy/Tar/CopyTask.php index 570cdbf8..5c0f9348 100644 --- a/src/Task/BuiltIn/Deploy/Tar/CopyTask.php +++ b/src/Task/BuiltIn/Deploy/Tar/CopyTask.php @@ -1,4 +1,5 @@ runtime->getEnvOption('releases', false)) { throw new ErrorException('This task is only available with releases enabled', 40); @@ -50,10 +51,19 @@ public function execute() $tarLocal = $this->runtime->getVar('tar_local'); $tarRemote = basename($tarLocal); - $cmdCopy = sprintf('scp -P %d %s %s %s@%s:%s/%s', $sshConfig['port'], $sshConfig['flags'], $tarLocal, $user, $host, $targetDir, $tarRemote); + $cmdCopy = sprintf( + 'scp -P %d %s %s %s@%s:%s/%s', + $sshConfig['port'], + $sshConfig['flags'], + $tarLocal, + $user, + $host, + $targetDir, + $tarRemote + ); /** @var Process $process */ - $process = $this->runtime->runLocalCommand($cmdCopy, $sshConfig['timeout']); + $process = $this->runtime->runLocalCommand($cmdCopy, intval($sshConfig['timeout'])); if ($process->isSuccessful()) { $cmdUnTar = sprintf('cd %s && %s %s %s', $targetDir, $tarPath, $flags, $tarRemote); $process = $this->runtime->runRemoteCommand($cmdUnTar, false, 600); diff --git a/src/Task/BuiltIn/Deploy/Tar/PrepareTask.php b/src/Task/BuiltIn/Deploy/Tar/PrepareTask.php index e4c5daaf..d1e853e0 100644 --- a/src/Task/BuiltIn/Deploy/Tar/PrepareTask.php +++ b/src/Task/BuiltIn/Deploy/Tar/PrepareTask.php @@ -1,4 +1,5 @@ runtime->getEnvOption('releases', false)) { throw new ErrorException('This task is only available with releases enabled', 40); @@ -42,7 +43,10 @@ public function execute() $excludes = $this->getExcludes(); $tarPath = $this->runtime->getEnvOption('tar_create_path', 'tar'); - $flags = $this->runtime->getEnvOption('tar_create', $this->runtime->isWindows() ? '--force-local -c -z -p -f' : 'cfzp'); + $flags = $this->runtime->getEnvOption( + 'tar_create', + $this->runtime->isWindows() ? '--force-local -c -z -p -f' : 'cfzp' + ); $from = $this->runtime->getEnvOption('from', './'); if ($this->runtime->getEnvOption('copyDirectory', false)) { @@ -56,7 +60,7 @@ public function execute() return $process->isSuccessful(); } - protected function getExcludes() + protected function getExcludes(): string { $excludes = $this->runtime->getMergedOption('exclude', []); $excludes = array_merge(['.git'], array_filter($excludes)); diff --git a/src/Task/BuiltIn/ExecTask.php b/src/Task/BuiltIn/ExecTask.php index 0c7fc178..589e3f46 100644 --- a/src/Task/BuiltIn/ExecTask.php +++ b/src/Task/BuiltIn/ExecTask.php @@ -1,4 +1,5 @@ getOptions(); @@ -48,7 +49,7 @@ public function getDescription() * * @throws ErrorException */ - public function execute() + public function execute(): bool { $options = $this->getOptions(); @@ -57,14 +58,14 @@ public function execute() } /** @var Process $process */ - $process = $this->runtime->runCommand($options['cmd'], $options['timeout']); + $process = $this->runtime->runCommand(strval($options['cmd']), intval($options['timeout'])); return $process->isSuccessful(); } /** - * @return array + * @return array */ - protected function getOptions() + protected function getOptions(): array { $options = array_merge( ['cmd' => '', 'desc' => '', 'timeout' => 120], diff --git a/src/Task/BuiltIn/FS/AbstractFileTask.php b/src/Task/BuiltIn/FS/AbstractFileTask.php index 6243946c..2ce5d2b5 100644 --- a/src/Task/BuiltIn/FS/AbstractFileTask.php +++ b/src/Task/BuiltIn/FS/AbstractFileTask.php @@ -1,4 +1,5 @@ * @throws ErrorException */ - protected function getOptions() + protected function getOptions(): array { $mandatory = $this->getParameters(); $defaults = array_keys($this->getDefaults()); @@ -44,18 +45,16 @@ protected function getOptions() /** * Returns the mandatory parameters * - * @return array + * @return string[] */ - abstract protected function getParameters(); + abstract protected function getParameters(): array; /** * Returns a file with the placeholders replaced * - * @param string $file - * @return string * @throws ErrorException */ - protected function getFile($file) + protected function getFile(string $file): string { $mapping = [ '%environment%' => $this->runtime->getEnvironment(), @@ -73,7 +72,7 @@ protected function getFile($file) return str_replace( array_keys($mapping), array_values($mapping), - $options[$file] + strval($options[$file]) ); } } diff --git a/src/Task/BuiltIn/FS/ChangeModeTask.php b/src/Task/BuiltIn/FS/ChangeModeTask.php index 1422c3f8..7619c443 100644 --- a/src/Task/BuiltIn/FS/ChangeModeTask.php +++ b/src/Task/BuiltIn/FS/ChangeModeTask.php @@ -1,4 +1,5 @@ getFile('file'), $this->options['mode']); - } catch (Exception $exception) { + } catch (\Exception $exception) { return '[FS] Chmod [missing parameters]'; } } - public function execute() + public function execute(): bool { $file = $this->getFile('file'); $mode = $this->options['mode']; @@ -48,12 +48,12 @@ public function execute() return $process->isSuccessful(); } - protected function getParameters() + protected function getParameters(): array { return ['file', 'mode', 'flags']; } - public function getDefaults() + public function getDefaults(): array { return ['flags' => null]; } diff --git a/src/Task/BuiltIn/FS/CopyTask.php b/src/Task/BuiltIn/FS/CopyTask.php index 469b19c7..eca25d80 100644 --- a/src/Task/BuiltIn/FS/CopyTask.php +++ b/src/Task/BuiltIn/FS/CopyTask.php @@ -1,4 +1,5 @@ getFile('from'), $this->getFile('to')); - } catch (Exception $exception) { + } catch (\Exception $exception) { return '[FS] Copy [missing parameters]'; } } - public function execute() + public function execute(): bool { $copyFrom = $this->getFile('from'); $copyTo = $this->getFile('to'); @@ -48,12 +48,12 @@ public function execute() return $process->isSuccessful(); } - protected function getParameters() + protected function getParameters(): array { return ['from', 'to', 'flags']; } - public function getDefaults() + public function getDefaults(): array { return ['flags' => '-p']; } diff --git a/src/Task/BuiltIn/FS/LinkTask.php b/src/Task/BuiltIn/FS/LinkTask.php index 12721e09..5d5ed624 100644 --- a/src/Task/BuiltIn/FS/LinkTask.php +++ b/src/Task/BuiltIn/FS/LinkTask.php @@ -1,4 +1,5 @@ getFile('from'), $this->getFile('to')); - } catch (Exception $exception) { + } catch (\Exception $exception) { return '[FS] Link [missing parameters]'; } } - public function execute() + public function execute(): bool { $linkFrom = $this->getFile('from'); $linkTo = $this->getFile('to'); @@ -48,12 +48,12 @@ public function execute() return $process->isSuccessful(); } - protected function getParameters() + protected function getParameters(): array { return ['from', 'to', 'flags']; } - public function getDefaults() + public function getDefaults(): array { return ['flags' => '-snf']; } diff --git a/src/Task/BuiltIn/FS/MoveTask.php b/src/Task/BuiltIn/FS/MoveTask.php index a13ecc1b..bd8ce8f2 100644 --- a/src/Task/BuiltIn/FS/MoveTask.php +++ b/src/Task/BuiltIn/FS/MoveTask.php @@ -1,4 +1,5 @@ getFile('from'), $this->getFile('to')); @@ -34,7 +35,7 @@ public function getDescription() } } - public function execute() + public function execute(): bool { $moveFrom = $this->getFile('from'); $moveTo = $this->getFile('to'); @@ -48,12 +49,12 @@ public function execute() return $process->isSuccessful(); } - protected function getParameters() + protected function getParameters(): array { return ['from', 'to', 'flags']; } - public function getDefaults() + public function getDefaults(): array { return ['flags' => null]; } diff --git a/src/Task/BuiltIn/FS/RemoveTask.php b/src/Task/BuiltIn/FS/RemoveTask.php index 1f907245..d37b5854 100644 --- a/src/Task/BuiltIn/FS/RemoveTask.php +++ b/src/Task/BuiltIn/FS/RemoveTask.php @@ -1,4 +1,5 @@ getFile('file')); - } catch (Exception $exception) { + } catch (\Exception $exception) { return '[FS] Remove [missing parameters]'; } } - public function execute() + public function execute(): bool { $file = $this->getFile('file'); $flags = $this->options['flags']; @@ -47,12 +47,12 @@ public function execute() return $process->isSuccessful(); } - protected function getParameters() + protected function getParameters(): array { return ['file', 'flags']; } - public function getDefaults() + public function getDefaults(): array { return ['flags' => null]; } diff --git a/src/Task/BuiltIn/Git/ChangeBranchTask.php b/src/Task/BuiltIn/Git/ChangeBranchTask.php index 172207c5..94a4756a 100644 --- a/src/Task/BuiltIn/Git/ChangeBranchTask.php +++ b/src/Task/BuiltIn/Git/ChangeBranchTask.php @@ -1,4 +1,5 @@ getOptions(); $branch = $options['branch']; - if ($this->runtime->getVar('git_revert_branch', false)) { + if ($this->runtime->getVar('git_revert_branch', null)) { $branch = $this->runtime->getVar('git_revert_branch'); } return sprintf('[Git] Change Branch (%s)', $branch); } - public function execute() + public function execute(): bool { $options = $this->getOptions(); - $branch = $this->runtime->getVar('git_revert_branch', false); + /** @var string|bool */ + $branch = $this->runtime->getVar('git_revert_branch', null); - if ($branch === false) { + if (!$branch) { $cmdGetCurrent = sprintf('%s branch | grep "*"', $options['path']); /** @var Process $process */ @@ -68,7 +70,10 @@ public function execute() return $process->isSuccessful(); } - protected function getOptions() + /** + * @return array + */ + protected function getOptions(): array { $branch = $this->runtime->getEnvOption('branch', 'master'); $options = array_merge( diff --git a/src/Task/BuiltIn/Git/UpdateTask.php b/src/Task/BuiltIn/Git/UpdateTask.php index 33aa8aca..44cfef04 100644 --- a/src/Task/BuiltIn/Git/UpdateTask.php +++ b/src/Task/BuiltIn/Git/UpdateTask.php @@ -1,4 +1,5 @@ getOptions(); $command = $options['path'] . ' pull'; - /** @var Process $process */ $process = $this->runtime->runLocalCommand($command); return $process->isSuccessful(); } - protected function getOptions() + /** + * @return array + */ + protected function getOptions(): array { $branch = $this->runtime->getEnvOption('branch', 'master'); $options = array_merge( diff --git a/src/Task/BuiltIn/Symfony/AbstractSymfonyTask.php b/src/Task/BuiltIn/Symfony/AbstractSymfonyTask.php index 6ee9475c..ca22af54 100644 --- a/src/Task/BuiltIn/Symfony/AbstractSymfonyTask.php +++ b/src/Task/BuiltIn/Symfony/AbstractSymfonyTask.php @@ -1,4 +1,5 @@ + */ + protected function getOptions(): array { $options = array_merge( ['console' => 'bin/console', 'env' => 'dev', 'flags' => ''], @@ -31,7 +35,10 @@ protected function getOptions() return $options; } - protected function getSymfonyOptions() + /** + * @return array + */ + protected function getSymfonyOptions(): array { return []; } diff --git a/src/Task/BuiltIn/Symfony/AssetsInstallTask.php b/src/Task/BuiltIn/Symfony/AssetsInstallTask.php index d13300af..f84c264e 100644 --- a/src/Task/BuiltIn/Symfony/AssetsInstallTask.php +++ b/src/Task/BuiltIn/Symfony/AssetsInstallTask.php @@ -1,4 +1,5 @@ getOptions(); - $command = sprintf('%s assets:install %s --env=%s %s', $options['console'], $options['target'], $options['env'], $options['flags']); + $command = sprintf( + '%s assets:install %s --env=%s %s', + $options['console'], + $options['target'], + $options['env'], + $options['flags'] + ); - /** @var Process $process */ $process = $this->runtime->runCommand(trim($command)); return $process->isSuccessful(); } - protected function getSymfonyOptions() + protected function getSymfonyOptions(): array { return ['target' => 'web', 'flags' => '--symlink --relative']; } diff --git a/src/Task/BuiltIn/Symfony/CacheClearTask.php b/src/Task/BuiltIn/Symfony/CacheClearTask.php index a309ffa7..3f12b052 100644 --- a/src/Task/BuiltIn/Symfony/CacheClearTask.php +++ b/src/Task/BuiltIn/Symfony/CacheClearTask.php @@ -1,4 +1,5 @@ getOptions(); $command = $options['console'] . ' cache:clear --env=' . $options['env'] . ' ' . $options['flags']; diff --git a/src/Task/BuiltIn/Symfony/CachePoolClearTask.php b/src/Task/BuiltIn/Symfony/CachePoolClearTask.php index bd83d88f..d7882589 100644 --- a/src/Task/BuiltIn/Symfony/CachePoolClearTask.php +++ b/src/Task/BuiltIn/Symfony/CachePoolClearTask.php @@ -1,4 +1,5 @@ getOptions(); @@ -38,7 +39,13 @@ public function execute() throw new ErrorException('Parameter "pools" is not defined'); } - $command = $options['console'] . ' cache:pool:clear ' . $options['pools'] . ' --env=' . $options['env'] . ' ' . $options['flags']; + $command = sprintf( + '%s cache:pool:clear %s --env=%s %s', + $options['console'], + $options['pools'], + $options['env'], + $options['flags'] + ); /** @var Process $process */ $process = $this->runtime->runCommand(trim($command)); @@ -46,7 +53,7 @@ public function execute() return $process->isSuccessful(); } - protected function getSymfonyOptions() + protected function getSymfonyOptions(): array { return ['pools' => null]; } diff --git a/src/Task/BuiltIn/Symfony/CachePoolPruneTask.php b/src/Task/BuiltIn/Symfony/CachePoolPruneTask.php index f8c07ac6..4cf8c355 100644 --- a/src/Task/BuiltIn/Symfony/CachePoolPruneTask.php +++ b/src/Task/BuiltIn/Symfony/CachePoolPruneTask.php @@ -1,4 +1,5 @@ getOptions(); $command = $options['console'] . ' cache:pool:prune --env=' . $options['env'] . ' ' . $options['flags']; diff --git a/src/Task/BuiltIn/Symfony/CacheWarmupTask.php b/src/Task/BuiltIn/Symfony/CacheWarmupTask.php index d35f0a44..19b951b5 100644 --- a/src/Task/BuiltIn/Symfony/CacheWarmupTask.php +++ b/src/Task/BuiltIn/Symfony/CacheWarmupTask.php @@ -1,4 +1,5 @@ getOptions(); $command = $options['console'] . ' cache:warmup --env=' . $options['env'] . ' ' . $options['flags']; diff --git a/src/Task/Exception/ErrorException.php b/src/Task/Exception/ErrorException.php index 56b47516..164dceb7 100644 --- a/src/Task/Exception/ErrorException.php +++ b/src/Task/Exception/ErrorException.php @@ -1,4 +1,5 @@ */ -class ErrorException extends Exception +class ErrorException extends \Exception { - public function getTrimmedMessage($maxLength = 60) + public function getTrimmedMessage(int $maxLength = 60): string { $message = $this->getMessage(); diff --git a/src/Task/Exception/SkipException.php b/src/Task/Exception/SkipException.php index 4d23bb27..14868e38 100644 --- a/src/Task/Exception/SkipException.php +++ b/src/Task/Exception/SkipException.php @@ -1,4 +1,5 @@ */ -class SkipException extends Exception +class SkipException extends \Exception { } diff --git a/src/Task/ExecuteOnRollbackInterface.php b/src/Task/ExecuteOnRollbackInterface.php index 2c8fe81a..5f8e732b 100644 --- a/src/Task/ExecuteOnRollbackInterface.php +++ b/src/Task/ExecuteOnRollbackInterface.php @@ -1,4 +1,5 @@ setRuntime($this->runtime); $this->registeredTasks[$task->getName()] = $task; @@ -60,11 +54,10 @@ public function add(AbstractTask $task) * Get a Task by it's registered Name/Code, or it can be a Class Name, * in that case the class will be instantiated * - * @param string $name Name/Code or Class of the Task - * @return AbstractTask + * @param string|mixed[] $name * @throws RuntimeException */ - public function get($name) + public function get(mixed $name): AbstractTask { $options = []; if (is_array($name)) { @@ -96,14 +89,22 @@ public function get($name) /** * Load BuiltIn Tasks */ - protected function loadBuiltInTasks() + protected function loadBuiltInTasks(): void { $finder = new Finder(); $finder->files()->in(__DIR__ . '/BuiltIn')->name('*Task.php'); /** @var SplFileInfo $file */ foreach ($finder as $file) { - $taskClass = substr('\\Mage\\Task\\BuiltIn\\' . str_replace('/', '\\', $file->getRelativePathname()), 0, -4); + $taskClass = substr( + '\\Mage\\Task\\BuiltIn\\' . str_replace( + '/', + '\\', + $file->getRelativePathname() + ), + 0, + -4 + ); if (class_exists($taskClass)) { $reflex = new ReflectionClass($taskClass); if ($reflex->isInstantiable()) { @@ -118,10 +119,11 @@ protected function loadBuiltInTasks() /** * Load Custom Tasks - * @param array $tasksToLoad PreRegistered Tasks + * + * @param string[] $tasksToLoad * @throws RuntimeException */ - protected function loadCustomTasks($tasksToLoad) + protected function loadCustomTasks(array $tasksToLoad): void { foreach ($tasksToLoad as $taskClass) { if (!class_exists($taskClass)) { @@ -135,7 +137,9 @@ protected function loadCustomTasks($tasksToLoad) $task = new $taskClass(); if (!$task instanceof AbstractTask) { - throw new RuntimeException(sprintf('Custom Task "%s" must inherit "Mage\\Task\\AbstractTask".', $taskClass)); + throw new RuntimeException( + sprintf('Custom Task "%s" must inherit "Mage\\Task\\AbstractTask".', $taskClass) + ); } // Add Task diff --git a/src/Utils.php b/src/Utils.php index 4dbe5ba6..c90d2231 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -1,4 +1,5 @@ diff($releaseDate); if ($diff->days > 7) { diff --git a/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php b/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php index 7cb7cd93..bb94584a 100755 --- a/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php +++ b/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php @@ -530,6 +530,55 @@ public function testDeploymentFailCleanup() $this->assertNotEquals(0, $tester->getStatusCode()); } + public function testDeploymentFailCleanupReleases() + { + $application = new MageApplicationMockup(__DIR__ . '/../../Resources/testhost.yml'); + + $application->getRuntime()->setReleaseId('20170101015120'); + + /** @var AbstractCommand $command */ + $command = $application->find('deploy'); + $this->assertTrue($command instanceof DeployCommand); + + $application->getRuntime()->forceFail('ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015110"'); + + $tester = new CommandTester($command); + $tester->execute(['command' => $command->getName(), 'environment' => 'test']); + + $ranCommands = $application->getRuntime()->getRanCommands(); + + $testCase = array( + 0 => 'git branch | grep "*"', + 1 => 'git checkout test', + 2 => 'git pull', + 3 => 'composer install --optimize-autoloader', + 4 => 'composer dump-autoload --optimize', + 5 => 'tar cfzp /tmp/mageXYZ --exclude=".git" --exclude="./var/cache/*" --exclude="./var/log/*" --exclude="./web/app_dev.php" ./', + 6 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "mkdir -p /var/www/test/releases/1234567890"', + 7 => 'scp -P 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /tmp/mageXYZ tester@testhost:/var/www/test/releases/1234567890/mageXYZ', + 8 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && tar xfzop mageXYZ"', + 9 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm /var/www/test/releases/1234567890/mageXYZ"', + 10 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console cache:warmup --env=dev"', + 11 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console assets:install web --env=dev --symlink --relative"', + 12 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console cache:pool:prune --env=dev"', + 13 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test && ln -snf releases/1234567890 current"', + 14 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "ls -1 /var/www/test/releases"', + 15 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015110"', + ); + + // Check total of Executed Commands + $this->assertEquals(count($testCase), count($ranCommands)); + + // Check Generated Commands + foreach ($testCase as $index => $command) { + $this->assertEquals($command, $ranCommands[$index]); + } + + $this->assertStringContainsString('Running [Release] Cleaning up old Releases ... FAIL', $tester->getDisplay()); + $this->assertStringContainsString('Stage "Post Release" did not finished successfully, halting command.', $tester->getDisplay()); + $this->assertNotEquals(0, $tester->getStatusCode()); + } + public function testDeploymentFailMidway() { $application = new MageApplicationMockup(__DIR__ . '/../../Resources/testhost.yml'); diff --git a/tests/MageApplicationMockup.php b/tests/MageApplicationMockup.php index 674c195b..c472cdd3 100644 --- a/tests/MageApplicationMockup.php +++ b/tests/MageApplicationMockup.php @@ -20,7 +20,7 @@ class MageApplicationMockup extends MageApplication * * @return RuntimeMockup */ - protected function instantiateRuntime() + protected function instantiateRuntime(): RuntimeMockup { return new RuntimeMockup(); } diff --git a/tests/MageApplicationWindowsMockup.php b/tests/MageApplicationWindowsMockup.php index a1845ee1..75472c16 100644 --- a/tests/MageApplicationWindowsMockup.php +++ b/tests/MageApplicationWindowsMockup.php @@ -12,6 +12,7 @@ use Mage\Tests\Runtime\RuntimeWindowsMockup; use Mage\MageApplication; +use Mage\Runtime\Runtime; class MageApplicationWindowsMockup extends MageApplication { @@ -20,7 +21,7 @@ class MageApplicationWindowsMockup extends MageApplication * * @return RuntimeWindowsMockup */ - protected function instantiateRuntime() + protected function instantiateRuntime(): Runtime { return new RuntimeWindowsMockup(); } diff --git a/tests/Runtime/ProcessMockup.php b/tests/Runtime/ProcessMockup.php index ea6d5299..4d638a17 100644 --- a/tests/Runtime/ProcessMockup.php +++ b/tests/Runtime/ProcessMockup.php @@ -24,9 +24,10 @@ public function __construct($commandline, string $cwd = null, array $env = null, $this->commandline = $commandline; } - public function setTimeout($timeout) + public function setTimeout(?float $timeout): static { $this->timeout = $timeout; + return $this; } public function run(callable $callback = null, array $env = array()): int @@ -58,17 +59,17 @@ public function run(callable $callback = null, array $env = array()): int return 0; } - public function isSuccessful() + public function isSuccessful(): bool { return $this->success; } - public function getErrorOutput() + public function getErrorOutput(): string { return ''; } - public function getOutput() + public function getOutput(): string { if ($this->commandline == 'git branch | grep "*"') { return '* master'; diff --git a/tests/Runtime/RuntimeMockup.php b/tests/Runtime/RuntimeMockup.php index 65b6c325..d74d9038 100644 --- a/tests/Runtime/RuntimeMockup.php +++ b/tests/Runtime/RuntimeMockup.php @@ -31,10 +31,8 @@ public function getRanCommandTimeoutFor($cmd) /** * Generate the Release ID - * - * @return Runtime */ - public function generateReleaseId() + public function generateReleaseId(): Runtime { $this->setReleaseId('1234567890'); return $this; @@ -42,12 +40,8 @@ public function generateReleaseId() /** * Execute a command locally - * - * @param string $cmd Command to execute - * @param int $timeout Seconds to wait - * @return Process */ - public function runLocalCommand($cmd, $timeout = 120) + public function runLocalCommand(string $cmd, int $timeout = 120): Process { $this->ranCommands[] = $cmd; $this->ranCommandTimeouts[$cmd] = $timeout; @@ -62,10 +56,8 @@ public function runLocalCommand($cmd, $timeout = 120) /** * Gets a Temporal File name - * - * @return string */ - public function getTempFile() + public function getTempFile(): string { return '/tmp/mageXYZ'; } @@ -76,13 +68,13 @@ public function getTempFile() * @param string $environment * @return Runtime */ - public function setInvalidEnvironment($environment) + public function setInvalidEnvironment($environment): Runtime { $this->environment = $environment; return $this; } - public function forceFail($cmd) + public function forceFail($cmd): void { $this->forceFail[] = $cmd; } diff --git a/tests/Runtime/RuntimeWindowsMockup.php b/tests/Runtime/RuntimeWindowsMockup.php index 805031fc..0a9c6406 100644 --- a/tests/Runtime/RuntimeWindowsMockup.php +++ b/tests/Runtime/RuntimeWindowsMockup.php @@ -12,7 +12,7 @@ class RuntimeWindowsMockup extends RuntimeMockup { - public function isWindows() + public function isWindows(): bool { return true; } diff --git a/tests/Task/AbstractTaskTest.php b/tests/Task/AbstractTaskTest.php index 595ac41d..3e641216 100644 --- a/tests/Task/AbstractTaskTest.php +++ b/tests/Task/AbstractTaskTest.php @@ -16,14 +16,6 @@ class AbstractTaskTest extends TestCase { - public function testNotArrayOptions() - { - $task = new TestCaseTask(); - $task->setOptions('not an array'); - - $this->assertTrue(is_array($task->getOptions())); - } - public function testFailingTask() { $task = new TestCaseFailTask(); diff --git a/tests/Task/BuiltIn/Composer/BasicComposerTask.php b/tests/Task/BuiltIn/Composer/BasicComposerTask.php index 3261aefe..55b1aabb 100644 --- a/tests/Task/BuiltIn/Composer/BasicComposerTask.php +++ b/tests/Task/BuiltIn/Composer/BasicComposerTask.php @@ -20,17 +20,17 @@ */ class BasicComposerTask extends AbstractComposerTask { - public function getName() + public function getName(): string { return 'composer/help'; } - public function getDescription() + public function getDescription(): string { return '[Composer] Help'; } - public function execute() + public function execute(): bool { $options = $this->getOptions(); $cmd = sprintf('%s help', $options['path']); diff --git a/tests/Task/BuiltIn/Composer/SelfUpdateTaskTest.php b/tests/Task/BuiltIn/Composer/SelfUpdateTaskTest.php deleted file mode 100644 index 880dec79..00000000 --- a/tests/Task/BuiltIn/Composer/SelfUpdateTaskTest.php +++ /dev/null @@ -1,174 +0,0 @@ -setConfiguration(['environments' => ['test' => []]]); - $runtime->setEnvironment('test'); - - $task = new SelfUpdateTask(); - $task->setOptions(['path' => 'composer']); - $task->setRuntime($runtime); - $this->assertEquals('[Composer] Self Update', $task->getDescription()); - - try { - $task->execute(); - } catch (Exception $exception) { - $this->assertTrue($exception instanceof SkipException, 'Update should been skipped'); - } - - $ranCommands = $runtime->getRanCommands(); - $testCase = array( - 0 => 'composer --version', - ); - - // Check total of Executed Commands - $this->assertEquals(count($testCase), count($ranCommands)); - - // Check Generated Commands - foreach ($testCase as $index => $command) { - $this->assertEquals($command, $ranCommands[$index]); - } - } - - public function testSelfUpdateAsRootTask() - { - $runtime = new RuntimeMockup(); - $runtime->setConfiguration(['environments' => ['test' => []]]); - $runtime->setEnvironment('test'); - - $task = new SelfUpdateTask(); - $task->setOptions(['path' => './composer']); - $task->setRuntime($runtime); - - try { - $task->execute(); - } catch (Exception $exception) { - $this->assertTrue($exception instanceof SkipException, 'Update should been skipped'); - } - - $ranCommands = $runtime->getRanCommands(); - $testCase = array( - 0 => './composer --version', - ); - - // Check total of Executed Commands - $this->assertEquals(count($testCase), count($ranCommands)); - - // Check Generated Commands - foreach ($testCase as $index => $command) { - $this->assertEquals($command, $ranCommands[$index]); - } - } - - public function testSelfUpdateMustUpdateTask() - { - $runtime = new RuntimeMockup(); - $runtime->setConfiguration(['environments' => ['test' => []]]); - $runtime->setEnvironment('test'); - - $task = new SelfUpdateTask(); - $task->setOptions(['path' => 'composer.phar']); - $task->setRuntime($runtime); - - try { - $result = $task->execute(); - $this->assertTrue($result, 'Result should be successful'); - } catch (Exception $exception) { - if ($exception instanceof SkipException) { - $this->assertTrue(false, 'Update should not have been skipped'); - } - } - - $ranCommands = $runtime->getRanCommands(); - $testCase = array( - 0 => 'composer.phar --version', - 1 => 'composer.phar self-update', - ); - - // Check total of Executed Commands - $this->assertEquals(count($testCase), count($ranCommands)); - - // Check Generated Commands - foreach ($testCase as $index => $command) { - $this->assertEquals($command, $ranCommands[$index]); - } - } - - public function testSelfUpdateWrongOutputTask() - { - $runtime = new RuntimeMockup(); - $runtime->setConfiguration(['environments' => ['test' => []]]); - $runtime->setEnvironment('test'); - - $task = new SelfUpdateTask(); - $task->setOptions(['path' => 'php composer']); - $task->setRuntime($runtime); - - try { - $result = $task->execute(); - $this->assertFalse($result, 'Result should be failure'); - } catch (Exception $exception) { - if ($exception instanceof SkipException) { - $this->assertTrue(false, 'Update should not have been skipped'); - } - } - - $ranCommands = $runtime->getRanCommands(); - $testCase = array( - 0 => 'php composer --version', - ); - - // Check total of Executed Commands - $this->assertEquals(count($testCase), count($ranCommands)); - - // Check Generated Commands - foreach ($testCase as $index => $command) { - $this->assertEquals($command, $ranCommands[$index]); - } - } - - public function testSelfUpdateFailExecTask() - { - $runtime = new RuntimeMockup(); - $runtime->setConfiguration(['environments' => ['test' => []]]); - $runtime->setEnvironment('test'); - - $task = new SelfUpdateTask(); - $task->setOptions(['path' => 'composer']); - $task->setRuntime($runtime); - $runtime->forceFail('composer --version'); - - try { - $result = $task->execute(); - $this->assertFalse($result, 'Result should be failure'); - } catch (Exception $exception) { - if ($exception instanceof SkipException) { - $this->assertTrue(false, 'Update should not have been skipped'); - } - } - - $ranCommands = $runtime->getRanCommands(); - $testCase = array( - 0 => 'composer --version', - ); - - // Check total of Executed Commands - $this->assertEquals(count($testCase), count($ranCommands)); - - // Check Generated Commands - foreach ($testCase as $index => $command) { - $this->assertEquals($command, $ranCommands[$index]); - } - } -} diff --git a/tests/Task/Custom/NotInstantiableTask.php b/tests/Task/Custom/NotInstantiableTask.php index e7eff55f..0d534ca4 100644 --- a/tests/Task/Custom/NotInstantiableTask.php +++ b/tests/Task/Custom/NotInstantiableTask.php @@ -23,7 +23,7 @@ abstract class NotInstantiableTask extends AbstractTask /** * @return string */ - public function getName() + public function getName(): string { return 'custom-not-instantiable'; } @@ -31,7 +31,7 @@ public function getName() /** * @return string */ - public function getDescription() + public function getDescription(): string { return '[Custom] Not Instantiable*'; } @@ -39,7 +39,7 @@ public function getDescription() /** * @return bool */ - public function execute() + public function execute(): bool { /** @var Process $process */ $process = $this->runtime->runCommand('echo "custom-not-instantiable"'); diff --git a/tests/Task/Custom/ValidTask.php b/tests/Task/Custom/ValidTask.php index ce2b1a8d..261caadf 100644 --- a/tests/Task/Custom/ValidTask.php +++ b/tests/Task/Custom/ValidTask.php @@ -23,7 +23,7 @@ class ValidTask extends AbstractTask /** * @return string */ - public function getName() + public function getName(): string { return 'custom-valid'; } @@ -31,7 +31,7 @@ public function getName() /** * @return string */ - public function getDescription() + public function getDescription(): string { return '[Custom] Valid*'; } @@ -39,7 +39,7 @@ public function getDescription() /** * @return bool */ - public function execute() + public function execute(): bool { /** @var Process $process */ $process = $this->runtime->runCommand('echo "custom-valid"'); diff --git a/tests/Task/CustomTask.php b/tests/Task/CustomTask.php index 75c7acfa..42c21095 100644 --- a/tests/Task/CustomTask.php +++ b/tests/Task/CustomTask.php @@ -19,17 +19,17 @@ */ class CustomTask extends AbstractTask { - public function getName() + public function getName(): string { return 'custom'; } - public function getDescription() + public function getDescription(): string { return '[Custom] Dummy Task'; } - public function execute() + public function execute(): bool { return true; } diff --git a/tests/Task/TestCaseFailTask.php b/tests/Task/TestCaseFailTask.php index 41101e56..458ed71f 100644 --- a/tests/Task/TestCaseFailTask.php +++ b/tests/Task/TestCaseFailTask.php @@ -15,17 +15,17 @@ class TestCaseFailTask extends AbstractTask { - public function getName() + public function getName(): string { return 'test-fail'; } - public function getDescription() + public function getDescription(): string { return '[Test] This is a Test Task which Fails'; } - public function execute() + public function execute(): bool { throw new ErrorException('This is a text with a lot of characters'); } diff --git a/tests/Task/TestCaseTask.php b/tests/Task/TestCaseTask.php index daa16561..dba69b96 100644 --- a/tests/Task/TestCaseTask.php +++ b/tests/Task/TestCaseTask.php @@ -14,17 +14,17 @@ class TestCaseTask extends AbstractTask { - public function getName() + public function getName(): string { return 'test'; } - public function getDescription() + public function getDescription(): string { return '[Test] This is a Test Task'; } - public function execute() + public function execute(): bool { return true; } From a3ce2679e640132c8ec5b943bd7b68b441ea54b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 01:30:12 -0300 Subject: [PATCH 05/20] [Galactica] V5 - tests --- .github/workflows/tests.yml | 4 ++-- README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e3c563a8..45fa04e9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: - name: Run tests env: XDEBUG_MODE: coverage - run: ./vendor/bin/phpunit --testsuite=unit + run: ./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml - name: Run Coveralls env: XDEBUG_MODE: coverage @@ -53,7 +53,7 @@ jobs: - name: Run tests env: XDEBUG_MODE: coverage - run: ./vendor/bin/phpunit --testsuite=unit + run: ./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml - name: Run Coveralls env: XDEBUG_MODE: coverage diff --git a/README.md b/README.md index e20260ad..cab3efde 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Magallanes -[![SymfonyInsight](https://insight.symfony.com/projects/ed0de53a-a12e-459b-9464-34def5907b56/mini.svg)](https://insight.symfony.com/projects/ed0de53a-a12e-459b-9464-34def5907b56) -[![Build Status](https://img.shields.io/travis/andres-montanez/Magallanes/master.svg)](https://travis-ci.org/andres-montanez/Magallanes) +![Linters](https://github.com/andres-montanez/Magallanes/actions/workflows/linters.yml/badge.svg?) +![Tests](https://github.com/andres-montanez/Magallanes/actions/workflows/tests.yml/badge.svg?) [![Coverage Status](https://img.shields.io/coveralls/andres-montanez/Magallanes/master.svg)](https://coveralls.io/github/andres-montanez/Magallanes?branch=master) [![Code Quality](https://img.shields.io/scrutinizer/g/andres-montanez/Magallanes.svg)](https://scrutinizer-ci.com/g/andres-montanez/Magallanes/) [![Latest Stable Version](https://img.shields.io/packagist/v/andres-montanez/magallanes.svg?label=stable)](https://packagist.org/packages/andres-montanez/magallanes) From 23b179432163efe20466485e2cba9e41d919fe64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 01:41:27 -0300 Subject: [PATCH 06/20] [Galactica] V5 - tests --- .github/workflows/tests.yml | 6 +----- src/Runtime/Runtime.php | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 45fa04e9..c49af12e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: run: ./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml - name: Run Coveralls env: - XDEBUG_MODE: coverage + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./vendor/bin/php-coveralls -v --coverage_clover build/logs/coverage.xml unit_tests_81: @@ -54,7 +54,3 @@ jobs: env: XDEBUG_MODE: coverage run: ./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml - - name: Run Coveralls - env: - XDEBUG_MODE: coverage - run: ./vendor/bin/php-coveralls -v --coverage_clover build/logs/coverage.xml diff --git a/src/Runtime/Runtime.php b/src/Runtime/Runtime.php index ba483f54..571aebd4 100644 --- a/src/Runtime/Runtime.php +++ b/src/Runtime/Runtime.php @@ -441,7 +441,7 @@ public function getSSHConfig(): array */ public function getHostPort(): ?int { - $info = explode(':', $this->getWorkingHost()); + $info = explode(':', strval($this->getWorkingHost())); return isset($info[1]) ? intval($info[1]) : null; } @@ -450,7 +450,7 @@ public function getHostPort(): ?int */ public function getHostName(): ?string { - if (strpos($this->getWorkingHost(), ':') === false) { + if (strpos(strval($this->getWorkingHost()), ':') === false) { return $this->getWorkingHost(); } From e6ec0442307f0d19d2b06de793ae967733fba2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 01:55:49 -0300 Subject: [PATCH 07/20] [Galactica] V5 - improve exec task --- CHANGELOG.md | 1 + src/Task/BuiltIn/ExecTask.php | 16 +++++++++++++- tests/Task/BuiltIn/ExecTaskTest.php | 33 +++++++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d3fcfb8..60f0231a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,3 +6,4 @@ CHANGELOG for 5.X * Refactored for Symfony 6 and PHP 8 * Added strong types * Removed task `composer/self-update` + * Allow `exec` task to interpolate `%environment%` and `%release%` diff --git a/src/Task/BuiltIn/ExecTask.php b/src/Task/BuiltIn/ExecTask.php index 589e3f46..a5a37052 100644 --- a/src/Task/BuiltIn/ExecTask.php +++ b/src/Task/BuiltIn/ExecTask.php @@ -57,8 +57,22 @@ public function execute(): bool throw new ErrorException('Parameter "cmd" is not defined'); } + $mapping = [ + '%environment%' => $this->runtime->getEnvironment(), + ]; + + if ($this->runtime->getReleaseId() !== null) { + $mapping['%release%'] = $this->runtime->getReleaseId(); + } + + $cmd = str_replace( + array_keys($mapping), + array_values($mapping), + strval($options['cmd']) + ); + /** @var Process $process */ - $process = $this->runtime->runCommand(strval($options['cmd']), intval($options['timeout'])); + $process = $this->runtime->runCommand($cmd, intval($options['timeout'])); return $process->isSuccessful(); } diff --git a/tests/Task/BuiltIn/ExecTaskTest.php b/tests/Task/BuiltIn/ExecTaskTest.php index 048670ce..a17e78a2 100755 --- a/tests/Task/BuiltIn/ExecTaskTest.php +++ b/tests/Task/BuiltIn/ExecTaskTest.php @@ -25,10 +25,10 @@ public function testSimpleCommand() $runtime->setEnvironment('test'); $task = new ExecTask(); - $task->setOptions(['cmd' => 'ls -l', 'desc' => 'Loading docker']); + $task->setOptions(['cmd' => 'ls -l', 'desc' => 'Command description']); $task->setRuntime($runtime); - $this->assertStringContainsString('[Exec] Loading docker', $task->getDescription()); + $this->assertStringContainsString('[Exec] Command description', $task->getDescription()); $task->execute(); $ranCommands = $runtime->getRanCommands(); @@ -46,6 +46,35 @@ public function testSimpleCommand() } } + public function testSimpleCommandWithInterpolation() + { + $runtime = new RuntimeMockup(); + $runtime->setConfiguration(['environments' => ['test' => []]]); + $runtime->setEnvironment('test'); + $runtime->setReleaseId('1234'); + + $task = new ExecTask(); + $task->setOptions(['cmd' => 'cp %environment%.env /app/%release%/.env', 'desc' => 'Copy config']); + $task->setRuntime($runtime); + + $this->assertStringContainsString('[Exec] Copy config', $task->getDescription()); + $task->execute(); + + $ranCommands = $runtime->getRanCommands(); + + $testCase = array( + 0 => 'cp test.env /app/1234/.env', + ); + + // Check total of Executed Commands + $this->assertEquals(count($testCase), count($ranCommands)); + + // Check Generated Commands + foreach ($testCase as $index => $command) { + $this->assertEquals($command, $ranCommands[$index]); + } + } + public function testCommandWithoutDescription() { $runtime = new RuntimeMockup(); From 47cb64137cfcfbebf04d41f8b5d5e4be785f8704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 18:06:48 -0300 Subject: [PATCH 08/20] [Galactica] tweaks --- src/Task/BuiltIn/Deploy/Release/CleanupTask.php | 2 +- src/Task/BuiltIn/Git/ChangeBranchTask.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Task/BuiltIn/Deploy/Release/CleanupTask.php b/src/Task/BuiltIn/Deploy/Release/CleanupTask.php index 9abcaf67..0656d0df 100644 --- a/src/Task/BuiltIn/Deploy/Release/CleanupTask.php +++ b/src/Task/BuiltIn/Deploy/Release/CleanupTask.php @@ -49,7 +49,7 @@ public function execute(): bool sort($releases); $releasesToDelete = array_slice($releases, 0, count($releases) - $maxReleases); foreach ($releasesToDelete as $releaseId) { - if ($releaseId != $currentReleaseId) { + if ($releaseId !== $currentReleaseId) { $cmdDeleteRelease = sprintf('rm -rf %s/releases/%s', $hostPath, $releaseId); /** @var Process $process */ $process = $this->runtime->runRemoteCommand($cmdDeleteRelease, false); diff --git a/src/Task/BuiltIn/Git/ChangeBranchTask.php b/src/Task/BuiltIn/Git/ChangeBranchTask.php index 94a4756a..991c5c68 100644 --- a/src/Task/BuiltIn/Git/ChangeBranchTask.php +++ b/src/Task/BuiltIn/Git/ChangeBranchTask.php @@ -55,7 +55,7 @@ public function execute(): bool } $currentBranch = str_replace('* ', '', trim($process->getOutput())); - if ($currentBranch == $options['branch']) { + if ($currentBranch === $options['branch']) { throw new SkipException(); } From 728f70fe6d2b7b7e579ee4081dae7be4d9d303ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 18:13:59 -0300 Subject: [PATCH 09/20] [Galactica] Sleep task tweaks --- src/Task/BuiltIn/SleepTask.php | 22 +++++++--------------- tests/Task/BuiltIn/ExecTaskTest.php | 3 +-- tests/Task/BuiltIn/SleepTaskTest.php | 23 +++++++++++++++++++++-- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/Task/BuiltIn/SleepTask.php b/src/Task/BuiltIn/SleepTask.php index 24c60512..07dfda8f 100644 --- a/src/Task/BuiltIn/SleepTask.php +++ b/src/Task/BuiltIn/SleepTask.php @@ -21,42 +21,34 @@ */ class SleepTask extends AbstractTask { - /** - * @return string - */ - public function getName() + public function getName(): string { return 'sleep'; } - /** - * @return string - */ - public function getDescription() + public function getDescription(): string { $options = $this->getOptions(); - return sprintf('[Sleep] Sleeping for %s second(s)', (int) $options['seconds']); + return sprintf('[Sleep] Sleeping for %d second(s)', $options['seconds']); } /** - * @return bool - * * @throws ErrorException */ - public function execute() + public function execute(): bool { $options = $this->getOptions(); - sleep((int) $options['seconds']); + sleep(intval($options['seconds'])); return true; } /** - * @return array + * @return array */ - protected function getOptions() + protected function getOptions(): array { $options = array_merge( ['seconds' => 1], diff --git a/tests/Task/BuiltIn/ExecTaskTest.php b/tests/Task/BuiltIn/ExecTaskTest.php index a17e78a2..930a985f 100755 --- a/tests/Task/BuiltIn/ExecTaskTest.php +++ b/tests/Task/BuiltIn/ExecTaskTest.php @@ -12,7 +12,6 @@ use Mage\Task\Exception\ErrorException; use Mage\Task\BuiltIn\ExecTask; -use Exception; use Mage\Tests\Runtime\RuntimeMockup; use PHPUnit\Framework\TestCase; @@ -118,7 +117,7 @@ public function testWithoutCommand() try { $task->execute(); $this->assertTrue(false, 'Task did not failed'); - } catch (Exception $exception) { + } catch (\Exception $exception) { $this->assertTrue($exception instanceof ErrorException); $this->assertEquals('Parameter "cmd" is not defined', $exception->getMessage()); } diff --git a/tests/Task/BuiltIn/SleepTaskTest.php b/tests/Task/BuiltIn/SleepTaskTest.php index 26f1756f..0349b3cc 100644 --- a/tests/Task/BuiltIn/SleepTaskTest.php +++ b/tests/Task/BuiltIn/SleepTaskTest.php @@ -12,11 +12,11 @@ use Mage\Task\BuiltIn\SleepTask; use Mage\Tests\Runtime\RuntimeMockup; -use PHPUnit_Framework_TestCase as TestCase; +use PHPUnit\Framework\TestCase; class SleepTaskTest extends TestCase { - public function testCommand() + public function testTaskWithDefault() { $runtime = new RuntimeMockup(); $runtime->setConfiguration(['environments' => ['test' => []]]); @@ -28,4 +28,23 @@ public function testCommand() $this->assertSame('[Sleep] Sleeping for 1 second(s)', $task->getDescription()); $task->execute(); } + + public function testTaskWithValue() + { + $runtime = new RuntimeMockup(); + $runtime->setConfiguration(['environments' => ['test' => []]]); + $runtime->setEnvironment('test'); + + $task = new SleepTask(); + $task->setOptions(['seconds' => 2]); + $task->setRuntime($runtime); + + $this->assertSame('[Sleep] Sleeping for 2 second(s)', $task->getDescription()); + + $startedAt = microtime(true); + $task->execute(); + $finishedAt = microtime(true); + + $this->assertGreaterThanOrEqual(2, $finishedAt - $startedAt); + } } From 732b5d9cb6fed003d4af1316dd03b80942ba2d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 18:33:28 -0300 Subject: [PATCH 10/20] [Galactica] Allow to verride symlink name --- .../BuiltIn/DeployCommandWithReleasesTest.php | 50 +++++++++++++++++++ tests/Deploy/StrategyTest.php | 1 - tests/Resources/testhost-custom-symlink.yml | 28 +++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tests/Resources/testhost-custom-symlink.yml diff --git a/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php b/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php index bb94584a..8ea13f7d 100755 --- a/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php +++ b/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php @@ -69,6 +69,56 @@ public function testDeploymentWithReleasesCommands() $this->assertEquals(0, $tester->getStatusCode()); } + public function testDeploymentWithReleasesCommandsCustomSymlink() + { + $application = new MageApplicationMockup(__DIR__ . '/../../Resources/testhost-custom-symlink.yml'); + + $application->getRuntime()->setReleaseId('20170101015120'); + + /** @var AbstractCommand $command */ + $command = $application->find('deploy'); + $this->assertTrue($command instanceof DeployCommand); + + $tester = new CommandTester($command); + $tester->execute(['command' => $command->getName(), 'environment' => 'test']); + + $ranCommands = $application->getRuntime()->getRanCommands(); + + $testCase = array( + 0 => 'git branch | grep "*"', + 1 => 'git checkout test', + 2 => 'git pull', + 3 => 'composer install --optimize-autoloader', + 4 => 'composer dump-autoload --optimize', + 5 => 'tar cfzp /tmp/mageXYZ --exclude=".git" --exclude="./var/cache/*" --exclude="./var/log/*" --exclude="./web/app_dev.php" ./', + 6 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "mkdir -p /var/www/test/releases/1234567890"', + 7 => 'scp -P 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /tmp/mageXYZ tester@testhost:/var/www/test/releases/1234567890/mageXYZ', + 8 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && tar xfzop mageXYZ"', + 9 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm /var/www/test/releases/1234567890/mageXYZ"', + 10 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console cache:warmup --env=dev"', + 11 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console assets:install web --env=dev --symlink --relative"', + 12 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console cache:pool:prune --env=dev"', + 13 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test && ln -snf releases/1234567890 prod"', + 14 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "ls -1 /var/www/test/releases"', + 15 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015110"', + 16 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015111"', + 17 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015112"', + 18 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015113"', + 19 => 'rm /tmp/mageXYZ', + 20 => 'git checkout master', + ); + + // Check total of Executed Commands + $this->assertEquals(count($testCase), count($ranCommands)); + + // Check Generated Commands + foreach ($testCase as $index => $command) { + $this->assertEquals($command, $ranCommands[$index]); + } + + $this->assertEquals(0, $tester->getStatusCode()); + } + public function testDeploymentWithReleasesWithPortCommands() { $application = new MageApplicationMockup(__DIR__ . '/../../Resources/testhost-with-port.yml'); diff --git a/tests/Deploy/StrategyTest.php b/tests/Deploy/StrategyTest.php index 9800a02e..607dc09b 100755 --- a/tests/Deploy/StrategyTest.php +++ b/tests/Deploy/StrategyTest.php @@ -114,5 +114,4 @@ public function testCheckStateReleases() $this->assertEquals(sprintf('Invalid stage, got "%s" but expected "%s"', Runtime::PRE_DEPLOY, Runtime::POST_DEPLOY), $exception->getMessage()); } } - } diff --git a/tests/Resources/testhost-custom-symlink.yml b/tests/Resources/testhost-custom-symlink.yml new file mode 100644 index 00000000..be2a3e57 --- /dev/null +++ b/tests/Resources/testhost-custom-symlink.yml @@ -0,0 +1,28 @@ +magephp: + log_dir: /tmp + environments: + test: + user: tester + branch: test + host_path: /var/www/test + releases: 4 + symlink: prod + exclude: + - ./var/cache/* + - ./var/log/* + - ./web/app_dev.php + - + - + hosts: + - testhost + pre-deploy: + - git/update + - composer/install + - composer/dump-autoload + on-deploy: + - symfony/cache-warmup: { env: 'dev' } + - symfony/assets-install: { env: 'dev' } + - symfony/cache-pool-prune: { env: 'dev' } + on-release: + post-release: + post-deploy: From d3023a6767640849428d7b63be6442988b379d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 18:35:38 -0300 Subject: [PATCH 11/20] [Galactica] Improve PSR-12 --- src/Task/BuiltIn/Deploy/ReleaseTask.php | 2 +- src/Task/BuiltIn/SleepTask.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Task/BuiltIn/Deploy/ReleaseTask.php b/src/Task/BuiltIn/Deploy/ReleaseTask.php index 924e4ff1..adecf2b6 100644 --- a/src/Task/BuiltIn/Deploy/ReleaseTask.php +++ b/src/Task/BuiltIn/Deploy/ReleaseTask.php @@ -41,7 +41,7 @@ public function execute(): bool $hostPath = rtrim($this->runtime->getEnvOption('host_path'), '/'); $releaseId = $this->runtime->getReleaseId(); - + $symlink = $this->runtime->getEnvOption('symlink', 'current'); $cmdLinkRelease = sprintf('cd %s && ln -snf releases/%s %s', $hostPath, $releaseId, $symlink); diff --git a/src/Task/BuiltIn/SleepTask.php b/src/Task/BuiltIn/SleepTask.php index 07dfda8f..6415deaf 100644 --- a/src/Task/BuiltIn/SleepTask.php +++ b/src/Task/BuiltIn/SleepTask.php @@ -1,4 +1,5 @@ Date: Sun, 10 Apr 2022 18:53:26 -0300 Subject: [PATCH 12/20] [Galactica] Improve Windows compatibility --- src/Runtime/Runtime.php | 15 ++++++++++----- tests/Runtime/RuntimeWindowsMockup.php | 5 +++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Runtime/Runtime.php b/src/Runtime/Runtime.php index f0f30bb0..6b68611f 100644 --- a/src/Runtime/Runtime.php +++ b/src/Runtime/Runtime.php @@ -75,6 +75,11 @@ public function isWindows(): bool return stripos(PHP_OS, 'WIN') === 0; } + public function hasPosix(): bool + { + return function_exists('posix_getpwuid'); + } + /** * Generate the Release ID */ @@ -471,13 +476,13 @@ public function getTempFile(): string */ public function getCurrentUser(): string { - // Windows fallback - if (!function_exists('posix_getpwuid')) { - return getenv('USERNAME') ?: ''; + if ($this->hasPosix()) { + $userData = posix_getpwuid(posix_geteuid()); + return $userData['name']; } - $userData = posix_getpwuid(posix_geteuid()); - return $userData['name']; + // Windows fallback + return strval(getenv('USERNAME')); } /** diff --git a/tests/Runtime/RuntimeWindowsMockup.php b/tests/Runtime/RuntimeWindowsMockup.php index 0a9c6406..050aaa13 100644 --- a/tests/Runtime/RuntimeWindowsMockup.php +++ b/tests/Runtime/RuntimeWindowsMockup.php @@ -16,4 +16,9 @@ public function isWindows(): bool { return true; } + + public function hasPosix(): bool + { + return false; + } } From 2783292899bf5c8536518919fa61f971c2e0bca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 19:38:43 -0300 Subject: [PATCH 13/20] [Galactica] New log_limit option --- src/MageApplication.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/MageApplication.php b/src/MageApplication.php index 529498dd..d0087eb9 100644 --- a/src/MageApplication.php +++ b/src/MageApplication.php @@ -24,6 +24,7 @@ use Symfony\Component\Yaml\Parser; use Symfony\Component\Yaml\Exception\ParseException; use Mage\Runtime\Exception\RuntimeException; +use Symfony\Component\Filesystem\Filesystem; /** * The Console Application for launching the Mage command in a standalone instance @@ -89,6 +90,9 @@ public function configure(): void $logger = new Logger('magephp'); $logger->pushHandler(new StreamHandler($logfile)); + + $logLimit = isset($config['magephp']['log_limit']) ? intval($config['magephp']['log_limit']) : 30; + $this->clearOldLogs($config['magephp']['log_dir'], $logLimit); } elseif (array_key_exists('log_dir', $config['magephp']) && !is_dir($config['magephp']['log_dir'])) { throw new RuntimeException( sprintf( @@ -108,6 +112,24 @@ public function configure(): void ); } + protected function clearOldLogs(string $logDir, int $logLimit): void + { + $filesystem = new Filesystem(); + $finder = new Finder(); + + $finder + ->files() + ->followLinks() + ->in($logDir) + ->name('*.log') + ->sortByModifiedTime() + ->reverseSorting(); + + $logs = iterator_to_array($finder); + $logsToRemove = array_slice($logs, $logLimit - 1); + $filesystem->remove($logsToRemove); + } + /** * Loads the BuiltIn Commands */ From b893e102c66512d46b5c8954eba143b8aa6dc5d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 19:47:10 -0300 Subject: [PATCH 14/20] [Galactica] Improve tests --- .gitignore | 1 + tests/Resources/basic.yml | 4 ++-- tests/Resources/broken-git-branch.yml | 2 +- tests/Resources/composer-env.yml | 2 +- tests/Resources/composer.yml | 2 +- tests/Resources/global-exclude.yml | 2 +- tests/Resources/invalid-task.yml | 2 +- tests/Resources/no-hosts.yml | 4 ++-- tests/Resources/symfony-envconf.yml | 2 +- tests/Resources/testhost-custom-symlink.yml | 2 +- tests/Resources/testhost-custom-task.yml | 4 ++-- tests/Resources/testhost-fail-copy-tar.yml | 2 +- tests/Resources/testhost-fail-get-current.yml | 2 +- tests/Resources/testhost-fail-get-releases.yml | 2 +- tests/Resources/testhost-force-release.yml | 4 ++-- tests/Resources/testhost-force-tar1.yml | 4 ++-- tests/Resources/testhost-force-tar2.yml | 4 ++-- tests/Resources/testhost-force-tar3.yml | 4 ++-- tests/Resources/testhost-no-hosts.yml | 2 +- tests/Resources/testhost-no-releases.yml | 2 +- tests/Resources/testhost-not-have-release.yml | 2 +- tests/Resources/testhost-skipping.yml | 4 ++-- tests/Resources/testhost-sudo.yml | 4 ++-- tests/Resources/testhost-with-error.yml | 4 ++-- tests/Resources/testhost-with-from-copy-directory.yml | 4 ++-- tests/Resources/testhost-with-from.yml | 4 ++-- tests/Resources/testhost-with-port.yml | 4 ++-- tests/Resources/testhost-with-postdeploy-error.yml | 4 ++-- tests/Resources/testhost-with-release-timeout.yml | 4 ++-- tests/Resources/testhost-without-releases-with-from.yml | 4 ++-- tests/Resources/testhost-without-releases-with-port.yml | 4 ++-- tests/Resources/testhost-without-releases.yml | 4 ++-- tests/Resources/testhost.yml | 4 ++-- 33 files changed, 52 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index f8cb51bf..d72fbfbd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ composer.lock .mage.yml .phpunit.result.cache .phpcs-cache +.logs diff --git a/tests/Resources/basic.yml b/tests/Resources/basic.yml index 28c7978a..79ac85ad 100644 --- a/tests/Resources/basic.yml +++ b/tests/Resources/basic.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: production: user: app @@ -24,4 +24,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/broken-git-branch.yml b/tests/Resources/broken-git-branch.yml index 7263cf75..d0caa31b 100644 --- a/tests/Resources/broken-git-branch.yml +++ b/tests/Resources/broken-git-branch.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester diff --git a/tests/Resources/composer-env.yml b/tests/Resources/composer-env.yml index 2421fdf3..db969282 100644 --- a/tests/Resources/composer-env.yml +++ b/tests/Resources/composer-env.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ composer: path: /usr/bin/composer.phar environments: diff --git a/tests/Resources/composer.yml b/tests/Resources/composer.yml index f8f1bff3..134d1ee1 100644 --- a/tests/Resources/composer.yml +++ b/tests/Resources/composer.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ composer: path: /usr/bin/composer.phar environments: diff --git a/tests/Resources/global-exclude.yml b/tests/Resources/global-exclude.yml index cfa5ddfc..2795c8e8 100644 --- a/tests/Resources/global-exclude.yml +++ b/tests/Resources/global-exclude.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ composer: path: /usr/bin/composer.phar exclude: diff --git a/tests/Resources/invalid-task.yml b/tests/Resources/invalid-task.yml index 57dd0073..f60ab932 100644 --- a/tests/Resources/invalid-task.yml +++ b/tests/Resources/invalid-task.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester diff --git a/tests/Resources/no-hosts.yml b/tests/Resources/no-hosts.yml index 6771cc6c..914f6e75 100644 --- a/tests/Resources/no-hosts.yml +++ b/tests/Resources/no-hosts.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -20,4 +20,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/symfony-envconf.yml b/tests/Resources/symfony-envconf.yml index 3d4dff90..6833ebdd 100644 --- a/tests/Resources/symfony-envconf.yml +++ b/tests/Resources/symfony-envconf.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: symfony: { env: 'testenv' } diff --git a/tests/Resources/testhost-custom-symlink.yml b/tests/Resources/testhost-custom-symlink.yml index be2a3e57..6dd060d2 100644 --- a/tests/Resources/testhost-custom-symlink.yml +++ b/tests/Resources/testhost-custom-symlink.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester diff --git a/tests/Resources/testhost-custom-task.yml b/tests/Resources/testhost-custom-task.yml index 8253e174..cea56858 100644 --- a/tests/Resources/testhost-custom-task.yml +++ b/tests/Resources/testhost-custom-task.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -17,4 +17,4 @@ magephp: - Mage\Tests\Task\CustomTask on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost-fail-copy-tar.yml b/tests/Resources/testhost-fail-copy-tar.yml index 80809c77..dee2b992 100644 --- a/tests/Resources/testhost-fail-copy-tar.yml +++ b/tests/Resources/testhost-fail-copy-tar.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester diff --git a/tests/Resources/testhost-fail-get-current.yml b/tests/Resources/testhost-fail-get-current.yml index 635b457c..2073ed3f 100644 --- a/tests/Resources/testhost-fail-get-current.yml +++ b/tests/Resources/testhost-fail-get-current.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester diff --git a/tests/Resources/testhost-fail-get-releases.yml b/tests/Resources/testhost-fail-get-releases.yml index b9c4e882..9b5dc34c 100644 --- a/tests/Resources/testhost-fail-get-releases.yml +++ b/tests/Resources/testhost-fail-get-releases.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester diff --git a/tests/Resources/testhost-force-release.yml b/tests/Resources/testhost-force-release.yml index e59bccb9..1fba1880 100644 --- a/tests/Resources/testhost-force-release.yml +++ b/tests/Resources/testhost-force-release.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -12,4 +12,4 @@ magephp: hosts: - host2 on-deploy: - - deploy/release \ No newline at end of file + - deploy/release diff --git a/tests/Resources/testhost-force-tar1.yml b/tests/Resources/testhost-force-tar1.yml index 61a1a5ab..03e22c60 100644 --- a/tests/Resources/testhost-force-tar1.yml +++ b/tests/Resources/testhost-force-tar1.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -12,4 +12,4 @@ magephp: hosts: - host2 pre-deploy: - - deploy/tar/prepare \ No newline at end of file + - deploy/tar/prepare diff --git a/tests/Resources/testhost-force-tar2.yml b/tests/Resources/testhost-force-tar2.yml index db26ad0a..9ebc36c8 100644 --- a/tests/Resources/testhost-force-tar2.yml +++ b/tests/Resources/testhost-force-tar2.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -12,4 +12,4 @@ magephp: hosts: - host2 on-deploy: - - deploy/tar/copy \ No newline at end of file + - deploy/tar/copy diff --git a/tests/Resources/testhost-force-tar3.yml b/tests/Resources/testhost-force-tar3.yml index cd2eeee5..2b42f32b 100644 --- a/tests/Resources/testhost-force-tar3.yml +++ b/tests/Resources/testhost-force-tar3.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -12,4 +12,4 @@ magephp: hosts: - host2 post-deploy: - - deploy/tar/cleanup \ No newline at end of file + - deploy/tar/cleanup diff --git a/tests/Resources/testhost-no-hosts.yml b/tests/Resources/testhost-no-hosts.yml index a6c4a5ac..e206757e 100644 --- a/tests/Resources/testhost-no-hosts.yml +++ b/tests/Resources/testhost-no-hosts.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester diff --git a/tests/Resources/testhost-no-releases.yml b/tests/Resources/testhost-no-releases.yml index 88f9da0c..056f25b8 100644 --- a/tests/Resources/testhost-no-releases.yml +++ b/tests/Resources/testhost-no-releases.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester diff --git a/tests/Resources/testhost-not-have-release.yml b/tests/Resources/testhost-not-have-release.yml index 4a23a859..b01b138a 100644 --- a/tests/Resources/testhost-not-have-release.yml +++ b/tests/Resources/testhost-not-have-release.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester diff --git a/tests/Resources/testhost-skipping.yml b/tests/Resources/testhost-skipping.yml index 5ce8f07a..0981777f 100644 --- a/tests/Resources/testhost-skipping.yml +++ b/tests/Resources/testhost-skipping.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -21,4 +21,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost-sudo.yml b/tests/Resources/testhost-sudo.yml index 55a19ca2..109372f8 100644 --- a/tests/Resources/testhost-sudo.yml +++ b/tests/Resources/testhost-sudo.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -23,4 +23,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost-with-error.yml b/tests/Resources/testhost-with-error.yml index d2dba500..df2d8c5e 100644 --- a/tests/Resources/testhost-with-error.yml +++ b/tests/Resources/testhost-with-error.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -20,4 +20,4 @@ magephp: - deploy/rsync on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost-with-from-copy-directory.yml b/tests/Resources/testhost-with-from-copy-directory.yml index 4ef8d17a..6a894323 100644 --- a/tests/Resources/testhost-with-from-copy-directory.yml +++ b/tests/Resources/testhost-with-from-copy-directory.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -26,4 +26,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost-with-from.yml b/tests/Resources/testhost-with-from.yml index 1d4c91eb..247780fb 100644 --- a/tests/Resources/testhost-with-from.yml +++ b/tests/Resources/testhost-with-from.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -25,4 +25,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost-with-port.yml b/tests/Resources/testhost-with-port.yml index 94e3ee65..913df4e7 100644 --- a/tests/Resources/testhost-with-port.yml +++ b/tests/Resources/testhost-with-port.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -24,4 +24,4 @@ magephp: - symfony/cache-pool-prune: { env: 'prod' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost-with-postdeploy-error.yml b/tests/Resources/testhost-with-postdeploy-error.yml index c2e29566..ab1d3569 100644 --- a/tests/Resources/testhost-with-postdeploy-error.yml +++ b/tests/Resources/testhost-with-postdeploy-error.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -20,4 +20,4 @@ magephp: on-release: post-release: post-deploy: - - deploy/tar/cleanup \ No newline at end of file + - deploy/tar/cleanup diff --git a/tests/Resources/testhost-with-release-timeout.yml b/tests/Resources/testhost-with-release-timeout.yml index 61091f68..4639f102 100644 --- a/tests/Resources/testhost-with-release-timeout.yml +++ b/tests/Resources/testhost-with-release-timeout.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -28,4 +28,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost-without-releases-with-from.yml b/tests/Resources/testhost-without-releases-with-from.yml index 3520f7d6..b526feca 100644 --- a/tests/Resources/testhost-without-releases-with-from.yml +++ b/tests/Resources/testhost-without-releases-with-from.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -22,4 +22,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost-without-releases-with-port.yml b/tests/Resources/testhost-without-releases-with-port.yml index 27755a25..6b26bb72 100644 --- a/tests/Resources/testhost-without-releases-with-port.yml +++ b/tests/Resources/testhost-without-releases-with-port.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -21,4 +21,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost-without-releases.yml b/tests/Resources/testhost-without-releases.yml index 7165c964..1afb1b90 100644 --- a/tests/Resources/testhost-without-releases.yml +++ b/tests/Resources/testhost-without-releases.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -21,4 +21,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: diff --git a/tests/Resources/testhost.yml b/tests/Resources/testhost.yml index b1b630e6..a6d8d5a7 100644 --- a/tests/Resources/testhost.yml +++ b/tests/Resources/testhost.yml @@ -1,5 +1,5 @@ magephp: - log_dir: /tmp + log_dir: .logs/ environments: test: user: tester @@ -24,4 +24,4 @@ magephp: - symfony/cache-pool-prune: { env: 'dev' } on-release: post-release: - post-deploy: \ No newline at end of file + post-deploy: From 0d17d6b3453efb6c66e7c0c111f1cb018d4d4394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 19:53:25 -0300 Subject: [PATCH 15/20] [Galactica] Fix tests --- .github/workflows/tests.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c49af12e..0456b542 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,9 @@ jobs: - name: Run tests env: XDEBUG_MODE: coverage - run: ./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml + run: + mkdir .logs + ./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml - name: Run Coveralls env: COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -53,4 +55,6 @@ jobs: - name: Run tests env: XDEBUG_MODE: coverage - run: ./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml + run: + mkdir .logs + ./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml From b80efc1e09abde7733bb7f716b901e1ca8689733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 20:00:47 -0300 Subject: [PATCH 16/20] [Galactica] Fix tests --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0456b542..2b0f9722 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: - name: Run tests env: XDEBUG_MODE: coverage - run: + run: | mkdir .logs ./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml - name: Run Coveralls @@ -55,6 +55,6 @@ jobs: - name: Run tests env: XDEBUG_MODE: coverage - run: + run: | mkdir .logs ./vendor/bin/phpunit --coverage-clover build/logs/coverage.xml From 5d2ab6fa6476dfccb488cfff21458f28cc7dda84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 21:34:29 -0300 Subject: [PATCH 17/20] [Galactica] Allow to deploy a specific tag. --- src/Command/BuiltIn/DeployCommand.php | 22 ++++++++- src/Deploy/Strategy/ReleasesStrategy.php | 18 +++++-- src/Deploy/Strategy/RsyncStrategy.php | 13 ++++- src/Runtime/Runtime.php | 10 ++++ src/Task/BuiltIn/Git/ChangeBranchTask.php | 10 +++- src/Task/BuiltIn/Git/UpdateTask.php | 9 +++- .../Command/BuiltIn/DeployCommandMiscTest.php | 20 ++++++++ .../BuiltIn/DeployCommandWithReleasesTest.php | 49 +++++++++++++++++++ 8 files changed, 139 insertions(+), 12 deletions(-) diff --git a/src/Command/BuiltIn/DeployCommand.php b/src/Command/BuiltIn/DeployCommand.php index 684c57a5..027dff01 100644 --- a/src/Command/BuiltIn/DeployCommand.php +++ b/src/Command/BuiltIn/DeployCommand.php @@ -42,12 +42,19 @@ protected function configure(): void $this ->setName('deploy') ->setDescription('Deploy code to hosts') - ->addArgument('environment', InputArgument::REQUIRED, 'Name of the environment to deploy to') + ->addArgument('environment', InputArgument::REQUIRED, 'Name of the environment to deploy to.') ->addOption( 'branch', null, InputOption::VALUE_REQUIRED, - 'Force to switch to a branch other than the one defined', + 'Force to switch to a branch other than the one defined.', + false + ) + ->addOption( + 'tag', + null, + InputOption::VALUE_REQUIRED, + 'Deploys a specific tag.', false ); } @@ -83,14 +90,25 @@ protected function execute(InputInterface $input, OutputInterface $output): int $output->writeln(sprintf(' Strategy: %s', $strategy->getName())); + if (($input->getOption('branch') !== false) && ($input->getOption('tag') !== false)) { + throw new RuntimeException('Branch and Tag options are mutually exclusive.'); + } + if ($input->getOption('branch') !== false) { $this->runtime->setEnvOption('branch', $input->getOption('branch')); } + if ($input->getOption('tag') !== false) { + $this->runtime->setEnvOption('branch', false); + $this->runtime->setEnvOption('tag', $input->getOption('tag')); + $output->writeln(sprintf(' Tag: %s', $this->runtime->getEnvOption('tag'))); + } + if ($this->runtime->getEnvOption('branch', false)) { $output->writeln(sprintf(' Branch: %s', $this->runtime->getEnvOption('branch'))); } + $output->writeln(''); $this->runDeployment($output, $strategy); } catch (RuntimeException $exception) { diff --git a/src/Deploy/Strategy/ReleasesStrategy.php b/src/Deploy/Strategy/ReleasesStrategy.php index 800ab551..8d8dca37 100644 --- a/src/Deploy/Strategy/ReleasesStrategy.php +++ b/src/Deploy/Strategy/ReleasesStrategy.php @@ -38,7 +38,11 @@ public function getPreDeployTasks(): array $this->checkStage(Runtime::PRE_DEPLOY); $tasks = $this->runtime->getTasks(); - if ($this->runtime->getBranch() && !$this->runtime->inRollback() && !in_array('git/change-branch', $tasks)) { + if ( + ($this->runtime->getBranch() || $this->runtime->getTag()) && + !$this->runtime->inRollback() && + !in_array('git/change-branch', $tasks) + ) { array_unshift($tasks, 'git/change-branch'); } @@ -94,12 +98,16 @@ public function getPostDeployTasks(): array $this->checkStage(Runtime::POST_DEPLOY); $tasks = $this->runtime->getTasks(); - if (!$this->runtime->inRollback() && !in_array('deploy/tar/cleanup', $tasks)) { - array_unshift($tasks, 'deploy/tar/cleanup'); + if ( + ($this->runtime->getBranch() || $this->runtime->getTag()) && + !$this->runtime->inRollback() && + !in_array('git/change-branch', $tasks) + ) { + array_unshift($tasks, 'git/change-branch'); } - if ($this->runtime->getBranch() && !$this->runtime->inRollback() && !in_array('git/change-branch', $tasks)) { - array_push($tasks, 'git/change-branch'); + if (!$this->runtime->inRollback() && !in_array('deploy/tar/cleanup', $tasks)) { + array_unshift($tasks, 'deploy/tar/cleanup'); } return $tasks; diff --git a/src/Deploy/Strategy/RsyncStrategy.php b/src/Deploy/Strategy/RsyncStrategy.php index c7b5f1a1..15f6984b 100644 --- a/src/Deploy/Strategy/RsyncStrategy.php +++ b/src/Deploy/Strategy/RsyncStrategy.php @@ -38,7 +38,11 @@ public function getPreDeployTasks(): array $this->checkStage(Runtime::PRE_DEPLOY); $tasks = $this->runtime->getTasks(); - if ($this->runtime->getBranch() && !$this->runtime->inRollback() && !in_array('git/change-branch', $tasks)) { + if ( + ($this->runtime->getBranch() || $this->runtime->getTag()) && + !$this->runtime->inRollback() && + !in_array('git/change-branch', $tasks) + ) { array_unshift($tasks, 'git/change-branch'); } @@ -72,7 +76,12 @@ public function getPostDeployTasks(): array $this->checkStage(Runtime::POST_DEPLOY); $tasks = $this->runtime->getTasks(); - if ($this->runtime->getBranch() && !$this->runtime->inRollback() && !in_array('git/change-branch', $tasks)) { + if ( + ($this->runtime->getBranch() || + $this->runtime->getTag()) && + !$this->runtime->inRollback() && + !in_array('git/change-branch', $tasks) + ) { array_push($tasks, 'git/change-branch'); } diff --git a/src/Runtime/Runtime.php b/src/Runtime/Runtime.php index 6b68611f..ab864836 100644 --- a/src/Runtime/Runtime.php +++ b/src/Runtime/Runtime.php @@ -495,6 +495,16 @@ public function getBranch(): mixed return $this->getEnvOption('branch', false); } + /** + * Shortcut for getting Tag information + * + * @return bool|string + */ + public function getTag(): mixed + { + return $this->getEnvOption('tag', false); + } + /** * Guesses the Deploy Strategy to use */ diff --git a/src/Task/BuiltIn/Git/ChangeBranchTask.php b/src/Task/BuiltIn/Git/ChangeBranchTask.php index 991c5c68..c49a7cbe 100644 --- a/src/Task/BuiltIn/Git/ChangeBranchTask.php +++ b/src/Task/BuiltIn/Git/ChangeBranchTask.php @@ -30,12 +30,17 @@ public function getName(): string public function getDescription(): string { $options = $this->getOptions(); + $tag = $options['tag']; $branch = $options['branch']; if ($this->runtime->getVar('git_revert_branch', null)) { $branch = $this->runtime->getVar('git_revert_branch'); } + if ($tag) { + return sprintf('[Git] Checkout Tag (%s)', $tag); + } + return sprintf('[Git] Change Branch (%s)', $branch); } @@ -59,7 +64,7 @@ public function execute(): bool throw new SkipException(); } - $branch = $options['branch']; + $branch = $options['tag'] ? $options['tag'] : $options['branch']; $this->runtime->setVar('git_revert_branch', $currentBranch); } @@ -75,9 +80,10 @@ public function execute(): bool */ protected function getOptions(): array { + $tag = $this->runtime->getEnvOption('tag', false); $branch = $this->runtime->getEnvOption('branch', 'master'); $options = array_merge( - ['path' => 'git', 'branch' => $branch], + ['path' => 'git', 'branch' => $branch, 'tag' => $tag], $this->options ); diff --git a/src/Task/BuiltIn/Git/UpdateTask.php b/src/Task/BuiltIn/Git/UpdateTask.php index 44cfef04..1fae7b62 100644 --- a/src/Task/BuiltIn/Git/UpdateTask.php +++ b/src/Task/BuiltIn/Git/UpdateTask.php @@ -13,6 +13,7 @@ use Symfony\Component\Process\Process; use Mage\Task\AbstractTask; +use Mage\Task\Exception\SkipException; /** * Git Task - Pull @@ -34,6 +35,10 @@ public function getDescription(): string public function execute(): bool { $options = $this->getOptions(); + if ($options['tag']) { + throw new SkipException(); + } + $command = $options['path'] . ' pull'; $process = $this->runtime->runLocalCommand($command); @@ -47,8 +52,10 @@ public function execute(): bool protected function getOptions(): array { $branch = $this->runtime->getEnvOption('branch', 'master'); + $tag = $this->runtime->getEnvOption('tag', false); + $options = array_merge( - ['path' => 'git', 'branch' => $branch], + ['path' => 'git', 'branch' => $branch, 'tag' => $tag], $this->options ); diff --git a/tests/Command/BuiltIn/DeployCommandMiscTest.php b/tests/Command/BuiltIn/DeployCommandMiscTest.php index 240ee21c..9fb501f7 100755 --- a/tests/Command/BuiltIn/DeployCommandMiscTest.php +++ b/tests/Command/BuiltIn/DeployCommandMiscTest.php @@ -37,6 +37,26 @@ public function testDeploymentWithNoHosts() $this->assertEquals(0, $tester->getStatusCode()); } + public function testTagAndBranch() + { + $application = new MageApplicationMockup(__DIR__ . '/../../Resources/no-hosts.yml'); + + /** @var AbstractCommand $command */ + $command = $application->find('deploy'); + $this->assertTrue($command instanceof DeployCommand); + + $tester = new CommandTester($command); + $tester->execute([ + 'command' => $command->getName(), + 'environment' => 'test', + '--branch' => 'branch', + '--tag' => 'tag' + ]); + + $this->assertTrue(strpos($tester->getDisplay(), 'Branch and Tag options are mutually exclusive.') !== false); + $this->assertGreaterThan(0, $tester->getStatusCode()); + } + public function testInvalidLog() { $application = new MageApplicationMockup(__DIR__ . '/../../Resources/invalid-log.yml'); diff --git a/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php b/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php index 8ea13f7d..fd38478b 100755 --- a/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php +++ b/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php @@ -69,6 +69,55 @@ public function testDeploymentWithReleasesCommands() $this->assertEquals(0, $tester->getStatusCode()); } + public function testDeploymentWithReleasesCommandsWithTag() + { + $application = new MageApplicationMockup(__DIR__ . '/../../Resources/testhost.yml'); + + $application->getRuntime()->setReleaseId('20170101015120'); + + /** @var AbstractCommand $command */ + $command = $application->find('deploy'); + $this->assertTrue($command instanceof DeployCommand); + + $tester = new CommandTester($command); + $tester->execute(['command' => $command->getName(), 'environment' => 'test', '--tag' => 'v1.0.0']); + + $ranCommands = $application->getRuntime()->getRanCommands(); + + $testCase = array( + 0 => 'git branch | grep "*"', + 1 => 'git checkout v1.0.0', + 2 => 'composer install --optimize-autoloader', + 3 => 'composer dump-autoload --optimize', + 4 => 'tar cfzp /tmp/mageXYZ --exclude=".git" --exclude="./var/cache/*" --exclude="./var/log/*" --exclude="./web/app_dev.php" ./', + 5 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "mkdir -p /var/www/test/releases/1234567890"', + 6 => 'scp -P 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /tmp/mageXYZ tester@testhost:/var/www/test/releases/1234567890/mageXYZ', + 7 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && tar xfzop mageXYZ"', + 8 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm /var/www/test/releases/1234567890/mageXYZ"', + 9 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console cache:warmup --env=dev"', + 10 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console assets:install web --env=dev --symlink --relative"', + 11 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console cache:pool:prune --env=dev"', + 12 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test && ln -snf releases/1234567890 current"', + 13 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "ls -1 /var/www/test/releases"', + 14 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015110"', + 15 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015111"', + 16 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015112"', + 17 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015113"', + 18 => 'rm /tmp/mageXYZ', + 19 => 'git checkout master', + ); + + // Check total of Executed Commands + $this->assertEquals(count($testCase), count($ranCommands)); + + // Check Generated Commands + foreach ($testCase as $index => $command) { + $this->assertEquals($command, $ranCommands[$index]); + } + + $this->assertEquals(0, $tester->getStatusCode()); + } + public function testDeploymentWithReleasesCommandsCustomSymlink() { $application = new MageApplicationMockup(__DIR__ . '/../../Resources/testhost-custom-symlink.yml'); From 223bd680cf0a7e7bbeb02d505645041088e9d44c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 21:38:27 -0300 Subject: [PATCH 18/20] [Galactica] Update readme and changelog. --- CHANGELOG.md | 15 ++++++++++----- README.md | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60f0231a..0b9d14a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,13 @@ CHANGELOG for 5.X ================= * 5.0.0 (2022-04-15) - * v5 series release - * Refactored for Symfony 6 and PHP 8 - * Added strong types - * Removed task `composer/self-update` - * Allow `exec` task to interpolate `%environment%` and `%release%` + * v5 series release. + * Refactored for Symfony 6 and PHP 8. + * Added strong types. + * Removed task `composer/self-update`. + * Allow `exec` task to interpolate `%environment%` and `%release%`. + * Added new `sleep` task to day execution [PR#414]. + * Added new `symlink` option to define the name of symbolic link on the Release [PR#425]. + * Improved Windows compatibility [PR#427]. + * Added new `log_limit` option to limit how many logs are kept [Issue#403]. + * Add new deploy option `--tag` to specify deploying a specific tag [Issue#192] [Issue#315]. diff --git a/README.md b/README.md index cab3efde..fb201604 100644 --- a/README.md +++ b/README.md @@ -25,5 +25,5 @@ Finally you can use **Magallanes** from the vendor's bin: vendor/bin/mage version ``` -### Codename Discovery One +### Codename Galactica Each new mayor version of **Magallanes** will have a codename (like Ubuntu), version 3 was _Nostromo_, version 4 was _Discovery One_, and in the current version it is **_Galactica_**, in homage to the space battleship from the TV series Battlestar Galactica, both the '70s and the mind blowing revision of 2005. From 11839074098dbafc14562da71855b7982af3d41c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Sun, 10 Apr 2022 23:48:09 -0300 Subject: [PATCH 19/20] [Galactica] Add alternative flags for SCP. --- CHANGELOG.md | 1 + src/Task/BuiltIn/Deploy/Tar/CopyTask.php | 2 +- .../BuiltIn/DeployCommandWithReleasesTest.php | 50 +++++++++++++++++++ .../testhost-with-release-scp-flags.yml | 30 +++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 tests/Resources/testhost-with-release-scp-flags.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b9d14a3..282b07b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,3 +12,4 @@ CHANGELOG for 5.X * Improved Windows compatibility [PR#427]. * Added new `log_limit` option to limit how many logs are kept [Issue#403]. * Add new deploy option `--tag` to specify deploying a specific tag [Issue#192] [Issue#315]. + * Added new `scp_flags` option for the `scp` command when SSH flags are incompatible with. diff --git a/src/Task/BuiltIn/Deploy/Tar/CopyTask.php b/src/Task/BuiltIn/Deploy/Tar/CopyTask.php index 5c0f9348..909dd34b 100644 --- a/src/Task/BuiltIn/Deploy/Tar/CopyTask.php +++ b/src/Task/BuiltIn/Deploy/Tar/CopyTask.php @@ -54,7 +54,7 @@ public function execute(): bool $cmdCopy = sprintf( 'scp -P %d %s %s %s@%s:%s/%s', $sshConfig['port'], - $sshConfig['flags'], + isset($sshConfig['scp_flags']) ? $sshConfig['scp_flags'] : $sshConfig['flags'], $tarLocal, $user, $host, diff --git a/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php b/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php index fd38478b..fc909f27 100755 --- a/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php +++ b/tests/Command/BuiltIn/DeployCommandWithReleasesTest.php @@ -418,6 +418,56 @@ public function testDeploymentWithReleasesWithTimeout() $this->assertEquals(0, $tester->getStatusCode()); } + public function testDeploymentWithReleasesWithSCPFlags() + { + $application = new MageApplicationMockup(__DIR__ . '/../../Resources/testhost-with-release-scp-flags.yml'); + + $application->getRuntime()->setReleaseId('20170101015120'); + + /** @var AbstractCommand $command */ + $command = $application->find('deploy'); + $this->assertTrue($command instanceof DeployCommand); + + $tester = new CommandTester($command); + $tester->execute(['command' => $command->getName(), 'environment' => 'test']); + + $ranCommands = $application->getRuntime()->getRanCommands(); + + $testCase = array( + 0 => 'git branch | grep "*"', + 1 => 'git checkout test', + 2 => 'git pull', + 3 => 'composer install --optimize-autoloader', + 4 => 'composer dump-autoload --optimize', + 5 => 'tar cfzp /tmp/mageXYZ --exclude=".git" --exclude="./var/cache/*" --exclude="./var/log/*" --exclude="./web/app_dev.php" ./', + 6 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "mkdir -p /var/www/test/releases/1234567890"', + 7 => 'scp -P 22 -p -l 1000 /tmp/mageXYZ tester@testhost:/var/www/test/releases/1234567890/mageXYZ', + 8 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && tar xfzop mageXYZ"', + 9 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm /var/www/test/releases/1234567890/mageXYZ"', + 10 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console cache:warmup --env=dev"', + 11 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console assets:install web --env=dev --symlink --relative"', + 12 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test/releases/1234567890 && bin/console cache:pool:prune --env=dev"', + 13 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "cd /var/www/test && ln -snf releases/1234567890 current"', + 14 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "ls -1 /var/www/test/releases"', + 15 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015110"', + 16 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015111"', + 17 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015112"', + 18 => 'ssh -p 22 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no tester@testhost "rm -rf /var/www/test/releases/20170101015113"', + 19 => 'rm /tmp/mageXYZ', + 20 => 'git checkout master', + ); + + // Check total of Executed Commands + $this->assertEquals(count($testCase), count($ranCommands)); + + // Check Generated Commands + foreach ($testCase as $index => $command) { + $this->assertEquals($command, $ranCommands[$index]); + } + + $this->assertEquals(0, $tester->getStatusCode()); + } + public function testDeploymentWithoutReleasesTarPrepare() { $application = new MageApplicationMockup(__DIR__ . '/../../Resources/testhost-force-tar1.yml'); diff --git a/tests/Resources/testhost-with-release-scp-flags.yml b/tests/Resources/testhost-with-release-scp-flags.yml new file mode 100644 index 00000000..28cab311 --- /dev/null +++ b/tests/Resources/testhost-with-release-scp-flags.yml @@ -0,0 +1,30 @@ +magephp: + log_dir: .logs/ + environments: + test: + user: tester + branch: test + from: ./ + host_path: /var/www/test + releases: 4 + exclude: + - ./var/cache/* + - ./var/log/* + - ./web/app_dev.php + - + - + hosts: + - testhost + ssh: + scp_flags: '-p -l 1000' + pre-deploy: + - git/update + - composer/install + - composer/dump-autoload + on-deploy: + - symfony/cache-warmup: { env: 'dev' } + - symfony/assets-install: { env: 'dev' } + - symfony/cache-pool-prune: { env: 'dev' } + on-release: + post-release: + post-deploy: From a41e07eba6cd3b1abdd82974178e1753405a0648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Monta=C3=B1ez?= Date: Mon, 11 Apr 2022 00:20:05 -0300 Subject: [PATCH 20/20] [Galactica] Changelog update --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 282b07b2..39f81fbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,4 +12,4 @@ CHANGELOG for 5.X * Improved Windows compatibility [PR#427]. * Added new `log_limit` option to limit how many logs are kept [Issue#403]. * Add new deploy option `--tag` to specify deploying a specific tag [Issue#192] [Issue#315]. - * Added new `scp_flags` option for the `scp` command when SSH flags are incompatible with. + * Added new `scp_flags` option for the `scp` command when SSH flags are incompatible with [Issue#439].