Multiple environments with the Zapier CLI
I’ve been working with Zapier’s CLI to create new Zapier tasks and it’s been pretty great. The documentation is great, the tooling around everything is really simple, easy to use and it just always works. The only small pain point I came across was how to deal with multiple environments such as staging and production but it’s a simple workaround to isolate the two.
You can build Zaps in Zapier two different ways, with their web builder and with the CLI. The CLI gives you quite a bit more control and since you’re just writing Javascript so you have quite a bit of customization available to you as well.
I’d recommend reading the getting started with the Zapier CLI article to get a little bit of background. The Zap that I most recently worked on was for giftLinks which connects giftLinks to Zapier for creating new giftLink purchases. We’ll just run through the same process that I used to get things going and configuring both environments.
To provide some background around the Zapier app creation process, here’s a few things to know:
- Your app is not live in the marketplace by default which is good. You have to get to a certain amount of users and that changes the status of the app, more details about the Zap creation lifecycle here.
- You have the ability to keep your app private indefinitely, good for staging.
- You can invite people to work on your Zap as well as install it in their own Zapier account which is useful while you’re developing a Zap.
The way I went about isolating my staging and production environments is mostly via git branches which maps closely to a typical development workflow. Your staging environment deploys from a specific branch, your production environment deploys from another. The only difference is locally there ends up being two directories, one for staging, one for production. The reason I went this route was for a couple of reasons:
- I wanted it to always be extremely obvious which enviroment I was pushing to.
- The CLI tool and Zaps don’t currently have a concept of environments, just environment variables. So while I could swap
API_URL
and then push I like to keep things as simple as possible and it’s one less thing to remember, one less thing to mess up. Environment variables also persist between versions which is a good thing but I wanted to avoid any type of bad environment configuration mixups. I’ve seen similar setups with the Heroku CLI where you can set it up so that agit push staging master
pushes to your staging application, I’d guess Zapier will eventually add similar support but for now you just havezapier push
which loads.zapierapprc
within the current directory and points to a specific Zap ID and a Zap Key. - Utilizing branches makes deploying to production more intentional by having to merge your work into the production branch and then push.
Our end directory listing will look like this:
$ pwd
/Users/nick/projects/zapier
$ ls
production
staging
Where zapier
is the project directory, production & staging are the environment specific directories.
From within the project directory you can go ahead and create the first environment which I’d recommend be staging.
$ zapier init staging
Once that finishes you can CD into it, run an NPM install and then we’ll push it up to get it created within Zapier.
$ cd staging
$ npm install
At this point is when you’ll name it for yourself so that it’s clear within the dashboard.
$ zapier push
Preparing to build and upload your app.
Looks like this is your first push. Let's register your app on Zapier.
Enter app title (Ctrl-C to cancel): nick (staging)
Registering a new app on Zapier named "nick (staging)"
✔ Confirming registration of app "nick (staging)"
✔ Linking app to current directory with `.zapierapprc`
✔ Copying project to temp directory
✔ Installing project dependencies
✔ Applying entry point file
✔ Building app definition.json
✔ Validating project
✔ Zipping project and dependencies
✔ Testing build
✔ Cleaning up temp directory
✔ Uploading version 1.0.0
Build and upload complete! You should see it in your Zapier editor at https://zapier.com/app/editor now!
Now if you go into your developer account you’ll see that you have this new staging specific Zap.
From here you can now set staging specific environment variables such as URLs and API keys. These environment variables will persist between versions and the version is required when specifying a variable as well.
$ zapier env 1.0.0 CLIENT_SECRET 12345
With the staging app built it’s time to get the production Zap going. Go ahead and create a git repository if you haven’t and ensure you have at least the following in the .gitignore
file:
build
node_modules
*.log
.zapierapprc
The most important one for this post being the .zapierapprc
which points to the specific Zap ID and key within Zapier.
$ cat .zapierapprc
{
"id": 1234,
"key": "App1234"
}
Once you’ve committed everything to master then you can push that up to your remote repository host, we’ll clone the remote repository for the production version.
cd ..
git clone git@github.com/nickhammond/zapier.git production
cd production
From here to keep things isolated I’d recommend you create a production oriented branch such as production
. This way you can utilize the same working git repository and it’s just a matter of what’s on the branch within that directory is what gets pushed up to Zapier.
$ git checkout -b production
Since we ignored .zapierapprc
from git the production
folder isn’t currently connected to a Zap which is easily created when you issue your first push.
$ zapier push
Preparing to build and upload your app.
Looks like this is your first push. Let's register your app on Zapier.
Enter app title (Ctrl-C to cancel): Nick's Live App
Registering a new app on Zapier named "Nick's Live App"
✔ Confirming registration of app "Nick's Live App"
✔ Linking app to current directory with `.zapierapprc`
✔ Copying project to temp directory
✔ Installing project dependencies
✔ Applying entry point file
✔ Building app definition.json
✔ Validating project
✔ Zipping project and dependencies
✔ Testing build
✔ Cleaning up temp directory
✔ Uploading version 1.0.0
Build and upload complete! You should see it in your Zapier editor at https://zapier.com/app/editor now!
And now when you run cat .zapierapprc
you’ll see that it’s pointing to a whole new Zap:
{
"id": 5678,
"key": "App5678"
}
From here you can set production specific environment variables since it’s within the production app.
$ zapier env 1.0.0 CLIENT_SECRET 67890
A few things to note:
- The only difference between the production and staging directory is the pointer to the Zap in Zapier(.zapierapprc) and the git branch that you’re utilizing.
- Environment variables are stored within Zapier and there’s no reference to them locally.
Now that there are two isolated directories pointing to two different branches and two different Zaps you can easily go back and forth between staging and production.
➜ cd staging && zapier env 1.0.0
The env of your "nick (staging)" listed below.
┌─────────┬───────────────┬───────┐
│ Version │ Key │ Value │
├─────────┼───────────────┼───────┤
│ 1.0.0 │ CLIENT_SECRET │ 12345 │
└─────────┴───────────────┴───────┘
$ giftlinks cd production && zapier env 1.0.0
The env of your "Nick's Live App" listed below.
┌─────────┬───────────────┬───────┐
│ Version │ Key │ Value │
├─────────┼───────────────┼───────┤
│ 1.0.0 │ CLIENT_SECRET │ 67890 │
└─────────┴───────────────┴───────┘
Since you can utilize git and have a context of staging and production it allows you to continue your normal workflows of pull requests, merges, etc. Happy Zapping!