Author: Shivam Mathur (shivammathur)
Date: 2026-04-10T14:18:11+05:30

Commit: 
https://github.com/php/web-downloads/commit/1b63e917f46c7f35763748821a1bbc253ca7564f
Raw diff: 
https://github.com/php/web-downloads/commit/1b63e917f46c7f35763748821a1bbc253ca7564f.diff

Promote series file on stable PHP releases

Changed paths:
  A  config/vs.json
  M  src/Console/Command/PhpCommand.php
  M  tests/Console/Command/PhpCommandTest.php


Diff:

diff --git a/config/vs.json b/config/vs.json
new file mode 100644
index 0000000..27ebb27
--- /dev/null
+++ b/config/vs.json
@@ -0,0 +1,14 @@
+{
+    "7.1": "vc14",
+    "7.2": "vc15",
+    "7.3": "vc15",
+    "7.4": "vc15",
+    "8.0": "vs16",
+    "8.1": "vs16",
+    "8.2": "vs16",
+    "8.3": "vs16",
+    "8.4": "vs17",
+    "8.5": "vs17",
+    "8.6": "vs17",
+    "master": "vs17"
+}
diff --git a/src/Console/Command/PhpCommand.php 
b/src/Console/Command/PhpCommand.php
index 5ba935c..e8df00b 100644
--- a/src/Console/Command/PhpCommand.php
+++ b/src/Console/Command/PhpCommand.php
@@ -77,6 +77,7 @@ public function handle(): int
                 unlink($filepath);
 
                 $destinationDirectory = 
$this->getDestinationDirectory($tempDirectory);
+                $version = $this->getBuildVersion($tempDirectory);
 
                 $this->moveBuild($tempDirectory, $destinationDirectory);
 
@@ -85,6 +86,8 @@ public function handle(): int
                 $this->updateReleasesJson->handle($releases, 
$destinationDirectory);
                 if ($destinationDirectory === $this->baseDirectory . 
'/releases') {
                     $this->updateLatestBuilds($releases, 
$destinationDirectory);
+                    $parts = explode('.', $version);
+                    $this->promoteSeriesFiles($parts[0] . '.' . $parts[1]);
                 }
 
                 Helpers::rmdirr($tempDirectory);
@@ -108,15 +111,25 @@ public function handle(): int
      * @throws Exception
      */
     private function getDestinationDirectory(string $tempDirectory): string
+    {
+        $version = $this->getBuildVersion($tempDirectory);
+        return $this->baseDirectory . (preg_match('/^\d+\.\d+\.\d+$/', 
$version) ? '/releases' : '/qa');
+    }
+
+    /**
+     * @throws Exception
+     */
+    private function getBuildVersion(string $tempDirectory): string
     {
         $testPackFiles = glob($tempDirectory . '/php-test-pack-*.zip');
         if(empty($testPackFiles)) {
             throw new Exception('No test pack found in the artifact');
         }
         $testPackFile = basename($testPackFiles[0]);
-        $testPackFileName = str_replace('.zip', '', $testPackFile);
-        $version = explode('-', $testPackFileName)[3];
-        return $this->baseDirectory . (preg_match('/^\d+\.\d+\.\d+$/', 
$version) ? '/releases' : '/qa');
+        if (!preg_match('/^php-test-pack-(.+)\.zip$/', $testPackFile, 
$matches)) {
+            throw new Exception('No test pack found in the artifact');
+        }
+        return $matches[1];
     }
 
     /**
@@ -170,6 +183,37 @@ private function getFileVersion(string $file): string
         return str_replace('.zip', '', $parts[0]);
     }
 
+    /**
+     * @throws Exception
+     */
+    private function promoteSeriesFiles(string $phpVersion): void
+    {
+        $vsVersions = json_decode(
+            file_get_contents(dirname(__DIR__, 3) . '/config/vs.json'),
+            true,
+            512,
+            JSON_THROW_ON_ERROR
+        );
+        if (!isset($vsVersions[$phpVersion])) {
+            throw new Exception('No VS version found for PHP ' . $phpVersion);
+        }
+        $vsVersion = $vsVersions[$phpVersion];
+
+        $baseDirectory = $this->baseDirectory . "/php-sdk/deps/series";
+
+        if (!is_dir($baseDirectory)) {
+            mkdir($baseDirectory, 0755, true);
+        }
+        foreach(['x86', 'x64'] as $arch) {
+            $sourceFile = $baseDirectory . '/packages-' . $phpVersion . '-' . 
$vsVersion . '-' . $arch . '-staging.txt';
+            $destinationFile = $baseDirectory . '/packages-' . $phpVersion . 
'-' . $vsVersion . '-' . $arch . '-stable.txt';
+            if(!file_exists($sourceFile)) {
+                throw new Exception($sourceFile . ' does not exist');
+            }
+            copy($sourceFile, $destinationFile);
+        }
+    }
+
     private function updateLatestBuilds($releases, $directory): void
     {
         if(!is_dir($directory . '/latest')) {
@@ -186,4 +230,4 @@ private function updateLatestBuilds($releases, $directory): 
void
             });
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/Console/Command/PhpCommandTest.php 
b/tests/Console/Command/PhpCommandTest.php
index ac090a0..5d984f5 100644
--- a/tests/Console/Command/PhpCommandTest.php
+++ b/tests/Console/Command/PhpCommandTest.php
@@ -23,9 +23,15 @@ protected function setUp(): void
         $this->baseDirectory = sys_get_temp_dir() . '/php_test_base';
         $this->buildsDirectory = sys_get_temp_dir() . '/builds';
 
