Skip to content

Commit c5be279

Browse files
authored
fix: Fix the RootVersionChecker (#790)
1 parent 6b26e99 commit c5be279

File tree

9 files changed

+285
-164
lines changed

9 files changed

+285
-164
lines changed

.github/workflows/composer-root-version.yaml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,25 @@ jobs:
2424
php-version: "${{ matrix.php }}"
2525
tools: composer
2626

27+
# https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#setting-an-environment-variable
28+
- name: Configure composer root version
29+
run: |
30+
source .composer-root-version
31+
echo "COMPOSER_ROOT_VERSION=${COMPOSER_ROOT_VERSION}" >> $GITHUB_ENV
32+
33+
- name: Install the Composer (root) dependencies
34+
uses: ramsey/composer-install@v2
35+
36+
- name: Ensure that the root dependencies are updated correctly
37+
run: make vendor_install
38+
2739
- name: Install PHP-CS-Fixer
2840
uses: ramsey/composer-install@v2
2941
with:
3042
working-directory: 'vendor-bin/php-cs-fixer'
31-
tools: composer
3243

33-
- name: Ensures the makefile does not remake the PHP-CS-Fixer target
34-
run: touch -c vendor-bin/php-cs-fixer/vendor/friendsofphp/php-cs-fixer/php-cs-fixer
44+
- name: Ensure that PHP-CS-Fixer dependencies are updated correctly
45+
run: make install_php_cs_fixer
3546

3647
- name: Install the Composer dependencies
3748
uses: ramsey/composer-install@v2

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,9 @@ vendor-bin/covers-validator/composer.lock: vendor-bin/covers-validator/composer.
545545
@echo "$(@) is not up to date. You may want to run the following command:"
546546
@echo "$$ composer bin covers-validator update --lock && touch -c $(@)"
547547

548+
.PHONY: install_php_cs_fixer
549+
install_php_cs_fixer: $(PHP_CS_FIXER_BIN)
550+
548551
$(PHP_CS_FIXER_BIN): vendor-bin/php-cs-fixer/vendor
549552
touch -c $@
550553
vendor-bin/php-cs-fixer/vendor: vendor-bin/php-cs-fixer/composer.lock $(COMPOSER_BIN_PLUGIN_VENDOR)

composer-root-version-checker/src/Checker.php

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,31 @@ public static function check(): int
2525
$fetcher = new TagFetcher($logger);
2626

2727
try {
28-
$expectedComposerRootVersion = $fetcher->fetchLastTag();
28+
$lastTag = $fetcher->fetchLastTag();
29+
} catch (CouldNotParseTag $couldNotParseTag) {
30+
$logger->notice(
31+
sprintf(
32+
'Skipped: %s',
33+
$couldNotParseTag->getMessage(),
34+
),
35+
);
36+
37+
// This is the GitHub API playing tricks on us... I could not find a way to reliably fix it so it is just better
38+
// to avoid bailing out because of it for now.
39+
return 0;
2940
} catch (RuntimeException $couldNotFetchTag) {
3041
if (false !== getenv('PHP_SCOPER_GITHUB_TOKEN') && false === getenv('GITHUB_TOKEN')) {
31-
$logger->info('Skipped.');
42+
$logger->info('Skipped: not GitHub token configured. Export the environment variable "PHP_SCOPER_GITHUB_TOKEN" or "GITHUB_TOKEN" to fix this.');
3243

3344
// Ignore this PR to avoid too many builds to fail untimely or locally due to API rate limits because the last
3445
// release version could not be retrieved.
3546
return 0;
3647
}
3748

38-
if (100 === $couldNotFetchTag->getCode()) {
39-
$logger->info('Skipped.');
40-
41-
// This is the GitHub API playing tricks on us... I could not find a way to reliably fix it so it is just better
42-
// to avoid bailing out because of it for now.
43-
return 0;
44-
}
45-
4649
throw $couldNotFetchTag;
4750
}
4851

52+
$expectedComposerRootVersion = VersionCalculator::calculateDesiredVersion($lastTag);
4953
$currentRootVersion = RootVersionProvider::provideCurrentVersion();
5054

5155
if ($expectedComposerRootVersion === $currentRootVersion) {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the humbug/php-scoper package.
7+
*
8+
* Copyright (c) 2017 Théo FIDRY <[email protected]>,
9+
* Pádraic Brady <[email protected]>
10+
*
11+
* For the full copyright and license information, please view the LICENSE
12+
* file that was distributed with this source code.
13+
*/
14+
15+
namespace Humbug\PhpScoperComposerRootChecker;
16+
17+
use RuntimeException;
18+
use function sprintf;
19+
use const PHP_EOL;
20+
21+
final class CouldNotParseTag extends RuntimeException
22+
{
23+
public static function noTagFound(
24+
string $content
25+
): self {
26+
return new self(
27+
sprintf(
28+
'No tag could be found in: "%s".',
29+
$content,
30+
),
31+
);
32+
}
33+
34+
public static function noNameTagFound(
35+
string $content
36+
): self {
37+
return new self(
38+
sprintf(
39+
'No tag name could be found in:%s"%s".',
40+
PHP_EOL,
41+
$content,
42+
),
43+
);
44+
}
45+
46+
public static function withReason(
47+
null|bool|int|float|string $tag,
48+
string $reason
49+
): self {
50+
return new self(
51+
sprintf(
52+
'Could not parse the tag "%s": %s',
53+
$tag,
54+
$reason,
55+
),
56+
);
57+
}
58+
}

composer-root-version-checker/src/Dumper.php

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,32 @@ public static function dump(): void
3232
$fetcher = new TagFetcher($logger);
3333

3434
try {
35-
$composerRootVersion = $fetcher->fetchLastTag();
35+
$lastTag = $fetcher->fetchLastTag();
36+
} catch (CouldNotParseTag $couldNotParseTag) {
37+
$logger->notice(
38+
sprintf(
39+
'Skipped: %s',
40+
$couldNotParseTag->getMessage(),
41+
),
42+
);
43+
44+
// This is the GitHub API playing tricks on us... I could not find a way to reliably fix it so it is just better
45+
// to avoid bailing out because of it for now.
46+
return;
3647
} catch (RuntimeException $couldNotFetchTag) {
37-
if (false !== getenv('TRAVIS') && false === getenv('GITHUB_TOKEN')) {
38-
$logger->info('Skipped.');
48+
if (false !== getenv('PHP_SCOPER_GITHUB_TOKEN') && false === getenv('GITHUB_TOKEN')) {
49+
$logger->info('Skipped: not GitHub token configured. Export the environment variable "PHP_SCOPER_GITHUB_TOKEN" or "GITHUB_TOKEN" to fix this.');
3950

4051
// Ignore this PR to avoid too many builds to fail untimely or locally due to API rate limits because the last
4152
// release version could not be retrieved.
4253
return;
4354
}
4455

45-
if (100 === $couldNotFetchTag->getCode()) {
46-
$logger->info('Skipped.');
47-
48-
// This is the GitHub API playing tricks on us... I could not find a way to reliably fix it so it is just better
49-
// to avoid bailing out because of it for now.
50-
return;
51-
}
52-
5356
throw $couldNotFetchTag;
5457
}
5558

59+
$composerRootVersion = VersionCalculator::calculateDesiredVersion($lastTag);
60+
5661
file_put_contents(
5762
self::COMPOSER_ROOT_VERSION_PATH,
5863
sprintf(

composer-root-version-checker/src/TagParser.php

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,61 +14,65 @@
1414

1515
namespace Humbug\PhpScoperComposerRootChecker;
1616

17-
use RuntimeException;
17+
use JsonException;
1818
use function current;
19+
use function get_debug_type;
1920
use function is_array;
2021
use function is_string;
2122
use function Safe\json_decode;
23+
use function Safe\json_encode;
2224
use function sprintf;
2325
use function trim;
26+
use const JSON_PRETTY_PRINT;
2427

2528
final class TagParser
2629
{
2730
public static function parse(string $responseContent): string
2831
{
29-
$decodedContent = json_decode(
30-
$responseContent,
31-
false,
32-
512,
33-
JSON_PRETTY_PRINT & JSON_THROW_ON_ERROR,
34-
);
32+
try {
33+
$decodedContent = json_decode(
34+
$responseContent,
35+
false,
36+
512,
37+
JSON_PRETTY_PRINT & JSON_THROW_ON_ERROR,
38+
);
39+
} catch (JsonException) {
40+
throw CouldNotParseTag::noTagFound($responseContent);
41+
}
3542

3643
if (!is_array($decodedContent)) {
37-
throw new RuntimeException(
38-
sprintf(
39-
'No tag name could be found in: %s',
40-
$responseContent,
41-
),
42-
100,
43-
);
44+
throw CouldNotParseTag::noTagFound($responseContent);
4445
}
4546

4647
$lastReleaseInfo = current($decodedContent);
4748

4849
if (false === $lastReleaseInfo) {
49-
throw new RuntimeException(
50-
sprintf(
51-
'No tag name could be found in: %s',
52-
$responseContent,
53-
),
54-
100,
55-
);
50+
throw CouldNotParseTag::noTagFound($responseContent);
51+
}
52+
53+
if (!isset($lastReleaseInfo->name)) {
54+
throw CouldNotParseTag::noNameTagFound(json_encode($lastReleaseInfo, JSON_PRETTY_PRINT));
5655
}
5756

58-
if (!($lastReleaseInfo->name) || !is_string($lastReleaseInfo->name)) {
59-
throw new RuntimeException(
57+
$tagName = $lastReleaseInfo->name;
58+
59+
if (!is_string($tagName)) {
60+
throw CouldNotParseTag::withReason(
61+
$tagName,
6062
sprintf(
61-
'No tag name could be found in: %s',
62-
$responseContent,
63+
'Expected the tag to be a non-blank string, got "%s".',
64+
get_debug_type($tagName),
6365
),
64-
100,
6566
);
6667
}
6768

68-
$lastRelease = trim($lastReleaseInfo->name);
69+
$lastRelease = trim($tagName);
6970

7071
if ('' === $lastRelease) {
71-
throw new RuntimeException('Invalid tag name found.');
72+
throw CouldNotParseTag::withReason(
73+
$tagName,
74+
'Expected the tag to be a non-blank string, got an empty string.',
75+
);
7276
}
7377

7478
return $lastRelease;

composer-root-version-checker/src/VersionCalculator.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,36 @@
1414

1515
namespace Humbug\PhpScoperComposerRootChecker;
1616

17+
use function str_contains;
18+
use function strtolower;
19+
1720
final class VersionCalculator
1821
{
1922
public static function calculateDesiredVersion(string $tag): string
2023
{
2124
$tagParts = explode('.', $tag);
25+
$desiredVersionParts = [];
26+
27+
foreach ($tagParts as $tagPart) {
28+
$normalizedPart = strtolower($tagPart);
29+
30+
if (str_contains($normalizedPart, 'rc')
31+
|| str_contains($normalizedPart, 'alpha')
32+
|| str_contains($normalizedPart, 'beta')
33+
) {
34+
$desiredVersionParts[] = '99';
35+
36+
return implode('.', $desiredVersionParts);
37+
}
38+
39+
$desiredVersionParts[] = $tagPart;
40+
}
2241

23-
array_pop($tagParts);
42+
array_pop($desiredVersionParts);
2443

25-
$tagParts[] = '99';
44+
$desiredVersionParts[] = '99';
2645

27-
return implode('.', $tagParts);
46+
return implode('.', $desiredVersionParts);
2847
}
2948

3049
private function __construct()

0 commit comments

Comments
 (0)