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