
Our guest, a developer tools creator from Pantheon, explains how to automate WordPress deployments using GitLab CI/CD.
In I work in developer relations, so I'm always looking for new ways to help WordPress and Drupal developers solve automation issues in their workflows. I love experimenting with new tools and combining them for effective work.
I often see developers struggling with a single staging server.
It’s not much fun waiting for your turn to use the staging server or sending clients a URL with a note: 'Watch here, but don’t look here yet.'
— one of Pantheon's cool tools — solve this issue as they allow for environments to be created on demand for Git branches. Each multidev environment has its own URL and database, enabling developers to work, check quality, and get approvals without stepping on each other's toes.
However, Pantheon lacks version control tools or continuous integration and deployment (CI/CD). On the upside, it's a flexible platform that can integrate with any tools.
I've also noticed that teams use different tools for development and for building and deploying.
For example, they have different tools for version control and CI/CD. This means a lot of fiddling and switching between tools to edit code and troubleshoot issues.
At there's a comprehensive suite of development tools available: for version control, tickets, merge requests, a best-in-class CI/CD pipeline, a container registry, and so on. I haven't encountered applications that have as many tools for managing the development workflow.
I love automation, so I explored how to connect Pantheon to GitLab, allowing commits to the main branch in GitLab to deploy to the main development environment in Pantheon. Also, merge requests on GitLab can create and deploy code to multidev environments in Pantheon.
In this guide, I will explain how to set up the connection between GitLab and Pantheon and optimize the WordPress and Drupal workflow.
Of course, you can , but we’ll do everything manually to dig deeper into. and in the future, use this tool not only for deployment.
Introduction
For this post, it is important to understand that Pantheon divides each site into three components: code, database, and files.
The code includes CMS files, such as the core, plugins, and WordPress themes. These files are managed in , hosted on Pantheon, which means we can deploy code from GitLab to Pantheon using Git.
The files in Pantheon refer to media files, such as images for the site. They are usually uploaded by users, and Git ignores them.
, learn more about or at pantheon.io.
Assumptions
My project on Pantheon and GitLab is called pantheon-gitlab-blog-demo. The project name must be unique. Here we will work with a WordPress site. Drupal can also be used, but some changes will be necessary.
I will be using , but you can work in , if you prefer.
Creating the project
First, we create a (we'll come back to this).
Now . Then we install WordPress for the site's dashboard.
If you're eager to change something, such as removing and adding plugins, hold off. The site is not yet connected to GitLab, and we want all code changes to go through GitLab.
Once we install WordPress, we return to the Pantheon site dashboard and switch the development mode to Git.
Initial commit to GitLab
Now we need to transfer the initial WordPress code from the Pantheon site to GitLab. For that, we clone the code from the Pantheon site's Git repository locally, and then push it to the GitLab repository.
To make it easier and safer, and won't have to enter the password every time we clone the Pantheon Git repository. At the same time, we’ll .
To do this, we clone the Pantheon site locally, copying the command from the Clone with Git field on the site dashboard.
If you need help, read the documentation .
Now we will change git remote origin, to point to GitLab instead of Pantheon. This can be done using .
Let's go to the GitLab project and copy the repository URL from the Clone dropdown on the project details page. We will choose the Clone with SSH option, since we have already set up the SSH key.
the net/http git remote for the local copy of the code repository – origin. This can be changed with git remote set-url origin [GitLab repository URL], where instead of brackets, the actual URL is entered.
Finally, we run git push origin master --force, to push WordPress code from Pantheon to GitLab.
The --force parameter is needed only once. After that, it won't be in the commands
git pushon GitLab.
Setting up credentials and variables
Remember how we locally added an SSH key to authenticate with Pantheon and GitLab? An SSH token can be used to authenticate with GitLab and Pantheon.
GitLab has excellent documentation. Let's take a look .
Now we will perform the first two steps: we will create a new pair of SSH keys locally with ssh-keygen and add the private key as a variable in the project.
Then we will set SSH_PRIVATE_KEY as in the project settings.
In steps three and four, we will create a file .gitlab-ci.yml with the following content:
before_script:
# See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d 'r' | ssh-add - > /dev/null
- mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
- git config --global user.email "$GITLAB_USER_EMAIL"
- git config --global user.name "Gitlab CI"For now, let's not commit the file .gitlab-ci.yml, as it will need a few more additions.
Now we perform step five and add the public key we created in the first step to the services you need access to in the build environment.
In our case, we want to access Pantheon from GitLab. Follow the instructions in the Pantheon document on and complete this step.
Remember: the private SSH key goes in GitLab, the public key goes in Pantheon.
Let's set up a few more environment variables. The first is called PANTHEON_SITE. Its value is the name of the Pantheon site on your machine.
The name on the machine is specified at the end of the Clone with Git command. Since you have already cloned the site locally, this will be the name of the local repository directory.
Next, let's set the environment variable PANTHEON_GIT_URL. This is the Git repository URL for the Pantheon site that we have already used.
We enter only the SSH repository URL, without
git cloneand the site name on the machine at the end.
Phew. We did that, now we can finish our file .gitlab-ci.yml.
Create a deployment task
What we will initially do with GitLab CI is very similar to what we did with Git repositories before. But this time we will add the Pantheon repository as a second remote Git source and then push the code from GitLab to Pantheon.
To do this, we will set up deploy and deploy:dev, since we will be deploying to the development environment on Pantheon. As a result, the file .gitlab-ci.yml will look like this:
stages:
- deploy
before_script:
# See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d 'r' | ssh-add > /dev/null
- mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
- git config --global user.email "$GITLAB_USER_EMAIL"
- git config --global user.name "Gitlab CI"
deploy:dev:
stage: deploy
environment:
name: dev
url: https://dev-$PANTHEON_SITE.pantheonsite.io/
script:
- git remote add pantheon $PANTHEON_GIT_URL
- git push pantheon master --force
only:
- masterVariables SSH_PRIVATE_KEY, PANTHEON_SITE and PANTHEON_GIT_URL should look familiar — we set up these environment variables earlier. With these variables, we can use the values in the file .gitlab-ci.yml many times, and updating them will only need to be done in one place.
Finally, we'll add, commit, and send the file .gitlab-ci.yml to GitLab.
Checking the deployment
If we did everything correctly, the job deploy:dev will successfully run in GitLab CI/CD and push the commit .gitlab-ci.yml to Pantheon. Let's take a look.
Sending merge request branches to Pantheon
Here we will use my favorite Pantheon feature — , where you can create additional Pantheon environments for Git branches on demand.
, so this section can be skipped. But if you have access, you can significantly boost productivity by setting up automatic multidev environments on Pantheon from GitLab merge requests.
First, we will create a new Git branch locally using git checkout -b multidev-support. Now let's modify something again in .gitlab-ci.yml.
I like to include the merge request number in the name of the Pantheon environment. For example, the first merge request is mr-1, the second is mr-2 and so on.
The merge request changes, so we need to dynamically determine the names of Pantheon branches. On GitLab, it's simple — we just need to use .
We can take $CI_MERGE_REQUEST_IID, to specify the merge request number. Let's apply all of this along with the global environment variables we defined earlier and add a new task deploy:multidev at the end of the file .gitlab-ci.yml.
deploy:multidev:
stage: deploy
environment:
name: multidev/mr-$CI_MERGE_REQUEST_IID
url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
script:
# Checkout the merge request source branch
- git checkout $CI_COMMIT_REF_NAME
# Add the Pantheon git repository as an additional remote
- git remote add pantheon $PANTHEON_GIT_URL
# Push the merge request source branch to Pantheon
- git push pantheon $CI_COMMIT_REF_NAME:mr-$CI_MERGE_REQUEST_IID --force
only:
- merge_requestsIt will look like our task deploy:dev, only the branch is pushed to Pantheon, not to master.
We added and committed the updated file .gitlab-ci.yml, and now let's push the new branch to GitLab with git push -u origin multidev-support.
Now let's create a new merge request from the branch multidev-support, by clicking Create merge request.
After creating the merge request, we can see how the CI/CD task is progressing deploy:multidev.
Look — a new branch is sent to Pantheon. But if we go to the multidev section on the Pantheon site dashboard, we won't see the new environment there
Let's take a look at the Git Branches section.
As a result, our branch mr-1 has reached Pantheon. Let's create an environment from the branch mr-1.
We created a multidev environment, and now let's go back to GitLab and check the Operations > Environments. We will see entries for dev and mr-1.
This is because we added an entry environment named name and url in the CI/CD tasks. If we click the open environment icon, we will go to the multidev environment URL on Pantheon.
Let's automate the creation of multidev
In principle, we could stop here and just remember to create a multidev environment for each merge request, but this process can be automated.
Pantheon has a command-line tool , where you can work with the platform automatically. In Terminus, we can create multidev environments from the command line — ideal for .
We need a new merge request to test this. Let's create a new branch using git checkout -b auto-multidev-creation.
To use Terminus in GitLab CI/CD tasks, a machine token is needed for authentication in Terminus and a container image with Terminus.
, save it in a secure place and add it as a global environment variable in GitLab named PANTHEON_MACHINE_TOKEN.
If you forgot how to add GitLab environment variables, go back to where we defined
PANTHEON_SITE.
Creating Dockerfile with Terminus
If you're not using Docker or don't like files Dockerfile, grab my image registry.gitlab.com/ataylorme/pantheon-gitlab-blog-demo:latest and skip this section.
, where you can build and host Dockerfile for our project. Let's create a Dockerfile with Terminus to work with Pantheon.
Terminus is a command-line tool in PHP, so let's start with a PHP image. I install Terminus via Composer, so I'll base it on . We create Dockerfile in the local repository directory with the following content:
# Use the official Composer image as a parent image
FROM composer:1.8
# Update/upgrade apk
RUN apk update
RUN apk upgrade
# Make the Terminus directory
RUN mkdir -p /usr/local/share/terminus
# Install Terminus 2.x with Composer
RUN /usr/bin/env COMPOSER_BIN_DIR=/usr/local/bin composer -n --working-dir=/usr/local/share/terminus require pantheon-systems/terminus:"^2"Follow the instructions for building and pushing images from the Build and push images downward API support (simultaneously with this in , to build the image from Dockerfile and push it to GitLab.
Open the section Registry in the GitLab project. If everything went as planned, our image will be there. Write down the image tag link — we need it for the file .gitlab-ci.yml.
Partition script in the task deploy:multidev starts to grow, so let's move it to a separate file. We create a new file private/multidev-deploy.sh:
#!/bin/bash
# Store the mr- environment name
export PANTHEON_ENV=mr-$CI_MERGE_REQUEST_IID
# Authenticate with Terminus
terminus auth:login --machine-token=$PANTHEON_MACHINE_TOKEN
# Checkout the merge request source branch
git checkout $CI_COMMIT_REF_NAME
# Add the Pantheon Git repository as an additional remote
git remote add pantheon $PANTHEON_GIT_URL
# Push the merge request source branch to Pantheon
git push pantheon $CI_COMMIT_REF_NAME:$PANTHEON_ENV --force
# Create a function for determining if a multidev exists
TERMINUS_DOES_MULTIDEV_EXIST()
{
# Stash a list of Pantheon multidev environments
PANTHEON_MULTIDEV_LIST="$(terminus multidev:list ${PANTHEON_SITE} --format=list --field=id)"
while read -r multiDev; do
if [[ "${multiDev}" == "$1" ]]
then
return 0;
fi
done <<< "$PANTHEON_MULTIDEV_LIST"
return 1;
}
# If the mutltidev doesn't exist
if ! TERMINUS_DOES_MULTIDEV_EXIST $PANTHEON_ENV
then
# Create it with Terminus
echo "No multidev for $PANTHEON_ENV found, creating one..."
terminus multidev:create $PANTHEON_SITE.dev $PANTHEON_ENV
else
echo "The multidev $PANTHEON_ENV already exists, skipping creating it..."
fiThe script is located in a private directory and . We have a script for our multidev logic. Now let's update the section deploy:multidev file .gitlab-ci.yml, so it looks like this:
deploy:multidev:
stage: deploy
environment:
name: multidev/mr-$CI_MERGE_REQUEST_IID
url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
script:
# Run the multidev deploy script
- "/bin/bash ./private/multidev-deploy.sh"
only:
- merge_requestsWe need to ensure that our tasks run in the created custom image, so let's add the definition image with the registry URL in .gitlab-ci.yml. As a result, we have the following file .gitlab-ci.yml:
image: registry.gitlab.com/ataylorme/pantheon-gitlab-blog-demo:latest
stages:
- deploy
before_script:
# See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d 'r' | ssh-add - > /dev/null
- mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
- git config --global user.email "$GITLAB_USER_EMAIL"
- git config --global user.name "Gitlab CI"
deploy:dev:
stage: deploy
environment:
name: dev
url: https://dev-$PANTHEON_SITE.pantheonsite.io/
script:
- git remote add pantheon $PANTHEON_GIT_URL
- git push pantheon master --force
only:
- master
deploy:multidev:
stage: deploy
environment:
name: multidev/mr-$CI_MERGE_REQUEST_IID
url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
script:
# Run the multidev deploy script
- "/bin/bash ./private/multidev-deploy.sh"
only:
- merge_requestsAdding, committing, and pushing private/multidev-deploy.sh and .gitlab-ci.yml. Now let's return to GitLab and wait for the CI/CD job to complete. Please hold on: the multidev may take a few minutes to create.
Then we go to check the multidev list on Pantheon. Oh miracle! The multidev environment mr-2 is already here.
Conclusion
My team became much more productive when we started opening merge requests and creating environments automatically.
With powerful tools like GitLab and Pantheon, you can connect GitLab to Pantheon automatically.
Since we are using GitLab CI/CD, our workflow has room to grow. Here are a couple of ideas to get started:
- Add a build step.
- Add automated testing.
- Add a task to ensure coding standards compliance.
- Add .
Let us know what you think about GitLab, Pantheon, and automation.
P.S. Did you know that Terminus, the Pantheon command line tool, ?
We've been hard at work on version 2 of our with GitLab support. If you don’t want to bother with setup for each project, try this plugin and help us test beta v2. For the Terminus team build:project:create only a Pantheon token and a GitLab token are needed. It will deploy one of the project examples with Composer and automated testing, create a new project in GitLab, a new site on Pantheon, and connect them using environment variables and SSH keys.
About the Author
Andrew Taylor creates tools for developers at .
Source: habr.com
