1*290ea73dSAndreas Gohr<?php 2*290ea73dSAndreas Gohr 3*290ea73dSAndreas Gohrif (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../'); 4*290ea73dSAndreas Gohrrequire_once(DOKU_INC . 'vendor/autoload.php'); 5*290ea73dSAndreas Gohrrequire_once DOKU_INC . 'inc/load.php'; 6*290ea73dSAndreas Gohr 7*290ea73dSAndreas Gohr/** 8*290ea73dSAndreas Gohr * Command Line utility to gather and check data for building a release 9*290ea73dSAndreas Gohr */ 10*290ea73dSAndreas Gohrclass Release extends splitbrain\phpcli\CLI 11*290ea73dSAndreas Gohr{ 12*290ea73dSAndreas Gohr // base URL to fetch raw files from the stable branch 13*290ea73dSAndreas Gohr protected $BASERAW = 'https://raw.githubusercontent.com/splitbrain/dokuwiki/stable/'; 14*290ea73dSAndreas Gohr 15*290ea73dSAndreas Gohr /** @inheritdoc */ 16*290ea73dSAndreas Gohr public function __construct($autocatch = true) 17*290ea73dSAndreas Gohr { 18*290ea73dSAndreas Gohr parent::__construct($autocatch); 19*290ea73dSAndreas Gohr 20*290ea73dSAndreas Gohr $this->error(print_r($_ENV, true)); 21*290ea73dSAndreas Gohr 22*290ea73dSAndreas Gohr // when running on a clone, use the correct base URL 23*290ea73dSAndreas Gohr $repo = getenv('GITHUB_REPOSITORY'); 24*290ea73dSAndreas Gohr if ($repo) { 25*290ea73dSAndreas Gohr $this->BASERAW = 'https://raw.githubusercontent.com/' . $repo . '/stable/'; 26*290ea73dSAndreas Gohr } 27*290ea73dSAndreas Gohr } 28*290ea73dSAndreas Gohr 29*290ea73dSAndreas Gohr 30*290ea73dSAndreas Gohr protected function setup(\splitbrain\phpcli\Options $options) 31*290ea73dSAndreas Gohr { 32*290ea73dSAndreas Gohr $options->setHelp('This tool is used to gather and check data for building a release'); 33*290ea73dSAndreas Gohr 34*290ea73dSAndreas Gohr $options->registerCommand('new', 'Get environment for creating a new release'); 35*290ea73dSAndreas Gohr $options->registerOption('type', 'The type of release to build', null, 'stable|hotfix|rc', 'new'); 36*290ea73dSAndreas Gohr $options->registerOption('date', 'The date to use for the version. Defaults to today', null, 'YYYY-MM-DD', 'new'); 37*290ea73dSAndreas Gohr $options->registerOption('name', 'The codename to use for the version. Defaults to the last used one', null, 'codename', 'new'); 38*290ea73dSAndreas Gohr 39*290ea73dSAndreas Gohr $options->registerCommand('current', 'Get environment of the current release'); 40*290ea73dSAndreas Gohr } 41*290ea73dSAndreas Gohr 42*290ea73dSAndreas Gohr protected function main(\splitbrain\phpcli\Options $options) 43*290ea73dSAndreas Gohr { 44*290ea73dSAndreas Gohr switch ($options->getCmd()) { 45*290ea73dSAndreas Gohr case 'new': 46*290ea73dSAndreas Gohr $this->prepareNewEnvironment($options); 47*290ea73dSAndreas Gohr break; 48*290ea73dSAndreas Gohr case 'current': 49*290ea73dSAndreas Gohr $this->prepareCurrentEnvironment($options); 50*290ea73dSAndreas Gohr break; 51*290ea73dSAndreas Gohr default: 52*290ea73dSAndreas Gohr echo $options->help(); 53*290ea73dSAndreas Gohr } 54*290ea73dSAndreas Gohr } 55*290ea73dSAndreas Gohr 56*290ea73dSAndreas Gohr /** 57*290ea73dSAndreas Gohr * Prepare environment for the current branch 58*290ea73dSAndreas Gohr */ 59*290ea73dSAndreas Gohr protected function prepareCurrentEnvironment(\splitbrain\phpcli\Options $options) 60*290ea73dSAndreas Gohr { 61*290ea73dSAndreas Gohr $current = $this->getLocalVersion(); 62*290ea73dSAndreas Gohr // we name files like the string in the VERSION file, with rc at the front 63*290ea73dSAndreas Gohr $current['file'] = ($current['type'] === 'rc' ? 'rc' : '') . $current['date'] . $current['hotfix']; 64*290ea73dSAndreas Gohr 65*290ea73dSAndreas Gohr // output to be piped into GITHUB_ENV 66*290ea73dSAndreas Gohr foreach ($current as $k => $v) { 67*290ea73dSAndreas Gohr echo "current_$k=$v\n"; 68*290ea73dSAndreas Gohr } 69*290ea73dSAndreas Gohr } 70*290ea73dSAndreas Gohr 71*290ea73dSAndreas Gohr /** 72*290ea73dSAndreas Gohr * Prepare environment for creating a new release 73*290ea73dSAndreas Gohr */ 74*290ea73dSAndreas Gohr protected function prepareNewEnvironment(\splitbrain\phpcli\Options $options) 75*290ea73dSAndreas Gohr { 76*290ea73dSAndreas Gohr $current = $this->getUpstreamVersion(); 77*290ea73dSAndreas Gohr 78*290ea73dSAndreas Gohr // continue if we want to create a new release 79*290ea73dSAndreas Gohr $next = [ 80*290ea73dSAndreas Gohr 'type' => $options->getOpt('type'), 81*290ea73dSAndreas Gohr 'date' => $options->getOpt('date'), 82*290ea73dSAndreas Gohr 'codename' => $options->getOpt('name'), 83*290ea73dSAndreas Gohr 'hotfix' => '', 84*290ea73dSAndreas Gohr ]; 85*290ea73dSAndreas Gohr if (!$next['type']) $next['type'] = 'stable'; 86*290ea73dSAndreas Gohr if (!$next['date']) $next['date'] = date('Y-m-d'); 87*290ea73dSAndreas Gohr if (!$next['codename']) $next['codename'] = $current['codename']; 88*290ea73dSAndreas Gohr $next['codename'] = ucwords(strtolower($next['codename'])); 89*290ea73dSAndreas Gohr 90*290ea73dSAndreas Gohr if (!in_array($next['type'], ['stable', 'hotfix', 'rc'])) { 91*290ea73dSAndreas Gohr throw new \splitbrain\phpcli\Exception('Invalid release type, use release or rc'); 92*290ea73dSAndreas Gohr } 93*290ea73dSAndreas Gohr 94*290ea73dSAndreas Gohr if ($next['type'] === 'hotfix') { 95*290ea73dSAndreas Gohr $next['update'] = floatval($current['update']) + 0.1; 96*290ea73dSAndreas Gohr $next['codename'] = $current['codename']; 97*290ea73dSAndreas Gohr $next['date'] = $current['date']; 98*290ea73dSAndreas Gohr $next['hotfix'] = $this->increaseHotfix($current['hotfix']); 99*290ea73dSAndreas Gohr } else { 100*290ea73dSAndreas Gohr $next['update'] = intval($current['update']) + 1; 101*290ea73dSAndreas Gohr } 102*290ea73dSAndreas Gohr 103*290ea73dSAndreas Gohr if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $next['date'])) { 104*290ea73dSAndreas Gohr throw new \splitbrain\phpcli\Exception('Invalid date format, use YYYY-MM-DD'); 105*290ea73dSAndreas Gohr } 106*290ea73dSAndreas Gohr 107*290ea73dSAndreas Gohr if ($current['date'] > $next['date']) { 108*290ea73dSAndreas Gohr throw new \splitbrain\phpcli\Exception('Date must be equal or later than the last release'); 109*290ea73dSAndreas Gohr } 110*290ea73dSAndreas Gohr 111*290ea73dSAndreas Gohr if ($current['type'] === 'rc' && $next['type'] === 'hotfix') { 112*290ea73dSAndreas Gohr throw new \splitbrain\phpcli\Exception( 113*290ea73dSAndreas Gohr 'Cannot create hotfixes for release candidates, create a new RC instead' 114*290ea73dSAndreas Gohr ); 115*290ea73dSAndreas Gohr } 116*290ea73dSAndreas Gohr 117*290ea73dSAndreas Gohr if ($current['type'] === 'stable' && $next['type'] !== 'hotfix' && $current['codename'] === $next['codename']) { 118*290ea73dSAndreas Gohr throw new \splitbrain\phpcli\Exception('Codename must be different from the last release'); 119*290ea73dSAndreas Gohr } 120*290ea73dSAndreas Gohr 121*290ea73dSAndreas Gohr $next['version'] = $next['date'] . ($next['type'] === 'rc' ? 'rc' : $next['hotfix']); 122*290ea73dSAndreas Gohr $next['raw'] = ($next['type'] === 'rc' ? 'rc' : '') . 123*290ea73dSAndreas Gohr $next['date'] . 124*290ea73dSAndreas Gohr $next['hotfix'] . 125*290ea73dSAndreas Gohr ' "' . $next['codename'] . '"'; 126*290ea73dSAndreas Gohr 127*290ea73dSAndreas Gohr // output to be piped into GITHUB_ENV 128*290ea73dSAndreas Gohr foreach ($current as $k => $v) { 129*290ea73dSAndreas Gohr echo "current_$k=$v\n"; 130*290ea73dSAndreas Gohr } 131*290ea73dSAndreas Gohr foreach ($next as $k => $v) { 132*290ea73dSAndreas Gohr echo "next_$k=$v\n"; 133*290ea73dSAndreas Gohr } 134*290ea73dSAndreas Gohr } 135*290ea73dSAndreas Gohr 136*290ea73dSAndreas Gohr /** 137*290ea73dSAndreas Gohr * Get current version info from local VERSION file 138*290ea73dSAndreas Gohr * 139*290ea73dSAndreas Gohr * @return string[] 140*290ea73dSAndreas Gohr */ 141*290ea73dSAndreas Gohr protected function getLocalVersion() 142*290ea73dSAndreas Gohr { 143*290ea73dSAndreas Gohr $versioninfo = \dokuwiki\Info::parseVersionString(trim(file_get_contents('VERSION'))); 144*290ea73dSAndreas Gohr $doku = file_get_contents('doku.php'); 145*290ea73dSAndreas Gohr if (!preg_match('/\$updateVersion = "(\d+(\.\d+)?)";/', $doku, $m)) { 146*290ea73dSAndreas Gohr throw new \Exception('Could not find $updateVersion in doku.php'); 147*290ea73dSAndreas Gohr } 148*290ea73dSAndreas Gohr $versioninfo['update'] = floatval($m[1]); 149*290ea73dSAndreas Gohr return $versioninfo; 150*290ea73dSAndreas Gohr } 151*290ea73dSAndreas Gohr 152*290ea73dSAndreas Gohr /** 153*290ea73dSAndreas Gohr * Get current version info from stable branch 154*290ea73dSAndreas Gohr * 155*290ea73dSAndreas Gohr * @return string[] 156*290ea73dSAndreas Gohr * @throws Exception 157*290ea73dSAndreas Gohr */ 158*290ea73dSAndreas Gohr protected function getUpstreamVersion() 159*290ea73dSAndreas Gohr { 160*290ea73dSAndreas Gohr // basic version info 161*290ea73dSAndreas Gohr $versioninfo = \dokuwiki\Info::parseVersionString(trim(file_get_contents($this->BASERAW . 'VERSION'))); 162*290ea73dSAndreas Gohr 163*290ea73dSAndreas Gohr // update version grepped from the doku.php file 164*290ea73dSAndreas Gohr $doku = file_get_contents($this->BASERAW . 'doku.php'); 165*290ea73dSAndreas Gohr if (!preg_match('/\$updateVersion = "(\d+(\.\d+)?)";/', $doku, $m)) { 166*290ea73dSAndreas Gohr throw new \Exception('Could not find $updateVersion in doku.php'); 167*290ea73dSAndreas Gohr } 168*290ea73dSAndreas Gohr $versioninfo['update'] = floatval($m[1]); 169*290ea73dSAndreas Gohr 170*290ea73dSAndreas Gohr return $versioninfo; 171*290ea73dSAndreas Gohr } 172*290ea73dSAndreas Gohr 173*290ea73dSAndreas Gohr /** 174*290ea73dSAndreas Gohr * Increase the hotfix letter 175*290ea73dSAndreas Gohr * 176*290ea73dSAndreas Gohr * (max 26 hotfixes) 177*290ea73dSAndreas Gohr * 178*290ea73dSAndreas Gohr * @param string $hotfix 179*290ea73dSAndreas Gohr * @return string 180*290ea73dSAndreas Gohr */ 181*290ea73dSAndreas Gohr protected function increaseHotfix($hotfix) 182*290ea73dSAndreas Gohr { 183*290ea73dSAndreas Gohr if (empty($hotfix)) return 'a'; 184*290ea73dSAndreas Gohr return substr($hotfix, 0, -1) . chr(ord($hotfix) + 1); 185*290ea73dSAndreas Gohr } 186*290ea73dSAndreas Gohr} 187*290ea73dSAndreas Gohr 188*290ea73dSAndreas Gohr(new Release())->run(); 189