+        Helpers::rmdirr($this->baseDirectory);
+        Helpers::rmdirr($this->buildsDirectory);
+
         mkdir($this->baseDirectory . '/releases/archives', 0755, true);
         mkdir($this->baseDirectory . '/qa/archives', 0755, true);
         mkdir($this->buildsDirectory . '/php', 0755, true);
+        mkdir($this->baseDirectory . '/php-sdk/deps/series', 0755, true);
+        file_put_contents($this->baseDirectory . 
'/php-sdk/deps/series/packages-8.4-vs17-x86-staging.txt', 'x86-staging');
+        file_put_contents($this->baseDirectory . 
'/php-sdk/deps/series/packages-8.4-vs17-x64-staging.txt', 'x64-staging');
     }
 
     protected function tearDown(): void
@@ -157,4 +163,36 @@ public function testCleanupAfterCommand(): void
         $tempDirectory = "/tmp/php-*";
         $this->assertEmpty(glob($tempDirectory));
     }
+
+    public function testStableReleasePromotesSeriesFiles(): void
+    {
+        $command = new PhpCommand(new GetListing(), new UpdateReleasesJson());
+        $command->setOption('base-directory', $this->baseDirectory);
+        $command->setOption('builds-directory', $this->buildsDirectory);
+
+        $this->stageBuilds(self::buildsProvider()[0][0], 
$this->buildsDirectory . '/php/test.zip');
+
+        $result = $command->handle();
+
+        $this->assertSame(0, $result);
+        $this->assertFileExists($this->baseDirectory . 
'/php-sdk/deps/series/packages-8.4-vs17-x86-stable.txt');
+        $this->assertFileExists($this->baseDirectory . 
'/php-sdk/deps/series/packages-8.4-vs17-x64-stable.txt');
+        $this->assertSame('x86-staging', 
file_get_contents($this->baseDirectory . 
'/php-sdk/deps/series/packages-8.4-vs17-x86-stable.txt'));
+        $this->assertSame('x64-staging', 
file_get_contents($this->baseDirectory . 
'/php-sdk/deps/series/packages-8.4-vs17-x64-stable.txt'));
+    }
+
+    public function testQaReleaseDoesNotPromoteSeriesFiles(): void
+    {
+        $command = new PhpCommand(new GetListing(), new UpdateReleasesJson());
+        $command->setOption('base-directory', $this->baseDirectory);
+        $command->setOption('builds-directory', $this->buildsDirectory);
+
+        $this->stageBuilds(self::buildsProvider()[1][0], 
$this->buildsDirectory . '/php/test.zip');
+
+        $result = $command->handle();
+
+        $this->assertSame(0, $result);
+        $this->assertFileDoesNotExist($this->baseDirectory . 
'/php-sdk/deps/series/packages-8.4-vs17-x86-stable.txt');
+        $this->assertFileDoesNotExist($this->baseDirectory . 
'/php-sdk/deps/series/packages-8.4-vs17-x64-stable.txt');
+    }
 }

Reply via email to