Author: Shivam Mathur (shivammathur)
Date: 2024-08-25T09:37:31+05:30
Commit: Add support for winlib builds · php/web-downloads@cf644c5 · GitHub
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