Skip to content

Commit 120edf4

Browse files
authored
refactor: implement development versions for CodeIgniter::CI_VERSION (#9951)
* Refactor for better variable names * Replace `CodeIgniter::CI_VERSION` with dev version * Add auto review test * Change CI_VERSION * Fetch tags manually
1 parent 2fab00d commit 120edf4

File tree

3 files changed

+199
-42
lines changed

3 files changed

+199
-42
lines changed

admin/create-new-changelog.php

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,81 +9,90 @@ function replace_file_content(string $path, string $pattern, string $replace): v
99
file_put_contents($path, $output);
1010
}
1111

12-
// Main.
1312
chdir(__DIR__ . '/..');
1413

15-
if ($argc !== 3) {
16-
echo "Usage: php {$argv[0]} <current_version> <new_version>" . PHP_EOL;
17-
echo "E.g.,: php {$argv[0]} 4.4.3 4.4.4" . PHP_EOL;
14+
if (! isset($argv[1]) || ! isset($argv[2])) {
15+
echo "Usage: php {$argv[0]} <current_version> <new_version> [--dry-run]\n";
16+
echo "E.g. : php {$argv[0]} 4.4.3 4.4.4 --dry-run\n";
1817

1918
exit(1);
2019
}
2120

2221
// Gets version number from argument.
23-
$versionCurrent = $argv[1]; // e.g., '4.4.3'
24-
$versionCurrentParts = explode('.', $versionCurrent);
25-
$minorCurrent = $versionCurrentParts[0] . '.' . $versionCurrentParts[1];
26-
$version = $argv[2]; // e.g., '4.4.4'
27-
$versionParts = explode('.', $version);
28-
$minor = $versionParts[0] . '.' . $versionParts[1];
29-
$isMinorUpdate = ($minorCurrent !== $minor);
30-
31-
// Creates a branch for release.
32-
if (! $isMinorUpdate) {
33-
system('git switch develop');
22+
$currentVersion = $argv[1]; // e.g., '4.4.3'
23+
$currentVersionParts = explode('.', $currentVersion, 3);
24+
$currentMinorVersion = $currentVersionParts[0] . '.' . $currentVersionParts[1];
25+
$newVersion = $argv[2]; // e.g., '4.4.4'
26+
$newVersionParts = explode('.', $newVersion, 3);
27+
$newMinorVersion = $newVersionParts[0] . '.' . $newVersionParts[1];
28+
$isMinorUpdate = $currentMinorVersion !== $newMinorVersion;
29+
30+
// Creates a branch for release
31+
if (! in_array('--dry-run', $argv, true)) {
32+
if (! $isMinorUpdate) {
33+
system('git switch develop');
34+
}
35+
36+
system("git switch -c docs-changelog-{$newVersion}");
37+
system("git switch docs-changelog-{$newVersion}");
3438
}
35-
system('git switch -c docs-changelog-' . $version);
36-
system('git switch docs-changelog-' . $version);
3739

3840
// Copy changelog
39-
$changelog = "./user_guide_src/source/changelogs/v{$version}.rst";
41+
$newChangelog = "./user_guide_src/source/changelogs/v{$newVersion}.rst";
4042
$changelogIndex = './user_guide_src/source/changelogs/index.rst';
43+
4144
if ($isMinorUpdate) {
42-
copy('./admin/next-changelog-minor.rst', $changelog);
45+
copy('./admin/next-changelog-minor.rst', $newChangelog);
4346
} else {
44-
copy('./admin/next-changelog-patch.rst', $changelog);
47+
copy('./admin/next-changelog-patch.rst', $newChangelog);
4548
}
49+
50+
// Replace version in CodeIgniter.php to {version}-dev.
51+
replace_file_content(
52+
'./system/CodeIgniter.php',
53+
'/public const CI_VERSION = \'.*?\';/u',
54+
"public const CI_VERSION = '{$newVersion}-dev';",
55+
);
56+
4657
// Add changelog to index.rst.
4758
replace_file_content(
4859
$changelogIndex,
4960
'/\.\. toctree::\n :titlesonly:\n/u',
50-
".. toctree::\n :titlesonly:\n\n v{$version}",
61+
".. toctree::\n :titlesonly:\n\n v{$newVersion}",
5162
);
63+
5264
// Replace {version}
53-
$length = mb_strlen("Version {$version}");
54-
$underline = str_repeat('#', $length);
65+
$underline = str_repeat('#', mb_strlen("Version {$newVersion}"));
5566
replace_file_content(
56-
$changelog,
67+
$newChangelog,
5768
'/#################\nVersion {version}\n#################/u',
58-
"{$underline}\nVersion {$version}\n{$underline}",
59-
);
60-
replace_file_content(
61-
$changelog,
62-
'/{version}/u',
63-
"{$version}",
69+
"{$underline}\nVersion {$newVersion}\n{$underline}",
6470
);
71+
replace_file_content($newChangelog, '/{version}/u', $newVersion);
6572

6673
// Copy upgrading
67-
$versionWithoutDots = str_replace('.', '', $version);
68-
$upgrading = "./user_guide_src/source/installation/upgrade_{$versionWithoutDots}.rst";
74+
$versionWithoutDots = str_replace('.', '', $newVersion);
75+
$newUpgrading = "./user_guide_src/source/installation/upgrade_{$versionWithoutDots}.rst";
6976
$upgradingIndex = './user_guide_src/source/installation/upgrading.rst';
70-
copy('./admin/next-upgrading-guide.rst', $upgrading);
77+
copy('./admin/next-upgrading-guide.rst', $newUpgrading);
78+
7179
// Add upgrading to upgrading.rst.
7280
replace_file_content(
7381
$upgradingIndex,
7482
'/ backward_compatibility_notes\n/u',
7583
" backward_compatibility_notes\n\n upgrade_{$versionWithoutDots}",
7684
);
85+
7786
// Replace {version}
78-
$length = mb_strlen("Upgrading from {$versionCurrent} to {$version}");
79-
$underline = str_repeat('#', $length);
87+
$underline = str_repeat('#', mb_strlen("Upgrading from {$currentVersion} to {$newVersion}"));
8088
replace_file_content(
81-
$upgrading,
89+
$newUpgrading,
8290
'/##############################\nUpgrading from {version} to {version}\n##############################/u',
83-
"{$underline}\nUpgrading from {$versionCurrent} to {$version}\n{$underline}",
91+
"{$underline}\nUpgrading from {$currentVersion} to {$newVersion}\n{$underline}",
8492
);
8593

86-
// Commits
87-
system("git add {$changelog} {$changelogIndex}");
88-
system("git add {$upgrading} {$upgradingIndex}");
89-
system('git commit -m "docs: add changelog and upgrade for v' . $version . '"');
94+
if (! in_array('--dry-run', $argv, true)) {
95+
system("git add {$newChangelog} {$changelogIndex}");
96+
system("git add {$newUpgrading} {$upgradingIndex}");
97+
system("git commit -m \"docs: add changelog and upgrade for v{$newVersion}\"");
98+
}

system/CodeIgniter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class CodeIgniter
5555
/**
5656
* The current version of CodeIgniter Framework
5757
*/
58-
public const CI_VERSION = '4.7.0';
58+
public const CI_VERSION = '4.7.1-dev';
5959

6060
/**
6161
* App startup time.
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <admin@codeigniter.com>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\AutoReview;
15+
16+
use PHPUnit\Framework\Attributes\CoversNothing;
17+
use PHPUnit\Framework\Attributes\DataProvider;
18+
use PHPUnit\Framework\Attributes\Group;
19+
use PHPUnit\Framework\TestCase;
20+
21+
/**
22+
* @internal
23+
*/
24+
#[CoversNothing]
25+
#[Group('AutoReview')]
26+
final class CreateNewChangelogTest extends TestCase
27+
{
28+
private string $currentVersion;
29+
30+
public static function setUpBeforeClass(): void
31+
{
32+
parent::setUpBeforeClass();
33+
34+
if (getenv('GITHUB_ACTIONS') !== false) {
35+
exec('git fetch --unshallow 2>&1', $output, $exitCode);
36+
exec('git fetch --tags 2>&1', $output, $exitCode);
37+
38+
if ($exitCode !== 0) {
39+
self::fail(sprintf(
40+
"Failed to fetch git history and tags.\nOutput: %s",
41+
implode("\n", $output),
42+
));
43+
}
44+
}
45+
}
46+
47+
protected function setUp(): void
48+
{
49+
parent::setUp();
50+
51+
exec('git describe --tags --abbrev=0 2>&1', $output, $exitCode);
52+
53+
if ($exitCode !== 0) {
54+
$this->markTestSkipped(sprintf(
55+
"Unable to get the latest git tag.\nOutput: %s",
56+
implode("\n", $output),
57+
));
58+
}
59+
60+
// Current tag should already have the next patch docs done, so for testing purposes,
61+
// we will treat the next patch version as the current version.
62+
$this->currentVersion = $this->incrementVersion(trim($output[0], 'v'));
63+
}
64+
65+
#[DataProvider('provideCreateNewChangelog')]
66+
public function testCreateNewChangelog(string $mode): void
67+
{
68+
$currentVersion = $this->currentVersion;
69+
$newVersion = $this->incrementVersion($currentVersion, $mode);
70+
71+
exec(
72+
sprintf('php ./admin/create-new-changelog.php %s %s --dry-run', $currentVersion, $newVersion),
73+
$output,
74+
$exitCode,
75+
);
76+
77+
$this->assertSame(0, $exitCode, "Script exited with code {$exitCode}. Output: " . implode("\n", $output));
78+
79+
$this->assertStringContainsString(
80+
"public const CI_VERSION = '{$newVersion}-dev';",
81+
$this->getContents('./system/CodeIgniter.php'),
82+
);
83+
84+
$this->assertFileExists("./user_guide_src/source/changelogs/v{$newVersion}.rst");
85+
$this->assertStringContainsString(
86+
"Version {$newVersion}",
87+
$this->getContents("./user_guide_src/source/changelogs/v{$newVersion}.rst"),
88+
);
89+
$this->assertStringContainsString(
90+
"**{$newVersion} release of CodeIgniter4**",
91+
$this->getContents("./user_guide_src/source/changelogs/v{$newVersion}.rst"),
92+
);
93+
$this->assertStringContainsString(
94+
$newVersion,
95+
$this->getContents('./user_guide_src/source/changelogs/index.rst'),
96+
);
97+
98+
$versionWithoutDots = str_replace('.', '', $newVersion);
99+
$this->assertFileExists("./user_guide_src/source/installation/upgrade_{$versionWithoutDots}.rst");
100+
$this->assertStringContainsString(
101+
"Upgrading from {$currentVersion} to {$newVersion}",
102+
$this->getContents("./user_guide_src/source/installation/upgrade_{$versionWithoutDots}.rst"),
103+
);
104+
$this->assertStringContainsString(
105+
"upgrade_{$versionWithoutDots}",
106+
$this->getContents('./user_guide_src/source/installation/upgrading.rst'),
107+
);
108+
109+
// cleanup added and modified files
110+
exec('git restore .');
111+
exec('git clean -fd');
112+
}
113+
114+
/**
115+
* @return iterable<string, array{0: string}>
116+
*/
117+
public static function provideCreateNewChangelog(): iterable
118+
{
119+
yield 'patch update' => ['patch'];
120+
121+
yield 'minor update' => ['minor'];
122+
123+
yield 'major update' => ['major'];
124+
}
125+
126+
private function incrementVersion(string $version, string $mode = 'patch'): string
127+
{
128+
$parts = explode('.', $version);
129+
130+
return match ($mode) {
131+
'major' => sprintf('%d.0.0', ++$parts[0]),
132+
'minor' => sprintf('%d.%d.0', $parts[0], ++$parts[1]),
133+
'patch' => sprintf('%d.%d.%d', $parts[0], $parts[1], ++$parts[2]),
134+
default => $this->fail('Invalid version increment mode. Use "major", "minor", or "patch".'),
135+
};
136+
}
137+
138+
private function getContents(string $path): string
139+
{
140+
$contents = @file_get_contents($path);
141+
142+
if ($contents === false) {
143+
$this->fail("Failed to read file contents from {$path}.");
144+
}
145+
146+
return $contents;
147+
}
148+
}

0 commit comments

Comments
 (0)