1290ea73dSAndreas Gohr<?php 2290ea73dSAndreas Gohr 3290ea73dSAndreas Gohrif (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../'); 4290ea73dSAndreas Gohrrequire_once(DOKU_INC . 'vendor/autoload.php'); 5290ea73dSAndreas Gohrrequire_once DOKU_INC . 'inc/load.php'; 6290ea73dSAndreas Gohr 7290ea73dSAndreas Gohr/** 8290ea73dSAndreas Gohr * Command Line utility to gather and check data for building a release 9290ea73dSAndreas Gohr */ 10290ea73dSAndreas Gohrclass Release extends splitbrain\phpcli\CLI 11290ea73dSAndreas Gohr{ 12*017f2aa2SAndreas Gohr const TYPES = ['stable', 'hotfix', 'rc']; 13*017f2aa2SAndreas Gohr 14290ea73dSAndreas Gohr // base URL to fetch raw files from the stable branch 15290ea73dSAndreas Gohr protected $BASERAW = 'https://raw.githubusercontent.com/splitbrain/dokuwiki/stable/'; 16290ea73dSAndreas Gohr 17290ea73dSAndreas Gohr /** @inheritdoc */ 18290ea73dSAndreas Gohr public function __construct($autocatch = true) 19290ea73dSAndreas Gohr { 20290ea73dSAndreas Gohr parent::__construct($autocatch); 21290ea73dSAndreas Gohr 22290ea73dSAndreas Gohr $this->error(print_r($_ENV, true)); 23290ea73dSAndreas Gohr 24290ea73dSAndreas Gohr // when running on a clone, use the correct base URL 25290ea73dSAndreas Gohr $repo = getenv('GITHUB_REPOSITORY'); 26290ea73dSAndreas Gohr if ($repo) { 27290ea73dSAndreas Gohr $this->BASERAW = 'https://raw.githubusercontent.com/' . $repo . '/stable/'; 28290ea73dSAndreas Gohr } 29290ea73dSAndreas Gohr } 30290ea73dSAndreas Gohr 31290ea73dSAndreas Gohr 32290ea73dSAndreas Gohr protected function setup(\splitbrain\phpcli\Options $options) 33290ea73dSAndreas Gohr { 34290ea73dSAndreas Gohr $options->setHelp('This tool is used to gather and check data for building a release'); 35290ea73dSAndreas Gohr 36290ea73dSAndreas Gohr $options->registerCommand('new', 'Get environment for creating a new release'); 37*017f2aa2SAndreas Gohr $options->registerOption('type', 'The type of release to build', null, join('|', self::TYPES), 'new'); 38290ea73dSAndreas Gohr $options->registerOption('date', 'The date to use for the version. Defaults to today', null, 'YYYY-MM-DD', 'new'); 39290ea73dSAndreas Gohr $options->registerOption('name', 'The codename to use for the version. Defaults to the last used one', null, 'codename', 'new'); 40290ea73dSAndreas Gohr 41290ea73dSAndreas Gohr $options->registerCommand('current', 'Get environment of the current release'); 42290ea73dSAndreas Gohr } 43290ea73dSAndreas Gohr 44290ea73dSAndreas Gohr protected function main(\splitbrain\phpcli\Options $options) 45290ea73dSAndreas Gohr { 46290ea73dSAndreas Gohr switch ($options->getCmd()) { 47290ea73dSAndreas Gohr case 'new': 48290ea73dSAndreas Gohr $this->prepareNewEnvironment($options); 49290ea73dSAndreas Gohr break; 50290ea73dSAndreas Gohr case 'current': 51290ea73dSAndreas Gohr $this->prepareCurrentEnvironment($options); 52290ea73dSAndreas Gohr break; 53290ea73dSAndreas Gohr default: 54290ea73dSAndreas Gohr echo $options->help(); 55290ea73dSAndreas Gohr } 56290ea73dSAndreas Gohr } 57290ea73dSAndreas Gohr 58290ea73dSAndreas Gohr /** 59290ea73dSAndreas Gohr * Prepare environment for the current branch 60290ea73dSAndreas Gohr */ 61290ea73dSAndreas Gohr protected function prepareCurrentEnvironment(\splitbrain\phpcli\Options $options) 62290ea73dSAndreas Gohr { 63290ea73dSAndreas Gohr $current = $this->getLocalVersion(); 64290ea73dSAndreas Gohr // we name files like the string in the VERSION file, with rc at the front 65290ea73dSAndreas Gohr $current['file'] = ($current['type'] === 'rc' ? 'rc' : '') . $current['date'] . $current['hotfix']; 66290ea73dSAndreas Gohr 67290ea73dSAndreas Gohr // output to be piped into GITHUB_ENV 68290ea73dSAndreas Gohr foreach ($current as $k => $v) { 69290ea73dSAndreas Gohr echo "current_$k=$v\n"; 70290ea73dSAndreas Gohr } 71290ea73dSAndreas Gohr } 72290ea73dSAndreas Gohr 73290ea73dSAndreas Gohr /** 74290ea73dSAndreas Gohr * Prepare environment for creating a new release 75290ea73dSAndreas Gohr */ 76290ea73dSAndreas Gohr protected function prepareNewEnvironment(\splitbrain\phpcli\Options $options) 77290ea73dSAndreas Gohr { 78290ea73dSAndreas Gohr $current = $this->getUpstreamVersion(); 79290ea73dSAndreas Gohr 80290ea73dSAndreas Gohr // continue if we want to create a new release 81290ea73dSAndreas Gohr $next = [ 82290ea73dSAndreas Gohr 'type' => $options->getOpt('type'), 83290ea73dSAndreas Gohr 'date' => $options->getOpt('date'), 84290ea73dSAndreas Gohr 'codename' => $options->getOpt('name'), 85290ea73dSAndreas Gohr 'hotfix' => '', 86290ea73dSAndreas Gohr ]; 87290ea73dSAndreas Gohr if (!$next['type']) $next['type'] = 'stable'; 88290ea73dSAndreas Gohr if (!$next['date']) $next['date'] = date('Y-m-d'); 89290ea73dSAndreas Gohr if (!$next['codename']) $next['codename'] = $current['codename']; 90290ea73dSAndreas Gohr $next['codename'] = ucwords(strtolower($next['codename'])); 91290ea73dSAndreas Gohr 92*017f2aa2SAndreas Gohr if (!in_array($next['type'], self::TYPES)) { 93*017f2aa2SAndreas Gohr throw new \splitbrain\phpcli\Exception('Invalid release type. Use one of ' . join(', ', self::TYPES)); 94290ea73dSAndreas Gohr } 95290ea73dSAndreas Gohr 96290ea73dSAndreas Gohr if ($next['type'] === 'hotfix') { 97290ea73dSAndreas Gohr $next['update'] = floatval($current['update']) + 0.1; 98290ea73dSAndreas Gohr $next['codename'] = $current['codename']; 99290ea73dSAndreas Gohr $next['date'] = $current['date']; 100290ea73dSAndreas Gohr $next['hotfix'] = $this->increaseHotfix($current['hotfix']); 101290ea73dSAndreas Gohr } else { 102290ea73dSAndreas Gohr $next['update'] = intval($current['update']) + 1; 103290ea73dSAndreas Gohr } 104290ea73dSAndreas Gohr 105290ea73dSAndreas Gohr if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $next['date'])) { 106290ea73dSAndreas Gohr throw new \splitbrain\phpcli\Exception('Invalid date format, use YYYY-MM-DD'); 107290ea73dSAndreas Gohr } 108290ea73dSAndreas Gohr 109290ea73dSAndreas Gohr if ($current['date'] > $next['date']) { 110290ea73dSAndreas Gohr throw new \splitbrain\phpcli\Exception('Date must be equal or later than the last release'); 111290ea73dSAndreas Gohr } 112290ea73dSAndreas Gohr 113290ea73dSAndreas Gohr if ($current['type'] === 'rc' && $next['type'] === 'hotfix') { 114290ea73dSAndreas Gohr throw new \splitbrain\phpcli\Exception( 115290ea73dSAndreas Gohr 'Cannot create hotfixes for release candidates, create a new RC instead' 116290ea73dSAndreas Gohr ); 117290ea73dSAndreas Gohr } 118290ea73dSAndreas Gohr 119290ea73dSAndreas Gohr if ($current['type'] === 'stable' && $next['type'] !== 'hotfix' && $current['codename'] === $next['codename']) { 120290ea73dSAndreas Gohr throw new \splitbrain\phpcli\Exception('Codename must be different from the last release'); 121290ea73dSAndreas Gohr } 122290ea73dSAndreas Gohr 123290ea73dSAndreas Gohr $next['version'] = $next['date'] . ($next['type'] === 'rc' ? 'rc' : $next['hotfix']); 124290ea73dSAndreas Gohr $next['raw'] = ($next['type'] === 'rc' ? 'rc' : '') . 125290ea73dSAndreas Gohr $next['date'] . 126290ea73dSAndreas Gohr $next['hotfix'] . 127290ea73dSAndreas Gohr ' "' . $next['codename'] . '"'; 128290ea73dSAndreas Gohr 129290ea73dSAndreas Gohr // output to be piped into GITHUB_ENV 130290ea73dSAndreas Gohr foreach ($current as $k => $v) { 131290ea73dSAndreas Gohr echo "current_$k=$v\n"; 132290ea73dSAndreas Gohr } 133290ea73dSAndreas Gohr foreach ($next as $k => $v) { 134290ea73dSAndreas Gohr echo "next_$k=$v\n"; 135290ea73dSAndreas Gohr } 136290ea73dSAndreas Gohr } 137290ea73dSAndreas Gohr 138290ea73dSAndreas Gohr /** 139290ea73dSAndreas Gohr * Get current version info from local VERSION file 140290ea73dSAndreas Gohr * 141290ea73dSAndreas Gohr * @return string[] 142290ea73dSAndreas Gohr */ 143290ea73dSAndreas Gohr protected function getLocalVersion() 144290ea73dSAndreas Gohr { 145290ea73dSAndreas Gohr $versioninfo = \dokuwiki\Info::parseVersionString(trim(file_get_contents('VERSION'))); 146290ea73dSAndreas Gohr $doku = file_get_contents('doku.php'); 147290ea73dSAndreas Gohr if (!preg_match('/\$updateVersion = "(\d+(\.\d+)?)";/', $doku, $m)) { 148290ea73dSAndreas Gohr throw new \Exception('Could not find $updateVersion in doku.php'); 149290ea73dSAndreas Gohr } 150290ea73dSAndreas Gohr $versioninfo['update'] = floatval($m[1]); 151290ea73dSAndreas Gohr return $versioninfo; 152290ea73dSAndreas Gohr } 153290ea73dSAndreas Gohr 154290ea73dSAndreas Gohr /** 155290ea73dSAndreas Gohr * Get current version info from stable branch 156290ea73dSAndreas Gohr * 157290ea73dSAndreas Gohr * @return string[] 158290ea73dSAndreas Gohr * @throws Exception 159290ea73dSAndreas Gohr */ 160290ea73dSAndreas Gohr protected function getUpstreamVersion() 161290ea73dSAndreas Gohr { 162290ea73dSAndreas Gohr // basic version info 163290ea73dSAndreas Gohr $versioninfo = \dokuwiki\Info::parseVersionString(trim(file_get_contents($this->BASERAW . 'VERSION'))); 164290ea73dSAndreas Gohr 165290ea73dSAndreas Gohr // update version grepped from the doku.php file 166290ea73dSAndreas Gohr $doku = file_get_contents($this->BASERAW . 'doku.php'); 167290ea73dSAndreas Gohr if (!preg_match('/\$updateVersion = "(\d+(\.\d+)?)";/', $doku, $m)) { 168290ea73dSAndreas Gohr throw new \Exception('Could not find $updateVersion in doku.php'); 169290ea73dSAndreas Gohr } 170290ea73dSAndreas Gohr $versioninfo['update'] = floatval($m[1]); 171290ea73dSAndreas Gohr 172290ea73dSAndreas Gohr return $versioninfo; 173290ea73dSAndreas Gohr } 174290ea73dSAndreas Gohr 175290ea73dSAndreas Gohr /** 176290ea73dSAndreas Gohr * Increase the hotfix letter 177290ea73dSAndreas Gohr * 178290ea73dSAndreas Gohr * (max 26 hotfixes) 179290ea73dSAndreas Gohr * 180290ea73dSAndreas Gohr * @param string $hotfix 181290ea73dSAndreas Gohr * @return string 182290ea73dSAndreas Gohr */ 183290ea73dSAndreas Gohr protected function increaseHotfix($hotfix) 184290ea73dSAndreas Gohr { 185290ea73dSAndreas Gohr if (empty($hotfix)) return 'a'; 186290ea73dSAndreas Gohr return substr($hotfix, 0, -1) . chr(ord($hotfix) + 1); 187290ea73dSAndreas Gohr } 188290ea73dSAndreas Gohr} 189290ea73dSAndreas Gohr 190290ea73dSAndreas Gohr(new Release())->run(); 191