Author: Shivam Mathur (shivammathur)
Date: 2025-11-19T00:04:04+05:30

Commit: 
https://github.com/php/web-downloads/commit/7b294549bbf926ba6c8620ea93e1959634f574de
Raw diff: 
https://github.com/php/web-downloads/commit/7b294549bbf926ba6c8620ea93e1959634f574de.diff

Add support to upload PECL deps

Changed paths:
  M  .github/workflows/winlibs.yml
  M  API.md
  M  src/Console/Command/WinlibsCommand.php
  M  src/Http/Controllers/WinlibsController.php
  M  tests/Console/Command/WinlibsCommandTest.php


Diff:

diff --git a/.github/workflows/winlibs.yml b/.github/workflows/winlibs.yml
index f6c981a..8ead945 100644
--- a/.github/workflows/winlibs.yml
+++ b/.github/workflows/winlibs.yml
@@ -9,6 +9,10 @@ on:
       ref:
         description: 'Library Ref'
         required: true
+      type:
+        description: 'Library Type (php or pecl)'
+        required: true
+        default: 'php'
       workflow_run_id:
         description: 'Workflow Run ID'
         required: true
@@ -32,4 +36,4 @@ jobs:
           --request POST \
           --location https://downloads.php.net/api/winlibs \
           --header 'Authorization: Bearer ${{ secrets.AUTH_TOKEN }}' \
-          --data '{ "library": "${{ inputs.library }}", "ref": "${{ inputs.ref 
}}", "workflow_run_id": "${{ inputs.workflow_run_id }}", "php_versions": "${{ 
inputs.php_versions }}", "vs_version": "${{ inputs.vs_version }}", 
"vs_version_targets": "${{ inputs.vs_version_targets }}", "stability": "${{ 
inputs.stability }}", "token": "${{ secrets.TOKEN }}" }'
+          --data '{ "library": "${{ inputs.library }}", "ref": "${{ inputs.ref 
}}", "type": "${{ inputs.type }}", "workflow_run_id": "${{ 
inputs.workflow_run_id }}", "php_versions": "${{ inputs.php_versions }}", 
"vs_version": "${{ inputs.vs_version }}", "vs_version_targets": "${{ 
inputs.vs_version_targets }}", "stability": "${{ inputs.stability }}", "token": 
"${{ secrets.TOKEN }}" }'
diff --git a/API.md b/API.md
index b5dacb2..9240bff 100644
--- a/API.md
+++ b/API.md
@@ -138,6 +138,7 @@ curl -i -X POST \
 - Request body (JSON):
     - `library` (string, required)
     - `ref` (string, required)
+    - `type` (string, required): `php`, or `pecl`.
     - `workflow_run_id` (string, required)
     - `php_versions` (string, required): Comma-separated list matching 
`^(?:\d+\.\d+|master)(?:,\s*(?:\d+\.\d+|master))*$`.
     - `vs_version_targets` (string, required): Comma-separated list matching 
`^(v[c|s]\d{2})(,v[c|s]\d{2})*$`.
diff --git a/src/Console/Command/WinlibsCommand.php 
b/src/Console/Command/WinlibsCommand.php
index 4ddac95..1edc3a7 100644
--- a/src/Console/Command/WinlibsCommand.php
+++ b/src/Console/Command/WinlibsCommand.php
@@ -45,14 +45,18 @@ public function handle(): int
                 $files = glob($directoryPath . '/*.zip');
                 $files = $this->parseFiles($files);
                 if ($files) {
-                    $this->copyFiles($files, $data['library'], 
$data['vs_version_targets']);
-                    $this->updateSeriesFiles(
-                        $files,
-                        $data['library'],
-                        $data['php_versions'],
-                        $data['vs_version_targets'],
-                        $data['stability']
-                    );
+                    if($data['type'] === 'php') {
+                        $this->copyPhpFiles($files, $data['library'], 
$data['vs_version_targets']);
+                        $this->updateSeriesFiles(
+                            $files,
+                            $data['library'],
+                            $data['php_versions'],
+                            $data['vs_version_targets'],
+                            $data['stability']
+                        );
+                    } else {
+                        $this->copyPeclFiles($files, $data['library']);
+                    }
                 }
 
                 (new Helpers)->rmdirr($directoryPath);
@@ -85,7 +89,7 @@ public function parseFiles(array $files): array
         return $data;
     }
 
