/** * @param string $path */ function requireDeployServerInclude($path) { if (file_exists($include = __DIR__ . '/../../' . $path) || file_exists($include = __DIR__ . '/../../../../../' . $path)) { serverList($include); return; } Context::get()->getOutput()->writeln(sprintf('Could not locate required deploy server file include "%s(/../../|/../../../../../)%s".', __DIR__, $path)); exit(255); }
/** * Create a lazy ask password getter with use context output and input interfaces * * @return CallablePasswordGetter */ public static function createLazyGetter() { return new CallablePasswordGetter(function ($host, $user) { $context = Context::get(); $output = $context->getOutput(); $input = $context->getInput(); $askPasswordGetter = new AskPasswordGetter($input, $output); return $askPasswordGetter->getPassword($host, $user); }); }
/** * @param string $method * @param string $class * * @return bool|\Closure */ private static function isValidMethod($method, $class) { $inspect = Inspect::thisClass($class); if ($inspect->hasMethod($method) && $inspect->getMethod($method)->visibilityPublic()) { return true; } return function () use($method, $class) { Context::get()->getOutput()->writeln(sprintf('[WARNING] Request task "%s::%s" could not be found.', $class, $method)); }; }
/** * Upload directory to current server. * * @param string $local * @param string $remote * @param array $options * * @throws \RuntimeException */ function upload_dir($local, $remote, $options = []) { $options = array_merge(['ignore_unreadable_dirs' => true, 'ignore_vcs' => true, 'ignore_dot_files' => false], $options); $server = Context::get()->getServer(); $local = parse($local); if (!is_dir($local)) { throw new \RuntimeException("Directory '{$local}' does not exist."); } $remote = parse($remote); writeln("Upload from <info>{$local}</info> to <info>{$remote}</info>"); $finder = new Finder(); $files = $finder->files()->ignoreUnreadableDirs($options['ignore_unreadable_dirs'])->ignoreVCS($options['ignore_vcs'])->ignoreDotFiles($options['ignore_dot_files'])->in($local); /** @var $file \Symfony\Component\Finder\SplFileInfo */ foreach ($files as $file) { $server->upload($file->getRealPath(), $remote . DIRECTORY_SEPARATOR . $file->getRelativePathname()); } }
/** * Return current server env or set default values or get env value. * When set env value you can write over values line "{{name}}". * * @param string|null $name * @param mixed $value * @return Environment|mixed */ function env($name = null, $value = null) { if (false === Context::get()) { Environment::setDefault($name, $value); } else { if (null === $name && null === $value) { return Context::get()->getEnvironment(); } elseif (null !== $name && null === $value) { return Context::get()->getEnvironment()->get($name); } else { Context::get()->getEnvironment()->set($name, $value); } return null; } }
// Symlink to old release. run("cd {{deploy_path}} && ln -nfs {$releaseDir} current"); // Remove release run("rm -rf {{deploy_path}}/releases/{$releases[0]}"); if (isVerbose()) { writeln("Rollback to `{$releases[1]}` release was successful."); } } else { writeln("<comment>No more releases you can revert to.</comment>"); } })->desc('Rollback to previous release'); /** * Preparing server for deployment. */ task('deploy:prepare', function () { \Deployer\Task\Context::get()->getServer()->connect(); // Check if shell is POSIX-compliant try { cd(''); // To run command as raw. run('echo $0'); } catch (\RuntimeException $e) { $formatter = \Deployer\Deployer::get()->getHelper('formatter'); $errorMessage = ["Shell on your server is not POSIX-compliant. Please change to sh, bash or similar.", "Usually, you can change your shell to bash by running: chsh -s /bin/bash"]; write($formatter->formatBlock($errorMessage, 'error', true)); throw $e; } run('if [ ! -d {{deploy_path}} ]; then echo ""; fi'); // Create releases dir. run("cd {{deploy_path}} && if [ ! -d releases ]; then mkdir releases; fi"); // Create shared dir.
return trim(run("whoami")); }); // Do not skip slack notifications by default set('slack_skip_notification', false); desc('Notifying Slack channel of deployment'); task('deploy:slack', function () { if (true === get('slack_skip_notification')) { return; } global $php_errormsg; $defaultConfig = ['channel' => '#general', 'icon' => ':sunny:', 'username' => 'Deploy', 'message' => "Deployment to `{{host}}` on *{{stage}}* was successful\n({{release_path}})", 'app' => 'app-name']; $config = array_merge($defaultConfig, (array) get('slack')); if (!is_array($config) || !isset($config['token']) || !isset($config['team']) || !isset($config['channel'])) { throw new \RuntimeException("Please configure new slack: set('slack', ['token' => 'xoxp...', 'team' => 'team', 'channel' => '#channel', 'messsage' => 'message to send']);"); } $server = \Deployer\Task\Context::get()->getServer(); if ($server instanceof \Deployer\Server\Local) { $user = get('local_user'); } else { $user = $server->getConfiguration()->getUser() ?: null; } $messagePlaceHolders = ['{{release_path}}' => get('release_path'), '{{host}}' => get('server.host'), '{{stage}}' => get('stages')[0], '{{user}}' => $user, '{{branch}}' => get('branch'), '{{app_name}}' => isset($config['app']) ? $config['app'] : 'app-name']; $config['message'] = strtr($config['message'], $messagePlaceHolders); $urlParams = ['channel' => $config['channel'], 'token' => $config['token'], 'text' => $config['message'], 'username' => $config['username'], 'icon_emoji' => $config['icon'], 'pretty' => true]; if (isset($config['icon_url'])) { unset($urlParams['icon_emoji']); $urlParams['icon_url'] = $config['icon_url']; } $url = 'https://slack.com/api/chat.postMessage?' . http_build_query($urlParams); $result = @file_get_contents($url); if (!$result) {
<?php /* WP UPLOADS TASK /* --------------------- */ task('uploads:sync', function () { $server = \Deployer\Task\Context::get()->getServer()->getConfiguration(); $upload_dir = 'web/app/uploads'; $user = $server->getUser(); $host = $server->getHost(); $port = $server->getPort() ? ' -p ' . $server->getPort() : ''; $identityFile = $server->getPrivateKey() ? ' -i ' . $server->getPrivateKey() : ''; writeln('<comment>> Receive remote uploads ... </comment>'); runLocally("rsync -avzO -e 'ssh{$port}{$identityFile}' {$user}@{$host}:{{deploy_path}}/shared/{$upload_dir}/ {$upload_dir}"); writeln('<comment>> Send local uploads ... </comment>'); runLocally("rsync -avzO -e 'ssh{$port}{$identityFile}' {$upload_dir}/ {$user}@{$host}:{{deploy_path}}/shared/{$upload_dir}"); })->desc('Sync uploads');
/* (c) Anton Medvedev <*****@*****.**> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Deployer; use Deployer\Task\Context; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Style\SymfonyStyle; desc('Print server configuration'); task('config:dump', function () { $server = Context::get()->getServer(); $config = Deployer::get()->config; $env = Context::get()->getEnvironment(); $dump = []; foreach ($config as $name => $value) { try { $env->get($name); } catch (\RuntimeException $exception) { // Ignore fails. $message = 'Failed to dump'; $env->set($name, output()->isDecorated() ? "[1;30m{$message}[0m" : $message); } } foreach ($env->getValues() as $name => $value) { if (is_array($value)) { $value = json_encode($value); } elseif (is_bool($value)) { $value = $value ? 'Yes' : 'No';
/** * Parse set values. * * @param string $value * @return string */ function parse($value) { return Context::get()->getEnvironment()->parse($value); }
/** * Deploy fixtures to remote */ public function deployFixtures() { if (count($fixtures = get('shared_file_fixtures')) === 0) { return; } $serverName = @env('server')['name'] ?: ''; $replaceAnchors = function ($string, array $replacements = []) { foreach ($replacements as $search => $replace) { $string = str_replace($search, $replace, $string); } return $string; }; $replaceCollection = ['%server_name' => $serverName]; $i = 1; foreach ($fixtures as $from => $goto) { $fromFile = env()->parse(sprintf('%s/%s', getcwd(), $replaceAnchors($from, $replaceCollection))); $gotoFile = env()->parse(sprintf('{{deploy_path}}/shared/%s', $replaceAnchors($goto, $replaceCollection))); $gotoPath = dirname($gotoFile); if (false === ($fromFile = realpath($fromFile))) { $this->writeErrorLine('Fixture not found: <info>%s</info>.', sprintf('%s/%s', getcwd(), $from)); continue; } $this->writeTaskLine('Uploading file: <info>%s</info> to <info>%s</info>', $fromFile, $gotoFile); run(sprintf('if [ -f $(echo %s) ]; then rm -rf %s; fi', $gotoFile, $gotoFile)); run(sprintf('if [ ! -d $(echo %s) ]; then mkdir -p %s; fi', $gotoPath, $gotoPath)); Context::get()->getServer()->upload($fromFile, $gotoFile); $i++; } }