Deployment
Deploy to VIP servers is done by pushing a commit to a GitHub repository in the VIP’s GitHub organization.
This package supports a model where a “website project” repository is privately owned, then via an automation tool (e.g. GitHub Actions, GitLab CI/CD Jenkins, and the like) that repository is “prepared” and then a commit is made to the VIP repository.
Preparing the Project Repository
When using the composer vip
command, we end up having a vip/
folder that resembles what VIP expects to be pushed on their repository.
So, in theory, we could make that folder the root of a Git repository having the VIPs’ GitHub repository as remote, and push it. But this is problematic because:
- The
vip/
folder is generated by the plugin and should be VCS-ignored from the “website project” repository - Initializing a Git repository from scratch in such folder, would require us to always force-push to the VIP GitHub remote
- Having a Git root in a VCS-ignored sub-folder of another repository isn’t exactly “nice”
Besides this VCS-specific issues, another major issue is that while the vip/
folder resembles the structure of a VIP repository, locally it likely contains things we don’t want to push.
For example, dev-dependencies, node_modules/
folders, etc.
All these issues are solved via the composer vip --deploy
.
The Configuration
To be able to deploy successfully, the plugin needs to know which is the project’s VIP repository to pull from and push to. This information is configured in the extra
section of the project composer.json
file.
{
"extra": {
"vip-composer": {
"git": {
"url": "https://github.com/wpcomvip/acme",
"branch": "develop"
}
}
}
}
This configuration is optional, but if not provided to make deployment work, but if not provided we will need to pass Git URL and branch as command options.
There are several more configuration possibilities. Please refer to the “Plugin Configuration” chapter for the full documentation.
The vip --deploy
Command
Executing composer vip --deploy
the vip/
folder is generated very similarly to when we prepare for the VIP local development environment, with the exclusion of tasks specifically designed for local environments.
After that, the command:
- Creates a temporary folder inside
vip/
- Git-clone in the temporary folder the VIP GitHub repository
- Moves files from the outer
vip/
folder into the newly created temporary folder, filtering out files and folders not needed online, such as dev dependencies,node_modules/
folders, etc. - Create a commit for the changes in the temporary folder
- Push the changes to VIP GitHub repository
- Deletes the temporary folder
It means that by executing composer vip --deploy
we do everything is needed to deploy to VIP, keeping a consistent Git history. All of that being transparent in the regard of the local development of the “website project” repository.
Multiple Environments
When pushing to the remote VIP repository, we trigger a deployment. To handle multiple environments, VIP uses multiple Git branches. They map some “special” branches to server environments.
The master
branch is always mapped to the production environment, so pushing to master
means to make a production deployment. The non-production environments might have different names and be connected to different environments. A common setup is:
master
branch mapped to the production environmentdevelop
branch mapped to a develop environmentpreprod
branch mapped to a preprod environment
To deploy to a specific environment we can use the --branch
flag for the composer vip
command. In case that flag is missing, the branch used is the one configured in composer.json
.
Even if not required, we often want to have a symmetric branch setup in our “website project” repository. That allow us to easily understand which code in our repository is deployed to which environment on VIP.
It also simplify the automatic deployment via CI/CD tooling, considering we can dynamically set the --branch
flag to whatever is the current repository.
A GitHub Action Workflow Example
The following workflow assumes we have three Git branches on the “website project” repository where workflow lives, which correspond to the three Git branches on the VIP GitHub repository where we want to deploy.
This is probably the simplest way to configure the mapping, but surely not the only one.
With the workflow below, on every commit on one of those branches, a deployment to VIP is started. Thanks to the workflow_dispatch
event we can also trigger a deployment manually or even via GitHub REST API.
name: VIP Deployment
on:
workflow_dispatch:
push:
branches:
- 'development'
- 'preprod'
- 'master'
jobs:
deployment:
runs-on: ubuntu-latest
steps:
- name: Configure Git
run: |
git config --global user.email "$"
git config --global user.name "$"
- name: Configure SSH key
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: $
- name: Checkout
uses: actions/checkout@v4
with:
ssh-key: $
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
- name: Deploy to VIP
run: |
composer install
composer vip --deploy --branch="$"
To be noted:
- The workflow above uses GitHub Action secrets to configure Git and SSH key so that when we commit to the VIP repository we are recognized as a specific GitHub user. That GitHub user needs write access on the VIP repository. It is suggested to limit access on the VIP repository. It might be a good idea to configure a “machine user” and allow only that user to push to the VIP repository, ensuring all deployments happen via this workflow and human error is limited.
- When the workflow ends, it means a commit has been made to the VIP repository. That does not mean the code is on the servers already. The commit, in facts, only starts the deployment process to VIP servers. That process usually take a few minutes and it is possible to set up notifications on successful and failed deployments. See the VIP documentation for deployment notifications.
Deployment ID
The composer vip
command has a step that generates a unique ID on every deployment. This is a UUID v4 string that is saved in a file named deploy-id
saved in the vip/private
folder and so deployed in the VIP /private
folder.
This UUID is printed to the console when composer vip --deploy
is used, here’s an example of the terminal output:
Task: Generate deploy version files
Deploy ID: 'a130f01f-e9b1-4635-8ef7-51c2b1ee0d0f' written to file.
Thanks to a MU plugin that is part of this package, and that is copied to the website project, the same deploy ID is visible in the WordPress dashboard footer. Thanks to that, it is possible to uniquely relate a deployment CI/CD workflow with the code currently available on the servers. This is useful for debugging purposes.
For more info about the MU plugins coming with this package, please refer to the “Application MU Plugins” chapter.
Moreover, this package also ships an helper function Inpsyde\Vip\deployId()
which returns that same ID. That makes it possible to use this ID as part of cache keys as well as “version” parameter when enqueueing assets in WordPress. Doing that, application cache as well as browser cache for assets is invalidated at every deployment.
Inpsyde\Vip\deployId()
is only one of the many helpers that comes with this package. Please refer to the “Application Helpers” chapter for the documentation of all available helpers.