-    private function copyFiles(array $files, string $library, string 
$vs_version_targets): void
+    private function copyPhpFiles(array $files, string $library, string 
$vs_version_targets): void
     {
         $baseDirectory = $this->baseDirectory . "/php-sdk/deps";
         if (!is_dir($baseDirectory)) {
@@ -104,6 +108,22 @@ private function copyFiles(array $files, string $library, 
string $vs_version_tar
         }
     }
 
+    private function copyPeclFiles(array $files, string $library): void
+    {
+        $baseDirectory = $this->baseDirectory . "/pecl/deps";
+        if (!is_dir($baseDirectory)) {
+            mkdir($baseDirectory, 0755, true);
+        }
+        foreach ($files as $file) {
+            $destinationDirectory = $baseDirectory;
+            if (!is_dir($destinationDirectory)) {
+                mkdir($destinationDirectory, 0755, true);
+            }
+            $destinationFileName = str_replace($file['artifact_name'], 
$library, $file['file_name']);
+            copy($file['file_path'], $destinationDirectory . '/' . 
$destinationFileName);
+        }
+    }
+
     private function updateSeriesFiles(
         array  $files,
         string $library,
diff --git a/src/Http/Controllers/WinlibsController.php 
b/src/Http/Controllers/WinlibsController.php
index a997f5a..2679c20 100644
--- a/src/Http/Controllers/WinlibsController.php
+++ b/src/Http/Controllers/WinlibsController.php
@@ -14,6 +14,7 @@ protected function validate(array $data): bool
         $validator = new Validator([
             'library' => 'required|string',
             'ref' => 'required|string',
+            'type' => 'required|string|regex:/^(php|pecl)$/',
             'workflow_run_id' => 'required|string',
             'php_versions' => 
'required|string|regex:/^(?:\d+\.\d+|master)(?:,\s*(?:\d+\.\d+|master))*$/',
             'vs_version_targets' => 
'required|string|regex:/^(v[c|s]\d{2})(,v[c|s]\d{2})*$/',
diff --git a/tests/Console/Command/WinlibsCommandTest.php 
b/tests/Console/Command/WinlibsCommandTest.php
index 720e0db..c2127c9 100644
--- a/tests/Console/Command/WinlibsCommandTest.php
+++ b/tests/Console/Command/WinlibsCommandTest.php
@@ -15,6 +15,8 @@ class WinlibsCommandTest extends TestCase
     
     private string $winlibsDirectory;
 
+    private string $buildsDirectory;
+
     protected function setUp(): void
     {
         parent::setUp();
@@ -42,6 +44,7 @@ public function testSuccessfulFileOperations($phpVersion, 
$vsVersion, $arch, $st
         $seriesFilePath = $this->baseDirectory . 
"/php-sdk/deps/series/packages-$phpVersion-$vsVersion-$arch-$stability.txt";
 
         file_put_contents($this->winlibsDirectory . '/lib/data.json', 
json_encode([
+            'type' => 'php',
             'library' => $library,
             'ref' => $ref,
             'vs_version_targets' => $vsVersion,
@@ -77,6 +80,7 @@ public function 
testSuccessfulFileOperationsWithExistingSeriesFile($phpVersion,
         $seriesFilePath = $this->baseDirectory . 
"/php-sdk/deps/series/packages-$phpVersion-$vsVersion-$arch-$stability.txt";
 
         file_put_contents($this->winlibsDirectory . '/lib/data.json', 
json_encode([
+            'type' => 'php',
             'library' => $library,
             'ref' => $ref,
             'vs_version_targets' => $vsVersion,
@@ -114,6 +118,7 @@ public function 
testSuccessfulFileOperationsWithExistingOldLibraryInSeriesFile($
         $seriesFilePath = $this->baseDirectory . 
"/php-sdk/deps/series/packages-$phpVersion-$vsVersion-$arch-$stability.txt";
 
         file_put_contents($this->winlibsDirectory . '/lib/data.json', 
json_encode([
+            'type' => 'php',
             'library' => $library,
             'ref' => $ref,
             'vs_version_targets' => $vsVersion,
@@ -141,6 +146,42 @@ public function 
testSuccessfulFileOperationsWithExistingOldLibraryInSeriesFile($
         $this->assertStringNotContainsString("lib-1.0.0-$vsVersion-$arch.zip", 
file_get_contents($seriesFilePath), "Series file should be updated correctly.");
     }
 
+    public function testSuccessfulPeclFileOperations(): void
+    {
+        mkdir($this->winlibsDirectory . '/redis', 0755, true);
+        mkdir($this->baseDirectory . '/pecl/deps', 0755, true);
+
+        $library = 'phpredis';
+        $ref = '5.3.7';
+        $vsVersion = 'vs16';
+        $arch = 'x64';
+
+        file_put_contents($this->winlibsDirectory . '/redis/data.json', 
json_encode([
+            'type' => 'pecl',
+            'library' => $library,
+            'ref' => $ref,
+            'vs_version_targets' => $vsVersion,
+            'php_versions' => '8.2',
+            'stability' => 'stable'
+        ]));
+
+        $zipPath = $this->winlibsDirectory . 
"/redis/redis-$ref-$vsVersion-$arch.zip";
+        $zip = new ZipArchive();
+        if ($zip->open($zipPath, ZipArchive::CREATE) === TRUE) {
+            $zip->addFromString('dummy_file.txt', 'dummy content');
+            $zip->close();
+        }
+
+        $command = new WinlibsCommand();
+        $command->setOption('base-directory', $this->baseDirectory);
+        $command->setOption('builds-directory', $this->buildsDirectory);
+
+        $result = $command->handle();
+
+        $this->assertEquals(0, $result, 'Command should return success.');
+        $this->assertFileExists($this->baseDirectory . 
"/pecl/deps/$library-$ref-$vsVersion-$arch.zip");
+    }
+
     public static function versionProvider(): array
     {
         return [

Reply via email to