├── .gitignore ├── 000-block-emails.php ├── Dockerfile ├── LICENSE ├── README.md ├── action.yml ├── composer.json ├── composer.lock ├── deploy.php ├── entrypoint.sh ├── example ├── addon.php └── addon.sh ├── hosts.yml └── main.sh /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .vscode/ 3 | .idea/ -------------------------------------------------------------------------------- /000-block-emails.php: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:24.04 2 | 3 | ARG DEBIAN_FRONTEND=noninteractive 4 | 5 | LABEL "com.github.actions.icon"="upload-cloud" 6 | LABEL "com.github.actions.color"="yellow" 7 | LABEL "com.github.actions.name"="Deploy WordPress" 8 | LABEL "com.github.actions.description"="Deploy WordPress code to a server" 9 | LABEL "org.opencontainers.image.source"="https://github.com/rtCamp/action-deploy-wordpress" 10 | 11 | 12 | ENV PATH="/composer/vendor/bin:~/.local/bin:$PATH" 13 | ENV COMPOSER_ALLOW_SUPERUSER=1 14 | ENV COMPOSER_HOME=/composer 15 | ENV DEFAULT_PHP_VERSION=7.4 16 | 17 | RUN apt update && \ 18 | apt install -y \ 19 | bash \ 20 | git \ 21 | curl \ 22 | jq \ 23 | rsync \ 24 | zip \ 25 | unzip \ 26 | python3-pip \ 27 | software-properties-common && \ 28 | add-apt-repository ppa:ondrej/php && \ 29 | apt update && \ 30 | apt-get install -y php7.4-cli php7.4-curl php7.4-json php7.4-mbstring php7.4-xml php7.4-iconv php7.4-yaml && \ 31 | pip3 install shyaml --break-system-packages && \ 32 | rm -rf /var/lib/apt/lists/* 33 | 34 | # Setup wp-cli 35 | RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && \ 36 | chmod +x wp-cli.phar && \ 37 | mv wp-cli.phar /usr/local/bin/wp 38 | 39 | # Setup composer 40 | RUN mkdir -p /composer && \ 41 | curl -sS https://getcomposer.org/installer | \ 42 | php -- --install-dir=/usr/bin/ --filename=composer 43 | COPY composer.* /composer/ 44 | RUN cd /composer && composer install 45 | 46 | RUN curl -sL https://deb.nodesource.com/setup_16.x | bash && \ 47 | apt install -y nodejs && \ 48 | rm -rf /var/lib/apt/lists/* 49 | 50 | COPY deploy.php hosts.yml 000-block-emails.php / 51 | COPY *.sh / 52 | RUN chmod +x /*.sh 53 | 54 | ENTRYPOINT ["/entrypoint.sh"] 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 rtCamp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This action is a part of [GitHub Actions Library](https://github.com/rtCamp/github-actions-library/) created 2 | by [rtCamp](https://github.com/rtCamp/). 3 | 4 | # Deploy WordPress - GitHub Action 5 | 6 | [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) 7 | 8 | A [GitHub Action](https://github.com/features/actions) to deploy WordPress on a server 9 | using [PHP's Deployer.org project](https://deployer.org/). 10 | 11 | Please note that, this action expects git repo structure in a certain way. Your webroot should include content 12 | inside `wp-content` except `uploads`. You may use our [WordPress Skeleton](https://github.com/rtCamp/wordpress-skeleton) 13 | as a base, or restructre existing project to fit in. 14 | 15 | During deployment, by default this action will download [WordPress](https://wordpress.org/latest.zip), put the content 16 | of the repo in `wp-content` directory and then deploy the entire WordPress setup on the deploy path specified 17 | in `hosts.yml`. 18 | 19 | `hosts.yml` is [Deployer's inventory file](https://deployer.org/docs/hosts.html#inventory-file). 20 | 21 | ## Usage 22 | 23 | 1. Create a `.github/workflows/deploy.yml` file in your GitHub repo, if one doesn't exist already. 24 | 2. Add the following code to the `deploy.yml` file. 25 | 26 | ```yml 27 | on: push 28 | name: Deploying WordPress Site 29 | jobs: 30 | deploy: 31 | name: Deploy 32 | runs-on: ubuntu-latest 33 | steps: 34 | - uses: actions/checkout@v3 35 | - name: Deploy 36 | uses: rtCamp/action-deploy-wordpress@v3 37 | env: 38 | SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} 39 | ``` 40 | 41 | 3. Create `SSH_PRIVATE_KEY` secret 42 | using [GitHub Action's Secret](https://developer.github.com/actions/creating-workflows/storing-secrets) and store the 43 | private key that you use use to ssh to server(s) defined in `hosts.yml`. 44 | 4. Create `.github/hosts.yml` inventory file, based 45 | on [Deployer inventory file](https://deployer.org/docs/hosts.html#inventory-file) format. Make sure you explictly 46 | define GitHub branch mapping. Only the GitHub branches mapped in `hosts.yml` will be deployed, rest will be filtered 47 | out. Here is a sample [hosts.yml](https://github.com/rtCamp/wordpress-skeleton/blob/main/.github/hosts.yml). 48 | 49 | ## Inventory file Variables 50 | 51 | ### Mandatory 52 | 53 | | Variable | Default | Possible Values | Purpose | 54 | |---------------|---------|----------------------------------------------------------------|--------------------------------| 55 | | `user` | null | valid username. eg: `root` | Username for ssh. | 56 | | `deploy_path` | null | valid path. eg: `/opt/easyengine/sites/example.com/app/htdocs` | path where action will deploy. | 57 | | `hostname` | null | hostname/ip. eg: `example.com` | hostname for ssh. | 58 | 59 | 60 | ### Optional 61 | 62 | | Variable | Default | Possible Values | Description | 63 | |---------------------------------|------------------|-------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 64 | | `block_emails` | null | `true`/`false` | If set to true, this will enable email blocking functionality. | 65 | | `block_emails_plugin_path` | null | Accept relative path from wp-content directory, eg: `custom-mu-plugins` | If you have set the `MU_PLUGIN_DIR` constant in your wp-config.php file to specify a custom path for mu-plugins, you can use this variable to install Block Emails into your custom mu-plugins directory. | 66 | | `block_emails_plugin_file_name` | 000-block-emails | String without the .php extension. | If you wish to modify the loading position of this plugin within the mu-plugins loading phase. | 67 | | `WP_VERSION` | null | Any valid WordPress version | If you specify a WordPress version, then that speicifc WordPress version will be downloaded, instead of latest WordPress version. **Note:** Please use double quotes while giving value to this variable. This will have higher priority then the one defined in workflow file. | 68 | 69 | 70 | ## Environment Variables 71 | 72 | This GitHub action's behavior can be customized using following environment variables: 73 | 74 | | Variable | Default | Possible Values | Purpose | 75 | |------------------------|---------|---------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 76 | | `MU_PLUGINS_URL` | null | vip, any git repo url | If value is `vip`, then action will clone [VIP's MU plugins](https://github.com/Automattic/vip-mu-plugins-public) as `mu-plugins` folder. If you want to specifiy a non-VIP mu-plugins repo, you can provide a publicly accessible mu-plugins repo URL as the value. | 77 | | `WP_VERSION` | latest | Any valid WordPress version | If you specify a WordPress version, then that speicifc WordPress version will be downloaded, instead of latest WordPress version. **Note:** Please use double quotes while giving value to this variable. Also, `WP_VERSION`, if defined in hosts.yml will have higher priority then the one defined in workflow file. | 78 | | `WP_MINOR_UPDATE` | null | `true` / `false` | If set to `true`, latest minor version of `WP_VERSION` will be taken. | 79 | | `JUMPHOST_SERVER` | null | Hostname/IP address of the jumphost server | If the deployment server is not directly accessible, and needs a jumphost, then this method should be used. (Note: The `SSH_PRIVATE_KEY` env variable should have access to the jumphost as well as deployment server for this to work. Also, this method does not work with vault.) | 80 | | `SUBMODULE_DEPLOY_KEY` | null | Read access deploy key created in the submodule repo's deploy keys. | Only required for privated submodule repo. For now only one private submodule deploy key is allowed. All public submodules in repo will be fetched by default without the need of this env variable. (To create a deploy key go to: Settings > Deploy Keys > Add deploy key) | 81 | | `SKIP_WP_TASKS` | null | `true`/`false` | If set to `true`, WordPress specific deplyment tasks will skipped. | 82 | | `PHP_VERSION` | 7.4 | Valid PHP version | Determines the cachetool version compatible to use for purging opcache. | 83 | | `NPM_VERSION` | null | Valid NPM Version | NPM Version. If not specified, latest version will be used. | 84 | | `NODE_VERSION` | null | Valid Node Version | If not specified, default version built into action will be used. | 85 | | `NODE_BUILD_DIRECTORY` | null | path to valid directory on repository. | Build directory. Generally root directory or directory like frontend. | 86 | | `NODE_BUILD_COMMAND` | null | `npm run build` or similar command. | Command used to to build the dependencies needed on deployment. | 87 | | `NODE_BUILD_SCRIPT` | null | path to valid shell script | Custom or predefined script to run after compilation. | 88 | | `PHP_BUILD_DIRECTORY` | null | Path to valid directory | Directory to run PHP build commands/scripts in. | 89 | | `PHP_BUILD_COMMAND` | null | Any shell command | Command to run for building PHP dependencies or other PHP build steps. | 90 | | `PHP_BUILD_SCRIPT` | null | Path to valid shell script | Custom or predefined script to run for PHP build steps. | 91 | 92 | All node and php related variables are completely optional. You can use them if your site needs to have such dependencies built. 93 | 94 | ### PHP Build Support 95 | 96 | You can now run custom PHP build steps before deployment by setting the following environment variables in your workflow: 97 | 98 | ```yaml 99 | env: 100 | PHP_VERSION: "8.1" 101 | PHP_BUILD_DIRECTORY: "./" 102 | PHP_BUILD_COMMAND: "composer install --no-dev" 103 | PHP_BUILD_SCRIPT: "./scripts/php-build.sh" 104 | ``` 105 | 106 | - `PHP_VERSION`: Installs the specified PHP version before running build steps. 107 | - `PHP_BUILD_DIRECTORY`: Directory to change into before running build commands/scripts. 108 | - `PHP_BUILD_COMMAND`: Shell command to run for PHP build (e.g., `composer install`). 109 | - `PHP_BUILD_SCRIPT`: Path to a shell script to execute for PHP build steps. 110 | 111 | ### Node Build Support 112 | 113 | You can also run custom Node.js build steps before deployment by setting the following environment variables in your workflow: 114 | 115 | ```yaml 116 | env: 117 | NODE_VERSION: "20" 118 | NPM_VERSION: "10" 119 | NODE_BUILD_DIRECTORY: "./frontend" 120 | NODE_BUILD_COMMAND: "npm run build" 121 | NODE_BUILD_SCRIPT: "./scripts/node-build.sh" 122 | ``` 123 | 124 | - `NODE_VERSION`: Installs the specified Node.js version before running build steps. 125 | - `NPM_VERSION`: Installs the specified npm version (defaults to latest if not set). 126 | - `NODE_BUILD_DIRECTORY`: Directory to change into before running build commands/scripts. 127 | - `NODE_BUILD_COMMAND`: Shell command to run for Node.js build (e.g., `npm run build`). 128 | - `NODE_BUILD_SCRIPT`: Path to a shell script to execute for Node.js build steps. 129 | 130 | These steps will be executed before PHP build steps. 131 | 132 | ## Server Setup 133 | 134 | The Deployer.org expects server setup in a particular way. 135 | 136 | ### Using [EasyEngine](https://easyengine.io/) v4 137 | 138 | #### New Site 139 | 140 | 1. Pass flag `--public-dir=current` during site creation. 141 | 2. Delete the `current` folder using `rm -r /opt/easyengine/sites/example.com/app/htdocs/current`. 142 | 143 | The `current` folder will be automatically created by Deployer during execution. 144 | 145 | #### Existing Site 146 | 147 | 1. Open file `/opt/easyengine/sites/example.com/config/nginx/conf.d/main.conf`. 148 | 2. Replace `/var/www/htdocs` with `/var/www/htdocs/current`. 149 | 3. Run `ee site reload example.com`. 150 | 4. Move `wp-config.php` to `htdocs`. You can use following command: 151 | 152 | ```bash 153 | mv /opt/easyengine/sites/example.com/app/wp-config.php /opt/easyengine/sites/example.com/app/htdocs/wp-config.php 154 | ``` 155 | 156 | ### Not using EasyEngine 157 | 158 | 1. Make sure your web server points to `current` subdirectory inside original webroot. Make sure `current` subdirectory 159 | do NOT exist actually. 160 | 2. You may need to reload your webserver. 161 | 3. You may need to change location of `wp-config.php` as we need in above section. 162 | 163 | ## Hashicorp Vault (Optional) 164 | 165 | This GitHub action supports [Hashicorp Vault](https://www.vaultproject.io/). This comes in handy if you manage multiple 166 | servers and providing `SSH_PRIVATE_KEY` as GitHub secret per project becomes cumbersome. 167 | 168 | To enable Hashicorp Vault support, please define following GitHub secrets: 169 | 170 | Variable | Purpose | Example Vaule 171 | --------------|-------------------------------------------------------------------------------|------------- 172 | `VAULT_ADDR` | [Vault server address](https://www.vaultproject.io/docs/commands/#vault_addr) | `https://example.com:8200` 173 | `VAULT_TOKEN` | [Vault token](https://www.vaultproject.io/docs/concepts/tokens.html) | `s.gIX5MKov9TUp7iiIqhrP1HgN` 174 | 175 | You will need to change `secrets` line in `deploy.yml` file to look like below. 176 | 177 | ```yml 178 | on: push 179 | name: Deploying WordPress Site using vault 180 | jobs: 181 | deploy: 182 | name: Deploy 183 | runs-on: ubuntu-latest 184 | steps: 185 | - uses: actions/checkout@v2 186 | - name: Deploy 187 | uses: rtCamp/action-deploy-wordpress@v3 188 | env: 189 | VAULT_ADDR: ${{ secrets.VAULT_ADDR }} 190 | VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }} 191 | ``` 192 | 193 | GitHub action uses `VAULT_TOKEN` to connect to `VAULT_ADDR` to 194 | retrieve [Signed SSH Certificates](https://www.vaultproject.io/docs/secrets/ssh/signed-ssh-certificates.html#signing-key-amp-role-configuration) 195 | and uses it for deployment. 196 | 197 | Please remember that you must configure each of your target deployment server to accept ssh connection via signed 198 | certificate using Vault beforehand. Ususally, you need to run following commands once per server: 199 | 200 | ```bash 201 | export VAULT_ADDR='https://example.com:8200' 202 | export VAULT_TOKEN='s.gIX5MKov9TUp7iiIqhrP1HgN' 203 | 204 | # Add the public key to all target host's SSH configuration. 205 | curl -o /etc/ssh/trusted-user-ca-keys.pem "$VAULT_ADDR/v1/ssh-client-signer/public_key" 206 | 207 | # Add the path where the public key contents are stored to the SSH configuration file as the TrustedUserCAKeys option. 208 | echo "TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem" >> /etc/ssh/sshd_config 209 | 210 | # Restart ssh service. This may differ according to the OS. 211 | systemctl restart ssh 212 | ``` 213 | 214 | ## Overriding default deployement behavior 215 | 216 | 1. If you would like to completely override this actions deployer recipe. Create a file at 217 | location `.github/deploy/deploy.php` in your git repository to provide your own [Deployer.org](https://deployer.org/) 218 | script. 219 | * Please note that it will completely override this 220 | action's [original deploy.php](https://github.com/rtCamp/action-deploy-wordpress/blob/master/deploy.php). So if 221 | you need some portion 222 | of [original deploy.php](https://github.com/rtCamp/action-deploy-wordpress/blob/master/deploy.php), you need to 223 | copy that to your own `.github/deploy/deploy.php`. 224 | 2. If you need to add one or a few custom tasks on top of this actions `deploy.php`, you can create a file at 225 | location `.github/deploy/addon.php` in your git repository. Checkout the [example addon.php](./example/addon.php) to 226 | see how to customize it. 227 | 3. If you need to modify the `main.sh` shell script of this action, you can create a file at 228 | location `.github/deploy/addon.sh` in your git repository. Checkout the [example addon.sh](./example/addon.sh) to see 229 | how to customize. 230 | 231 | ## License 232 | 233 | [MIT](LICENSE) © 2022 rtCamp 234 | 235 | ## Does this interest you? 236 | 237 | Join us at rtCamp, we specialize in providing high performance enterprise WordPress solutions 238 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Deploy WordPress' 2 | description: 'Deploy WordPress code to a server' 3 | author: 'rtCamp' 4 | runs: 5 | using: 'docker' 6 | image: 'docker://ghcr.io/rtcamp/action-deploy-wordpress:v3.2.0' 7 | branding: 8 | icon: 'upload-cloud' 9 | color: 'yellow' 10 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "deployer/deployer": "^6.8", 4 | "deployer/recipes": "^6.2" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "d4dcf524481a88f24a672431352717b9", 8 | "packages": [ 9 | { 10 | "name": "deployer/deployer", 11 | "version": "v6.8.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/deployphp/deployer.git", 15 | "reference": "4e243a64ed61e779fbb31c5a74e258a8e52fdaff" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/deployphp/deployer/zipball/4e243a64ed61e779fbb31c5a74e258a8e52fdaff", 20 | "reference": "4e243a64ed61e779fbb31c5a74e258a8e52fdaff", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "deployer/phar-update": "~2.2", 25 | "php": "^7.2", 26 | "pimple/pimple": "~3.0", 27 | "symfony/console": "~2.7|~3.0|~4.0|~5.0", 28 | "symfony/process": "~2.7|~3.0|~4.0|~5.0", 29 | "symfony/yaml": "~2.7|~3.0|~4.0|~5.0" 30 | }, 31 | "require-dev": { 32 | "phpunit/phpunit": "^8" 33 | }, 34 | "bin": [ 35 | "bin/dep" 36 | ], 37 | "type": "library", 38 | "autoload": { 39 | "files": [ 40 | "src/Support/helpers.php", 41 | "src/functions.php" 42 | ], 43 | "psr-4": { 44 | "Deployer\\": "src/" 45 | } 46 | }, 47 | "notification-url": "https://packagist.org/downloads/", 48 | "license": [ 49 | "MIT" 50 | ], 51 | "authors": [ 52 | { 53 | "name": "Anton Medvedev", 54 | "email": "anton@medv.io" 55 | } 56 | ], 57 | "description": "Deployment Tool", 58 | "homepage": "https://deployer.org", 59 | "support": { 60 | "docs": "https://deployer.org/docs", 61 | "issues": "https://github.com/deployphp/deployer/issues", 62 | "source": "https://github.com/deployphp/deployer" 63 | }, 64 | "funding": [ 65 | { 66 | "url": "https://github.com/antonmedv", 67 | "type": "github" 68 | }, 69 | { 70 | "url": "https://www.patreon.com/deployer", 71 | "type": "patreon" 72 | } 73 | ], 74 | "time": "2020-04-25T16:05:31+00:00" 75 | }, 76 | { 77 | "name": "deployer/phar-update", 78 | "version": "v2.2.0", 79 | "source": { 80 | "type": "git", 81 | "url": "https://github.com/deployphp/phar-update.git", 82 | "reference": "9ad07422f2cd43a1382ee8e134bdcd3a374848e3" 83 | }, 84 | "dist": { 85 | "type": "zip", 86 | "url": "https://api.github.com/repos/deployphp/phar-update/zipball/9ad07422f2cd43a1382ee8e134bdcd3a374848e3", 87 | "reference": "9ad07422f2cd43a1382ee8e134bdcd3a374848e3", 88 | "shasum": "" 89 | }, 90 | "require": { 91 | "php": ">=5.3.3", 92 | "symfony/console": "~2.7|~3.0|~4.0|~5.0" 93 | }, 94 | "require-dev": { 95 | "mikey179/vfsstream": "1.1.0", 96 | "phpunit/phpunit": "3.7.*", 97 | "symfony/process": "~2.7|~3.0|~4.0|~5.0" 98 | }, 99 | "type": "library", 100 | "autoload": { 101 | "psr-4": { 102 | "Deployer\\Component\\PharUpdate\\": "src/", 103 | "Deployer\\Component\\PHPUnit\\": "src/PHPUnit/", 104 | "Deployer\\Component\\Version\\": "src/Version/" 105 | } 106 | }, 107 | "notification-url": "https://packagist.org/downloads/", 108 | "license": [ 109 | "MIT" 110 | ], 111 | "authors": [ 112 | { 113 | "name": "Kevin Herrera", 114 | "email": "kevin@herrera.io", 115 | "homepage": "http://kevin.herrera.io" 116 | }, 117 | { 118 | "name": "Anton Medvedev", 119 | "email": "anton@medv.io", 120 | "homepage": "https://medv.io" 121 | } 122 | ], 123 | "description": "Integrates Phar Update to Symfony Console.", 124 | "homepage": "https://github.com/deployphp/phar-update", 125 | "keywords": [ 126 | "console", 127 | "phar", 128 | "update" 129 | ], 130 | "support": { 131 | "issues": "https://github.com/deployphp/phar-update/issues", 132 | "source": "https://github.com/deployphp/phar-update/tree/v2.2.0" 133 | }, 134 | "abandoned": true, 135 | "time": "2019-12-12T13:45:57+00:00" 136 | }, 137 | { 138 | "name": "deployer/recipes", 139 | "version": "6.2.2", 140 | "source": { 141 | "type": "git", 142 | "url": "https://github.com/deployphp/recipes.git", 143 | "reference": "84b3229c518c094a950e1fe785b7b8f9598770fe" 144 | }, 145 | "dist": { 146 | "type": "zip", 147 | "url": "https://api.github.com/repos/deployphp/recipes/zipball/84b3229c518c094a950e1fe785b7b8f9598770fe", 148 | "reference": "84b3229c518c094a950e1fe785b7b8f9598770fe", 149 | "shasum": "" 150 | }, 151 | "require": { 152 | "php": "~7.0" 153 | }, 154 | "replace": { 155 | "deployer/recipes": "self.version" 156 | }, 157 | "require-dev": { 158 | "deployer/deployer": "^6.3" 159 | }, 160 | "type": "library", 161 | "autoload": { 162 | "files": [ 163 | "autoload.php" 164 | ] 165 | }, 166 | "notification-url": "https://packagist.org/downloads/", 167 | "license": [ 168 | "MIT" 169 | ], 170 | "authors": [ 171 | { 172 | "name": "Anton Medvedev", 173 | "email": "anton@medv.io" 174 | } 175 | ], 176 | "description": "3rd party deployer recipes", 177 | "homepage": "https://github.com/deployphp/recipes", 178 | "keywords": [ 179 | "cachetool", 180 | "cloudflare", 181 | "deploy", 182 | "deployer", 183 | "deployment", 184 | "hipchat", 185 | "newrelic", 186 | "rabbit", 187 | "recipes", 188 | "sentry", 189 | "slack", 190 | "yarn" 191 | ], 192 | "support": { 193 | "issues": "https://github.com/deployphp/recipes/issues", 194 | "source": "https://github.com/deployphp/recipes" 195 | }, 196 | "abandoned": true, 197 | "time": "2019-06-27T06:47:18+00:00" 198 | }, 199 | { 200 | "name": "pimple/pimple", 201 | "version": "v3.5.0", 202 | "source": { 203 | "type": "git", 204 | "url": "https://github.com/silexphp/Pimple.git", 205 | "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed" 206 | }, 207 | "dist": { 208 | "type": "zip", 209 | "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a94b3a4db7fb774b3d78dad2315ddc07629e1bed", 210 | "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed", 211 | "shasum": "" 212 | }, 213 | "require": { 214 | "php": ">=7.2.5", 215 | "psr/container": "^1.1 || ^2.0" 216 | }, 217 | "require-dev": { 218 | "symfony/phpunit-bridge": "^5.4@dev" 219 | }, 220 | "type": "library", 221 | "extra": { 222 | "branch-alias": { 223 | "dev-master": "3.4.x-dev" 224 | } 225 | }, 226 | "autoload": { 227 | "psr-0": { 228 | "Pimple": "src/" 229 | } 230 | }, 231 | "notification-url": "https://packagist.org/downloads/", 232 | "license": [ 233 | "MIT" 234 | ], 235 | "authors": [ 236 | { 237 | "name": "Fabien Potencier", 238 | "email": "fabien@symfony.com" 239 | } 240 | ], 241 | "description": "Pimple, a simple Dependency Injection Container", 242 | "homepage": "https://pimple.symfony.com", 243 | "keywords": [ 244 | "container", 245 | "dependency injection" 246 | ], 247 | "support": { 248 | "source": "https://github.com/silexphp/Pimple/tree/v3.5.0" 249 | }, 250 | "time": "2021-10-28T11:13:42+00:00" 251 | }, 252 | { 253 | "name": "psr/container", 254 | "version": "2.0.2", 255 | "source": { 256 | "type": "git", 257 | "url": "https://github.com/php-fig/container.git", 258 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" 259 | }, 260 | "dist": { 261 | "type": "zip", 262 | "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", 263 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", 264 | "shasum": "" 265 | }, 266 | "require": { 267 | "php": ">=7.4.0" 268 | }, 269 | "type": "library", 270 | "extra": { 271 | "branch-alias": { 272 | "dev-master": "2.0.x-dev" 273 | } 274 | }, 275 | "autoload": { 276 | "psr-4": { 277 | "Psr\\Container\\": "src/" 278 | } 279 | }, 280 | "notification-url": "https://packagist.org/downloads/", 281 | "license": [ 282 | "MIT" 283 | ], 284 | "authors": [ 285 | { 286 | "name": "PHP-FIG", 287 | "homepage": "https://www.php-fig.org/" 288 | } 289 | ], 290 | "description": "Common Container Interface (PHP FIG PSR-11)", 291 | "homepage": "https://github.com/php-fig/container", 292 | "keywords": [ 293 | "PSR-11", 294 | "container", 295 | "container-interface", 296 | "container-interop", 297 | "psr" 298 | ], 299 | "support": { 300 | "issues": "https://github.com/php-fig/container/issues", 301 | "source": "https://github.com/php-fig/container/tree/2.0.2" 302 | }, 303 | "time": "2021-11-05T16:47:00+00:00" 304 | }, 305 | { 306 | "name": "symfony/console", 307 | "version": "v5.4.3", 308 | "source": { 309 | "type": "git", 310 | "url": "https://github.com/symfony/console.git", 311 | "reference": "a2a86ec353d825c75856c6fd14fac416a7bdb6b8" 312 | }, 313 | "dist": { 314 | "type": "zip", 315 | "url": "https://api.github.com/repos/symfony/console/zipball/a2a86ec353d825c75856c6fd14fac416a7bdb6b8", 316 | "reference": "a2a86ec353d825c75856c6fd14fac416a7bdb6b8", 317 | "shasum": "" 318 | }, 319 | "require": { 320 | "php": ">=7.2.5", 321 | "symfony/deprecation-contracts": "^2.1|^3", 322 | "symfony/polyfill-mbstring": "~1.0", 323 | "symfony/polyfill-php73": "^1.9", 324 | "symfony/polyfill-php80": "^1.16", 325 | "symfony/service-contracts": "^1.1|^2|^3", 326 | "symfony/string": "^5.1|^6.0" 327 | }, 328 | "conflict": { 329 | "psr/log": ">=3", 330 | "symfony/dependency-injection": "<4.4", 331 | "symfony/dotenv": "<5.1", 332 | "symfony/event-dispatcher": "<4.4", 333 | "symfony/lock": "<4.4", 334 | "symfony/process": "<4.4" 335 | }, 336 | "provide": { 337 | "psr/log-implementation": "1.0|2.0" 338 | }, 339 | "require-dev": { 340 | "psr/log": "^1|^2", 341 | "symfony/config": "^4.4|^5.0|^6.0", 342 | "symfony/dependency-injection": "^4.4|^5.0|^6.0", 343 | "symfony/event-dispatcher": "^4.4|^5.0|^6.0", 344 | "symfony/lock": "^4.4|^5.0|^6.0", 345 | "symfony/process": "^4.4|^5.0|^6.0", 346 | "symfony/var-dumper": "^4.4|^5.0|^6.0" 347 | }, 348 | "suggest": { 349 | "psr/log": "For using the console logger", 350 | "symfony/event-dispatcher": "", 351 | "symfony/lock": "", 352 | "symfony/process": "" 353 | }, 354 | "type": "library", 355 | "autoload": { 356 | "psr-4": { 357 | "Symfony\\Component\\Console\\": "" 358 | }, 359 | "exclude-from-classmap": [ 360 | "/Tests/" 361 | ] 362 | }, 363 | "notification-url": "https://packagist.org/downloads/", 364 | "license": [ 365 | "MIT" 366 | ], 367 | "authors": [ 368 | { 369 | "name": "Fabien Potencier", 370 | "email": "fabien@symfony.com" 371 | }, 372 | { 373 | "name": "Symfony Community", 374 | "homepage": "https://symfony.com/contributors" 375 | } 376 | ], 377 | "description": "Eases the creation of beautiful and testable command line interfaces", 378 | "homepage": "https://symfony.com", 379 | "keywords": [ 380 | "cli", 381 | "command line", 382 | "console", 383 | "terminal" 384 | ], 385 | "support": { 386 | "source": "https://github.com/symfony/console/tree/v5.4.3" 387 | }, 388 | "funding": [ 389 | { 390 | "url": "https://symfony.com/sponsor", 391 | "type": "custom" 392 | }, 393 | { 394 | "url": "https://github.com/fabpot", 395 | "type": "github" 396 | }, 397 | { 398 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 399 | "type": "tidelift" 400 | } 401 | ], 402 | "time": "2022-01-26T16:28:35+00:00" 403 | }, 404 | { 405 | "name": "symfony/deprecation-contracts", 406 | "version": "v2.5.0", 407 | "source": { 408 | "type": "git", 409 | "url": "https://github.com/symfony/deprecation-contracts.git", 410 | "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" 411 | }, 412 | "dist": { 413 | "type": "zip", 414 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", 415 | "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", 416 | "shasum": "" 417 | }, 418 | "require": { 419 | "php": ">=7.1" 420 | }, 421 | "type": "library", 422 | "extra": { 423 | "branch-alias": { 424 | "dev-main": "2.5-dev" 425 | }, 426 | "thanks": { 427 | "name": "symfony/contracts", 428 | "url": "https://github.com/symfony/contracts" 429 | } 430 | }, 431 | "autoload": { 432 | "files": [ 433 | "function.php" 434 | ] 435 | }, 436 | "notification-url": "https://packagist.org/downloads/", 437 | "license": [ 438 | "MIT" 439 | ], 440 | "authors": [ 441 | { 442 | "name": "Nicolas Grekas", 443 | "email": "p@tchwork.com" 444 | }, 445 | { 446 | "name": "Symfony Community", 447 | "homepage": "https://symfony.com/contributors" 448 | } 449 | ], 450 | "description": "A generic function and convention to trigger deprecation notices", 451 | "homepage": "https://symfony.com", 452 | "support": { 453 | "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" 454 | }, 455 | "funding": [ 456 | { 457 | "url": "https://symfony.com/sponsor", 458 | "type": "custom" 459 | }, 460 | { 461 | "url": "https://github.com/fabpot", 462 | "type": "github" 463 | }, 464 | { 465 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 466 | "type": "tidelift" 467 | } 468 | ], 469 | "time": "2021-07-12T14:48:14+00:00" 470 | }, 471 | { 472 | "name": "symfony/polyfill-ctype", 473 | "version": "v1.24.0", 474 | "source": { 475 | "type": "git", 476 | "url": "https://github.com/symfony/polyfill-ctype.git", 477 | "reference": "30885182c981ab175d4d034db0f6f469898070ab" 478 | }, 479 | "dist": { 480 | "type": "zip", 481 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", 482 | "reference": "30885182c981ab175d4d034db0f6f469898070ab", 483 | "shasum": "" 484 | }, 485 | "require": { 486 | "php": ">=7.1" 487 | }, 488 | "provide": { 489 | "ext-ctype": "*" 490 | }, 491 | "suggest": { 492 | "ext-ctype": "For best performance" 493 | }, 494 | "type": "library", 495 | "extra": { 496 | "branch-alias": { 497 | "dev-main": "1.23-dev" 498 | }, 499 | "thanks": { 500 | "name": "symfony/polyfill", 501 | "url": "https://github.com/symfony/polyfill" 502 | } 503 | }, 504 | "autoload": { 505 | "psr-4": { 506 | "Symfony\\Polyfill\\Ctype\\": "" 507 | }, 508 | "files": [ 509 | "bootstrap.php" 510 | ] 511 | }, 512 | "notification-url": "https://packagist.org/downloads/", 513 | "license": [ 514 | "MIT" 515 | ], 516 | "authors": [ 517 | { 518 | "name": "Gert de Pagter", 519 | "email": "BackEndTea@gmail.com" 520 | }, 521 | { 522 | "name": "Symfony Community", 523 | "homepage": "https://symfony.com/contributors" 524 | } 525 | ], 526 | "description": "Symfony polyfill for ctype functions", 527 | "homepage": "https://symfony.com", 528 | "keywords": [ 529 | "compatibility", 530 | "ctype", 531 | "polyfill", 532 | "portable" 533 | ], 534 | "support": { 535 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" 536 | }, 537 | "funding": [ 538 | { 539 | "url": "https://symfony.com/sponsor", 540 | "type": "custom" 541 | }, 542 | { 543 | "url": "https://github.com/fabpot", 544 | "type": "github" 545 | }, 546 | { 547 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 548 | "type": "tidelift" 549 | } 550 | ], 551 | "time": "2021-10-20T20:35:02+00:00" 552 | }, 553 | { 554 | "name": "symfony/polyfill-intl-grapheme", 555 | "version": "v1.24.0", 556 | "source": { 557 | "type": "git", 558 | "url": "https://github.com/symfony/polyfill-intl-grapheme.git", 559 | "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" 560 | }, 561 | "dist": { 562 | "type": "zip", 563 | "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", 564 | "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", 565 | "shasum": "" 566 | }, 567 | "require": { 568 | "php": ">=7.1" 569 | }, 570 | "suggest": { 571 | "ext-intl": "For best performance" 572 | }, 573 | "type": "library", 574 | "extra": { 575 | "branch-alias": { 576 | "dev-main": "1.23-dev" 577 | }, 578 | "thanks": { 579 | "name": "symfony/polyfill", 580 | "url": "https://github.com/symfony/polyfill" 581 | } 582 | }, 583 | "autoload": { 584 | "files": [ 585 | "bootstrap.php" 586 | ], 587 | "psr-4": { 588 | "Symfony\\Polyfill\\Intl\\Grapheme\\": "" 589 | } 590 | }, 591 | "notification-url": "https://packagist.org/downloads/", 592 | "license": [ 593 | "MIT" 594 | ], 595 | "authors": [ 596 | { 597 | "name": "Nicolas Grekas", 598 | "email": "p@tchwork.com" 599 | }, 600 | { 601 | "name": "Symfony Community", 602 | "homepage": "https://symfony.com/contributors" 603 | } 604 | ], 605 | "description": "Symfony polyfill for intl's grapheme_* functions", 606 | "homepage": "https://symfony.com", 607 | "keywords": [ 608 | "compatibility", 609 | "grapheme", 610 | "intl", 611 | "polyfill", 612 | "portable", 613 | "shim" 614 | ], 615 | "support": { 616 | "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0" 617 | }, 618 | "funding": [ 619 | { 620 | "url": "https://symfony.com/sponsor", 621 | "type": "custom" 622 | }, 623 | { 624 | "url": "https://github.com/fabpot", 625 | "type": "github" 626 | }, 627 | { 628 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 629 | "type": "tidelift" 630 | } 631 | ], 632 | "time": "2021-11-23T21:10:46+00:00" 633 | }, 634 | { 635 | "name": "symfony/polyfill-intl-normalizer", 636 | "version": "v1.24.0", 637 | "source": { 638 | "type": "git", 639 | "url": "https://github.com/symfony/polyfill-intl-normalizer.git", 640 | "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" 641 | }, 642 | "dist": { 643 | "type": "zip", 644 | "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", 645 | "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", 646 | "shasum": "" 647 | }, 648 | "require": { 649 | "php": ">=7.1" 650 | }, 651 | "suggest": { 652 | "ext-intl": "For best performance" 653 | }, 654 | "type": "library", 655 | "extra": { 656 | "branch-alias": { 657 | "dev-main": "1.23-dev" 658 | }, 659 | "thanks": { 660 | "name": "symfony/polyfill", 661 | "url": "https://github.com/symfony/polyfill" 662 | } 663 | }, 664 | "autoload": { 665 | "files": [ 666 | "bootstrap.php" 667 | ], 668 | "psr-4": { 669 | "Symfony\\Polyfill\\Intl\\Normalizer\\": "" 670 | }, 671 | "classmap": [ 672 | "Resources/stubs" 673 | ] 674 | }, 675 | "notification-url": "https://packagist.org/downloads/", 676 | "license": [ 677 | "MIT" 678 | ], 679 | "authors": [ 680 | { 681 | "name": "Nicolas Grekas", 682 | "email": "p@tchwork.com" 683 | }, 684 | { 685 | "name": "Symfony Community", 686 | "homepage": "https://symfony.com/contributors" 687 | } 688 | ], 689 | "description": "Symfony polyfill for intl's Normalizer class and related functions", 690 | "homepage": "https://symfony.com", 691 | "keywords": [ 692 | "compatibility", 693 | "intl", 694 | "normalizer", 695 | "polyfill", 696 | "portable", 697 | "shim" 698 | ], 699 | "support": { 700 | "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0" 701 | }, 702 | "funding": [ 703 | { 704 | "url": "https://symfony.com/sponsor", 705 | "type": "custom" 706 | }, 707 | { 708 | "url": "https://github.com/fabpot", 709 | "type": "github" 710 | }, 711 | { 712 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 713 | "type": "tidelift" 714 | } 715 | ], 716 | "time": "2021-02-19T12:13:01+00:00" 717 | }, 718 | { 719 | "name": "symfony/polyfill-mbstring", 720 | "version": "v1.24.0", 721 | "source": { 722 | "type": "git", 723 | "url": "https://github.com/symfony/polyfill-mbstring.git", 724 | "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" 725 | }, 726 | "dist": { 727 | "type": "zip", 728 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", 729 | "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", 730 | "shasum": "" 731 | }, 732 | "require": { 733 | "php": ">=7.1" 734 | }, 735 | "provide": { 736 | "ext-mbstring": "*" 737 | }, 738 | "suggest": { 739 | "ext-mbstring": "For best performance" 740 | }, 741 | "type": "library", 742 | "extra": { 743 | "branch-alias": { 744 | "dev-main": "1.23-dev" 745 | }, 746 | "thanks": { 747 | "name": "symfony/polyfill", 748 | "url": "https://github.com/symfony/polyfill" 749 | } 750 | }, 751 | "autoload": { 752 | "files": [ 753 | "bootstrap.php" 754 | ], 755 | "psr-4": { 756 | "Symfony\\Polyfill\\Mbstring\\": "" 757 | } 758 | }, 759 | "notification-url": "https://packagist.org/downloads/", 760 | "license": [ 761 | "MIT" 762 | ], 763 | "authors": [ 764 | { 765 | "name": "Nicolas Grekas", 766 | "email": "p@tchwork.com" 767 | }, 768 | { 769 | "name": "Symfony Community", 770 | "homepage": "https://symfony.com/contributors" 771 | } 772 | ], 773 | "description": "Symfony polyfill for the Mbstring extension", 774 | "homepage": "https://symfony.com", 775 | "keywords": [ 776 | "compatibility", 777 | "mbstring", 778 | "polyfill", 779 | "portable", 780 | "shim" 781 | ], 782 | "support": { 783 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" 784 | }, 785 | "funding": [ 786 | { 787 | "url": "https://symfony.com/sponsor", 788 | "type": "custom" 789 | }, 790 | { 791 | "url": "https://github.com/fabpot", 792 | "type": "github" 793 | }, 794 | { 795 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 796 | "type": "tidelift" 797 | } 798 | ], 799 | "time": "2021-11-30T18:21:41+00:00" 800 | }, 801 | { 802 | "name": "symfony/polyfill-php73", 803 | "version": "v1.24.0", 804 | "source": { 805 | "type": "git", 806 | "url": "https://github.com/symfony/polyfill-php73.git", 807 | "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" 808 | }, 809 | "dist": { 810 | "type": "zip", 811 | "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", 812 | "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", 813 | "shasum": "" 814 | }, 815 | "require": { 816 | "php": ">=7.1" 817 | }, 818 | "type": "library", 819 | "extra": { 820 | "branch-alias": { 821 | "dev-main": "1.23-dev" 822 | }, 823 | "thanks": { 824 | "name": "symfony/polyfill", 825 | "url": "https://github.com/symfony/polyfill" 826 | } 827 | }, 828 | "autoload": { 829 | "files": [ 830 | "bootstrap.php" 831 | ], 832 | "psr-4": { 833 | "Symfony\\Polyfill\\Php73\\": "" 834 | }, 835 | "classmap": [ 836 | "Resources/stubs" 837 | ] 838 | }, 839 | "notification-url": "https://packagist.org/downloads/", 840 | "license": [ 841 | "MIT" 842 | ], 843 | "authors": [ 844 | { 845 | "name": "Nicolas Grekas", 846 | "email": "p@tchwork.com" 847 | }, 848 | { 849 | "name": "Symfony Community", 850 | "homepage": "https://symfony.com/contributors" 851 | } 852 | ], 853 | "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", 854 | "homepage": "https://symfony.com", 855 | "keywords": [ 856 | "compatibility", 857 | "polyfill", 858 | "portable", 859 | "shim" 860 | ], 861 | "support": { 862 | "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" 863 | }, 864 | "funding": [ 865 | { 866 | "url": "https://symfony.com/sponsor", 867 | "type": "custom" 868 | }, 869 | { 870 | "url": "https://github.com/fabpot", 871 | "type": "github" 872 | }, 873 | { 874 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 875 | "type": "tidelift" 876 | } 877 | ], 878 | "time": "2021-06-05T21:20:04+00:00" 879 | }, 880 | { 881 | "name": "symfony/polyfill-php80", 882 | "version": "v1.24.0", 883 | "source": { 884 | "type": "git", 885 | "url": "https://github.com/symfony/polyfill-php80.git", 886 | "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" 887 | }, 888 | "dist": { 889 | "type": "zip", 890 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", 891 | "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", 892 | "shasum": "" 893 | }, 894 | "require": { 895 | "php": ">=7.1" 896 | }, 897 | "type": "library", 898 | "extra": { 899 | "branch-alias": { 900 | "dev-main": "1.23-dev" 901 | }, 902 | "thanks": { 903 | "name": "symfony/polyfill", 904 | "url": "https://github.com/symfony/polyfill" 905 | } 906 | }, 907 | "autoload": { 908 | "files": [ 909 | "bootstrap.php" 910 | ], 911 | "psr-4": { 912 | "Symfony\\Polyfill\\Php80\\": "" 913 | }, 914 | "classmap": [ 915 | "Resources/stubs" 916 | ] 917 | }, 918 | "notification-url": "https://packagist.org/downloads/", 919 | "license": [ 920 | "MIT" 921 | ], 922 | "authors": [ 923 | { 924 | "name": "Ion Bazan", 925 | "email": "ion.bazan@gmail.com" 926 | }, 927 | { 928 | "name": "Nicolas Grekas", 929 | "email": "p@tchwork.com" 930 | }, 931 | { 932 | "name": "Symfony Community", 933 | "homepage": "https://symfony.com/contributors" 934 | } 935 | ], 936 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 937 | "homepage": "https://symfony.com", 938 | "keywords": [ 939 | "compatibility", 940 | "polyfill", 941 | "portable", 942 | "shim" 943 | ], 944 | "support": { 945 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" 946 | }, 947 | "funding": [ 948 | { 949 | "url": "https://symfony.com/sponsor", 950 | "type": "custom" 951 | }, 952 | { 953 | "url": "https://github.com/fabpot", 954 | "type": "github" 955 | }, 956 | { 957 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 958 | "type": "tidelift" 959 | } 960 | ], 961 | "time": "2021-09-13T13:58:33+00:00" 962 | }, 963 | { 964 | "name": "symfony/process", 965 | "version": "v5.4.3", 966 | "source": { 967 | "type": "git", 968 | "url": "https://github.com/symfony/process.git", 969 | "reference": "553f50487389a977eb31cf6b37faae56da00f753" 970 | }, 971 | "dist": { 972 | "type": "zip", 973 | "url": "https://api.github.com/repos/symfony/process/zipball/553f50487389a977eb31cf6b37faae56da00f753", 974 | "reference": "553f50487389a977eb31cf6b37faae56da00f753", 975 | "shasum": "" 976 | }, 977 | "require": { 978 | "php": ">=7.2.5", 979 | "symfony/polyfill-php80": "^1.16" 980 | }, 981 | "type": "library", 982 | "autoload": { 983 | "psr-4": { 984 | "Symfony\\Component\\Process\\": "" 985 | }, 986 | "exclude-from-classmap": [ 987 | "/Tests/" 988 | ] 989 | }, 990 | "notification-url": "https://packagist.org/downloads/", 991 | "license": [ 992 | "MIT" 993 | ], 994 | "authors": [ 995 | { 996 | "name": "Fabien Potencier", 997 | "email": "fabien@symfony.com" 998 | }, 999 | { 1000 | "name": "Symfony Community", 1001 | "homepage": "https://symfony.com/contributors" 1002 | } 1003 | ], 1004 | "description": "Executes commands in sub-processes", 1005 | "homepage": "https://symfony.com", 1006 | "support": { 1007 | "source": "https://github.com/symfony/process/tree/v5.4.3" 1008 | }, 1009 | "funding": [ 1010 | { 1011 | "url": "https://symfony.com/sponsor", 1012 | "type": "custom" 1013 | }, 1014 | { 1015 | "url": "https://github.com/fabpot", 1016 | "type": "github" 1017 | }, 1018 | { 1019 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1020 | "type": "tidelift" 1021 | } 1022 | ], 1023 | "time": "2022-01-26T16:28:35+00:00" 1024 | }, 1025 | { 1026 | "name": "symfony/service-contracts", 1027 | "version": "v1.1.2", 1028 | "source": { 1029 | "type": "git", 1030 | "url": "https://github.com/symfony/service-contracts.git", 1031 | "reference": "191afdcb5804db960d26d8566b7e9a2843cab3a0" 1032 | }, 1033 | "dist": { 1034 | "type": "zip", 1035 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/191afdcb5804db960d26d8566b7e9a2843cab3a0", 1036 | "reference": "191afdcb5804db960d26d8566b7e9a2843cab3a0", 1037 | "shasum": "" 1038 | }, 1039 | "require": { 1040 | "php": "^7.1.3" 1041 | }, 1042 | "suggest": { 1043 | "psr/container": "", 1044 | "symfony/service-implementation": "" 1045 | }, 1046 | "type": "library", 1047 | "extra": { 1048 | "branch-alias": { 1049 | "dev-master": "1.1-dev" 1050 | } 1051 | }, 1052 | "autoload": { 1053 | "psr-4": { 1054 | "Symfony\\Contracts\\Service\\": "" 1055 | } 1056 | }, 1057 | "notification-url": "https://packagist.org/downloads/", 1058 | "license": [ 1059 | "MIT" 1060 | ], 1061 | "authors": [ 1062 | { 1063 | "name": "Nicolas Grekas", 1064 | "email": "p@tchwork.com" 1065 | }, 1066 | { 1067 | "name": "Symfony Community", 1068 | "homepage": "https://symfony.com/contributors" 1069 | } 1070 | ], 1071 | "description": "Generic abstractions related to writing services", 1072 | "homepage": "https://symfony.com", 1073 | "keywords": [ 1074 | "abstractions", 1075 | "contracts", 1076 | "decoupling", 1077 | "interfaces", 1078 | "interoperability", 1079 | "standards" 1080 | ], 1081 | "support": { 1082 | "source": "https://github.com/symfony/service-contracts/tree/v1.1.2" 1083 | }, 1084 | "time": "2019-05-28T07:50:59+00:00" 1085 | }, 1086 | { 1087 | "name": "symfony/string", 1088 | "version": "v5.4.3", 1089 | "source": { 1090 | "type": "git", 1091 | "url": "https://github.com/symfony/string.git", 1092 | "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10" 1093 | }, 1094 | "dist": { 1095 | "type": "zip", 1096 | "url": "https://api.github.com/repos/symfony/string/zipball/92043b7d8383e48104e411bc9434b260dbeb5a10", 1097 | "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10", 1098 | "shasum": "" 1099 | }, 1100 | "require": { 1101 | "php": ">=7.2.5", 1102 | "symfony/polyfill-ctype": "~1.8", 1103 | "symfony/polyfill-intl-grapheme": "~1.0", 1104 | "symfony/polyfill-intl-normalizer": "~1.0", 1105 | "symfony/polyfill-mbstring": "~1.0", 1106 | "symfony/polyfill-php80": "~1.15" 1107 | }, 1108 | "conflict": { 1109 | "symfony/translation-contracts": ">=3.0" 1110 | }, 1111 | "require-dev": { 1112 | "symfony/error-handler": "^4.4|^5.0|^6.0", 1113 | "symfony/http-client": "^4.4|^5.0|^6.0", 1114 | "symfony/translation-contracts": "^1.1|^2", 1115 | "symfony/var-exporter": "^4.4|^5.0|^6.0" 1116 | }, 1117 | "type": "library", 1118 | "autoload": { 1119 | "psr-4": { 1120 | "Symfony\\Component\\String\\": "" 1121 | }, 1122 | "files": [ 1123 | "Resources/functions.php" 1124 | ], 1125 | "exclude-from-classmap": [ 1126 | "/Tests/" 1127 | ] 1128 | }, 1129 | "notification-url": "https://packagist.org/downloads/", 1130 | "license": [ 1131 | "MIT" 1132 | ], 1133 | "authors": [ 1134 | { 1135 | "name": "Nicolas Grekas", 1136 | "email": "p@tchwork.com" 1137 | }, 1138 | { 1139 | "name": "Symfony Community", 1140 | "homepage": "https://symfony.com/contributors" 1141 | } 1142 | ], 1143 | "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", 1144 | "homepage": "https://symfony.com", 1145 | "keywords": [ 1146 | "grapheme", 1147 | "i18n", 1148 | "string", 1149 | "unicode", 1150 | "utf-8", 1151 | "utf8" 1152 | ], 1153 | "support": { 1154 | "source": "https://github.com/symfony/string/tree/v5.4.3" 1155 | }, 1156 | "funding": [ 1157 | { 1158 | "url": "https://symfony.com/sponsor", 1159 | "type": "custom" 1160 | }, 1161 | { 1162 | "url": "https://github.com/fabpot", 1163 | "type": "github" 1164 | }, 1165 | { 1166 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1167 | "type": "tidelift" 1168 | } 1169 | ], 1170 | "time": "2022-01-02T09:53:40+00:00" 1171 | }, 1172 | { 1173 | "name": "symfony/yaml", 1174 | "version": "v5.4.3", 1175 | "source": { 1176 | "type": "git", 1177 | "url": "https://github.com/symfony/yaml.git", 1178 | "reference": "e80f87d2c9495966768310fc531b487ce64237a2" 1179 | }, 1180 | "dist": { 1181 | "type": "zip", 1182 | "url": "https://api.github.com/repos/symfony/yaml/zipball/e80f87d2c9495966768310fc531b487ce64237a2", 1183 | "reference": "e80f87d2c9495966768310fc531b487ce64237a2", 1184 | "shasum": "" 1185 | }, 1186 | "require": { 1187 | "php": ">=7.2.5", 1188 | "symfony/deprecation-contracts": "^2.1|^3", 1189 | "symfony/polyfill-ctype": "^1.8" 1190 | }, 1191 | "conflict": { 1192 | "symfony/console": "<5.3" 1193 | }, 1194 | "require-dev": { 1195 | "symfony/console": "^5.3|^6.0" 1196 | }, 1197 | "suggest": { 1198 | "symfony/console": "For validating YAML files using the lint command" 1199 | }, 1200 | "bin": [ 1201 | "Resources/bin/yaml-lint" 1202 | ], 1203 | "type": "library", 1204 | "autoload": { 1205 | "psr-4": { 1206 | "Symfony\\Component\\Yaml\\": "" 1207 | }, 1208 | "exclude-from-classmap": [ 1209 | "/Tests/" 1210 | ] 1211 | }, 1212 | "notification-url": "https://packagist.org/downloads/", 1213 | "license": [ 1214 | "MIT" 1215 | ], 1216 | "authors": [ 1217 | { 1218 | "name": "Fabien Potencier", 1219 | "email": "fabien@symfony.com" 1220 | }, 1221 | { 1222 | "name": "Symfony Community", 1223 | "homepage": "https://symfony.com/contributors" 1224 | } 1225 | ], 1226 | "description": "Loads and dumps YAML files", 1227 | "homepage": "https://symfony.com", 1228 | "support": { 1229 | "source": "https://github.com/symfony/yaml/tree/v5.4.3" 1230 | }, 1231 | "funding": [ 1232 | { 1233 | "url": "https://symfony.com/sponsor", 1234 | "type": "custom" 1235 | }, 1236 | { 1237 | "url": "https://github.com/fabpot", 1238 | "type": "github" 1239 | }, 1240 | { 1241 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1242 | "type": "tidelift" 1243 | } 1244 | ], 1245 | "time": "2022-01-26T16:32:32+00:00" 1246 | } 1247 | ], 1248 | "packages-dev": [], 1249 | "aliases": [], 1250 | "minimum-stability": "stable", 1251 | "stability-flags": [], 1252 | "prefer-stable": false, 1253 | "prefer-lowest": false, 1254 | "platform": [], 1255 | "platform-dev": [], 1256 | "plugin-api-version": "2.0.0" 1257 | } 1258 | -------------------------------------------------------------------------------- /deploy.php: -------------------------------------------------------------------------------- 1 | hosts; 26 | 27 | foreach ( $hosts as $host ) { 28 | $host 29 | ->addSshOption( 'UserKnownHostsFile', '/dev/null' ) 30 | ->addSshOption( 'StrictHostKeyChecking', 'no' ); 31 | 32 | $deployer->hosts->set( $host->getHostname(), $host ); 33 | } 34 | 35 | // Add tests and other directory unnecessary things for 36 | // production to exclude block. 37 | set( 'rsync', [ 38 | 'exclude' => [ 39 | '.git', 40 | '.github', 41 | 'deploy.php', 42 | 'composer.lock', 43 | '.env', 44 | '.env.example', 45 | '.gitignore', 46 | '.gitlab-ci.yml', 47 | 'Gruntfile.js', 48 | 'package.json', 49 | 'gulpfile.js', 50 | '.circleci', 51 | 'package-lock.json', 52 | 'package.json', 53 | 'phpcs.xml', 54 | ], 55 | 'exclude-file' => true, 56 | 'include' => [], 57 | 'include-file' => false, 58 | 'filter' => [], 59 | 'filter-file' => false, 60 | 'filter-perdir' => false, 61 | 'flags' => 'rz', // Recursive, with compress 62 | 'options' => [ 'delete', 'delete-excluded', 'links', 'no-perms', 'no-owner', 'no-group' ], 63 | 'timeout' => 300, 64 | ] ); 65 | 66 | set( 'rsync_src', getenv( 'build_root' ) ); 67 | set( 'rsync_dest', '{{release_path}}' ); 68 | 69 | 70 | /* custom task defination */ 71 | desc( 'Download cachetool' ); 72 | task( 'cachetool:download', function () { 73 | 74 | $php_version = getenv( 'PHP_VERSION' ); 75 | if ( empty( $php_version ) ) { 76 | $ee_version = ''; 77 | try { 78 | $ee_version = run( 'ee --version' ); 79 | } catch ( \Exception $e ) { 80 | echo 'Not using EasyEngine.'; 81 | } 82 | 83 | if ( false !== strpos( $ee_version, 'EE 4' ) ) { 84 | try { 85 | $php_version = run( 'cd {{deploy_path}} && ee shell --command="php -r \'echo PHP_MAJOR_VERSION;\'" --skip-tty' ); 86 | } catch ( \Exception $e ) { 87 | echo 'Could not determine PHP version. Use `PHP_VERSION` env variable to specify the version.'; 88 | echo 'Falling back to version 7.4 as default'; 89 | $php_version = 7.4; 90 | } 91 | } 92 | } 93 | 94 | if ( $php_version < 8 ) { 95 | # Using 5.x for PHP >=7.2 compatibility 96 | run( 'wget https://github.com/gordalina/cachetool/releases/download/5.1.3/cachetool.phar -O {{release_path}}/cachetool.phar' ); 97 | } else { 98 | run( 'wget https://github.com/gordalina/cachetool/releases/download/8.4.0/cachetool.phar -O {{release_path}}/cachetool.phar' ); 99 | } 100 | } ); 101 | 102 | /* custom task defination */ 103 | desc( 'Reset opcache' ); 104 | task( 'opcache:reset', function () { 105 | 106 | $ee_version = ''; 107 | try { 108 | $ee_version = run( 'ee --version' ); 109 | } catch ( \Exception $e ) { 110 | echo 'Not using EasyEngine.'; 111 | } 112 | 113 | if ( false !== strpos( $ee_version, 'EasyEngine v3' ) ) { 114 | 115 | $output = run( 'php {{release_path}}/cachetool.phar opcache:reset --fcgi=127.0.0.1:9070' ); 116 | 117 | } elseif ( false !== strpos( $ee_version, 'EE 4' ) ) { 118 | 119 | cd( '{{deploy_path}}' ); 120 | $output = run( 'ee shell --command="php current/cachetool.phar opcache:reset --fcgi=127.0.0.1:9000" --skip-tty' ); 121 | 122 | } else { 123 | echo 'Skipping opcache reset as EasyEnigne is not installed.'; 124 | } 125 | 126 | writeln( '' . $output . '' ); 127 | 128 | } ); 129 | 130 | desc( 'Upgrade WordPress DB' ); 131 | task( 'core_db:update', function () { 132 | 133 | $ee_version = ''; 134 | try { 135 | $ee_version = run( 'ee --version' ); 136 | } catch ( \Exception $e ) { 137 | echo 'Not using EasyEngine.'; 138 | } 139 | 140 | if ( false !== strpos( $ee_version, 'EasyEngine v3' ) ) { 141 | 142 | $output = run( 'cd {{release_path}} && wp core update-db' ); 143 | 144 | } elseif ( false !== strpos( $ee_version, 'EE 4' ) ) { 145 | 146 | cd( '{{deploy_path}}' ); 147 | $output = run( 'cd current && ee shell --command="wp core update-db" --skip-tty' ); 148 | 149 | } else { 150 | echo 'Skipping WordPress db core update as EasyEnigne is not installed.'; 151 | } 152 | 153 | writeln( '' . $output . '' ); 154 | 155 | } ); 156 | 157 | desc( 'Symlink wp-config.php' ); 158 | task( 'wp:config', function () { 159 | 160 | run( '[ ! -f {{release_path}}/../wp-config.php ] && cd {{release_path}}/../ && ln -sn ../wp-config.php && echo "Created Symlink for wp-config.php." || echo ""' ); 161 | } ); 162 | 163 | /* 164 | * Change permissions to 'www-data' for 'current/', 165 | * so that 'wp-cli' can read/write files. 166 | */ 167 | desc( 'Correct Permissions' ); 168 | task( 'permissions:set', function () { 169 | 170 | $output = run( 'chown -R www-data:www-data {{deploy_path}}' ); 171 | writeln( '' . $output . '' ); 172 | 173 | } ); 174 | 175 | $wp_tasks = [ 176 | 'deploy:prepare', 177 | 'deploy:unlock', 178 | 'deploy:lock', 179 | 'deploy:release', 180 | 'rsync', 181 | 'wp:config', 182 | 'cachetool:download', 183 | 'deploy:shared', 184 | 'deploy:symlink', 185 | 'permissions:set', 186 | 'opcache:reset', 187 | 'core_db:update', 188 | 'deploy:unlock', 189 | 'cleanup', 190 | ]; 191 | 192 | $non_wp_tasks = [ 193 | 'deploy:prepare', 194 | 'deploy:unlock', 195 | 'deploy:lock', 196 | 'deploy:release', 197 | 'rsync', 198 | 'deploy:shared', 199 | 'deploy:symlink', 200 | 'deploy:unlock', 201 | 'cleanup', 202 | ]; 203 | 204 | if ( 'true' === getenv( 'SKIP_WP_TASKS' ) ) { 205 | $tasks = $non_wp_tasks; 206 | } else { 207 | $tasks = $wp_tasks; 208 | } 209 | 210 | $addon_recipe = getenv( 'GITHUB_WORKSPACE' ) . '/.github/deploy/addon.php'; 211 | if ( file_exists( $addon_recipe ) ) { 212 | require $addon_recipe; 213 | } 214 | 215 | /* deployment task */ 216 | desc( 'Deploy the project' ); 217 | task( 'deploy', $tasks ); 218 | after( 'deploy', 'success' ); 219 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Check required env variables 4 | flag=0 5 | if [[ -z "$SSH_PRIVATE_KEY" ]]; then 6 | flag=1 7 | missing_secret="SSH_PRIVATE_KEY" 8 | if [[ -n "$VAULT_ADDR" ]] && [[ -n "$VAULT_TOKEN" ]]; then 9 | flag=0 10 | fi 11 | if [[ -n "$VAULT_ADDR" ]] || [[ -n "$VAULT_TOKEN" ]]; then 12 | missing_secret="VAULT_ADDR and/or VAULT_TOKEN" 13 | fi 14 | fi 15 | 16 | if [[ "$flag" -eq 1 ]]; then 17 | printf "[\e[0;31mERROR\e[0m] Secret \`$missing_secret\` is missing. Please add it to this action for proper execution.\nRefer https://github.com/rtCamp/action-deploy-wordpress for more information.\n" 18 | exit 1 19 | fi 20 | 21 | # custom path for files to override default files 22 | custom_path="$GITHUB_WORKSPACE/.github/deploy" 23 | main_script="/main.sh" 24 | 25 | if [[ -d "$custom_path" ]]; then 26 | rsync -av "$custom_path/" / 27 | chmod +x /*.sh 28 | fi 29 | 30 | bash "$main_script" 31 | -------------------------------------------------------------------------------- /example/addon.php: -------------------------------------------------------------------------------- 1 | "$SSH_DIR/id_rsa" 67 | chmod 600 "$SSH_DIR/id_rsa" 68 | eval "$(ssh-agent -s)" 69 | ssh-add "$SSH_DIR/id_rsa" 70 | 71 | if [[ -n "$JUMPHOST_SERVER" ]]; then 72 | ssh-keyscan -H "$JUMPHOST_SERVER" >>/etc/ssh/known_hosts 73 | fi 74 | else 75 | # Generate a key-pair 76 | ssh-keygen -t rsa -b 4096 -C "GH-actions-ssh-deploy-key" -f "$HOME/.ssh/id_rsa" -N "" 77 | fi 78 | } 79 | 80 | function maybe_get_ssh_cert_from_vault() { 81 | 82 | # Get signed key from vault 83 | if [[ -n "$VAULT_GITHUB_TOKEN" ]]; then 84 | unset VAULT_TOKEN 85 | vault login -method=github token="$VAULT_GITHUB_TOKEN" >/dev/null 86 | fi 87 | 88 | if [[ -n "$VAULT_ADDR" ]]; then 89 | vault write -field=signed_key ssh-client-signer/sign/my-role public_key=@$HOME/.ssh/id_rsa.pub >$HOME/.ssh/signed-cert.pub 90 | fi 91 | } 92 | 93 | function configure_ssh_config() { 94 | 95 | if [[ -z "$JUMPHOST_SERVER" ]]; then 96 | # Create ssh config file. `~/.ssh/config` does not work. 97 | cat >/etc/ssh/ssh_config </etc/ssh/ssh_config <>/etc/ssh/known_hosts 153 | 154 | identity_file='' 155 | if [[ -n "$SUBMODULE_DEPLOY_KEY" ]]; then 156 | echo "$SUBMODULE_DEPLOY_KEY" | tr -d '\r' >"$SSH_DIR/submodule_deploy_key" 157 | chmod 600 "$SSH_DIR/submodule_deploy_key" 158 | ssh-add "$SSH_DIR/submodule_deploy_key" 159 | identity_file="IdentityFile ${SSH_DIR}/submodule_deploy_key" 160 | fi 161 | 162 | # Setup config file for proper git cloning 163 | cat >>/etc/ssh/ssh_config </dev/null || true) 249 | 250 | # Check if WP_VERSION is already defined in hosts.yml 251 | # Priority: 1. hosts.yml, 2. workflow file, else use latest 252 | if [[ -n $hosts_wp_version ]]; then 253 | WP_VERSION="$hosts_wp_version" 254 | elif [[ -z $WP_VERSION ]]; then 255 | WP_VERSION="latest" 256 | fi 257 | 258 | # If it is integer, add trailing `.0` 259 | if [[ "$WP_VERSION" =~ ^[+-]?[0-9]+$ ]]; then 260 | WP_VERSION="$WP_VERSION.0" 261 | fi 262 | 263 | if [[ "$WP_MINOR_UPDATE" == "true" ]] && [[ "$WP_VERSION" != "latest" ]]; then 264 | LATEST_MINOR_VERSION=$( 265 | curl -s "https://api.wordpress.org/core/version-check/1.7/?version=$WP_VERSION" | 266 | jq -r '[.offers[]|select(.response=="autoupdate")][-1].version' 267 | ) 268 | MAJOR_DOT_MINOR=$(echo "$WP_VERSION" | cut -c1-3) 269 | if [[ "$LATEST_MINOR_VERSION" == "$MAJOR_DOT_MINOR"* ]]; then 270 | WP_VERSION="$LATEST_MINOR_VERSION" 271 | echo "Using $LATEST_MINOR_VERSION as the latest minor version." 272 | else 273 | echo "$WP_VERSION is the latest minor version." 274 | fi 275 | fi 276 | 277 | wp core download --version="$WP_VERSION" --allow-root 278 | 279 | rm -r wp-content/ 280 | 281 | # Include webroot-files in htdocs if they exists 282 | if [[ -d "$GITHUB_WORKSPACE/webroot-files" ]]; then 283 | rsync -av "$GITHUB_WORKSPACE/webroot-files/" "$HTDOCS/" >/dev/null 284 | rm -rf "$GITHUB_WORKSPACE/webroot-files/" 285 | fi 286 | 287 | rsync -av "$GITHUB_WORKSPACE/" "$HTDOCS/wp-content/" >/dev/null 288 | 289 | # Remove uploads directory 290 | cd "$HTDOCS/wp-content/" 291 | rm -rf uploads 292 | 293 | # Setup mu-plugins if VIP 294 | if [[ -n "$MU_PLUGINS_URL" ]]; then 295 | if [[ "$MU_PLUGINS_URL" = "vip" ]]; then 296 | MU_PLUGINS_URL="https://github.com/Automattic/vip-mu-plugins-public" 297 | fi 298 | MU_PLUGINS_DIR="$HTDOCS/wp-content/mu-plugins" 299 | echo "Cloning mu-plugins from: $MU_PLUGINS_URL" 300 | git clone -q --recursive --depth=1 "$MU_PLUGINS_URL" "$MU_PLUGINS_DIR" 301 | fi 302 | } 303 | 304 | function deploy() { 305 | 306 | cd "$GITHUB_WORKSPACE" 307 | dep deploy "$GITHUB_BRANCH" 308 | } 309 | 310 | function block_emails() { 311 | 312 | hosts_block_email=$(shyaml get-value "$GITHUB_BRANCH.block_emails" < "$hosts_file" 2>/dev/null || exit 0) 313 | 314 | if [[ -n "$hosts_block_email" ]]; then 315 | match_hosts_block_email=$(echo "$hosts_block_email" | awk '{$1=$1;print tolower($0)}') 316 | fi 317 | 318 | if [[ "$match_hosts_block_email" == 'true' ]]; then 319 | 320 | # priority: 1. hosts.yml 2. vip 3. WP 321 | echo -e "\033[34mSETTING UP EMAIL BLOCKING\033[0m" 322 | 323 | hosts_block_email_dir=$(shyaml get-value "$GITHUB_BRANCH.block_emails_plugin_path" < "$hosts_file" 2>/dev/null || exit 0) 324 | 325 | if [[ -n "$hosts_block_email_dir" ]]; then 326 | BLOCK_EMAIL_DIR="$HTDOCS/wp-content/$hosts_block_email_dir" 327 | elif [[ -d "$HTDOCS/wp-content/client-mu-plugins" ]]; then 328 | BLOCK_EMAIL_DIR="$HTDOCS/wp-content/client-mu-plugins" 329 | elif [[ -d "$HTDOCS/wp-content/mu-plugins" ]]; then 330 | BLOCK_EMAIL_DIR="$HTDOCS/wp-content/mu-plugins" 331 | else 332 | BLOCK_EMAIL_DIR="$HTDOCS/wp-content/mu-plugins" 333 | mkdir -p "$BLOCK_EMAIL_DIR" 334 | fi 335 | 336 | # remove traling slash 337 | BLOCK_EMAIL_DIR="${BLOCK_EMAIL_DIR%/}" 338 | 339 | # using this naming convention by default to load this plugin first in mu-plugin loading phase. 340 | BLOCK_EMAIL_PLUGIN_NAME="000-block-emails.php" 341 | 342 | hosts_block_email_file_name=$(shyaml get-value "$GITHUB_BRANCH.block_emails_plugin_file_name" < "$hosts_file" 2>/dev/null || exit 0) 343 | 344 | if [[ -n "$hosts_block_email_file_name" ]]; then 345 | BLOCK_EMAIL_PLUGIN_NAME="${hosts_block_email_file_name}.php" 346 | fi 347 | 348 | BLOCK_EMAIL_PLUGIN_PATH="$BLOCK_EMAIL_DIR/$BLOCK_EMAIL_PLUGIN_NAME" 349 | 350 | if [[ -d "$BLOCK_EMAIL_DIR" ]]; then 351 | rsync -av "/000-block-emails.php" "$BLOCK_EMAIL_PLUGIN_PATH" 352 | echo -e "\033[34mEMAIL BLOCK [ACTIVATED]: $BLOCK_EMAIL_PLUGIN_PATH \033[0m" 353 | else 354 | echo -e "\033[31mEMAIL BLOCK [PATH ERROR]: $BLOCK_EMAIL_DIR doesn't exist.\033[0m" 355 | 356 | fi 357 | fi 358 | 359 | } 360 | 361 | 362 | function main() { 363 | 364 | init_checks 365 | if [[ -f "$CUSTOM_SCRIPT_DIR/addon.sh" ]]; then 366 | source "$CUSTOM_SCRIPT_DIR/addon.sh" 367 | else 368 | setup_hosts_file 369 | check_branch_in_hosts_file 370 | setup_ssh_access 371 | maybe_install_submodules 372 | maybe_install_node_dep 373 | maybe_run_node_build 374 | maybe_install_php_dep 375 | maybe_run_php_build 376 | setup_wordpress_files 377 | block_emails 378 | deploy 379 | fi 380 | } 381 | 382 | main 383 | --------------------------------------------------------------------------------