Introduction

The drush.io runtime enables you to encapsulate jobs that are highly specific to your needs and the ways your team works.

Many workflows you may wish to implement are common among Pantheon users or can be accomplished using common strategies. Use these recipes to help you get up to speed more quickly.

Common Job Templates

Below are a few common jobs you may wish to tailor to your needs or use as inspiration.

Deploy to dev through live

One common scenario is pulling the latest master branch from a remote git repository (like GitHub, GitLab, BitBucket, etc), pushing to Pantheon, then pushing through test and live. Use a job like this to make this process as simple and repeatable as possible.

# Clone from a non-Pantheon git remote to the cwd
git clone --quiet git@github.com:YOUR-ORG/YOUR-SITE .

# Push this code to your dev env.
git remote add pantheon ssh://codeserver.dev.UUID@codeserver.dev.UUID.drush.in:2222/~/repository.git
git push pantheon master

# Deploy to test env
terminus env:deploy YOUR-SITE.test -y --note="Deployed via drush.io"

# Deploy to live env
terminus env:deploy YOUR-SITE.live -y --note="Deployed via drush.io"

Refresh test environment

Keeping pre-production environments in a state closely matching production can be a chore. Use a job like this to help automate the process.

# Clone from live to test
terminus env:clone-content YOUR-SITE.live test -y

# Clean out unneeded data on the test site
`terminus connection:info YOUR-SITE.test --field=mysql_command` \
  -e "TRUNCATE watchdog;"

# Set up test user accounts if necessary
terminus remote:drush YOUR-SITE.test -- \
  user-add-role "administrator" --mail="user@example.com"

You may even wish to go a step further and run this job on a nightly basis using a cron service so that your test environment automatically reflects production each morning.

Install and run a task runner

Developers commonly use a task runners like grunt or gulp to compile and optimize front-end code. You can write a job on drush.io to clone from your non-Pantheon git repository, install and run your task runner and tasks, force commit the results, and push the built assets to Pantheon. For example:

echo "Cloning site code from GitHub"
git clone --quiet git@github.com:YOUR-ORG/YOUR-SITE .

echo "Installing gulp and other node modules required in package.json"
npm install -g gulp-cli
npm install

echo "Running gulp build task as defined in gulpfile.js"
gulp build

echo  "Force adding built files and vendor code that is normally gitignore'd"
git add --force .
git commit -a -m "Adding built assets."

echo "Force pushing compiled assets to Pantheon master"
git remote add pantheon ssh://codeserver.dev.UUID@codeserver.dev.UUID.drush.in:2222/~/repository.git
git push pantheon master --force

Maintain a leaner codebase

Another common theme in the PHP world is to build projects using composable dependencies using Composer and Packagist. You can use the same concept as the front-end code above to achieve similar outcomes with back-end vendor code.

echo "Cloning site code from GitHub"
git clone --quiet git@github.com:YOUR-ORG/YOUR-SITE .

echo "Installing vendor requirements"
composer install --ignore-platform-reqs

echo  "Force adding vendor code"
git add --force .
git commit -a -m "Adding vendor dependencies."

echo "Force pushing composed code to Pantheon master"
git remote add pantheon ssh://codeserver.dev.UUID@codeserver.dev.UUID.drush.in:2222/~/repository.git
git push pantheon master --force

Mix and match the above to suit your needs!

Custom and Complex Code

For jobs that require advanced conditional logic, parsing of API responses, or other complex customizations, we recommend writing a Terminus plugin or using an existing plugin.

You can use composer to install Terminus plugins from packagist.

composer create-project -d ~/.terminus/plugins terminus-plugin-project/terminus-site-status-plugin:~1

Once installed, you can use the Terminus plugin as intended:

terminus site:status

For additional resources, check…

ChatOps: Slack

ChatOps is a collaboration model that puts people, process, tools, and automation into one place. Implemented well, it allows dev teams to work, collaborate, and learn together in an efficient, transparent way.

The de facto tool for workplace collaboration is Slack and drush.io integrates natively with Slack! Use this integration to run your drush.io jobs right from Slack.

Installing the drush.io Slack App

In order to install the drush.io Slack App, you must be an administrator of a project. You can either edit an existing project and click the Connect Slack button, or click the button below!

Add to Slack

You’ll be taken through an authorization process which will install the drush.io app into your Slack workspace. Note that each Slack workspace may only be connected with a single drush.io project.

Authorizing your Slack account to use your drush.io account

Once installed, the drush.io Slack App exposes a new slash command: /ish

The first thing you and members of your team will need to do is to each run /ish connect. This command will generate an authorization link which will connect your Slack account with your drush.io account when clicked.

Once connected, you will be able to list and run drush.io jobs in your project.

Listing and running jobs

You can list jobs in your drush.io project by running /ish jobs in Slack.

Along with the name of each job, you’ll see a Run this job button. You can run a job by clicking the button and confirming your action in the dialog. If your job makes use of variables, you will have a chance to enter values in the confirmation dialog.

Once confirmed, your job run will be queued and a message will be sent in the Slack channel indicating to your teammates that you just triggered a job run.

The result of the run will be sent as a threaded message underneath this notification once the run is complete.

Running jobs directly

If you know the machine name of the job you wish to run (e.g. hello-world), you can directly invoke the job by running /ish run hello-world in Slack.

Similar to the flow above, you’ll be prompted to confirm your action and optionally fill in any variables that may be used in your job definition.

ChatOps: Custom

ChatOps is a collaboration model that puts people, process, tools, and automation into one place. Implemented well, it allows dev teams to work, collaborate, and learn together in an efficient, transparent way.

One common tool used to implement ChatOps at organizations is Hubot, an open source chat bot platform. Use adapters to integrate Hubot with your chat service (Slack, HipChat, etc). Install or write scripts to add custom functionality to your chatbot.

If you don’t use Hubot already, check out these guides on getting started with your first chat bot:

drush.io hubot script

You can install the official drush.io hubot script to quickly integrate drush.io with your chat bot. Once installed, you can run commands like

  • hubot drush.io token set [API TOKEN] in private chat with your bot to authenticate with drush.io
  • hubot drush.io run [PROJECT] job [JOB] to trigger a specific job on drush.io

Custom drush.io hubot integration

To get the most out of drush.io/hubot integration, you may wish to write your own library of hubot commands, built on top of the hubot drush.io script.

Here’s an example custom hubot script that adds a “delete multidev” command that triggers a job called delete-multidev on the MY-CORP project, passing two custom variables (Pantheon site and Pantheon environment name) parsed from the command.

# Description:
#   MY CORP's custom drush.io hubot integration
#
# Dependencies:
#   "@drush-io/hubot-drush-io": "~1.0.0"
#
# Commands:
#   hubot delete <site> multidev <multidev>

module.exports = (robot) ->
  drushIoProject = 'MY-CORP'

  # Hubot, delete (site) multidev (env)
  robot.hear /delete ([a-z0-9\-]{2,48}) multidev ([a-z0-9\-]{2,12})/i, (msg) ->
    jobPayload =
      TSITE: msg.match[1]
      TENV: msg.match[2]

    msg.send "Beginning multidev delete."
    robot.drush.io.run(msg, drushIoProject, 'delete-multidev', jobPayload).then (run) ->
      if (run.data.status == 'complete')
        msg.send "Multidev successfully deleted."
        msg.send run.data.log
      else
        msg.send "There may have been a problem..."
        msg.send run.data.log

On drush.io, the corresponding delete-multidev job might look something like this:

terminus env:delete ${TSITE}.${TENV} --delete-branch --yes