{"id":19205301,"url":"https://github.com/tyler-tee/push-deploy-repeat","last_synced_at":"2026-04-19T06:40:14.886Z","repository":{"id":259777741,"uuid":"879405530","full_name":"tyler-tee/push-deploy-repeat","owner":"tyler-tee","description":"Demonstrates how to auto-update a server every time a new commit is pushed to main.","archived":false,"fork":false,"pushed_at":"2024-11-22T21:47:25.000Z","size":18,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-04T14:48:21.694Z","etag":null,"topics":["api","automation","flask","python","webhook"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tyler-tee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-27T20:14:25.000Z","updated_at":"2024-11-22T21:47:28.000Z","dependencies_parsed_at":"2025-01-04T14:48:00.670Z","dependency_job_id":"b32e1b55-333f-4890-9add-5cfbfa99d870","html_url":"https://github.com/tyler-tee/push-deploy-repeat","commit_stats":null,"previous_names":["tyler-tee/push-deploy-repeat"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tyler-tee%2Fpush-deploy-repeat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tyler-tee%2Fpush-deploy-repeat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tyler-tee%2Fpush-deploy-repeat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tyler-tee%2Fpush-deploy-repeat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tyler-tee","download_url":"https://codeload.github.com/tyler-tee/push-deploy-repeat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240277235,"owners_count":19775855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","automation","flask","python","webhook"],"created_at":"2024-11-09T13:12:11.643Z","updated_at":"2026-04-19T06:40:09.841Z","avatar_url":"https://github.com/tyler-tee.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# **Push, Deploy, Repeat: Automating Server Updates with GitHub Webhooks 🚀**  \n\n![SonarCloud Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=tyler-tee_push-deploy-repeat\u0026metric=alert_status)\n\n\nThis repository accompanies the article _[\"Push, Deploy, Repeat: Automating Server Updates with GitHub Webhooks\"](https://lambdasandlapdogs.com/)_. It demonstrates how to automatically update a server every time a new commit is pushed to the `main` branch of a GitHub repository, using Flask and webhooks.\n\n## **Table of Contents**  \n- [**Push, Deploy, Repeat: Automating Server Updates with GitHub Webhooks 🚀**](#push-deploy-repeat-automating-server-updates-with-github-webhooks-)\n  - [**Table of Contents**](#table-of-contents)\n  - [**Overview**](#overview)\n  - [**Features**](#features)\n  - [**Setup Instructions**](#setup-instructions)\n    - [1. **Clone the Repository**](#1-clone-the-repository)\n    - [2. **Set Up a Virtual Environment**](#2-set-up-a-virtual-environment)\n    - [3. **Install Dependencies**](#3-install-dependencies)\n    - [4. **Configure the Secret Key**](#4-configure-the-secret-key)\n  - [**How It Works**](#how-it-works)\n  - [**Testing the Webhook**](#testing-the-webhook)\n  - [**Security Considerations**](#security-considerations)\n  - [**License**](#license)\n\n---\n\n## **Overview**  \nThis project automates the deployment process by using a webhook listener to pull the latest code from the GitHub repository when a push event is detected on the `main` branch.\n\n---\n\n## **Features**  \n- **Automatic Pull from Main Branch:** Ensures the server always runs the latest code.  \n- **Secure Webhook Integration:** Validates requests using a GitHub IP whitelist and HMAC signature verification.  \n- **Modular Design:** Blueprint-based structure for easy extensibility.  \n- **Error Handling:** Handles network issues, invalid IPs, and signature mismatches gracefully.\n\n---\n\n## **Setup Instructions**  \n\n### 1. **Clone the Repository**  \n```bash\ngit clone https://github.com/tyler-tee/push-deploy-repeat.git\ncd push-deploy-repeat\n```\n\n### 2. **Set Up a Virtual Environment**  \n```bash\npython3 -m venv venv\nsource venv/bin/activate  # On macOS/Linux\nvenv\\Scripts\\activate  # On Windows\n```\n\n### 3. **Install Dependencies**  \n```bash\npip install -r requirements.txt\n```\n\n### 4. **Configure the Secret Key**  \n1. Open the existing config/update_config.json file.\n2. Replace the placeholder secret token with your desired secret token:\n\n```json\n{\n    \"SECRET_KEY\": \"your-secret-token\"\n}\n```\n\n3. Use the same **secret token** in your GitHub webhook configuration.\n\n---\n\n## **How It Works**  \n1. **GitHub Webhook Setup:**  \n   - GitHub sends a POST request to the server’s `/update_server` endpoint on every push to the `main` branch.\n\n2. **IP Validation:**  \n   - The server verifies that the request originated from GitHub by checking the IP range.\n\n3. **Signature Verification:**  \n   - The payload’s HMAC signature is compared with the secret key to prevent unauthorized access.\n\n4. **Code Pull and Update:**  \n   - If the validation passes, the server pulls the latest code from the `main` branch using Git.\n\n---\n\n## **Testing the Webhook**  \n1. **Start the Flask App:**  \n   ```bash\n   python app.py\n   ```\n\n2. **Configure the GitHub Webhook:**  \n   - In your GitHub repository, go to **Settings** → **Webhooks**.  \n   - Add a new webhook with the following details:\n     - **Payload URL:** `http://\u003cyour-server-ip\u003e:5000/webhook/update_server`\n     - **Content type:** `application/json`\n     - **Secret:** Use the same secret from `update_config.json`\n     - **Events:** Select **Just the push event**.\n\n3. **Push a Commit:**  \n   - Push a new commit to the `main` branch:\n     ```bash\n     git add .\n     git commit -m \"Test webhook\"\n     git push origin main\n     ```\n\n4. **Check the Server Logs:**  \n   - Ensure the server receives the event and pulls the latest code successfully.\n\n---\n\n## **Security Considerations**  \n- **IP Whitelisting:** Verifies that the request originates from GitHub’s IP range using the [GitHub Meta API](https://api.github.com/meta).  \n- **Signature Validation:** Uses HMAC with SHA-256 to validate the payload against the configured secret.  \n- **HTTPS:** Ensure your server is secured with SSL/TLS for production use.  \n\n---\n\n## **License**  \nThis project is licensed under the MIT License.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftyler-tee%2Fpush-deploy-repeat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftyler-tee%2Fpush-deploy-repeat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftyler-tee%2Fpush-deploy-repeat/lists"}