Deploy to now from CircleCI

Deploying websites to now is simple and enjoyable. Even so, I find myself typing the same commands to deploy, set new aliases, and remove unaliased deployments.

My solution to reducing repetition in my workflow is deploying code from CircleCI. Every time I push code to master, CircleCI will run tests and build the website. If both commands succeed, CircleCI will then deploy my changes to now.

Configuration

Here’s a simplified version of my CircleCI 2.0 configuration, followed by a breakdown of how it works.

# config.yml
version: 2
jobs:
  build:
    working_directory: ~/repo-name
    docker:
      - image: circleci/node:8
    steps:
      - checkout

      - run: npm install
      - run: sudo apt-get install jq
      - run: sudo yarn global add now now-realias now-no-alias

      - run: npm run test

      - run: npm run build
      - store_artifacts:
          path: build

      - run: now build -t ${NOW_TOKEN} --name=website-name --static --public
      - run: now-realias
      - run: now rm -t ${NOW_TOKEN} $(now-no-alias | jq -r '.[] | .uid') -y

Setup

First, generate a now API token and add that environment variable to CircleCI with the name NOW_TOKEN.

Next, create a now.json file at the root of your repository, ensuring you have at least the “alias” field set:

{
  "alias": ["website-name"],
  "files": ["build"],
  "name": "website-name",
  "public": true
}

Let’s install the necessary dependencies we’ll need to build the application and deploy to now.

# config.yml
- run: npm install
- run: sudo apt-get install jq
- run: sudo yarn global add now now-realias now-no-alias

Test

Let’s run the tests next and any other checks required before building the application (things like linting, code coverage reports, etc. would go here).

# config.yml
- run: npm run test

Build

Next, we will run the build script and save the resulting output directory, build/. This directory contains the static site that will be deployed to now.

# config.yml
- run: npm run build
- store_artifacts:
    path: build

Deploy

Let’s break down these series of deployment commands:

# config.yml
- run: now build -t ${NOW_TOKEN} --name=website-name --static --public
- run: now-realias
- run: now rm -t ${NOW_TOKEN} $(now-no-alias | jq -r '.[] | .uid') -y
  1. now build deploys the build/ directory to now. The --name=website-name argument will set the resulting URL to website-name-UNIQUEID.now.sh.
  2. website-name-UNIQUEID.now.sh isn’t a memorable URL, so running now-realias will alias the most recent deployment with what’s defined in now.json. Now, website-name.now.sh points to the latest build.
  3. (Optional) Remove any deployment that isn’t tied to an alias using now-no-alias. This is helpful, at least on Zeit’s free plan, because the free plan only allows 3 concurrent active instances.

Next Steps

Down the line, I’d like to translate this process into CircleCI 2.0’s new Workflows feature, and I hope to follow up with a post on what that looks like. :+1: