From 40139d144bac5aff50af9dbe3d131f21459ff12f Mon Sep 17 00:00:00 2001 From: "stephan.kasdorf" Date: Wed, 29 May 2024 15:32:08 +0200 Subject: [PATCH] Added GitHub webhook functionality and configuration for API interaction This commit introduces functionality for GitHub webhook interaction and API calls. The git operations are handled by a custom GitHub client in PHP, details for API endpoints are outlined in a new OpenAPI schema, and the project setup includes PHP FPM and NGINX configuration using Docker. A webhook receiver is also added to process incoming webhook payloads. --- .env | 5 + docker-compose.yml | 29 ++++ gpt-schema.yml | 302 ++++++++++++++++++++++++++++++++++++++++ nginx/nginx.conf | 36 +++++ php-fpm/Dockerfile | 21 +++ src/GitHubClient.php | 39 ++++++ src/composer.json | 29 ++++ src/webhookReceiver.php | 21 +++ 8 files changed, 482 insertions(+) create mode 100644 .env create mode 100644 docker-compose.yml create mode 100644 gpt-schema.yml create mode 100644 nginx/nginx.conf create mode 100644 php-fpm/Dockerfile create mode 100644 src/GitHubClient.php create mode 100644 src/composer.json create mode 100644 src/webhookReceiver.php diff --git a/.env b/.env new file mode 100644 index 0000000..dc8c2bf --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +COMPOSE_PROJECT_NAME=nibiru-framework-api +VIRTUAL_HOST=agent.api.nibiru-framework.com +VIRTUAL_PORT=80 +PROXY_NETWORK=nginx-proxy +GITHUB_TOKEN=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 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..aacf4ce --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,29 @@ +version: '3.8' + +services: + php-fpm: + build: + context: ./php-fpm + volumes: + - ./src:/var/www/html + networks: + - nginx-proxy + restart: always + + nginx: + image: nginx:latest + environment: + - VIRTUAL_HOST=${VIRTUAL_HOST} + - VIRTUAL_PORT=${VIRTUAL_PORT} + volumes: + - ./src:/var/www/html + - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf + depends_on: + - php-fpm + networks: + - nginx-proxy + restart: always + +networks: + nginx-proxy: + external: true \ No newline at end of file diff --git a/gpt-schema.yml b/gpt-schema.yml new file mode 100644 index 0000000..1a9c215 --- /dev/null +++ b/gpt-schema.yml @@ -0,0 +1,302 @@ +openapi: 3.0.0 +info: + title: UpdateGPTOnPush Webhook + description: Webhook to update GPT on push events from a GitHub repository. + version: 1.0.0 +servers: + - url: https://api.github.com + description: GitHub API Server +paths: + /repos/{owner}/{repo}/contents/{path}: + get: + operationId: getRepositoryContent + summary: Get the contents of a repository + description: Fetch the contents of a file or directory in a repository. + parameters: + - name: owner + in: path + required: true + schema: + type: string + description: The owner of the repository. + - name: repo + in: path + required: true + schema: + type: string + description: The name of the repository. + - name: path + in: path + required: true + schema: + type: string + description: The content path. + - name: ref + in: query + schema: + type: string + description: The name of the commit/branch/tag. Default is the repository’s default branch (usually master). + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + type: + type: string + description: Type of content (file, directory, symlink, submodule). + encoding: + type: string + description: Encoding of the content (if file). + size: + type: integer + description: Size of the content (if file). + name: + type: string + description: Name of the content. + path: + type: string + description: Path of the content. + content: + type: string + description: Base64 encoded content (if file). + sha: + type: string + description: SHA identifier of the content. + url: + type: string + description: URL to access the content. + git_url: + type: string + description: Git URL to access the content. + html_url: + type: string + description: HTML URL to access the content. + download_url: + type: string + description: Download URL to access the content. + _links: + type: object + properties: + self: + type: string + description: Self link. + git: + type: string + description: Git link. + html: + type: string + description: HTML link. + '404': + description: Content not found + + /repos/{owner}/{repo}/commits: + get: + operationId: listCommits + summary: List commits in a repository + description: Retrieve a list of commits in a repository. + parameters: + - name: owner + in: path + required: true + schema: + type: string + description: The owner of the repository. + - name: repo + in: path + required: true + schema: + type: string + description: The name of the repository. + - name: sha + in: query + schema: + type: string + description: SHA or branch to start listing commits from. + - name: path + in: query + schema: + type: string + description: Only commits containing this file path will be returned. + - name: author + in: query + schema: + type: string + description: GitHub username or email of the author. + - name: since + in: query + schema: + type: string + format: date-time + description: Only commits after this date will be returned. + - name: until + in: query + schema: + type: string + format: date-time + description: Only commits before this date will be returned. + - name: per_page + in: query + schema: + type: integer + default: 30 + description: Number of results per page (max 100). + - name: page + in: query + schema: + type: integer + default: 1 + description: Page number of the results to fetch. + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: array + items: + type: object + properties: + sha: + type: string + description: SHA of the commit. + node_id: + type: string + description: Node ID of the commit. + commit: + type: object + properties: + author: + type: object + properties: + name: + type: string + email: + type: string + date: + type: string + format: date-time + committer: + type: object + properties: + name: + type: string + email: + type: string + date: + type: string + format: date-time + message: + type: string + tree: + type: object + properties: + sha: + type: string + url: + type: string + url: + type: string + comment_count: + type: integer + url: + type: string + html_url: + type: string + comments_url: + type: string + author: + type: object + properties: + login: + type: string + id: + type: integer + node_id: + type: string + avatar_url: + type: string + gravatar_id: + type: string + url: + type: string + html_url: + type: string + followers_url: + type: string + following_url: + type: string + gists_url: + type: string + starred_url: + type: string + subscriptions_url: + type: string + organizations_url: + type: string + repos_url: + type: string + events_url: + type: string + received_events_url: + type: string + type: + type: string + site_admin: + type: boolean + committer: + type: object + properties: + login: + type: string + id: + type: integer + node_id: + type: string + avatar_url: + type: string + gravatar_id: + type: string + url: + type: string + html_url: + type: string + followers_url: + type: string + following_url: + type: string + gists_url: + type: string + starred_url: + type: string + subscriptions_url: + type: string + organizations_url: + type: string + repos_url: + type: string + events_url: + type: string + received_events_url: + type: string + type: + type: string + site_admin: + type: boolean + parents: + type: array + items: + type: object + properties: + sha: + type: string + url: + type: string + html_url: + type: string + '404': + description: Repository not found +components: + schemas: {} \ No newline at end of file diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..2c005d7 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,36 @@ +server { + listen 80; + server_name ${VIRTUAL_HOST}; + + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss; + + location / { + proxy_read_timeout 7200; + proxy_connect_timeout 7200; + if (!-e $request_filename){ + rewrite ^(.*)$ / break; + } + root /usr/share/nginx/html; + index index.php; + } + + location ~ \.php$ { + root /var/www/html; + fastcgi_pass php-fpm:9000; + fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name; + include fastcgi_params; + fastcgi_buffers 16 32k; + fastcgi_buffer_size 64k; + fastcgi_busy_buffers_size 64k; + fastcgi_read_timeout 900; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + location ~ /\.ht { + deny all; + } +} \ No newline at end of file diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile new file mode 100644 index 0000000..ffdb600 --- /dev/null +++ b/php-fpm/Dockerfile @@ -0,0 +1,21 @@ +# Use the official PHP-FPM image for PHP 8.3 +FROM php:8.3-fpm + +# Set the working directory +WORKDIR /var/www/html + +# Install Composer +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + zip \ + unzip \ + git \ + && apt-get clean + +# Expose port 9000 for PHP-FPM +EXPOSE 9000 + +# Start PHP-FPM +CMD ["php-fpm"] \ No newline at end of file diff --git a/src/GitHubClient.php b/src/GitHubClient.php new file mode 100644 index 0000000..45c89e4 --- /dev/null +++ b/src/GitHubClient.php @@ -0,0 +1,39 @@ +client = new Client([ + 'base_uri' => 'https://api.github.com/', + 'headers' => [ + 'Authorization' => "token $token", + 'Accept' => 'application/vnd.github.v3+json', + ], + ]); + $this->token = $token; + } + + public function getRepositoryContent($owner, $repo, $path, $ref = 'main') + { + $response = $this->client->get("repos/$owner/$repo/contents/$path", [ + 'query' => ['ref' => $ref] + ]); + return json_decode($response->getBody(), true); + } + + public function listCommits($owner, $repo, $params = []) + { + $response = $this->client->get("repos/$owner/$repo/commits", [ + 'query' => $params + ]); + return json_decode($response->getBody(), true); + } +} \ No newline at end of file diff --git a/src/composer.json b/src/composer.json new file mode 100644 index 0000000..ddfe48b --- /dev/null +++ b/src/composer.json @@ -0,0 +1,29 @@ +{ + "name": "vendor_name/nibiru-framework-agent", + "description": "A project to interact with GitHub API using PHP", + "authors": [ + { + "name": "Stephan Kasdorf", + "email": "stephan.kasdorf@bittomine.com" + } + ], + "require": { + "php": "^8.3", + "guzzlehttp/guzzle": "^7.3" + }, + "autoload": { + "psr-4": { + "": "src/" + } + }, + "scripts": { + "post-install-cmd": [ + "chmod -R 777 storage" + ] + }, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true + } +} \ No newline at end of file diff --git a/src/webhookReceiver.php b/src/webhookReceiver.php new file mode 100644 index 0000000..9cc1c49 --- /dev/null +++ b/src/webhookReceiver.php @@ -0,0 +1,21 @@ + 'Webhook received']); \ No newline at end of file