Automate Synchronization Between Pantheon and GitHub
Pantheon has many tools to facilitate and automate our web development processes. This web server makes our daily job easier and these are some of the features that we value most.
- Standard Workflow: Every website comes with identical Dev, Test, and Live environments to make code merges, test new functionality, and easily deploy changes worry-free.
- Multidev Environments: They allow developers to fork the entire stack (code and content), work independently, then merge the code changes back into the main master site. Each forked branch will have its separate development environment, including database and files.
- Autopilot: It automatically detects, performs, and deploys updates for WordPress and Drupal, while automatically ensuring those updates don’t cause your website to break (and if it does, rolls back those updates and notifies you that there’s a problem.)
- Terminus: Provides advanced interaction with Pantheon. Terminus enables you to do almost everything in a terminal that you can do in the Dashboard, and much more.
Our solution stack includes Pantheon Hosting for most of our websites. Additionally, this year we opted to host all of our git repositories in Github, so we would have a single source of truth for all of our code changes.This is the reason why besides Pantheon we use Github as a code management tool.
Github is a tool our team is familiar with and most of the new devs we work with will also have familiarity with that platform. In fact, our Project Management tool, ZenHub, lives on top of Github, so now we have one place for all of our project-related needs.
Improving Processes
Digisavvy’s web development team is always seeking to develop processes that we can automate and allow us to deploy quality solutions. Thus, we always ask the question: How can we improve this process?
For every site that we host on Pantheon, we also create a repository inside Github. So, in our regular workflow, every commit is pushed into the Github repository and then it’s automatically pushed to Pantheon by a Github action.
However, we recently faced the issue of maintaining both repositories, one in Pantheon and one in Github, in sync after Pantheon Autopilot pushed updates.
Sure, we could have resolved this issue by manually syncing both repositories using some git commands. But we always try to automate our development process because that gives us more time to focus on our client related tasks.
After some research, we found a tool called Quicksilver Pushback that could possibly solve the syncing issue. However we decided to use Github Actions instead because we already have some experience using it, and we also thought that it was a more flexible and less time-consuming solution to implement.
The solution
Pantheon has a tool that provides visual regression testing (https://pantheon.io/docs/guides/autopilot) to automate the process of updating website plugins, themes, and core files. This tool automatically pushes commits into the Pantheon dev repository, so we needed a way to sync the Pantheon repo with the Github one after a visual regression test was fired.
The solution that we implemented can be divided into three steps:
- Create a synchronization between the Pantheon repository and the Github one.
- Create the Github action.
- Create the Pantheon hook by using Pantheon Silverhooks.
- Add Slack Notifications (Optional) (https://github.com/pantheon-systems/quicksilver-examples/tree/master/slack_notification)
First Synchronization
For every website that we host on Pantheon, we also have a Github repository. We push all the code into the Github repository and then it’s automatically pushed to Pantheon one by a Github action.
The first step is to make a manual synchronization between both repositories, one in Pantheon and one in Github. This is necessary to prevent merge conflict and inconsistencies in the code.
To do this you just need to clone the Pantheon repository, change the remote URL using Git, and finally make a push to the Github repository.
This article describes the process in more detail.
The Github Action
You will need to implement a Github action to automatically pull the code from the Pantheon repository and push it inside the Github one. Here is an example of the action we use to achieve this.
name: Pantheon Sync
# This action pulls the autopilot commits from Pantheon
# Controls when the action will run.
on: workflow_dispatch
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Installing PHP
uses: shivammathur/setup-php@master
with:
php-version: '7.4'
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
config: ${{ secrets.SSH_CONFIG }}
key: ${{ secrets.SSH_KEY_PABLO_LINUX }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
- name: Push Code
if: success()
run: |
git config --global user.name 'Your Username'
git config --global user.email 'email@youremail.com'
git remote add pantheon ${{ secrets.PANTHEON_REPO }}
git pull pantheon HEAD:master
git push origin master --force
These are the different steps executed by this action:
- The Github repository is cloned using the action “actions/checkout@v2”
- PHP is installed using the action “shivammathur/setup-php@master”
- An SSH connection between the virtual machine that runs the action and Pantheon is configured using the action “shimataro/ssh-key-action@v2”
- Finally, the action pulls the last changes from the Pantheon repository and pushes them into the Github one.
Also, notice that the ‘on’ attributes has the ‘workflow_dispatch’ value. This value configures the action to only be executed using the GitHub API. More on this in the next step.
Pantheon Silverhook
This tool provided by Pantheon allows the execution of a PHP file after a specific event occurs in Pantheon. Here is an excellent guide describing how to configure a Pantheon silverhook.
This PHP file is going to make a POST request to the GitHub API to execute the GitHub action we created before. This is the endpoint that we are going to use https://docs.github.com/es/actions/learn-github-actions/events-that-trigger-workflows#workflow_dispatch
At first, our idea was to use the Pantheon event called “sync_code”. According to the Pantheon documentation, this hook is fired every time a piece of code is pushed into a Pantheon repository.
We thought that this hook was going to be executed every time Pantheon pushes an autopilot update into the dev repository. But this wasn’t the case, because Pantheon inserts the updates of a visual regression test using the <<git merge>> command, and the “sync_code” hook is not fired for this scenario.
After conducting some research on how to solve this problem, we decided to implement a workaround. Our solution makes use of a hook called “autopilot_vrt”. This hook is fired every time a visual regression test passes. Also, notice that this hook is fired only in the autopilot branch.
Inside the pantheon.yml file, we configure the “autopilot_vrt” hook. Also, you will need to create the PHP file that is going to be executed after this hook is fired.
Here is the PHP file executed after the hook is fired:
<?php
/*
*This file is executed after a visual regression test passes in the autopilot repository. The code is going to call a GitHub Action to sync both repositories
*/
// Define the url the data should be sent to.
// {wf_type} will be replaced with the workflow operation:
// clone_database, clear_cache, deploy, or sync_code.
//
// Useful to have one webhook handle multiple events.
// e.g. https://ifttt.com/maker
$url = 'https://api.github.com/repos/DigiSavvy-Inc/firstpitch-reebok/actions/workflows/pantheon-commit-sync.yml/dispatches';
// Add the site name to the payload in case the receiving app handles
// multiple sites. You can enhance this payload with more data as
// needed at this point.
$payload = json_encode(array( "ref"=>"master" ));
$headr = array();
$headr[] = 'Content-Type: application/json';
$headr[] = 'Accept: application/vnd.github.v3+json';
$headr[] = 'Authorization: token {GitHub Token}';
sleep(60);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headr);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
print("\n==== Posting to Webhook URL ====\n");
$result = curl_exec($ch);
print("RESULT: $result");
print("\n===== Post Complete! =====\n");
curl_close($ch);
require_once 'slack-notifications.php';
_slack_notification( $secrets['slack_url'], $secrets['slack_username'], $text, $attachment, $secrets['always_show_text'] );
Notice that the code waits 60 seconds before making the POST request. This is necessary because Pantheon doesn’t have a hook to detect when a merge occurs between the autopilot repo and the dev one. After the “autopilot_vrt” hook is fired, Pantheon immediately merges the code of the autopilot repo into the dev one. This takes a few seconds, and that’s why the code waits 60 seconds before making the POST request to Github.
Slack Notifications
Also, a slack notification could be configured to get noticed every time there is a synchronization between the repositories.
The PHP file used to configure the Slack notification is the one provided by Pantheon (https://github.com/pantheon-systems/quicksilver-examples/blob/master/slack_notification/slack_notification.php). You can modify this file to suit your needs.
You just need to import the file “slack_notification.php” into the PHP file called after the Pantheon silverook is fired.
Also, in order to make this work, you will need to enable incoming webhooks for your Slack instance. Here is a tutorial on how to do this
Now, every time Pantheon deploys updates on a website after a visual regression test passes, a Github action is going to be fired automatically to insert the updates into the Github repository, and both repositories will be in sync.
Get Notified When We Publish New Content!
Join more than 2,500 people who get our marketing automation, business marketing, and WordPress news!