-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(endpoint): add a new "/latest" endpoint
Allows to retrieve latest version number for a specific channel Signed-off-by: Benjamin Gaussorgues <[email protected]>
- Loading branch information
Showing
4 changed files
with
214 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
# Rewrite all requests to "index.php" | ||
# Rewrite all requests to "index.php" except for latest | ||
|
||
DirectoryIndex index.php | ||
RewriteEngine On | ||
|
||
RewriteRule ^latest(?|$) latest.php [L] | ||
RewriteRule ^ index.php [L] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?php | ||
declare(strict_types = 1); | ||
require_once __DIR__.'/build/utils.php'; | ||
|
||
// Send headers | ||
header('Content-Type: application/json'); | ||
header('X-Frame-Options: DENY'); | ||
header('X-XSS-Protection: 1; mode=block'); | ||
header('X-Content-Type-Options: nosniff'); | ||
header('X-Robots-Tag: none'); | ||
header('Content-Security-Policy: default-src \'none\';'); | ||
|
||
$channel = $_GET['channel'] ?? 'stable'; | ||
$phpVersion = $_GET['php'] ?? ''; | ||
if (!preg_match('/^\d{1,2}\.\d{1,2}(?:\.\d{1,2}(?: \w{,20})?)?$|^$/', $phpVersion)){ | ||
http_response_code(400); | ||
echo json_encode(['error' => 'Invalid PHP version provided']); | ||
exit; | ||
} | ||
|
||
if (!in_array($channel, ['stable', 'beta', 'enterprise'])) { | ||
http_response_code(400); | ||
echo json_encode(['error' => 'Invalid channel provided']); | ||
exit; | ||
} | ||
|
||
// Filter suitable major versions | ||
$majorVersions = loadJson('major_versions'); | ||
try { | ||
$enterpriseMajorVersions = loadJson('enterprise_major_versions'); | ||
foreach($majorVersions as $name => $version) { | ||
if (isset($enterpriseMajorVersions[$name])) { | ||
$majorVersions[$name] = array_merge($version, $enterpriseMajorVersions[$name]); | ||
} | ||
} | ||
$majorVersions = array_replace_recursive($majorVersions + $enterpriseMajorVersions); | ||
} catch (\Exception) { | ||
if ($channel === 'enterprise') { | ||
http_response_code(400); | ||
echo json_encode(['error' => 'Invalid channel provided']); | ||
exit; | ||
} | ||
} | ||
|
||
if ($phpVersion) { | ||
$majorVersions = array_filter($majorVersions, static function ($release) use ($phpVersion) { | ||
return version_compare($release['minPHP'], $phpVersion, '<='); | ||
}); | ||
} | ||
|
||
if (empty($majorVersions)) { | ||
http_response_code(400); | ||
echo json_encode(['error' => 'No major version found for your version of PHP']); | ||
exit; | ||
} | ||
$suitableMajors = array_keys($majorVersions); | ||
|
||
// Filter suitable releases | ||
$allowedChannels = [$channel]; | ||
if ($channel === 'beta') { | ||
$allowedChannels[] = 'stable'; | ||
} | ||
$releases = loadJson($channel === 'enterprise' ? 'enterprise_releases' : 'releases'); | ||
$releases = array_filter($releases, function ($name) use ($allowedChannels, $suitableMajors) { | ||
return in_array(getStabilityFromName($name), $allowedChannels) | ||
&& preg_match('/^('.implode('|', $suitableMajors).')\./', $name); | ||
}, ARRAY_FILTER_USE_KEY); | ||
uksort($releases, static fn($a, $b) => version_compare($a, $b, '<')); | ||
if (empty($releases)) { | ||
http_response_code(400); | ||
echo json_encode(['error' => 'No version found for your version of PHP']); | ||
exit; | ||
} | ||
// Show latest | ||
$release = key($releases); | ||
$info = current($releases); | ||
echo json_encode([ | ||
'version' => $release, | ||
'url' => buildDownloadUrl($release, $info, $majorVersions[explode('.', $release)[0]]), | ||
], JSON_UNESCAPED_SLASHES); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
Feature: Testing the latest endpoint | ||
|
||
Scenario: Get latest stable version | ||
Given I want to know the latest stable release | ||
When I send a request latest.php | ||
Then The JSON response is non-empty | ||
And Version "30.0.5" is the latest release | ||
And URL to download is "https://download.nextcloud.com/server/releases/nextcloud-30.0.5.zip" | ||
|
||
Scenario: Get latest beta version | ||
Given I want to know the latest beta release | ||
When I send a request latest.php | ||
Then The JSON response is non-empty | ||
And Version "31.0.0 beta 5" is the latest release | ||
And URL to download is "https://download.nextcloud.com/server/prereleases/nextcloud-31.0.0beta5.zip" | ||
|
||
Scenario: Get latest stable version with PHP 8.0 | ||
Given I want to know the latest stable release | ||
And I use PHP "8.0" | ||
When I send a request latest.php | ||
Then The JSON response is non-empty | ||
And Version "29.0.11" is the latest release | ||
And URL to download is "https://download.nextcloud.com/server/releases/nextcloud-29.0.11.zip" | ||
|
||
Scenario: Get latest beta version with PHP 8.0 | ||
Given I want to know the latest beta release | ||
And I use PHP "8.0" | ||
When I send a request latest.php | ||
Then The JSON response is non-empty | ||
And Version "29.0.11" is the latest release | ||
And URL to download is "https://download.nextcloud.com/server/releases/nextcloud-29.0.11.zip" | ||
|
||
Scenario: Get latest version with invalid PHP version | ||
Given I want to know the latest beta release | ||
And I use PHP "test" | ||
When I send a request latest.php | ||
Then The JSON response is non-empty | ||
And I get error "Invalid PHP version provided" | ||
|
||
Scenario: Get latest version with too old PHP version | ||
Given I want to know the latest beta release | ||
And I use PHP "5.0" | ||
When I send a request latest.php | ||
Then The JSON response is non-empty | ||
And I get error "No major version found for your version of PHP" | ||
|
||
Scenario: Get latest version with invalid channel | ||
Given I want to know the latest whatever release | ||
When I send a request latest.php | ||
Then The JSON response is non-empty | ||
And I get error "Invalid channel provided" | ||
|