Works on localhost

Publishing in Netlify via TravisCI

The case of too much CI

I’ve recently started to dabble with Netlify to deploy this React + Redux app I’m building as *painless* and as transparent as possible. My initial roadblock was that Netlify was being “too eager” with building and deploying my app whenever I push to the production branch (yay Continuous Integration!). Meaning, the app would be built and deployed but without the tests being ran and considered. I initially hooked up the app to TravisCI which should take care of running the tests + linting. The problem now is that how do I tell Netlify to hold the deployment until TravisCI finished running?

TravisCI -> Netlify

I *think* I got the most sane way of triggering Netlify to publish (see I didn’t use the term deploy?) via TravisCI. Here’s what I did.

Step 1

You need to create a personal access token that can be found on your account dashboard:

Netlify token page

Step 2

Go to the settings tab of your repo’s TravisCI build page and add the key you just created as an environment variable. Be sure to keep the “Display value in build log” value to off:

TravisCI Environment Variables

Step 3

Add the following publish.sh file to your repo (anywhere in the repo is okay, just adjust your .travis.yml file). Be sure the replace the following:

  1. YOUR_SITE_HERE - Your app domain in Netlify
  2. ENV_NAME_HERE - The name of the environment variable you entered in Step 2. (Don’t omit the $ though)
  #!/usr/bin/env bash

  # die on error
  set -e

  # https://gist.github.com/cjus/1047794
  echo 'Retrieving latest deploy...'
  url=`curl -H "Authorization: Bearer $ENV_NAME_HERE" https://api.netlify.com/api/v1/sites/YOUR_SITE_HERE/deploys`
  temp=`echo $url | sed 's/\\\\\//\//g' | sed 's/[{}]//g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' | grep -w -m 1 'id'`

  # https://www.netlify.com/docs/api/#deploys
  echo "Publishing build ${temp##*|}..."
  curl -X POST -H "Authorization: Bearer $ENV_NAME_HERE" -d "{}" "https://api.netlify.com/api/v1/sites/YOUR_SITE_HERE/deploys/${temp##*|}/restore"

Step 4

Add the script in your .travis.yml file:

...your config...

after_success:
  - chmod +x ./publish.sh
  - ./publish.sh

Step 5

Be sure to turn off the “auto-publishing” setting for your domain. This is the key to what we’ve been doing. Whenever you push to your production branch, Netlify will automatically fetch and build your branch (you can’t turn this off). However, you can stop Netlify from auto-publishing it (i.e. making the branch live). This is then where TravisCI comes in. It will trigger Netlify to publish the recent build (your latest push) after it has verified that your app has passed all the tests.

Netlify’s auto publish

Sample run

Here’s what your TravisCI log should look like:

Retrieving latest deploy...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 15956    0 15956    0     0  45474      0 --:--:-- --:--:-- --:--:-- 45588

Publishing build <latest build>...

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1228  100  1226  100     2   2158      3 --:--:-- --:--:-- --:--:--  2158

>>>Some json response dump for Netlify<<<

Update

Thanks to @giuliano_varriale, Netlify does enable auto-publishing once a build is pushed. I’ve also reached out to Netlify about this and they say it is the expected behaviour.

Auto-Publishing is expected behaviour

To work around this, Netlify has an API called lockDeploy to which we can call to automatically re-lock our deployment.

It is as simple as adding the following snippet to our publish.sh file:

# https://open-api.netlify.com/#/default/lockDeploy
echo "Locking deploy to ${temp##*|}..."
curl -X POST -H "Authorization: Bearer $NETLIFY_PUBLISH_KEY" -d "{}" "https://api.netlify.com/api/v1/deploys/${temp##*|}/lock"

Again, thanks to @giuliano_varriale for pointing out the problem and providing a solution.