Author: Shivam Mathur (shivammathur)
Date: 2024-08-25T09:37:31+05:30

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

Add support for winlib builds

Changed paths:
  A  src/GetArtifacts.php
  M  src/Validator.php
  M  src/WinlibsHandler.php


Diff:

diff --git a/src/GetArtifacts.php b/src/GetArtifacts.php
new file mode 100644
index 0000000..2a18046
--- /dev/null
+++ b/src/GetArtifacts.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace App;
+
+class GetArtifacts
+{
+    public static function handle($workflow_run_id, $token): null|array
+    {
+        $ch = curl_init();
+
+        $base_url = "https://api.github.com/repos/";;
+
+        $repo = "winlibs/winlib-builder";
+        
+        curl_setopt_array($ch, [
+            CURLOPT_URL => 
"$base_url/$repo/actions/runs/$workflow_run_id/artifacts",
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_CUSTOMREQUEST => "GET",
+            CURLOPT_HTTPHEADER => [
+                "Accept: application/vnd.github+json",
+                "X-GitHub-Api-Version: 2022-11-28",
+                "User-Agent: PHP Web Downloads",
+            ],
+        ]);
+        
+        $response = curl_exec($ch);
+        $err = curl_error($ch);
+        curl_close($ch);
+        
+        if ($err) {
+            echo "cURL Error #:" . $err;
+            return null;
+        } else {
+            $files = [];
+            $artifacts = json_decode($response, true);
+            foreach ($artifacts['artifacts'] as $artifact) {
+                $filepath = "/tmp/" . $artifact['name'] . ".zip";
+                $files[] = $filepath;
+                FetchArtifact::handle($artifact['archive_download_url'], 
$filepath, $token);
+            }
+            return $files;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/Validator.php b/src/Validator.php
index d63db75..297b45d 100644
--- a/src/Validator.php
+++ b/src/Validator.php
@@ -28,7 +28,7 @@ public function validate(array $data): void
                 $ruleValue = $ruleParts[1] ?? null;
 
                 if (!$this->$ruleName($data[$field] ?? null, $ruleValue)) {
-                    $this->errors[$field][] = $this->getErrorMessage($field, 
$ruleName);
+                    $this->errors[$field][] = $this->getErrorMessage($field, 
$ruleName, $ruleValue);
                 }
             }
         }
@@ -72,12 +72,18 @@ protected function string($value): bool
         return is_string($value);
     }
 
-    protected function getErrorMessage($field, $rule): string
+    protected function regex($value, $pattern): bool
+    {
+        return preg_match($pattern, $value) === 1;
+    }
+
+    protected function getErrorMessage($field, $rule, $value): string
     {
         $messages = [
             'required' => "The $field field is required.",
             'url' => "The $field field must be a valid URL.",
             'string' => "The $field field must be a string.",
+            'regex' => "The $field field must match the pattern $value.",
         ];
 
         return $messages[$rule] ?? "The $field field has an invalid value.";
diff --git a/src/WinlibsHandler.php b/src/WinlibsHandler.php
index 63684b9..d7177ac 100644
--- a/src/WinlibsHandler.php
+++ b/src/WinlibsHandler.php
@@ -6,11 +6,100 @@ class WinlibsHandler extends BaseHandler
 {
     protected function validate(array $data): bool
     {
-        return true;
+        $validator = new Validator([
+            'library' => 'required|string',
+            'ref' => 'required|string',
+            'workflow_run_id' => 'required|string',
+            'php_versions' => 'required|string|regex:/^\d+\.\d+$}|^master$/',
+            'vs_version' => 
'required|string|regex:/^(v[c|s]\d{2})(,v[c|s]\d{2})*$/',
+            'vs_version_targets' => 'required|string|regex:/^v[c|s]\d{2}$/',
+            'stability' => 
'required|string|regex:/^(stable|staging)(,(stable|staging))?$/',
+            'token' => 'required|string',
+        ]);
+
+        $validator->validate($data);
+
+        $valid = $validator->isValid();
+
+        if(!$valid) {
+            http_response_code(400);
+            echo 'Invalid request: ' . $validator;
+        }
+
+        return $valid;
     }
 
     protected function execute(array $data): void
     {
-        //
+        extract($data);
+        $files = GetArtifacts::handle($workflow_run_id, $token);
+        $files = $this->parseFiles($files);
+        if($files) {
+            $this->copyFiles($files, $library, $ref, $vs_version_targets);
+            $this->updateSeriesFiles($files, $library, $ref, $php_versions, 
$vs_version_targets, $stability);
+        }
+    }
+
+    private function parseFiles(array $files): array
+    {
+        $data = [];
+        foreach ($files as $file) {
+            $fileName = basename($file);
+            $fileNameParts = explode('.', $fileName);
+            $parsedFileNameParts = explode('-', $fileNameParts[0]);
+            $data[] = [
+                'file_path' => $file,
+                'file_name' => $fileName,
+                'extension' => $fileNameParts[1],
+                'artifact_name' => $parsedFileNameParts[0],
+                'vs_version' => $parsedFileNameParts[1],
+                'arch' => $parsedFileNameParts[2],
+            ];
+        }
+        return $data;
+    }
+
+    private function copyFiles(array $files, $library, $ref, 
$vs_version_targets): void
+    {
+        $baseDirectory = $_ENV['BUILDS_DIRECTORY'] . "/php-sdk/deps";
+        if(!is_dir($baseDirectory)) {
+            mkdir($baseDirectory, 0755, true);
+        }
+        $vs_version_targets = explode(',', $vs_version_targets);
+        foreach($files as $file) {
+            foreach ($vs_version_targets as $vs_version_target) {
+                $destinationDirectory = $baseDirectory . '/' . 
$vs_version_target . '/' . $file['arch'];
+                $destinationFileName = str_replace($file['artifact_name'], 
$library . '-' . $ref, $file['file_name']);
+                copy($file['file_path'], $destinationDirectory . '/' . 
$destinationFileName);
+            }
+        }
+    }
+
+    private function updateSeriesFiles($files, $library, $ref, $php_versions, 
$vs_version_targets, $stability): void
+    {
+        $php_versions = explode(',', $php_versions);
+        $vs_version_targets = explode(',', $vs_version_targets);
+        $stability_values = explode(',', $stability);
+
+        $baseDirectory = $_ENV['BUILDS_DIRECTORY'] . "/php-sdk/deps/series";
+
+        foreach ($php_versions as $php_version) {
+            foreach ($vs_version_targets as $vs_version_target) {
+                foreach ($stability_values as $stability_value) {
+                    foreach ($files as $file) {
+                        $fileName = str_replace($file['artifact_name'], 
$library . '-' . $ref, $file['file_name']);
+                        $arch = $file['arch'];
+                        $seriesFile = $baseDirectory . 
"/packages-$php_version-$vs_version_target-$arch-$stability_value.txt";
+                        $file_lines = file($seriesFile, FILE_IGNORE_NEW_LINES);
+                        foreach($file_lines as $no => $line) {
+                            if(strpos($line, $library) === 0) {
+                                $file_lines[$no] = $fileName;
+                            }
+                        }
+                        file_put_contents($seriesFile, implode("\n", 
$file_lines));
+                    }
+                }
+            }
+        }
     }
 }
\ No newline at end of file

Reply via email to