xref: /dokuwiki/.github/release.php (revision 017f2aa27bddfec183008cd45bcabe32599bc2c3)
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