Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
meltmedia/meltconsole / src / App / Commands / DeployCodeCommand.php
Size: Mime:
<?php

namespace MeltConsole\App\Commands;

use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion;

/**
 * Class to deploy code.
 */
class DeployCodeCommand extends MeltCommand {

  /**
   * Question helper.
   *
   * @var \Symfony\Component\Console\Helper\QuestionHelper
   */
  private $question;

  /**
   * {@inheritdoc}
   */
  protected function configure() {
    // Initial config for command.
    $this
      ->setName('melt:deploy-code')
      ->setAliases(['melt:dc'])
      ->setDescription('Deploys code to remote environment.')
      ->setHelp('Deploys code to remote environment.')
      ->addOption('env', 'e', InputOption::VALUE_REQUIRED, 'Environment e.g dev, qa, stage')
      ->addOption('branch', 'b', InputOption::VALUE_REQUIRED, 'Git branch name');
  }

  /**
   * {@inheritdoc}
   */
  protected function interact(InputInterface $input, OutputInterface $output) {
    // TODO: Change the autogenerated stub.
    parent::interact($input, $output);

    $this->question = $this->getHelper('question');

    if (!$input->getOption('env')) {
      // Ask the user some stuff.
      $envs = $this->getEnvironmentsFromServer();
      $question = new ChoiceQuestion('Choose environment to deploy code to: ', $envs);

      if (empty($envs)) {
        throw new \Exception('There are currently no environments.');
      }

      $env = $this->question->ask($input, $output, $question);

      // Set options based on users answer.
      $input->setOption('env', $env);
    }

    if (!$input->getOption('branch')) {

      $currentRemoteBranch = $this->getCurrentRemoteBranch($env);
      $remotes = $this->getRemoteBranches();
      $output->writeln([
        '<info>----------------------------------------------</info>',
        '        <info>BEFORE YOU CHOOSE THE BRANCH!!</info>',

        '<info>----------------------------------------------</info>',
        'If you haven\'t already, make sure your remote repo has the latest code',
        'before deploying. Otherwise, you run the risk of overriding configuration.',
        '',
        "Looks like <info>{$env}</info> is currently on the <info>{$currentRemoteBranch}</info> branch.",
        '',
      ]);
      $question = new ChoiceQuestion("Which branch would you like deployed to <info>{$env}</info> environment? ", $remotes);
      $branch = $this->question->ask($input, $output, $question);
      $input->setOption('branch', $branch);

    }

  }

  /**
   * {@inheritdoc}
   */
  protected function execute(InputInterface $input, OutputInterface $output) {

    $env = $input->getOption('env');
    $branch = $input->getOption('branch');

    if (!$this->validateEnvironmentExistsOnServer($env)) {
      throw new \Exception('Environment doesn\'t exist.');
    }

    $envDir = "{$this->projectName}-{$env}";
    $question = new ConfirmationQuestion('Do you want to use BLT to deploy? (y/N) ', FALSE);
    $useBLT = $this->question->ask($input, $output, $question);

    if ($useBLT) {
      $commit = $this->getLatestCommitMessage();
      $output->writeln('Deploying using BLT...this will take a while...');
      $this->runLocalCommands([
        "blt artifact:deploy --commit-msg '{$commit}' --branch '{$branch}-build' --no-interaction",
      ]);
    }
    else {

      $this->runServerCommands([
        "cd /{$this->serverRoot}/{$envDir}",
        "git checkout -B {$branch}",
        "git fetch origin",
        "git reset --hard origin/{$branch}",
        'rm -rf vendor docroot/modules/contrib docroot/core',
        'composer install --no-dev --optimize-autoloader',
        'drush cr',
        'sudo systemctl reload php7.2-fpm' //
      ]);

    }

    $output->writeln('<info>Done!</info>');
  }

  /**
   * Backs up remote database.
   *
   * @param string $env
   *   Environment.
   */
  protected function backupRemoteDatabase(string $env) {

    // Year month day hour minute.
    $timestamp = date('Ymdhi');
    $envDir = "{$this->projectName}-{$env}";
    $backupName = "{$envDir}-backup-{$timestamp}.sql";

    $this->runServerCommands([
      "cd /{$this->serverRoot}/{$envDir}",
      "mkdir -p backups",
      "drush sql:dump --gzip --result-file=../backups/{$backupName}",
    ]);
  }

  /**
   * Get's the current branch of the remote environment.
   *
   * @param string $env
   *   Environment.
   *
   * @return string
   *   The branch the remote environment is currently on.
   */
  protected function getCurrentRemoteBranch(string $env) {
    $envDir = "{$this->projectName}-{$env}";

    $process = $this->runServerCommands([
      "cd /{$this->serverRoot}/{$envDir}",
      "git symbolic-ref --short HEAD",
    ], FALSE);

    return trim($process->getOutput());
  }

  /**
   * Get's the latest commit message.
   *
   * @return string
   *   Latest commit message.
   */
  protected function getLatestCommitMessage() {
    $process = $this->runLocalCommands([
      'git log -1 --pretty=%B',
    ]);

    return trim($process->getOutput());
  }

}