diff --git a/.env.example b/.env.example index 2494326..7ca29ea 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,4 @@ -GITEA_INSTANCE_BASE_URL="https://gitea.example.com" \ No newline at end of file +GITEA_INSTANCE_BASE_URL="https://gitea.example.com" +GITEA_ACCESS_TOKEN="access_token" +GITEA_OWNER="owner" +GITEA_REPOSITORY="repository" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 720d913..4bc77de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ WORKDIR /var/src COPY ./src /var/src -# RUN composer install +RUN composer install USER php diff --git a/docker-compose.yml b/docker-compose.yml index 9819e9d..8fa74ec 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,6 +7,9 @@ services: dockerfile: Dockerfile environment: GITEA_INSTANCE_BASE_URL: ${GITEA_INSTANCE_BASE_URL} + GITEA_ACCESS_TOKEN: ${GITEA_ACCESS_TOKEN} + GITEA_OWNER: ${GITEA_OWNER} + GITEA_REPOSITORY: ${GITEA_REPOSITORY} volumes: - ./src:/var/src networks: diff --git a/src/app.php b/src/app.php index b3d9bbc..d7275a2 100644 --- a/src/app.php +++ b/src/app.php @@ -1 +1,177 @@ 0) { + $payload = \json_encode($data['request']); + } + + $fh = null; + $fileSize = 0; + + if (isset($data['file']) && !empty($data['file']) && \file_exists($data['file'])) { + $fh = \fopen($data['file'], 'r'); + $fileSize = \filesize($data['file']); + } + + if (isset($data['user']) && !empty($data['user'])) { + \curl_setopt($curl, CURLOPT_USERPWD, $data['user'] . ':' . \getenv('GITEA_ACCESS_TOKEN')); + } + + \curl_setopt($curl, CURLOPT_URL, \getenv('GITEA_INSTANCE_BASE_URL') . $endpoint .'?access_token=' . \getenv('GITEA_ACCESS_TOKEN')); + \curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); + \curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); + \curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + \curl_setopt($curl, CURLOPT_HEADER, true); + + if ($method === 'POST' || $method === 'PUT') { + if (!empty($payload)) { + \curl_setopt($curl, CURLOPT_POSTFIELDS, $payload); + \curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); + } + } + + if ($method === 'PUT') { + \curl_setopt($curl, CURLOPT_PUT, true); + } + + if ($fh) { + \curl_setopt($curl, CURLOPT_INFILE, $fh); + \curl_setopt($curl, CURLOPT_INFILESIZE, $fileSize); + } + + \curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20); + \curl_setopt($curl, CURLOPT_TIMEOUT, 20); + + $response = \curl_exec($curl); + + if(\curl_errno($curl) > 0) { + throw new \Exception('Curl error: #' . \curl_errno($curl) . ' - ' . \curl_error($curl)); + } + + $header = \substr($response, 0, \curl_getinfo($curl, CURLINFO_HEADER_SIZE)); + $body = \substr($response, \curl_getinfo($curl, CURLINFO_HEADER_SIZE)); + $httpCode = (int) \curl_getinfo($curl, CURLINFO_HTTP_CODE); + + $headers = \explode("\r\n", $header); + + \curl_close($curl); + + if (isset($data['file']) && !empty($data['file']) && \file_exists($data['file'])) { + \fclose($fh); + } + + return [ + 'http_code' => $httpCode, + 'headers' => $headers, + 'body' => $body, + ]; +} + +function responseEncode (array $response): mixed { + + $data = \json_decode($response['body'], true); + + if (\json_last_error() !== JSON_ERROR_NONE) { + throw new \Exception('Invalid response json: ' . json_last_error_msg()); + } + + return $data; +} + +function showTerminalMessage (string $message = '', string $color = ''): void +{ + echo $color . $message . NC . "\r\n"; +} + +try { + + $response = sendRequest('GET', '/api/v1/user'); + $data = responseEncode($response); + + if ($response['http_code'] !== 200) { + throw new \Exception('Failed to get user information. Response http code: ' . $response['http_code'] . ', Message: ' . $data['message']); + } + + $user = $data; + $login = $user['login']; + showTerminalMessage('User data: OK', GREEN); + + + + $response = sendRequest('GET', '/api/v1/repos/' . \getenv('GITEA_OWNER') . '/' . \getenv('GITEA_REPOSITORY') . '/releases'); + $data = responseEncode($response); + + if ($response['http_code'] !== 200) { + throw new \Exception('Failed to get repository releases information. Response http code: ' . $response['http_code'] . ', Message: ' . $data['message']); + } + + if (!isset($data[0]) || !\is_array($data[0])) { + throw new \Exception('Unexpected release data structure'); + } + + $lastRelease = $data[0]; + $tag = $lastRelease['tag_name']; + showTerminalMessage('Last release data: OK', GREEN); + + + $response = sendRequest('GET', '/api/v1/repos/' . \getenv('GITEA_OWNER') . '/' . \getenv('GITEA_REPOSITORY') . '/archive/' . $tag . '.zip'); + $zipContent = $response['body']; + + if ($response['http_code'] !== 200) { + throw new \Exception('Failed receiving zip archive. Response http code: ' . $response['http_code'] . ', Message: ' . $data['message']); + } + + if (empty($response['body'])) { + throw new \Exception('Failed receiving zip archive. Empty file'); + } + + \file_put_contents(__DIR__ . '/package.zip', $zipContent); + showTerminalMessage('Download zip archive: OK', GREEN); + + + + $response = sendRequest('PUT', '/api/packages/' . \getenv('GITEA_OWNER') . '/composer?version=' . $tag, [ + 'user' => $login, + 'file' => __DIR__ . '/package.zip', + ]); + + \unlink(__DIR__ . '/package.zip'); + + if ($response['http_code'] !== 201) { + $data = responseEncode($response); + + throw new \Exception('Failed update package. Response http code: ' . $response['http_code'] . ', Message: ' . $data['errors'][0]['message']); + } + + showTerminalMessage('Update package: OK', GREEN); + + +} catch (\Exception $e) { + + showTerminalMessage("\r\n"); + showTerminalMessage( 'FAILED!', RED); + showTerminalMessage( "Error: " . $e->getMessage(), RED); + exit(1); +} + +showTerminalMessage("\r\n"); +showTerminalMessage('SUCCESS!', GREEN); \ No newline at end of file diff --git a/src/composer.json b/src/composer.json new file mode 100644 index 0000000..183d7d3 --- /dev/null +++ b/src/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "ext-curl": "*" + } +} \ No newline at end of file