diff --git a/src/Runtimes/Runtime.php b/src/Runtimes/Runtime.php index 4bf630c..b196ce7 100644 --- a/src/Runtimes/Runtime.php +++ b/src/Runtimes/Runtime.php @@ -47,9 +47,9 @@ public function getKey(): string * * @param string[] $supports */ - public function addVersion(string $version, string $base, string $image, array $supports): void + public function addVersion(string $version, string $base, string $image, array $supports, bool $deprecated = false): void { - $this->versions[] = new Version($version, $base, $image, $supports); + $this->versions[] = new Version($version, $base, $image, $supports, $deprecated); } /** diff --git a/src/Runtimes/Runtimes.php b/src/Runtimes/Runtimes.php index 4653c4d..c4d449e 100644 --- a/src/Runtimes/Runtimes.php +++ b/src/Runtimes/Runtimes.php @@ -5,6 +5,27 @@ use Exception; use Utopia\System\System; +/** + * Useful resources: + * + * Overall: https://endoflife.date/ + * + * Node: https://nodejs.org/en/about/previous-releases + * PHP: https://www.php.net/supported-versions.php + * Ruby: https://www.ruby-lang.org/en/downloads/branches/ + * Python: https://devguide.python.org/versions/ + * Deno: https://docs.deno.com/runtime/fundamentals/stability_and_releases/ + * .NET: https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core + * Java: https://www.oracle.com/java/technologies/java-se-support-roadmap.html + * Dart: https://dart.dev/resources/whats-new + * Swift: https://github.com/swiftlang/swift-evolution + * Kotlin: https://kotlinlang.org/docs/releases.html#update-to-a-new-kotlin-version + * + * Dart: No official document, support last 6 versions (~1.5 years) (plus latest 2.x until 4.x releases) + * Deno: Technically, all 1.x is deprecated. Mark them deprecated overtime, not all at once. + * Swift: No official document, support last 4 versions (~2 years) + */ + class Runtimes { /** @var array */ @@ -20,8 +41,8 @@ public function __construct(string $version = '') $this->version = $version; $node = new Runtime('node', 'Node.js', 'sh helpers/server.sh'); - $node->addVersion('14.5', 'node:14.5.0-alpine3.12', 'openruntimes/node:'.$this->version.'-14.5', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); - $node->addVersion('16.0', 'node:16.20.2-alpine3.18', 'openruntimes/node:'.$this->version.'-16.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); + $node->addVersion('14.5', 'node:14.5.0-alpine3.12', 'openruntimes/node:'.$this->version.'-14.5', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); # Deprecated since April 30, 2023 + $node->addVersion('16.0', 'node:16.20.2-alpine3.18', 'openruntimes/node:'.$this->version.'-16.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); # Deprecated since September 11, 2023 $node->addVersion('18.0', 'node:18.20.4-alpine3.20', 'openruntimes/node:'.$this->version.'-18.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $node->addVersion('19.0', 'node:19.9.0-alpine3.18', 'openruntimes/node:'.$this->version.'-19.0', [System::X86, System::ARM64]); $node->addVersion('20.0', 'node:20.17.0-alpine3.20', 'openruntimes/node:'.$this->version.'-20.0', [System::X86, System::ARM64]); @@ -30,21 +51,21 @@ public function __construct(string $version = '') $this->runtimes['node'] = $node; $php = new Runtime('php', 'PHP', 'sh helpers/server.sh'); - $php->addVersion('8.0', 'php:8.0.30-cli-alpine3.16', 'openruntimes/php:'.$this->version.'-8.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); + $php->addVersion('8.0', 'php:8.0.30-cli-alpine3.16', 'openruntimes/php:'.$this->version.'-8.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); # Deprecated since November 26, 2023 $php->addVersion('8.1', 'php:8.1.30-cli-alpine3.20', 'openruntimes/php:'.$this->version.'-8.1', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $php->addVersion('8.2', 'php:8.2.24-cli-alpine3.20', 'openruntimes/php:'.$this->version.'-8.2', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $php->addVersion('8.3', 'php:8.3.12-cli-alpine3.20', 'openruntimes/php:'.$this->version.'-8.3', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $this->runtimes['php'] = $php; $ruby = new Runtime('ruby', 'Ruby', 'sh helpers/server.sh'); - $ruby->addVersion('3.0', 'ruby:3.0.7-alpine3.16', 'openruntimes/ruby:'.$this->version.'-3.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); + $ruby->addVersion('3.0', 'ruby:3.0.7-alpine3.16', 'openruntimes/ruby:'.$this->version.'-3.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); # Deprecated since April 23, 2024 $ruby->addVersion('3.1', 'ruby:3.1.6-alpine3.20', 'openruntimes/ruby:'.$this->version.'-3.1', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $ruby->addVersion('3.2', 'ruby:3.2.5-alpine3.20', 'openruntimes/ruby:'.$this->version.'-3.2', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $ruby->addVersion('3.3', 'ruby:3.3.5-alpine3.20', 'openruntimes/ruby:'.$this->version.'-3.3', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $this->runtimes['ruby'] = $ruby; $python = new Runtime('python', 'Python', 'sh helpers/server.sh'); - $python->addVersion('3.8', 'python:3.8.20-alpine3.20', 'openruntimes/python:'.$this->version.'-3.8', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); + $python->addVersion('3.8', 'python:3.8.20-alpine3.20', 'openruntimes/python:'.$this->version.'-3.8', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); // Deprecated since October 7, 2024 $python->addVersion('3.9', 'python:3.9.20-alpine3.20', 'openruntimes/python:'.$this->version.'-3.9', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $python->addVersion('3.10', 'python:3.10.15-alpine3.20', 'openruntimes/python:'.$this->version.'-3.10', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $python->addVersion('3.11', 'python:3.11.10-alpine3.20', 'openruntimes/python:'.$this->version.'-3.11', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); @@ -56,20 +77,20 @@ public function __construct(string $version = '') $this->runtimes['python-ml'] = $pythonML; $deno = new Runtime('deno', 'Deno', 'sh helpers/server.sh'); - $deno->addVersion('1.21', 'denoland/deno:alpine-1.21.3', 'openruntimes/deno:'.$this->version.'-1.21', [System::X86]); - $deno->addVersion('1.24', 'denoland/deno:alpine-1.24.3', 'openruntimes/deno:'.$this->version.'-1.24', [System::X86]); - $deno->addVersion('1.35', 'denoland/deno:alpine-1.35.3', 'openruntimes/deno:'.$this->version.'-1.35', [System::X86]); + $deno->addVersion('1.21', 'denoland/deno:alpine-1.21.3', 'openruntimes/deno:'.$this->version.'-1.21', [System::X86], true); + $deno->addVersion('1.24', 'denoland/deno:alpine-1.24.3', 'openruntimes/deno:'.$this->version.'-1.24', [System::X86], true); + $deno->addVersion('1.35', 'denoland/deno:alpine-1.35.3', 'openruntimes/deno:'.$this->version.'-1.35', [System::X86], true); $deno->addVersion('1.40', 'denoland/deno:alpine-1.40.5', 'openruntimes/deno:'.$this->version.'-1.40', [System::X86, System::ARM64]); $deno->addVersion('1.46', 'denoland/deno:alpine-1.46.3', 'openruntimes/deno:'.$this->version.'-1.46', [System::X86, System::ARM64]); $deno->addVersion('2.0', 'denoland/deno:alpine-2.0.0-rc.5', 'openruntimes/deno:'.$this->version.'-2.0', [System::X86, System::ARM64]); $this->runtimes['deno'] = $deno; $dart = new Runtime('dart', 'Dart', 'sh helpers/server.sh'); - $dart->addVersion('2.15', 'dart:2.15.1', 'openruntimes/dart:'.$this->version.'-2.15', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); - $dart->addVersion('2.16', 'dart:2.16.2', 'openruntimes/dart:'.$this->version.'-2.16', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); - $dart->addVersion('2.17', 'dart:2.17.7', 'openruntimes/dart:'.$this->version.'-2.17', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); + $dart->addVersion('2.15', 'dart:2.15.1', 'openruntimes/dart:'.$this->version.'-2.15', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); + $dart->addVersion('2.16', 'dart:2.16.2', 'openruntimes/dart:'.$this->version.'-2.16', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); + $dart->addVersion('2.17', 'dart:2.17.7', 'openruntimes/dart:'.$this->version.'-2.17', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); $dart->addVersion('2.18', 'dart:2.18.7', 'openruntimes/dart:'.$this->version.'-2.18', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); - $dart->addVersion('2.18', 'dart:2.19.6', 'openruntimes/dart:'.$this->version.'-2.19', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); + $dart->addVersion('2.19', 'dart:2.19.6', 'openruntimes/dart:'.$this->version.'-2.19', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $dart->addVersion('3.0', 'dart:3.0.7', 'openruntimes/dart:'.$this->version.'-3.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $dart->addVersion('3.1', 'dart:3.1.5', 'openruntimes/dart:'.$this->version.'-3.1', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $dart->addVersion('3.3', 'dart:3.3.4', 'openruntimes/dart:'.$this->version.'-3.3', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); @@ -77,8 +98,8 @@ public function __construct(string $version = '') $this->runtimes['dart'] = $dart; $dotnet = new Runtime('dotnet', '.NET', 'sh helpers/server.sh'); - $dotnet->addVersion('6.0', 'mcr.microsoft.com/dotnet/sdk:6.0.425-alpine3.19', 'openruntimes/dotnet:'.$this->version.'-6.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); - $dotnet->addVersion('7.0', 'mcr.microsoft.com/dotnet/sdk:7.0.410-alpine3.19', 'openruntimes/dotnet:'.$this->version.'-7.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); + $dotnet->addVersion('6.0', 'mcr.microsoft.com/dotnet/sdk:6.0.425-alpine3.19', 'openruntimes/dotnet:'.$this->version.'-6.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); // Deprecated since November 12, 2024 + $dotnet->addVersion('7.0', 'mcr.microsoft.com/dotnet/sdk:7.0.410-alpine3.19', 'openruntimes/dotnet:'.$this->version.'-7.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); // Deprecated since May 14, 2024 $dotnet->addVersion('8.0', 'mcr.microsoft.com/dotnet/sdk:8.0.402-alpine3.19', 'openruntimes/dotnet:'.$this->version.'-8.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $this->runtimes['dotnet'] = $dotnet; @@ -86,19 +107,20 @@ public function __construct(string $version = '') $java->addVersion('8.0', 'eclipse-temurin:8-jdk-jammy', 'openruntimes/java:'.$this->version.'-8.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $java->addVersion('11.0', 'eclipse-temurin:11-jdk-jammy', 'openruntimes/java:'.$this->version.'-11.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $java->addVersion('17.0', 'eclipse-temurin:17-jdk-jammy', 'openruntimes/java:'.$this->version.'-17.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); - $java->addVersion('18.0', 'eclipse-temurin:18-jdk-jammy', 'openruntimes/java:'.$this->version.'-18.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); + $java->addVersion('18.0', 'eclipse-temurin:18-jdk-jammy', 'openruntimes/java:'.$this->version.'-18.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); // Deprecated since September 20, 2022 $java->addVersion('21.0', 'eclipse-temurin:21-jdk-jammy', 'openruntimes/java:'.$this->version.'-21.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); - $java->addVersion('22', 'eclipse-temurin:22-jdk-jammy', 'openruntimes/java:'.$this->version.'-22', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); + $java->addVersion('22', 'eclipse-temurin:22-jdk-jammy', 'openruntimes/java:'.$this->version.'-22', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); // Technically deprecated, but latest. Keeping active $this->runtimes['java'] = $java; $swift = new Runtime('swift', 'Swift', 'sh helpers/server.sh'); + $swift->addVersion('5.5', 'swiftarm/swift:5.5.3-ubuntu-jammy', 'openruntimes/swift:'.$this->version.'-5.5', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); $swift->addVersion('5.8', 'swiftarm/swift:5.8.1-ubuntu-22.04', 'openruntimes/swift:'.$this->version.'-5.8', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $swift->addVersion('5.9', 'swiftarm/swift:5.9.2-ubuntu-22.04', 'openruntimes/swift:'.$this->version.'-5.9', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $swift->addVersion('5.10', 'swiftarm/swift:5.10-ubuntu-22.04', 'openruntimes/swift:'.$this->version.'-5.10', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $this->runtimes['swift'] = $swift; $kotlin = new Runtime('kotlin', 'Kotlin', 'sh helpers/server.sh'); - $kotlin->addVersion('1.6', 'eclipse-temurin:18-jdk-alpine', 'openruntimes/kotlin:'.$this->version.'-1.6', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); + $kotlin->addVersion('1.6', 'eclipse-temurin:18-jdk-alpine', 'openruntimes/kotlin:'.$this->version.'-1.6', [System::X86, System::ARM64, System::ARMV7, System::ARMV8], true); $kotlin->addVersion('1.8', 'eclipse-temurin:19-jdk-alpine', 'openruntimes/kotlin:'.$this->version.'-1.8', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $kotlin->addVersion('1.9', 'eclipse-temurin:19-jdk-alpine', 'openruntimes/kotlin:'.$this->version.'-1.9', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); $kotlin->addVersion('2.0', 'eclipse-temurin:22-jdk-alpine', 'openruntimes/kotlin:'.$this->version.'-2.0', [System::X86, System::ARM64, System::ARMV7, System::ARMV8]); @@ -155,19 +177,36 @@ public function get(string $key): Runtime * Returns all supported runtimes. * * @param bool $supported Pass `false` to also return unsupported CPU architecture. + * @param bool $deprecated Pass `false` to filter out deprecated versions from runtimes * @param array $filter * @return array */ - public function getAll(bool $supported = true, array $filter = []): array + public function getAll(bool $supported = true, array $filter = [], $deprecated = true): array { $supportedRuntimes = []; foreach ($this->runtimes as $runtime) { - $supportedRuntimes = array_merge(array_reverse(array_filter($runtime->list(), function (array $version, string $key) use ($supported, $filter) { + $supportedRuntimes = array_merge(array_reverse(array_filter($runtime->list(), function (array $version, string $key) use ($supported, $filter, $deprecated) { $isSupported = in_array(System::getArchEnum(), $version['supports']); $isFiltered = in_array($key, $filter); + $isDeprecated = $version['deprecated']; + + // Apply supported filter + if ($supported && !$isSupported) { + return false; + } + + // Apply version filter + if (\count($filter) > 0 && !$isFiltered) { + return false; + } + + // Apply deprecation filter + if (!$deprecated && $isDeprecated) { + return false; + } - return $supported ? ($isSupported && ($filter ? $isFiltered : true)) : true; + return true; }, ARRAY_FILTER_USE_BOTH)), $supportedRuntimes); } diff --git a/src/Runtimes/Version.php b/src/Runtimes/Version.php index 4b06ac8..f7a0a48 100644 --- a/src/Runtimes/Version.php +++ b/src/Runtimes/Version.php @@ -18,23 +18,26 @@ class Version */ public array $supports; + public bool $deprecated; + /** * Version class that holds metadata about a Runtime Version. * * @param array $supports */ - public function __construct(string $version, string $base, string $image, array $supports) + public function __construct(string $version, string $base, string $image, array $supports, bool $deprecated = false) { $this->version = $version; $this->base = $base; $this->image = $image; $this->supports = $supports; + $this->deprecated = $deprecated; } /** * Get parsed Version. * - * @return (array|string)[] + * @return array */ public function get(): array { @@ -44,6 +47,7 @@ public function get(): array 'base' => $this->base, 'image' => $this->image, 'supports' => $this->supports, + 'deprecated' => $this->deprecated, ]; } } diff --git a/tests/Runtimes/RuntimesTest.php b/tests/Runtimes/RuntimesTest.php index 07a8c63..5281e38 100644 --- a/tests/Runtimes/RuntimesTest.php +++ b/tests/Runtimes/RuntimesTest.php @@ -167,6 +167,25 @@ public function testSupportedRuntimes(): void $this->assertCount(2, $this->instance->getAll(filter: ['node-14.5', 'node-16.0'])); } + public function testDeprecatedRuntimes(): void + { + $versions = $this->instance->getAll(); + $nodeDeprecated = $versions['node-14.5']; + $this->assertArrayHasKey('deprecated', $nodeDeprecated); + $this->assertTrue($nodeDeprecated['deprecated']); + + $nodeNonDeprecated = $versions['node-22']; + $this->assertArrayHasKey('deprecated', $nodeNonDeprecated); + $this->assertFalse($nodeNonDeprecated['deprecated']); + + $runtime = $this->instance->get('node'); + $this->assertArrayHasKey('deprecated', $runtime->list()["node-14.5"]); + $this->assertArrayHasKey('deprecated', $runtime->list()["node-22"]); + + $versions = $this->instance->getAll(deprecated: false); + $this->assertArrayNotHasKey('node-14.5', $versions); + } + public function testGetRuntimes(): void { foreach ($this->instance->getAll() as $runtime) {