diff --git a/src/ScaffoldInstallerPlugin.php b/src/ScaffoldInstallerPlugin.php index 2994fa27..340bfdae 100644 --- a/src/ScaffoldInstallerPlugin.php +++ b/src/ScaffoldInstallerPlugin.php @@ -232,11 +232,25 @@ private function installDdevCommand(): void private function installCICommands(): void { $scaffoldPath = $this->config->get('vendor-dir') . '/lullabot/drainpipe/scaffold'; + $this->installGitlabCI($scaffoldPath); + $this->installGitHubActions($scaffoldPath); + $this->installTugboat($scaffoldPath); + } + + /** + * Install GitLab CI configuration if defined in composer.json + * + * @param string $scaffoldPath The path to the scaffold files to copy from. + */ + private function installGitlabCI(string $scaffoldPath): void { $fs = new Filesystem(); - // GitLab $fs->removeDirectory('./.drainpipe/gitlab'); - if (isset($this->extra['drainpipe']['gitlab']) && is_array($this->extra['drainpipe']['gitlab'])) { - if (file_exists('./.ddev/config.yaml')) { + + if (!isset($this->extra['drainpipe']['gitlab']) || !is_array($this->extra['drainpipe']['gitlab'])) { + return; + } + + if (file_exists('./.ddev/config.yaml')) { $fs->ensureDirectoryExists('.gitlab/drainpipe'); $fs->copy("$scaffoldPath/gitlab/DDEV.gitlab-ci.yml", ".gitlab/drainpipe/DDEV.gitlab-ci.yml"); $this->io->write("🪠 [Drainpipe] .gitlab/drainpipe/DDEV.gitlab-ci.yml installed"); @@ -250,208 +264,247 @@ private function installCICommands(): void $file = "gitlab/$gitlab.gitlab-ci.yml"; if (file_exists("$scaffoldPath/$file")) { $fs->ensureDirectoryExists('./.drainpipe/gitlab'); - $fs->copy("$scaffoldPath/$file", ".drainpipe/$file"); - $this->io->write("🪠 [Drainpipe] .drainpipe/$file installed"); + $fs->copy("$scaffoldPath/$file", ".drainpipe/$file"); + $this->io->write("🪠 [Drainpipe] .drainpipe/$file installed"); + } + else { + $this->io->warning("🪠 [Drainpipe] $scaffoldPath/$file does not exist"); + } + + if ($gitlab === 'Pantheon') { + // @TODO this isn't really specific to GitLab + // .drainpipeignore + if (!file_exists('.drainpipeignore')) { + $fs->copy("$scaffoldPath/pantheon/.drainpipeignore", '.drainpipeignore'); } else { - $this->io->warning("🪠 [Drainpipe] $scaffoldPath/$file does not exist"); - } - - if ($gitlab === 'Pantheon') { - // @TODO this isn't really specific to GitLab - // .drainpipeignore - if (!file_exists('.drainpipeignore')) { - $fs->copy("$scaffoldPath/pantheon/.drainpipeignore", '.drainpipeignore'); - } - else { - $contents = file_get_contents('./.drainpipeignore'); - if (strpos($contents, '/web/sites/default/files') === false) { - $this->io->warning( - sprintf( - '.gitignore does not contain drainpipe ignores. Compare .drainpipeignore in the root of your repository with %s and update as needed.', - "$scaffoldPath/pantheon/.drainpipeignore" - ) - ); - } - } - // pantheon.yml - if (!file_exists('./pantheon.yml')) { - $fs->copy("$scaffoldPath/pantheon/pantheon.yml", './pantheon.yml'); - } - // settings.pantheon.php - if (!file_exists('./web/sites/default/settings.pantheon.php')) { - $fs->copy("$scaffoldPath/pantheon/settings.pantheon.php", './web/sites/default/settings.pantheon.php'); + $contents = file_get_contents('./.drainpipeignore'); + if (strpos($contents, '/web/sites/default/files') === false) { + $this->io->warning( + sprintf( + '.gitignore does not contain drainpipe ignores. Compare .drainpipeignore in the root of your repository with %s and update as needed.', + "$scaffoldPath/pantheon/.drainpipeignore" + ) + ); } } - } - if (!file_exists('./.gitlab-ci.yml')) { - $fs->copy("$scaffoldPath/gitlab/gitlab-ci.example.yml", './.gitlab-ci.yml'); - } - } - // GitHub - $fs->removeDirectory('./.github/actions/drainpipe'); - if (isset($this->extra['drainpipe']['github']) && is_array($this->extra['drainpipe']['github'])) { - $fs->ensureDirectoryExists('./.github/actions'); - $fs->copy("$scaffoldPath/github/actions/common", './.github/actions/drainpipe'); - foreach ($this->extra['drainpipe']['github'] as $github) { - if ($github === 'PantheonReviewApps') { - $fs->ensureDirectoryExists('./.github/actions/drainpipe/pantheon'); - $fs->ensureDirectoryExists('./.github/workflows'); - $fs->copy("$scaffoldPath/github/actions/pantheon", './.github/actions/drainpipe/pantheon'); - if (file_exists('./.ddev/config.yaml')) { - $fs->copy("$scaffoldPath/github/workflows/PantheonReviewAppsDDEV.yml", './.github/workflows/PantheonReviewApps.yml'); - } - else { - $fs->copy("$scaffoldPath/github/workflows/PantheonReviewApps.yml", './.github/workflows/PantheonReviewApps.yml'); - } + // pantheon.yml + if (!file_exists('./pantheon.yml')) { + $fs->copy("$scaffoldPath/pantheon/pantheon.yml", './pantheon.yml'); } - else if ($github === 'ComposerLockDiff') { - $fs->ensureDirectoryExists('./.github/workflows'); - $fs->copy("$scaffoldPath/github/workflows/ComposerLockDiff.yml", './.github/workflows/ComposerLockDiff.yml'); + // settings.pantheon.php + if (!file_exists('./web/sites/default/settings.pantheon.php')) { + $fs->copy("$scaffoldPath/pantheon/settings.pantheon.php", './web/sites/default/settings.pantheon.php'); } } } + if (!file_exists('./.gitlab-ci.yml')) { + $fs->copy("$scaffoldPath/gitlab/gitlab-ci.example.yml", './.gitlab-ci.yml'); + } + } - // Tugboat - if (isset($this->extra['drainpipe']['tugboat'])) { - // Look for a config override file before we wipe the directory. - $tugboatConfigOverride = []; - $tugboatConfigOverridePath = './.tugboat/config.drainpipe-override.yml'; - if (file_exists($tugboatConfigOverridePath)) { - $tugboatConfigOverride = Yaml::parseFile($tugboatConfigOverridePath); - $tugboatConfigOverrideFile = file_get_contents($tugboatConfigOverridePath); - } + /** + * Install GitLab CI configuration if defined in composer.json + * + * @param string $scaffoldPath The path to the scaffold files to copy from. + */ + private function installGitHubActions(string $scaffoldPath): void { + $fs = new Filesystem(); + $fs->removeDirectory('./.github/actions/drainpipe'); - // Wipe the Tugboat directory and define base config. - $fs->removeDirectory('./.tugboat'); - $binaryInstallerPlugin = new BinaryInstallerPlugin(); - $tugboatConfig = [ - 'nodejs_version' => '18', - 'webserver_image' => 'tugboatqa/php-nginx:8.1-fpm', - 'database_type' => 'mariadb', - 'database_version' => '10.11', - 'php_version' => '8.1', - 'sync_command' => 'sync', - 'build_command' => 'build', - 'update_command' => 'drupal:update', - 'init' => [], - 'task_version' => $binaryInstallerPlugin->getBinaryVersion('task'), - 'pantheon' => isset($this->extra['drainpipe']['tugboat']['pantheon']), - 'overrides' => ['php' => ''], - ]; - - // Read DDEV config. - if (file_exists('./.ddev/config.yaml')) { - $ddevConfig = Yaml::parseFile('./.ddev/config.yaml'); - $tugboatConfig['database_type'] = $ddevConfig['database']['type']; - $tugboatConfig['database_version'] = $ddevConfig['database']['version']; - $tugboatConfig['webserver_image'] = 'tugboatqa/php-nginx:' . $ddevConfig['php_version'] . '-fpm'; + if (!isset($this->extra['drainpipe']['github']) || !is_array($this->extra['drainpipe']['github'])) { + return; + } - if (!empty($ddevConfig['nodejs_version'])) { - $tugboatConfig['nodejs_version'] = $ddevConfig['nodejs_version']; + $fs->ensureDirectoryExists('./.github/actions'); + $fs->copy("$scaffoldPath/github/actions/common", './.github/actions/drainpipe'); + foreach ($this->extra['drainpipe']['github'] as $github) { + if ($github === 'PantheonReviewApps') { + $fs->ensureDirectoryExists('./.github/actions/drainpipe/pantheon'); + $fs->ensureDirectoryExists('./.github/workflows'); + $fs->copy("$scaffoldPath/github/actions/pantheon", './.github/actions/drainpipe/pantheon'); + if (file_exists('./.ddev/config.yaml')) { + $fs->copy("$scaffoldPath/github/workflows/PantheonReviewAppsDDEV.yml", './.github/workflows/PantheonReviewApps.yml'); } - if (!empty($ddevConfig['webserver_type']) && $ddevConfig['webserver_type'] === 'apache-fpm') { - $tugboatConfig['webserver_image'] = 'tugboatqa/php:' . $ddevConfig['php_version'] . '-apache'; + else { + $fs->copy("$scaffoldPath/github/workflows/PantheonReviewApps.yml", './.github/workflows/PantheonReviewApps.yml'); } } - - // Filter out unsupported config overrides. - if (!empty($tugboatConfigOverride['php']) && is_array($tugboatConfigOverride['php'])) { - $tugboatConfigOverride['php'] = array_filter($tugboatConfigOverride['php'], function($key) { - return in_array($key, ['aliases', 'urls', 'visualdiff', 'screenshot']); - }, ARRAY_FILTER_USE_KEY); - $overrideOutput = []; - foreach (explode(PHP_EOL, Yaml::dump($tugboatConfigOverride['php'], 2, 2)) as $line) { - $overrideOutput[] = str_repeat(' ', 4) . $line; - } - $tugboatConfig['overrides']['php'] = rtrim(implode("\n", $overrideOutput)); + else if ($github === 'ComposerLockDiff') { + $fs->ensureDirectoryExists('./.github/workflows'); + $fs->copy("$scaffoldPath/github/workflows/ComposerLockDiff.yml", './.github/workflows/ComposerLockDiff.yml'); } + } + } - // Add Redis service. - if (file_exists('./.ddev/docker-compose.redis.yaml')) { - $redisConfig = Yaml::parseFile('.ddev/docker-compose.redis.yaml'); - $redisImage = explode(':', $redisConfig['services']['redis']['image']); - $tugboatConfig['memory_cache_type'] = 'redis'; - $tugboatConfig['memory_cache_version'] = array_pop($redisImage); + /** + * Installs Tugboat if defined in composer.json. + * + * @param string $scaffoldPath + */ + private function installTugboat(string $scaffoldPath): void { + $fs = new Filesystem(); + + if (!isset($this->extra['drainpipe']['tugboat']) || !is_array($this->extra['drainpipe']['tugboat'])) { + return; + } + + // Look for a config override file before we wipe the directory. + $tugboatConfigOverride = []; + $tugboatConfigOverridePath = './.tugboat/config.drainpipe-override.yml'; + if (file_exists($tugboatConfigOverridePath)) { + $tugboatConfigOverride = Yaml::parseFile($tugboatConfigOverridePath); + $tugboatConfigOverrideFile = file_get_contents($tugboatConfigOverridePath); + } + + // Wipe the Tugboat directory and define base config. + $fs->removeDirectory('./.tugboat'); + $binaryInstallerPlugin = new BinaryInstallerPlugin(); + $tugboatConfig = [ + 'nodejs_version' => '18', + 'webserver_image' => 'tugboatqa/php-nginx:8.1-fpm', + 'database_type' => 'mariadb', + 'database_version' => '10.11', + 'php_version' => '8.1', + 'sync_command' => 'sync', + 'build_command' => 'build', + 'update_command' => 'drupal:update', + 'init' => [], + 'task_version' => $binaryInstallerPlugin->getBinaryVersion('task'), + 'pantheon' => isset($this->extra['drainpipe']['tugboat']['pantheon']), + 'overrides' => ['php' => ''], + ]; + + // Read DDEV config. + if (file_exists('./.ddev/config.yaml')) { + $ddevConfig = Yaml::parseFile('./.ddev/config.yaml'); + $tugboatConfig['database_type'] = $ddevConfig['database']['type']; + $tugboatConfig['database_version'] = $ddevConfig['database']['version']; + $tugboatConfig['webserver_image'] = 'tugboatqa/php-nginx:' . $ddevConfig['php_version'] . '-fpm'; + + if (!empty($ddevConfig['nodejs_version'])) { + $tugboatConfig['nodejs_version'] = $ddevConfig['nodejs_version']; + } + if (!empty($ddevConfig['webserver_type']) && $ddevConfig['webserver_type'] === 'apache-fpm') { + $tugboatConfig['webserver_image'] = 'tugboatqa/php:' . $ddevConfig['php_version'] . '-apache'; } + } - // Add Elasticsearch service. - if (file_exists('./.ddev/docker-compose.elasticsearch.yaml')) { - $esConfig = Yaml::parseFile('.ddev/docker-compose.elasticsearch.yaml'); - $esImage = explode(':', $esConfig['services']['elasticsearch']['image']); - $tugboatConfig['search_type'] = 'elasticsearch'; - $tugboatConfig['search_version'] = array_pop($esImage); + // Filter out unsupported config overrides. + if (!empty($tugboatConfigOverride['php']) && is_array($tugboatConfigOverride['php'])) { + $tugboatConfigOverride['php'] = array_filter($tugboatConfigOverride['php'], + function($key) { + return in_array($key, + ['aliases', 'urls', 'visualdiff', 'screenshot']); + }, + ARRAY_FILTER_USE_KEY); + $overrideOutput = []; + foreach (explode(PHP_EOL, + Yaml::dump($tugboatConfigOverride['php'], 2, 2)) as $line) { + $overrideOutput[] = str_repeat(' ', 4) . $line; } + $tugboatConfig['overrides']['php'] = rtrim(implode("\n", + $overrideOutput)); + } - // Add commands to Task. - if (file_exists('Taskfile.yml')) { - // Get steps out of the Taskfile. - $taskfile = Yaml::parseFile('./Taskfile.yml'); - if (isset($taskfile['tasks']['sync:tugboat'])) { - $tugboatConfig['sync_command'] = 'sync:tugboat'; - } - if (isset($taskfile['tasks']['build:tugboat'])) { - $tugboatConfig['build_command'] = 'build:tugboat'; - } - if (isset($taskfile['tasks']['update'])) { - $tugboatConfig['update_command'] = 'update'; - } - if (isset($taskfile['tasks']['update:tugboat'])) { - $tugboatConfig['update_command'] = 'update:tugboat'; - } - if (isset($taskfile['tasks']['online:tugboat'])) { - $tugboatConfig['online_command'] = 'online:tugboat'; - } - if (isset($taskfile['tasks']['tugboat:php:init'])) { - $tugboatConfig['init']['php'] = true; - } - if (isset($taskfile['tasks']['tugboat:mysql:init'])) { - $tugboatConfig['init']['mysql'] = true; - } - if (isset($taskfile['tasks']['tugboat:redis:init'])) { - $tugboatConfig['init']['redis'] = true; - } + // Add Redis service. + if (file_exists('./.ddev/docker-compose.redis.yaml')) { + $redisConfig = Yaml::parseFile('.ddev/docker-compose.redis.yaml'); + $redisImage = explode(':', + $redisConfig['services']['redis']['image']); + $tugboatConfig['memory_cache_type'] = 'redis'; + $tugboatConfig['memory_cache_version'] = array_pop($redisImage); + } + + // Add Elasticsearch service. + if (file_exists('./.ddev/docker-compose.elasticsearch.yaml')) { + $esConfig = Yaml::parseFile('.ddev/docker-compose.elasticsearch.yaml'); + $esImage = explode(':', + $esConfig['services']['elasticsearch']['image']); + $tugboatConfig['search_type'] = 'elasticsearch'; + $tugboatConfig['search_version'] = array_pop($esImage); + } + + // Add commands to Task. + if (file_exists('Taskfile.yml')) { + // Get steps out of the Taskfile. + $taskfile = Yaml::parseFile('./Taskfile.yml'); + if (isset($taskfile['tasks']['sync:tugboat'])) { + $tugboatConfig['sync_command'] = 'sync:tugboat'; + } + if (isset($taskfile['tasks']['build:tugboat'])) { + $tugboatConfig['build_command'] = 'build:tugboat'; + } + if (isset($taskfile['tasks']['update'])) { + $tugboatConfig['update_command'] = 'update'; + } + if (isset($taskfile['tasks']['update:tugboat'])) { + $tugboatConfig['update_command'] = 'update:tugboat'; + } + if (isset($taskfile['tasks']['online:tugboat'])) { + $tugboatConfig['online_command'] = 'online:tugboat'; + } + if (isset($taskfile['tasks']['tugboat:php:init'])) { + $tugboatConfig['init']['php'] = TRUE; + } + if (isset($taskfile['tasks']['tugboat:mysql:init'])) { + $tugboatConfig['init']['mysql'] = TRUE; + } + if (isset($taskfile['tasks']['tugboat:redis:init'])) { + $tugboatConfig['init']['redis'] = TRUE; } + } - // Write the config.yml and settings.tugboat.php files. - if (count($tugboatConfig) > 0) { - $fs->ensureDirectoryExists('./.tugboat'); - $fs->ensureDirectoryExists('./.tugboat/steps'); - $loader = new FilesystemLoader(__DIR__ . '/../scaffold/tugboat'); - $twig = new Environment($loader); - // Reinstate the override file. - if (isset($tugboatConfigOverrideFile)) { - file_put_contents('./.tugboat/config.drainpipe-override.yml', $tugboatConfigOverrideFile); - } - file_put_contents('./.tugboat/config.yml', $twig->render('config.yml.twig', $tugboatConfig)); - file_put_contents('./.tugboat/steps/1-init.sh', $twig->render('steps/1-init.sh.twig', $tugboatConfig)); - file_put_contents('./.tugboat/steps/2-update.sh', $twig->render('steps/2-update.sh.twig', $tugboatConfig)); - file_put_contents('./.tugboat/steps/3-build.sh', $twig->render('steps/3-build.sh.twig', $tugboatConfig)); - chmod('./.tugboat/steps/1-init.sh', 0755); - chmod('./.tugboat/steps/2-update.sh', 0755); - chmod('./.tugboat/steps/3-build.sh', 0755); - if (!empty($tugboatConfig['online_command'])) { - file_put_contents('./.tugboat/steps/4-online.sh', $twig->render('steps/4-online.sh.twig', $tugboatConfig)); - chmod('./.tugboat/steps/4-online.sh', 0755); - } + // Write the config.yml and settings.tugboat.php files. + if (count($tugboatConfig) > 0) { + $fs->ensureDirectoryExists('./.tugboat'); + $fs->ensureDirectoryExists('./.tugboat/steps'); + $loader = new FilesystemLoader(__DIR__ . '/../scaffold/tugboat'); + $twig = new Environment($loader); + // Reinstate the override file. + if (isset($tugboatConfigOverrideFile)) { + file_put_contents('./.tugboat/config.drainpipe-override.yml', + $tugboatConfigOverrideFile); + } + file_put_contents('./.tugboat/config.yml', + $twig->render('config.yml.twig', $tugboatConfig)); + file_put_contents('./.tugboat/steps/1-init.sh', + $twig->render('steps/1-init.sh.twig', $tugboatConfig)); + file_put_contents('./.tugboat/steps/2-update.sh', + $twig->render('steps/2-update.sh.twig', $tugboatConfig)); + file_put_contents('./.tugboat/steps/3-build.sh', + $twig->render('steps/3-build.sh.twig', $tugboatConfig)); + chmod('./.tugboat/steps/1-init.sh', 0755); + chmod('./.tugboat/steps/2-update.sh', 0755); + chmod('./.tugboat/steps/3-build.sh', 0755); + if (!empty($tugboatConfig['online_command'])) { + file_put_contents('./.tugboat/steps/4-online.sh', + $twig->render('steps/4-online.sh.twig', + $tugboatConfig)); + chmod('./.tugboat/steps/4-online.sh', 0755); + } - if ($tugboatConfig['database_type'] === 'mysql') { - $fs->ensureDirectoryExists('./.tugboat/scripts'); - $fs->copy("$scaffoldPath/tugboat/scripts/install-mysql-client.sh", './.tugboat/scripts/install-mysql-client.sh'); - chmod('./.tugboat/scripts/install-mysql-client.sh', 0755); - } + if ($tugboatConfig['database_type'] === 'mysql') { + $fs->ensureDirectoryExists('./.tugboat/scripts'); + $fs->copy("$scaffoldPath/tugboat/scripts/install-mysql-client.sh", + './.tugboat/scripts/install-mysql-client.sh'); + chmod('./.tugboat/scripts/install-mysql-client.sh', 0755); + } - file_put_contents('./web/sites/default/settings.tugboat.php', $twig->render('settings.tugboat.php.twig', $tugboatConfig)); - if (file_exists('./web/sites/default/settings.php')) { - $settings = file_get_contents('./web/sites/default/settings.php'); - if (strpos($settings, 'settings.tugboat.php') === false) { - $include = <<<'EOT' + file_put_contents('./web/sites/default/settings.tugboat.php', + $twig->render('settings.tugboat.php.twig', $tugboatConfig)); + if (file_exists('./web/sites/default/settings.php')) { + $settings = file_get_contents('./web/sites/default/settings.php'); + if (strpos($settings, 'settings.tugboat.php') === FALSE) { + $include = <<<'EOT' include __DIR__ . "/settings.tugboat.php"; EOT; - file_put_contents('./web/sites/default/settings.php', $include . PHP_EOL, FILE_APPEND); - } + file_put_contents('./web/sites/default/settings.php', + $include . PHP_EOL, + FILE_APPEND); } } } } + }