Pantheon Multidev allows you to spin environments on demand for your branches. So we could use those for creating environments per pull request and test them visually with Diffy.
Please bear in mind that Pantheon limits you with the number of environments you can create
Pantheon has its own repository example-drops-8-composer with the example setup of the CI to build the environments. In our example, we start from scratch with a clean Pantheon's project.
The basic workflow is:
Pull request created in GitHub
Branch copied to Pantheon git repo
Trigger creation of the multidev environment for the new branch
Run all post-deployment jobs (clear caches, import configuration, updatedb)
Copy the public key (/tmp/new_key_for_ci.pub) and add it to your Pantheon's SSH keys.
Copy the private key (/tmp/new_key_for_ci) and add it as PANTHEON_SSH_KEY secret in GitHub Actions.
Diffy configuration
In order for Diffy to post results back to GitHub as a check you need to add github repo to Diffy's Project settings under Notifications / GitHub and authenticate Diffy's GitHub check by visiting https://github.com/apps/diffy-testing
Full code
Pay attention that we check if we didn't reach the limit of number of multidev environments.
name: Test PRs MultiDev and Diffy
on:
pull_request:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.PANTHEON_SSH_KEY }}
config: ${{ secrets.SSH_CONFIG }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
- name: Install Terminus
uses: pantheon-systems/terminus-github-actions@main
with:
pantheon-machine-token: ${{ secrets.PANTHEON_MACHINE_TOKEN }}
- name: Deploy to MultiDev
env:
pantheon_repo: '${{ secrets.PANTHEON_REPO }}'
pantheon_site_name: '${{ secrets.PANTHEON_SITE_NAME }}'
pr_number: ${{ github.event.number }}
run: |
PR_BRANCH="pr-$pr_number"
git remote add pantheon $pantheon_repo
git fetch pantheon
git push --force pantheon HEAD:refs/heads/$PR_BRANCH
# Check if current branch environment exists. If so -- delete it first.
MULTIDEV_EXISTS=$(terminus env:list "${pantheon_site_name}" --format=list | grep "${PR_BRANCH}" | wc -l)
if (( "${MULTIDEV_EXISTS}" > 0 )); then
terminus multidev:delete "${pantheon_site_name}"."${PR_BRANCH}" --yes
else
# Check if we allowed to create new multidev and if not -- delete old ones.
# See https://github.com/pantheon-systems/pantheon_advanced_page_cache/blob/2.x/.circleci/scripts/ensure-available-multidev.sh
MAX_CDE_COUNT="$(terminus site:info "${pantheon_site_name}" --field='Max Multidevs')"
echo "Max Multidev Count: ${MAX_CDE_COUNT}"
DOMAINS="$(terminus env:list "${pantheon_site_name}" --format=string --fields=ID,Created)"
# Filter out dev, test, live as they don't count agains the Max Multidev count.
CDE_DOMAINS=$(echo "$DOMAINS" | grep -vE '\b(dev|test|live)\b')
# Count current environments
CDE_COUNT="$(echo "$CDE_DOMAINS" | wc -l)"
# remove whitespace to make the arithmetic work
CDE_COUNT="${CDE_COUNT//[[:blank:]]/}"
NUMBER_OF_CDES_REQUIRED=1
echo "There are currently ${CDE_COUNT}/${MAX_CDE_COUNT} multidevs. I need ${NUMBER_OF_CDES_REQUIRED}."
POTENTIAL_CDE_COUNT=$((CDE_COUNT + NUMBER_OF_CDES_REQUIRED))
if (( "${POTENTIAL_CDE_COUNT}" <= "${MAX_CDE_COUNT}" )); then
echo "There are enough multidevs."
else
NUMBER_OF_CDES_TO_DELETE=$((POTENTIAL_CDE_COUNT - MAX_CDE_COUNT))
echo "There are not enough multidevs, deleting the oldest ${NUMBER_OF_CDES_TO_DELETE} environment(s)."
# Filter out any multidev environments that should never be deleted.
# This is seperate from filtering out dev/test/live above as they still count towards 'Max Multidev'.
# Then, sort the list by the timestamps
SORTED_DOMAINS=$(echo "$CDE_DOMAINS" | grep -vE '\b(drupal10)\b' | sort -n -k2)
# Delete as many multidevs as we need to make room for testing.
for (( i = 1; i<=NUMBER_OF_CDES_TO_DELETE; i++ )); do
ENV_TO_REMOVE="$(echo "$SORTED_DOMAINS" | head -n "$i" | tail -n 1 | cut -f1)"
echo "Removing '${ENV_TO_REMOVE}'."
terminus multidev:delete --delete-branch "${pantheon_site_name}.${ENV_TO_REMOVE}" --yes
done
fi
fi
echo "Creating multidev ${PR_BRANCH}"
terminus multidev:create $pantheon_site_name.live $PR_BRANCH
- name: Cache rebuild, import configuration
env:
pantheon_site_name: '${{ secrets.PANTHEON_SITE_NAME }}'
pr_number: ${{ github.event.number }}
run: |
PR_BRANCH="pr-$pr_number"
terminus remote:drush $pantheon_site_name.$PR_BRANCH cr
terminus remote:drush $pantheon_site_name.$PR_BRANCH config:import -y
- name: Trigger Diffy testing
env:
diffy_api_key: '${{ secrets.DIFFY_API_KEY }}'
diffy_project_id: '${{ secrets.DIFFY_PROJECT_ID }}'
pantheon_site_name: '${{ secrets.PANTHEON_SITE_NAME }}'
pr_number: ${{ github.event.number }}
run: |
PR_BRANCH="pr-$pr_number"
MULTIDEV_SITE_URL="https://$PR_BRANCH-$pantheon_site_name.pantheonsite.io/"
# Download Diffy-CLI.
wget https://github.com/diffywebsite/diffy-cli/releases/latest/download/diffy.phar
# Authenticate.
php diffy.phar auth:login $diffy_api_key
echo ${{ github.event.pull_request.head.sha }}
# Compare with commit sha so Diffy's github check posts the results.
php diffy.phar project:compare $diffy_project_id dev custom --env2Url="${MULTIDEV_SITE_URL}" --commit-sha="${{ github.event.pull_request.head.sha }}"