Link Search Menu Expand Document

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:

  1. Creates a temporary folder inside vip/
  2. Git-clone in the temporary folder the VIP GitHub repository
  3. 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.
  4. Create a commit for the changes in the temporary folder
  5. Push the changes to VIP GitHub repository
  6. 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 environment
  • develop branch mapped to a develop environment
  • preprod 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.