Runtime
Every job run on drush.io is executed in an isolated container, offering a clean runtime environment for every run. No state persists between runs, ensuring predictable behavior.
The environment
Because job runs are queued by individuals, every job run is invoked in the context of the individual account’s credential. That means all commands executed during the job run are run with terminus pre-authenticated and with SSH keys appropriate to run remote commands. No need to run terminus auth:login
in your job!
All commands are run in an initially empty file directory. You can populate the current working directory using tools like git
, composer
, npm
, etc.
You can navigate the file directory using shell built-in commands like cd
and pwd
.
Available CLI tools
The following CLI tools are available and considered supported in the runtime:
terminus 1.x
git 2.13
mysql
redis-cli 3.x
composer 1.x
php 5.6
node 6.x
npm 3.x
Jobs are run on a recent version of Alpine Linux and all command line tools normally available therein are available to you, including curl
.
To get the most out of drush.io, you’ll want to make sure you’re familiar with terminus, Pantheon’s CLI. It’s also important to note that, while drush.io jobs resemble a shell script, they aren’t exactly shell scripts. Stick to the supported job syntax and you’ll be golden!
Speaking of syntax, dive in with logical operators.
Logical Operators
All commands exit with a status code when they complete: 0
means everything went according to plan, any number greater than that indicates some type of error or logical negative state. You can employ these exit codes to your advantage using logical operators to chain commands together in your jobs.
&&
between commands means “if the first command exits 0, run the next command.||
between commands means “only run the next command if the first command exited > 0”
Take this statement as an example:
terminus env:info my-corp.my-env || terminus env:create my-corp.test my-env
Because the env:info
terminus command exits 1
if the my-env
multidev doesn’t exist, the env:create
command only ever runs when it needs to.
Next, learn about command substitution.
Command Substitution
Sometimes, you want to use the output of a command as an argument to another command, or occasionally, the basis for another command entirely. Use command substitution to solve these needs.
Here’s an example statement that uses the output of one command as an argument in another.
terminus env:create my-corp.test `git rev-parse --abbrev-ref HEAD`
This would create a multidev environment, based on the database and files of the test environment, named after the currently active git branch in the current working directory.
This example statement uses the output of one command as the basis for a different command.
`terminus connection:info my-corp.test --field=mysql_command` -e "TRUNCATE sessions;"
This would truncate the sessions
table on the test environment using the MySQL client.
Next, learn about asynchronous commands.
Asynchronous Commands
Some terminus commands initiate (and then wait for) potentially long-running operations. An example of this is multidev environment creation.
While in most cases, you would want to wait for the operation to complete before proceeding or ending the job, occasionally, you may wish to run a job asynchronously, or in the background.
As an example, you might have a Recreate Integration Environment job, like this:
terminus env:delete my-corp.integrate --yes
terminus env:create my-corp.live integrate &
sleep 10
Here we’re synchronously deleting the integrate
environment, then once complete, asynchronously creating the same environment using the &
operator.
Note the use of the sleep
command, which gives terminus time to reach out to Pantheon and initiate multidev creation before the job ends.
Beware, not all terminus commands work this way.
Next, learn about variables.
Variables
As you build out your library of jobs, you may find that some of your operations are generic enough that they could easily be run on any number of sites. Instead of copy/pasting jobs, you can use variables to reduce repetition.
You’ll likely want to use variables with default values as you’re starting out:
terminus env:clear-cache ${TSITE_ENV:-my-corp.test}
This allows you to run the job using the drush.io UI (which doesn’t provide a way to customize variables at run-time), but enables API users to provide custom values.
For commands that don’t make sense without custom values, you could use simple variables like this:
terminus env:delete $TSITE_ENV --yes
This command would only delete a multidev environment if a value like my-corp.my-env
were provided via the API.
Also note that you can concatenate variables to form a single argument. For example, if you primarily work on one site, but wish to add the flexibility of swapping sites in your job, you could use this common pattern:
terminus env:delete ${TSITE:-my-corp}.$TENV --yes
Here, you could choose to only provide a TENV
value in your API call, which would default to deleting the provided environment on the my-corp
site. Or, you could provide both a TENV
and a TSITE
to delete a multidev elsewhere.
Setting variables inline
Variables are stateful and can be set and unset as in a shell script. This can help make jobs clearer and easier to digest. For example:
URL='https://live-my-corp.pantheonsite.io'
echo "Reading headers for url $URL"
curl -I --silent $URL
Variables can also be used to store and re-use a value that takes time to calculate or return:
URL=`terminus env:view my-corp.${TENV:-live}--print`
echo "Reading headers for url $URL"
curl -I --silent $URL
Note also that variables may be unset.
URL='https://live-my-corp.pantheonsite.io'
echo $URL
unset URL
echo $URL
Next, learn about I/O redirection
I/O Redirection
Sometimes, you don’t want the output of a command to be displayed. In such cases, you can use I/O redirection to pipe command output away from standard out.
A common use-case for this is running set-up commands, but returning a clean, API response:
terminus env:create ${TSITE}.test $TENV --yes > /dev/null 2>&1 && \
terminus env:info ${TSITE}.$TENV --format=json
This statement would create a multidev environment and, if successful, print a JSON payload to the log output containing useful information like domain or creation date.
By hiding the output of the set-up commands, you can design a JSON API for yourself based on the log output of the job run.
Simple Pipes
In addition to stdout/stderr redirection, drush.io supports basic piping. This is commonly used for filtering the output of a command, but you can pass the output of any command to any other command. For example:
terminus site:list --field=name | grep client-name
Now that you know the runtime environment and job syntax, you’re ready to build a custom ops platform on the drush.io API.