{"id":42243723,"url":"https://github.com/mnofresno/github-autodeploy","last_synced_at":"2026-01-27T04:20:08.181Z","repository":{"id":49985199,"uuid":"370140266","full_name":"mnofresno/github-autodeploy","owner":"mnofresno","description":"Automatic :robot: deploying webhook app for git repos to deploy your code into your production server :computer: to save your time :hourglass: and spend it with your family :baby: instead of manually deploying your personal projects :turtle:","archived":false,"fork":false,"pushed_at":"2025-11-29T01:42:44.000Z","size":208,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-01T02:57:07.450Z","etag":null,"topics":["automation","continuous-delivery","continuous-integration","deployment"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mnofresno.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-05-23T19:28:22.000Z","updated_at":"2025-11-29T01:42:46.000Z","dependencies_parsed_at":"2025-11-30T16:02:10.953Z","dependency_job_id":null,"html_url":"https://github.com/mnofresno/github-autodeploy","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/mnofresno/github-autodeploy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnofresno%2Fgithub-autodeploy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnofresno%2Fgithub-autodeploy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnofresno%2Fgithub-autodeploy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnofresno%2Fgithub-autodeploy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mnofresno","download_url":"https://codeload.github.com/mnofresno/github-autodeploy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnofresno%2Fgithub-autodeploy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28801918,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T03:44:14.111Z","status":"ssl_error","status_checked_at":"2026-01-27T03:43:33.507Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["automation","continuous-delivery","continuous-integration","deployment"],"created_at":"2026-01-27T04:20:07.524Z","updated_at":"2026-01-27T04:20:08.143Z","avatar_url":"https://github.com/mnofresno.png","language":"PHP","readme":"# Git Auto Deployment Tool\n\n[![Git Autodeploy CI](https://github.com/mnofresno/github-autodeploy/actions/workflows/push.yml/badge.svg)](https://github.com/mnofresno/github-autodeploy/actions/workflows/push.yml)\n\n## Introduction\n\nThe Git Auto Deployment Tool facilitates seamless deployments from GitHub or GitLab repositories via webhooks. It automatically fetches changes, executes custom deployment commands, and keeps your projects up-to-date without manual intervention. This project is inspired by [this Gist](https://gist.github.com/nichtich/5290675).\n\nRefer to the [original documentation](ORIGINAL.md) for more information.\n\n## Features\n\n- **Automatic deployment via webhooks** from GitHub or GitLab.\n- **Configurable commands** to be executed before and after fetching updates.\n- **Customizable deployment scripts** for each repository.\n- **Integrated CI/CD pipeline** using GitHub Actions.\n- **Comprehensive testing suite** to ensure stability and reliability.\n\n## Installation\n\nTo install the Git Auto Deployment Tool, run the following command in your terminal:\n\n```bash\nsudo curl -sSL https://raw.githubusercontent.com/mnofresno/github-autodeploy/master/install.sh | bash -s \u003cyour-domain\u003e\n```\n\nReplace `\u003cyour-domain\u003e` with the domain you want to use for the deployment tool (e.g., `git-autodeploy.example.com`).\n\n### What This Command Does\n\n1. **Downloads the Installation Script**: Fetches `install.sh` directly from the GitHub repository.\n2. **Executes the Installation Script**: Sets up the necessary Nginx configuration, checks prerequisites, downloads the tool, and configures it.\n\n### Manual Installation\n\nAlternatively, you can manually clone the repository and serve it through Nginx or Apache with PHP:\n\n1. Clone the repository:\n\n    ```bash\n    git clone https://github.com/mnofresno/github-autodeploy.git\n    cd github-autodeploy\n    ```\n\n2. Copy the example config file:\n\n    ```bash\n    cp config.example.json config.json\n    ```\n\n3. Serve the project with Nginx or Apache + PHP.\n\n## Configuration Parameters\n\nConfigure parameters in the `config.json` file:\n\n### IPsAllowList (array, mandatory)\n\nList of IP addresses allowed to hit the endpoint.\n\n### SSHKeysPath (string, mandatory)\n\nBase path where the SSH keys are stored.\n\n### ReposBasePath (string, mandatory)\n\nBase path where the git repositories are stored.\n\n### custom_commands (array|object, optional)\n\nCommands executed to update and refresh a deployment. Commands can use placeholders with a format of a dollar sign followed by a string:\n\n```json\n{\n    \"ReposBasePath\": \"repos_with_code\",\n    \"custom_commands\": [\n        \"ls /var/www\",\n        \"cd $ReposBasePath\",\n        \"rm tempfile\"\n    ]\n}\n```\n\nThis means the triggered endpoint will `cd` into `/var/www/repos_with_code` using the `ReposBasePath` config parameter.\n\nYou can configure `custom_commands` with an object using valid \"repo\" query parameters as keys to define different command sets for each repository:\n\n```json\n{\n    \"ReposBasePath\": \"repos_with_code\",\n    \"custom_commands\": {\n        \"example-repo1\": [\n            \"ls /var/www\",\n            \"cd $ReposBasePath\",\n            \"rm tempfile\"\n        ],\n        \"example-repo2\": [\n            \"other\",\n            \"set\",\n            \"of commands\"\n        ],\n        \"_default_\": [\n            \"default\",\n            \"commands to run\"\n        ]\n    }\n}\n```\n\n## Available Placeholders\n\n| Placeholder       | Description                                   |\n|-------------------|-----------------------------------------------|\n| ReposBasePath     | The `ReposBasePath` config parameter value    |\n| SSHKeysPath       | The `SSHKeysPath` config parameter value      |\n| repo              | The value of the 'repo' query parameter       |\n| key               | The value of the 'key' query parameter        |\n\nIf `custom_commands` is not specified, a default list of commands is executed to update the projects:\n\n```\ncd $ReposBasePath\necho $PWD\nwhoami\nGIT_SSH_COMMAND=\"ssh -i $SSHKeysPath/$key\" git fetch origin\ngit reset --hard origin/$(git symbolic-ref --short HEAD)\n```\n\n## Customizing Deployment with `.git-auto-deploy.yml`\n\nThe `.git-auto-deploy.yml` file customizes the deployment process for each repository. It defines commands to execute at different stages, providing granular control over the deployment workflow.\n\n### Structure of `.git-auto-deploy.yml`\n\nThe file is structured with two main sections:\n\n- **`pre_fetch_commands`**: Executed **before** fetching changes from the repository.\n- **`post_fetch_commands`**: Executed **after** fetching changes from the repository.\n\n### Example `.git-auto-deploy.yml`\n\n```yaml\n---\npre_fetch_commands:\n    - echo \"Preparing environment for deployment...\"\n    - echo ${{ secrets.github_ghcr_token }}\n    - 'echo \"Repository base path is $ReposBasePath\"'\n    - echo ${{ secrets.github_ghcr_username }}\npost_fetch_commands:\n    - composer install\n    - ./auto-update/create_revision.sh\n    - ./build_apk.sh\n    - 'echo \"Successfully upgraded to the last version: $(cat auto-update/public/revision.js)\"'\n    - echo $SSHKeysPath\n    - echo $secrets.github_ghcr_username\n```\n\n### Multiline Commands\n\nYou can use multiline commands in `.git-auto-deploy.yml` by using YAML's block scalar syntax with the `|` operator. Multiline commands are automatically executed within a bash shell.\n\n**Example with multiline commands:**\n\n```yaml\n---\npost_fetch_commands:\n    - docker compose pull\n    - docker compose up -d\n    - docker compose exec php composer install --ignore-platform-req=ext-mongodb\n    # Clonar dataset de ejercicios si no existe\n    - |\n      if [ ! -d \"assets/exercises/free-exercise-db\" ]; then\n        mkdir -p assets/exercises\n        git clone https://github.com/yuhonas/free-exercise-db.git assets/exercises/free-exercise-db\n        rm -rf assets/exercises/free-exercise-db/.git\n      fi\n    # Regenerar índice de ejercicios\n    - docker compose exec php php bin/generate-exercise-index.php\n```\n\n**Important notes:**\n- Use the `|` operator to create multiline block scalars in YAML\n- The indentation after `|` is preserved in the command\n- Multiline commands are automatically executed within `bash -c`\n- You can mix single-line and multiline commands in the same list\n\n### Explanation\n\n1. **`pre_fetch_commands`**:\n   - Commands executed before fetching changes from the repository.\n   - Examples: Preparing the environment, outputting a secret token, and printing configuration parameters.\n\n2. **`post_fetch_commands`**:\n   - Commands executed after changes have been fetched.\n   - Examples: Installing dependencies, building artifacts, outputting deployment results.\n\n### Using Placeholders in Commands\n\nPlaceholders in `.git-auto-deploy.yml` are replaced at runtime with values from the request, configuration, or secrets:\n\n| Placeholder                          | Description                                                    |\n|--------------------------------------|----------------------------------------------------------------|\n| `{{ repo }}`                         | The 'repo' query parameter value                               |\n| `{{ key }}`                          | The 'key' query parameter value                                |\n| `{{ ReposBasePath }}`                | The `ReposBasePath` config parameter value                     |\n| `{{ SSHKeysPath }}`                  | The `SSHKeysPath` config parameter value                       |\n| `{{ Secrets.\u003csecret_key\u003e }}`         | Secret values from configuration, masked with `***` in logs    |\n\n#### Example with Secret Handling and Config Placeholders\n\n```yaml\n---\npre_fetch_commands:\n    - echo ${{ secrets.github_ghcr_token }}\n    - echo ${{ secrets.github_ghcr_username }}\n    - echo $SSHKeysPath\n    - echo $secrets.github_ghcr_username\npost_fetch_commands:\n    - composer install\n    - echo \"Deployment for $repo has been successfully completed!\"\n```\n\n## CI/CD Pipeline\n\nThis project uses GitHub Actions for continuous integration and deployment:\n\n- **Build and Run Tests**:\n  - Runs on any push or pull request.\n  - Validates `composer.json` and `composer.lock`.\n  - Caches Composer dependencies.\n  - Installs dependencies and runs tests using `composer run-script test`.\n\n- **PHP Linting**:\n  - Uses a custom linter script (`linter/lint.sh`) in dry-run mode to detect potential issues.\n\n- **Self-Update Deployment**:\n  - Automatically updates all instances when you push to the repository.\n  - Only if tests and linting pass successfully.\n  - Uses environment variables for deployment URLs (`AUTODEPLOY_URL`).\n  - **Supports multiple instances**: You can update multiple servers by separating URLs with commas.\n  - Shows a clear summary with status for each instance.\n\n### Multi-Instance Self-Update\n\nTo update multiple instances simultaneously, set the `AUTODEPLOY_URL` variable in your GitHub repository settings with comma-separated values:\n\n```\nAUTODEPLOY_URL=github-autodeploy.fresno.ar,git-autodeploy.gastos.fresno.ar,git-autodeploy.localpass.cloud\n```\n\nThe workflow will:\n1. Self-update each instance sequentially\n2. Show the HTTP status code for each self-update\n3. Display a preview of each response\n4. Provide a clear summary at the end showing which instances succeeded or failed\n5. Fail the workflow if any instance fails\n\n### Self-Update Mechanism\n\nWhen you push changes to the `github-autodeploy` repository, the workflow automatically performs a **self-update** on all configured instances:\n\n**How it works:**\n\n1. The workflow calls the `/self-update` endpoint on each instance configured in `AUTODEPLOY_URL`\n2. Each instance executes `install.sh --self-update` which:\n   - Downloads the latest version from GitHub\n   - Uses rsync to update files (preserving `config.json` and other ignored files)\n   - Runs `composer install` to update dependencies\n   - Maintains proper file ownership (www-data)\n\n**Note:** This project uses the self-update mechanism for its own deployments. For monitoring other repositories, you would configure them separately with git hooks or `.git-auto-deploy.yml` files\n\n**Example self-update output:**\n```\n🔄 Self-updating 3 instance(s)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n┌─────────────────────────────────────────────┐\n│ Instance 1/3: github-autodeploy.fresno.ar\n└─────────────────────────────────────────────┘\n✅ SUCCESS - Self-update completed (HTTP 200)\n\n╔═══════════════════════════════════════════════╗\n║           SELF-UPDATE SUMMARY                 ║\n╚═══════════════════════════════════════════════╝\n  ✅ github-autodeploy.fresno.ar - Self-updated (HTTP 200)\n  ✅ git-autodeploy.gastos.fresno.ar - Self-updated (HTTP 200)\n  ✅ git-autodeploy.localpass.cloud - Self-updated (HTTP 200)\n\n🎉 All instances self-updated successfully!\n```\n\n**Manual self-update:**\n\nYou can also manually trigger a self-update on any server:\n\n```bash\n# SSH into the server\nssh user@your-server.com\n\n# Run self-update as www-data\nsudo -u www-data /opt/git-autodeploy/install.sh --self-update\n\n# Or via curl to the endpoint\ncurl https://git-autodeploy.your-domain.com/self-update\n```\n\n**What gets updated:**\n- ✅ All source code files (`src/`, `public/`, etc.)\n- ✅ Configuration files (`linter/`, `.github/`, etc.)\n- ✅ Composer dependencies\n- ❌ Your custom `config.json` (preserved)\n- ❌ Any files in `.gitignore` (preserved)\n\n## Usage\n\nUse the `trigger_for_repo` script in the `bin/` directory to trigger deployments manually:\n\n```bash\n./bin/trigger_for_repo \u003crepo_name\u003e \u003ckey_name\u003e\n```\n\nReplace `\u003crepo_name\u003e` and `\u003ckey_name\u003e` with the appropriate values.\n\n## Testing\n\nTo run the tests, install Composer dependencies and execute the following:\n\n```bash\ncomposer run-script test\n```\n\n### Test Suite\n\nThe `test/` directory contains various tests for the Git Auto Deployment Tool:\n\n- **`CustomCommandsTest.php`**: Tests placeholder replacement and command generation.\n- **`ExecuterTest.php`**: Tests the execution of deployment commands.\n- **`RequestTest.php`**: Validates request handling and parameters.\n- **`RunnerTest.php`**: Ensures the main runner functions correctly.\n- **`DeployConfigReaderTest.php`**: Validates configuration file parsing.\n- **`IPAllowListManagerTest.php`**: Tests IP allowlist functionality.\n- **`LoggerTest.php`**: Ensures logging is handled correctly.\n- **`SecurityTest.php`**: Tests security-related aspects.\n\n## Contributing\n\nContributions are welcome! Please raise an issue to discuss potential changes or fork the repository and submit a pull request.\n\n## Thanks\n\nThanks to the GitHub user [@nichtich](https://github.com/nichtich) for the inspirational gist this project was based on.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnofresno%2Fgithub-autodeploy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmnofresno%2Fgithub-autodeploy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnofresno%2Fgithub-autodeploy/lists"}