Files
piratepoet/RoboFile.php
Pavel Dohnal 9dcdd54a97 Fix code style
[MAILPOET-2004]
2019-05-28 11:00:48 -04:00

853 lines
27 KiB
PHP

<?php
class RoboFile extends \Robo\Tasks {
const ZIP_BUILD_PATH = __DIR__ . '/mailpoet.zip';
use \Codeception\Task\SplitTestsByGroups;
public function __construct() {
// disable xdebug to avoid slowing down command execution
$xdebug_handler = new \Composer\XdebugHandler\XdebugHandler('mailpoet');
$xdebug_handler->setPersistent();
$xdebug_handler->check();
$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();
}
function install() {
return $this->taskExecStack()
->stopOnFail()
->exec('./composer.phar install')
->exec('npm ci --prefer-offline')
->run();
}
function update() {
$this->say(getenv('WP_TEST_URL'));
return $this->taskExecStack()
->stopOnFail()
->exec('./composer.phar update')
->exec('npm update')
->run();
}
function watch() {
$this->say('Warning: this lints and compiles all files, not just the changed one. Use separate tasks watch:js and watch:css for faster and more efficient watching.');
$css_files = $this->rsearch('assets/css/src/', array('scss'));
$js_files = $this->rsearch('assets/js/src/', array('js', 'jsx'));
$this->taskWatch()
->monitor($js_files, function() {
$this->compileJs();
})
->monitor($css_files, function() {
$this->compileCss();
})
->run();
}
function watchCss() {
$css_files = $this->rsearch('assets/css/src/', array('scss'));
$this->taskWatch()
->monitor($css_files, function($changedFile) {
$file = $changedFile->getResource()->getResource();
$this->taskExecStack()
->stopOnFail()
->exec('npm run stylelint -- "' . $file . '"')
->exec('npm run scss')
->exec('npm run autoprefixer')
->run();
})
->run();
}
function watchJs() {
$this->_exec('./node_modules/webpack/bin/webpack.js --watch');
}
function compileAll($opts = ['env' => null]) {
$collection = $this->collectionBuilder();
$collection->addCode(function() use ($opts) {
return call_user_func(array($this, 'compileJs'), $opts);
});
$collection->addCode(function() use ($opts) {
return call_user_func(array($this, 'compileCss'), $opts);
});
return $collection->run();
}
function compileJs($opts = ['env' => null]) {
if (!is_dir('assets/dist/js')) {
mkdir('assets/dist/js', 0777, true);
}
$env = ($opts['env']) ?
sprintf('./node_modules/cross-env/dist/bin/cross-env.js NODE_ENV="%s"', $opts['env']) :
null;
return $this->_exec($env . ' ./node_modules/webpack/bin/webpack.js --bail');
}
function compileCss($opts = ['env' => null]) {
if (!is_dir('assets/dist/css')) {
mkdir('assets/dist/css', 0777, true);
}
// Clean up folder from previous files
array_map('unlink', glob("assets/dist/css/*.*"));
$this->_exec('npm run stylelint -- "assets/css/src/components/**/*.scss"');
$this->_exec('npm run scss');
$compilation_result = $this->_exec('npm run autoprefixer');
// Create manifest file
$manifest = [];
foreach (glob('assets/dist/css/*.css') as $style) {
// Hash and rename styles if production environment
if ($opts['env'] === 'production') {
$hashed_style = sprintf(
'%s.%s.css',
pathinfo($style)['filename'],
substr(md5_file($style), 0, 8)
);
$manifest[basename($style)] = $hashed_style;
rename($style, str_replace(basename($style), $hashed_style, $style));
} else {
$manifest[basename($style)] = basename($style);
}
}
file_put_contents('assets/dist/css/manifest.json', json_encode($manifest, JSON_PRETTY_PRINT));
return $compilation_result;
}
function translationsInit() {
// Define WP_TRANSIFEX_API_TOKEN env. variable
return $this->_exec('./tasks/transifex_init.sh');
}
function translationsBuild() {
return $this->_exec('./node_modules/.bin/grunt makepot'.
' --gruntfile='.__DIR__.'/tasks/makepot/makepot.js'.
' --base_path='.__DIR__
);
}
function translationsPack() {
return $this->collectionBuilder()
->addCode([$this, 'translationsInit'])
->taskExec('./tasks/pack_translations.sh')
->run();
}
function translationsPush() {
return $this->collectionBuilder()
->addCode([$this, 'translationsInit'])
->taskExec('tx push -s')
->run();
}
function testUnit(array $opts=['file' => null, 'xml' => false, 'multisite' => false, 'debug' => false]) {
$command = 'vendor/bin/codecept run unit';
if ($opts['file']) {
$command .= ' -f ' . $opts['file'];
}
if ($opts['xml']) {
$command .= ' --xml';
}
if ($opts['debug']) {
$command .= ' --debug';
}
return $this->_exec($command);
}
function testIntegration(array $opts=['file' => null, 'xml' => false, 'multisite' => false, 'debug' => false]) {
$command = 'vendor/bin/codecept run integration';
if ($opts['multisite']) {
$command = 'MULTISITE=true ' . $command;
}
if ($opts['file']) {
$command .= ' -f ' . $opts['file'];
}
if ($opts['xml']) {
$command .= ' --xml';
}
if ($opts['debug']) {
$command .= ' --debug';
}
return $this->_exec($command);
}
function testMultisiteIntegration($opts=['file' => null, 'xml' => false, 'multisite' => true]) {
return $this->testIntegration($opts);
}
function testCoverage($opts=['file' => null, 'xml' => false]) {
$command = join(' ', array(
'vendor/bin/codecept run -s acceptance',
(($opts['file']) ? $opts['file'] : ''),
'--coverage',
($opts['xml']) ? '--coverage-xml' : '--coverage-html'
));
if ($opts['xml']) {
$command .= ' --xml';
}
return $this->execWithXDebug($command);
}
function testJavascript($xml_output_file = null) {
$this->compileJs();
$command = join(' ', array(
'./node_modules/.bin/mocha',
'-r tests/javascript/mochaTestHelper.js',
'tests/javascript/testBundles/**/*.js'
));
if (!empty($xml_output_file)) {
$command .= sprintf(
' --reporter xunit --reporter-options output="%s"',
$xml_output_file
);
}
return $this->_exec($command);
}
function securityComposer() {
return $this->collectionBuilder()
->taskExec('vendor/bin/security-checker security:check --format=simple')
->taskExec('vendor/bin/security-checker security:check --format=simple prefixer/composer.lock')
->run();
}
function testDebugUnit($opts=['file' => null, 'xml' => false, 'debug' => true]) {
return $this->testUnit($opts);
}
function testDebugIntegration($opts=['file' => null, 'xml' => false, 'debug' => true]) {
return $this->testIntegration($opts);
}
function testAcceptance($opts=['file' => null, 'skip-deps' => false, 'timeout' => null]) {
return $this->taskExec(
'COMPOSE_HTTP_TIMEOUT=200 docker-compose run ' .
($opts['skip-deps'] ? '-e SKIP_DEPS=1 ' : '') .
($opts['timeout'] ? '-e WAIT_TIMEOUT=' . (int)$opts['timeout'] . ' ' : '') .
'codeception --steps --debug -vvv ' .
'-f ' . ($opts['file'] ? $opts['file'] : '')
)->dir(__DIR__ . '/tests/docker')->run();
}
function testAcceptanceMultisite($opts=['file' => null, 'skip-deps' => false, 'timeout' => null]) {
return $this->taskExec(
'COMPOSE_HTTP_TIMEOUT=200 docker-compose run ' .
($opts['skip-deps'] ? '-e SKIP_DEPS=1 ' : '') .
($opts['timeout'] ? '-e WAIT_TIMEOUT=' . (int)$opts['timeout'] . ' ' : '') .
'-e MULTISITE=1 ' .
'codeception --steps --debug -vvv' .
'-f ' . ($opts['file'] ? $opts['file'] : '')
)->dir(__DIR__ . '/tests/docker')->run();
}
function deleteDocker() {
return $this->taskExec(
'docker-compose down -v --remove-orphans --rmi all'
)->dir(__DIR__ . '/tests/docker')->run();
}
function testFailedUnit() {
$this->_exec('vendor/bin/codecept build');
return $this->_exec('vendor/bin/codecept run unit -g failed');
}
function testFailedIntegration() {
$this->_exec('vendor/bin/codecept build');
return $this->_exec('vendor/bin/codecept run integration -g failed');
}
function containerDump() {
define('ABSPATH', getenv('WP_ROOT') . '/');
if (!file_exists(ABSPATH . 'wp-config.php')) {
$this->yell('WP_ROOT env variable does not contain valid path to wordpress root.', 40, 'red');
exit(1);
}
$configurator = new \MailPoet\DI\ContainerConfigurator();
$dump_file = __DIR__ . '/generated/' . $configurator->getDumpClassname() . '.php';
$this->say('Deleting DI Container');
$this->_exec("rm -f $dump_file");
$this->say('Generating DI container cache');
$container_factory = new \MailPoet\DI\ContainerFactory($configurator);
$container = $container_factory->getConfiguredContainer();
$container->compile();
$dumper = new \MailPoetVendor\Symfony\Component\DependencyInjection\Dumper\PhpDumper($container);
file_put_contents(
$dump_file,
$dumper->dump([
'class' => $configurator->getDumpClassname(),
'namespace' => $configurator->getDumpNamespace()
])
);
}
function qa() {
$collection = $this->collectionBuilder();
$collection->addCode(array($this, 'qaLint'));
$collection->addCode(function() {
return $this->qaCodeSniffer('all');
});
$collection->addCode(array($this, 'qaLintJavascript'));
$collection->addCode(array($this, 'qaLintCss'));
return $collection->run();
}
function qaLint() {
return $this->_exec('./tasks/code_sniffer/vendor/bin/parallel-lint lib/ tests/ mailpoet.php');
}
function qaLintJavascript() {
return $this->_exec('npm run lint');
}
function qaLintCss() {
return $this->_exec('npm run stylelint -- "assets/css/src/components/**/*.scss"');
}
function qaCodeSniffer($severity='errors') {
if ($severity === 'all') {
$severityFlag = '-w';
} else {
$severityFlag = '-n';
}
return $this->collectionBuilder()
->taskExec(
'./tasks/code_sniffer/vendor/bin/phpcs '.
'--standard=./tasks/code_sniffer/MailPoet '.
'--runtime-set testVersion 5.6-7.3 '.
'--ignore=./lib/Util/Sudzy/*,./lib/Util/CSS.php,./lib/Util/XLSXWriter.php,'.
'./lib/Util/pQuery/*,./lib/Config/PopulatorData/Templates/* '.
'lib/ '.
$severityFlag
)
->taskExec(
'./tasks/code_sniffer/vendor/bin/phpcs '.
'--standard=./tasks/code_sniffer/MailPoet '.
'--runtime-set testVersion 5.6-7.3 '.
'--ignore=./tests/unit/_bootstrap.php,./tests/unit/_fixtures.php,./tests/integration/_bootstrap.php,./tests/integration/_fixtures.php '.
'tests/unit tests/integration tests/acceptance tests/DataFactories '.
$severityFlag
)
->run();
}
function qaPhpstan() {
// PHPStan must be run out of main plugin directory to avoid its autoloading
// from vendor/autoload.php where some dev dependencies cause conflicts.
$dir = __DIR__;
return $this->collectionBuilder()
->taskExec('rm -rf ' . __DIR__ . '/vendor/goaop')
->taskExec('rm -rf ' . __DIR__ . '/vendor/nikic')
->taskExec('cd ' . __DIR__ . ' && ./composer.phar dump-autoload')
->taskExec(
'WP_ROOT="'.getenv('WP_ROOT').'" '.
'php -d memory_limit=2G '.
"$dir/phpstan.phar analyse ".
"--configuration $dir/tasks/phpstan/phpstan.neon ".
'--level 5 '.
"$dir/lib"
)
->dir(__DIR__ . '/tasks/phpstan')
->taskExec('cd ' . __DIR__ . ' && ./composer.phar install')
->run();
}
function svnCheckout() {
$svn_dir = ".mp_svn";
$collection = $this->collectionBuilder();
// Clean up the SVN dir for faster shallow checkout
if (file_exists($svn_dir)) {
$collection->taskExecStack()
->exec('rm -rf ' . $svn_dir);
}
$collection->taskFileSystemStack()
->mkdir($svn_dir);
return $collection->taskExecStack()
->stopOnFail()
->dir($svn_dir)
->exec('svn co https://plugins.svn.wordpress.org/mailpoet/ -N .')
->exec('svn up trunk')
->exec('svn up assets')
->run();
}
function svnPushTemplates() {
$collection = $this->collectionBuilder();
$this->svnCheckout();
$awkCmd = '{print " --force \""$2"\""}';
$xargsFlag = (stripos(PHP_OS, 'Darwin') !== false) ? '' : '-r';
return $collection->taskExecStack()
->stopOnFail()
->dir('.mp_svn')
->exec('cp -R ../plugin_repository/assets/newsletter-templates/* assets/newsletter-templates')
->exec("svn st | grep ^! | awk '$awkCmd' | xargs $xargsFlag svn rm")
->exec('svn add --force * --auto-props --parents --depth infinity -q')
->exec('svn commit -m "Push Templates for test"')
->run();
}
function svnPublish() {
$svn_dir = ".mp_svn";
$plugin_version = $this->getPluginVersion('mailpoet.php');
$plugin_dist_name = 'mailpoet';
$plugin_dist_file = $plugin_dist_name . '.zip';
if (!$plugin_version) {
throw new \Exception('Could not parse plugin version, check the plugin header');
}
$this->say('Publishing version: ' . $plugin_version);
// Sanity checks
if (!is_readable($plugin_dist_file)) {
$this->say("Failed to access " . $plugin_dist_file);
return;
} elseif (!file_exists($svn_dir . "/.svn/")) {
$this->say("$svn_dir/.svn/ dir not found, is it a SVN repository?");
return;
} elseif (file_exists($svn_dir . "/tags/" . $plugin_version)) {
$this->say("A SVN tag already exists: " . $plugin_version);
return;
}
$collection = $this->collectionBuilder();
// Clean up tmp dirs if the previous run was halted
if (file_exists("$svn_dir/trunk_new") || file_exists("$svn_dir/trunk_old")) {
$collection->taskFileSystemStack()
->stopOnFail()
->remove(array("$svn_dir/trunk_new", "$svn_dir/trunk_old"));
}
// Extract the distributable zip to tmp trunk dir
$collection->taskExtract($plugin_dist_file)
->to("$svn_dir/trunk_new")
->preserveTopDirectory(false);
// Rename current trunk
if (file_exists("$svn_dir/trunk")) {
$collection->taskFileSystemStack()
->rename("$svn_dir/trunk", "$svn_dir/trunk_old");
}
// Replace old trunk with a new one
$collection->taskFileSystemStack()
->stopOnFail()
->rename("$svn_dir/trunk_new", "$svn_dir/trunk")
->remove("$svn_dir/trunk_old");
// Add new repository assets
$collection->taskFileSystemStack()
->mirror('./plugin_repository/assets', "$svn_dir/assets_new");
// Rename current assets folder
if (file_exists("$svn_dir/assets")) {
$collection->taskFileSystemStack()
->rename("$svn_dir/assets", "$svn_dir/assets_old");
}
// Replace old assets with new ones
$collection->taskFileSystemStack()
->stopOnFail()
->rename("$svn_dir/assets_new", "$svn_dir/assets")
->remove("$svn_dir/assets_old");
// Windows compatibility
$awkCmd = '{print " --force \""$2"\""}';
// Mac OS X compatibility
$xargsFlag = (stripos(PHP_OS, 'Darwin') !== false) ? '' : '-r';
$collection->taskExecStack()
->stopOnFail()
// Set SVN repo as working directory
->dir($svn_dir)
// Remove files from SVN repo that have already been removed locally
->exec("svn st | grep ^! | awk '$awkCmd' | xargs $xargsFlag svn rm")
// Recursively add files to SVN that haven't been added yet
->exec("svn add --force * --auto-props --parents --depth infinity -q");
$result = $collection->run();
if ($result->wasSuccessful()) {
$repo_url = "https://plugins.svn.wordpress.org/$plugin_dist_name";
$release_cmd = "svn ci -m \"Release $plugin_version\"";
$tag_cmd = "svn copy $repo_url/trunk $repo_url/tags/$plugin_version -m \"Tag $plugin_version\"";
$svn_login = getenv('WP_SVN_USERNAME');
$svn_password = getenv('WP_SVN_PASSWORD');
if ($svn_login && $svn_password) {
$release_cmd .= " --username $svn_login --password $svn_password";
$tag_cmd .= " --username $svn_login --password $svn_password";
} else {
$release_cmd .= ' --force-interactive';
$tag_cmd .= ' --force-interactive';
}
$result = $this->taskExecStack()
->stopOnFail()
->dir($svn_dir)
->exec($release_cmd)
->exec($tag_cmd)
->run();
}
return $result;
}
public function testAcceptanceGroupTests() {
return $this->taskSplitTestFilesByGroups(4)
->projectRoot('.')
->testsFrom('tests/acceptance')
->groupsTo('tests/acceptance/_groups/group_')
->run();
}
public function releasePrepare($version = null) {
$version = $this->releaseVersionAssign($version, ['return' => true]);
return $this->collectionBuilder()
->addCode(function () use ($version) {
return $this->releaseCheckIssues($version);
})
->addCode(function () {
$this->releasePrepareGit();
})
->addCode(function () use ($version) {
return $this->releaseVersionWrite($version);
})
->addCode(function () use ($version) {
return $this->releaseChangelogWrite($version);
})
->addCode(function () use ($version) {
$this->releaseCreatePullRequest($version);
})
->run();
}
public function releaseCheckIssues($version = null) {
$jira = $this->createJiraController();
$version = $jira->getVersion($this->releaseVersionGetNext($version));
$issues = $jira->getIssuesDataForVersion($version);
$pull_requests_id = \MailPoetTasks\Release\JiraController::PULL_REQUESTS_ID;
foreach ($issues as $issue) {
if (strpos($issue['fields'][$pull_requests_id], 'state=OPEN') !== false) {
$key = $issue['key'];
$this->yell("Some pull request associated to task {$key} is not merged yet!", 40, 'red');
exit(1);
}
}
}
public function releasePrepareGit() {
// make sure working directory is clean
$git_status = $this->taskGitStack()
->printOutput(false)
->exec('git status --porcelain')
->run();
if (strlen(trim($git_status->getMessage())) > 0) {
$this->yell('Please make sure your working directory is clean before running release.', 40, 'red');
exit(1);
}
// checkout master and pull from remote
$this->taskGitStack()
->stopOnFail()
->checkout('master')
->pull()
->run();
// make sure release branch doesn't exist on github
$release_branch_status = $this->taskGitStack()
->printOutput(false)
->exec('git ls-remote --heads git@github.com:mailpoet/mailpoet.git release')
->run();
if (strlen(trim($release_branch_status->getMessage())) > 0) {
$this->yell('Delete old release branch before running release.', 40, 'red');
exit(1);
}
// check if local branch with name "release" exists
$git_status = $this->taskGitStack()
->printOutput(false)
->exec('git rev-parse --verify release')
->run();
if ($git_status->wasSuccessful()) {
// delete local "release" branch
$this->taskGitStack()
->printOutput(false)
->exec('git branch -D release')
->run();
}
// create a new "release" branch and switch to it.
$this->taskGitStack()
->printOutput(false)
->exec('git checkout -b release')
->run();
}
public function releaseCreatePullRequest($version) {
$this->taskGitStack()
->stopOnFail()
->add('-A')
->commit('Release ' . $version)
->exec('git push --set-upstream git@github.com:mailpoet/mailpoet.git release')
->run();
$this->createGitHubController()
->createReleasePullRequest($version);
}
public function releasePublish($version = null) {
$version = $this->releaseVersionGetNext($version);
return $this->collectionBuilder()
->addCode(function () use ($version) {
return $this->releaseCheckPullRequest($version);
})
->addCode(function () {
return $this->releaseDownloadZip();
})
->addCode(function () {
return $this->translationsBuild();
})
->addCode(function () {
return $this->translationsPush();
})
->addCode(function () {
return $this->svnCheckout();
})
->addCode(function () {
return $this->svnPublish();
})
->addCode(function () use ($version) {
return $this->releasePublishGithub($version);
})
->addCode(function () use ($version) {
return $this->releasePublishJira($version);
})
->addCode(function () use ($version) {
return $this->releasePublishSlack($version);
})
->run();
}
public function releaseCheckPullRequest($version) {
$this->createGitHubController()
->checkReleasePullRequestPassed($version);
}
public function releaseVersionGetNext($version = null) {
if (!$version) {
$version = $this->getReleaseVersionController()
->determineNextVersion();
}
$this->validateVersion($version);
return $version;
}
public function releaseVersionAssign($version = null, $opts = []) {
$version = $this->releaseVersionGetNext($version);
try {
list($version, $output) = $this->getReleaseVersionController()
->assignVersionToCompletedTickets($version);
} catch (\Exception $e) {
$this->yell($e->getMessage(), 40, 'red');
exit(1);
}
$this->say($output);
if (!empty($opts['return'])) {
return $version;
}
}
public function releaseVersionWrite($version) {
$version = trim($version);
$this->validateVersion($version);
$this->taskReplaceInFile(__DIR__ . '/readme.txt')
->regex('/Stable tag:\s*\d+\.\d+\.\d+/i')
->to('Stable tag: ' . $version)
->run();
$this->taskReplaceInFile(__DIR__ . '/mailpoet.php')
->regex('/Version:\s*\d+\.\d+\.\d+/i')
->to('Version: ' . $version)
->run();
$this->taskReplaceInFile(__DIR__ . '/mailpoet.php')
->regex("/['\"]version['\"]\s*=>\s*['\"]\d+\.\d+\.\d+['\"],/i")
->to(sprintf("'version' => '%s',", $version))
->run();
}
function releaseChangelogGet($version = null) {
$outputs = $this->getChangelogController()->get($version);
$this->say("Changelog \n{$outputs[0]} \n{$outputs[1]}\n");
$this->say("IMPORTANT NOTES \n" . ($outputs[2] ?: 'none'));
}
function releaseChangelogWrite($version = null) {
$this->say("Updating changelog");
$outputs = $this->getChangelogController()->update($version);
$this->say("Changelog \n{$outputs[0]} \n{$outputs[1]}\n\n");
$this->say("IMPORTANT NOTES \n" . ($outputs[2] ?: 'none'));
}
public function releaseDownloadZip() {
$circleci_controller = $this->createCircleCiController();
$path = $circleci_controller->downloadLatestBuild(self::ZIP_BUILD_PATH);
$this->say('Release ZIP downloaded to: ' . $path);
$this->say(sprintf('Release ZIP file size: %.2F MB', filesize($path)/pow(1024, 2)));
}
public function releasePublishGithub($version = null) {
$jira_controller = $this->createJiraController();
$version = $jira_controller->getVersion($version);
$changelog = $this->getChangelogController()->get($version['name']);
$github_controller = $this->createGitHubController();
$github_controller->publishRelease($version['name'], $changelog[1], self::ZIP_BUILD_PATH);
$this->say("Release '$version[name]' was published to GitHub.");
}
public function releasePublishJira($version = null) {
$version = $this->releaseVersionGetNext($version);
$jira_controller = $this->createJiraController();
$jira_version = $jira_controller->releaseVersion($version);
$this->say("JIRA version '$jira_version[name]' was released.");
}
public function releasePublishSlack($version = null) {
$jira_controller = $this->createJiraController();
$version = $jira_controller->getVersion($version);
$changelog = $this->getChangelogController()->get($version['name']);
$slack_notifier = $this->createSlackNotifier();
$slack_notifier->notify($version['name'], $changelog[1], $version['id']);
$this->say("Release '$version[name]' info was published on Slack.");
}
protected function rsearch($folder, $extensions = array()) {
$dir = new RecursiveDirectoryIterator($folder);
$iterator = new RecursiveIteratorIterator($dir);
$pattern = '/^.+\.('.join($extensions, '|').')$/i';
$files = new RegexIterator(
$iterator,
$pattern,
RecursiveRegexIterator::GET_MATCH
);
$list = array();
foreach ($files as $file) {
$list[] = $file[0];
}
return $list;
}
protected function getPluginVersion($file) {
$data = file_get_contents($file);
preg_match('/^[ \t*]*Version:(.*)$/mi', $data, $m);
return !empty($m[1]) ? trim($m[1]) : false;
}
protected function validateVersion($version) {
if (!\MailPoetTasks\Release\VersionHelper::validateVersion($version)) {
$this->yell('Incorrect version format', 40, 'red');
exit(1);
}
}
protected function getChangelogController() {
return new \MailPoetTasks\Release\ChangelogController(
$this->createJiraController(),
__DIR__ . '/readme.txt'
);
}
protected function getReleaseVersionController() {
return new \MailPoetTasks\Release\ReleaseVersionController(
$this->createJiraController(),
\MailPoetTasks\Release\JiraController::PROJECT_MAILPOET
);
}
protected function createJiraController() {
$help = 'Use your JIRA username and a token from https://id.atlassian.com/manage/api-tokens.';
return new \MailPoetTasks\Release\JiraController(
$this->getEnv('WP_JIRA_TOKEN', $help),
$this->getEnv('WP_JIRA_USER', $help),
\MailPoetTasks\Release\JiraController::PROJECT_MAILPOET
);
}
protected function createCircleCiController() {
$help = "Use 'mailpoet' username and a token from https://circleci.com/gh/mailpoet/mailpoet/edit#api.";
return new \MailPoetTasks\Release\CircleCiController(
$this->getEnv('WP_CIRCLECI_USERNAME', $help),
$this->getEnv('WP_CIRCLECI_TOKEN', $help),
\MailPoetTasks\Release\CircleCiController::PROJECT_MAILPOET,
$this->createGitHubController()
);
}
protected function createGitHubController() {
$help = "Use your GitHub username and a token from https://github.com/settings/tokens with 'repo' scopes.";
return new \MailPoetTasks\Release\GitHubController(
$this->getEnv('WP_GITHUB_USERNAME', $help),
$this->getEnv('WP_GITHUB_TOKEN', $help),
\MailPoetTasks\Release\GitHubController::PROJECT_MAILPOET
);
}
protected function createSlackNotifier() {
$help = 'Use Webhook URL from https://mailpoet.slack.com/services/BHRB9AHSQ.';
return new \MailPoetTasks\Release\SlackNotifier(
$this->getEnv('WP_SLACK_WEBHOOK_URL', $help),
\MailPoetTasks\Release\SlackNotifier::PROJECT_MAILPOET
);
}
protected function getEnv($name, $help = null) {
$env = getenv($name);
if ($env === false || $env === '') {
$this->yell("Environment variable '$name' was not set.", 40, 'red');
if ($help !== null) {
$this->say('');
$this->say($help);
}
exit(1);
}
return $env;
}
private function execWithXDebug($command) {
$php_config = new \Composer\XdebugHandler\PhpConfig();
$php_config->useOriginal();
// exec command in subprocess with original settings
passthru($command, $exitCode);
$php_config->usePersistent();
return $exitCode;
}
}