Gatsby Up & Running: Creating a CD Pipeline
Tags: gatsby, javascript, devops, github
Published: 2020-09-26 18:36:02

---
title: "Gatsby Up & Running: Creating a CD Pipeline"
published: true
description: Continuously Deploy your Gatsby Site Using Travis CI
tags: gatsby, javascript, devops, github
---

My [last adventure](https://deborah-digges.github.io/2020/09/16/Jekyll-to-Gatsby) was migrating my crufty Jekyll site to Gatsby. I used to deploy my Jekyll site manually by building it locally and pushing the generated static content to the `gh-pages` branch on GitHub. With my new site in place, I decided it was time to leave my old ways behind and set up an automated pipeline to deploy my site to GitHub pages.

## Why GitHub Pages?

I've always used GitHub Pages to host my blog because it's lightweight and integrates seamlessly with GitHub. It is simple, free, and provides free goodies like enforcing HTTPS by default and also supports adding a custom domain.

## Deploying Locally

Before automating the deployment of my new Gatsby site, I learned how to deploy it locally. To do this, I added an entry to the `scripts` tag in `package.json` which creates a production-ready build for my Gatsby site.

```
"scripts": {
  ...
  "build": "gatsby build",
}
```

```npm run build``` builds the site and places the generated assets in a folder called `public`. Copying this `public` folder to any HTTP server would deploy my site to that server.

I started an HTTP server using [http-server](https://www.npmjs.com/package/http-server) to serve the assets in the `public` folder which effectively deployed my site locally.

```
➜  cd public
➜  http-server
Starting up http-server, serving ./
Available on:
  http://127.0.0.1:8082
  http://10.10.10.10:8082
  http://192.168.13.12:8082
```

## Deploying Manually to Github Pages

### Setting up Github Pages

I already had GitHub pages set up since I used it for my Jekyll site but I will go over the steps here for completeness.

![Github Repository](https://dev-to-uploads.s3.amazonaws.com/i/y25t3rw5rtm22galrt93.png)

I headed to my GitHub repository's settings page and scrolled down to the `GitHub Pages` section.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9nb6m9cs8mviym4xo5hk.png)

I did not want the files generated by the Gatsby build process to clutter up my `master` branch so I chose the `gh-pages` branch as the source branch for my GitHub Pages site. Any static site I pushed to this branch would then be published at `deborah-digges.github.io`. I also liked the fact that `Enforce HTTPS` was enabled by default. All the security!


### Deploying Manually

I deployed the site manually to GitHub Pages by building the site locally and pushing *only* the `public` folder to the `gh-pages` branch on GitHub.

This required a rather awkward sequence of commands.

```
git checkout -b gh-pages

gatsby build

# Temporarily move the public folder
mv public /tmp

# Remove all other files
rm -r *

# Move the contents of the public folder back to the root of the directory
cp -r  /tmp/public/* .

git commit -m "Release new version of blog"

git push origin gh-pages
```

That's a mouthful and it's easy to go and accidentally nuke your whole computer with commands like `rm -r *`. It's a good thing the [gh-pages](https://www.npmjs.com/package/gh-pages) package exists to save us from ourselves.

I added the dependency to my project to give it a spin.

```
yarn add gh-pages
```

To let `gh-pages` know where my repository was located, I  added the `homepage` property in `package.json`.

```
{
  ...
  "homepage": "deborah-digges.github.io",
  ...
}
```

I added another script `deploy` to my `package.json` which does a `build` and then pushes the `public` folder to the `gh-pages` branch of my repository on Github.

```
"scripts": {
  "build": "gatsby build",
  "deploy": "npm run build && gh-pages -d public",
}
```


And voila! I was able to deploy my site manually from my computer using the `npm run deploy` script. My site was then up and running at [deborah-digges.github.io](http://deborah-digges.github.io/)

## ✨Continuously✨ Deploying with Travis CI

Great! I deployed my Gatsby site! However, I wouldn't want to be deploying a site manually from my laptop on a Friday afternoon.

I decided to [continously deploy](https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment) my site so that every new commit would automatically be deployed to my GitHub Pages site. This was exciting, but I had bypassed an important step which is having automated tests for my site to ensure that a bad commit did not bring down my entire blog. However, I decided to live *dangerously* and keep the testing of my Gatsby site for a future blog post.

### Signing Up

I signed up on the [Travis CI](https://travis-ci.org/) website with my GitHub account and consented to sharing my GitHub data with Travis.

### Enabling the Repository

I then headed to the [repositories](https://travis-ci.org/account/repositories) page and enabled builds for the `deborah-digges.github.io` repository.

![Travis Toggle](https://dev-to-uploads.s3.amazonaws.com/i/qxnahg2cpjczoa1fbz00.png)

### Adding the travis.yml file

I added a `travis.yml` file to the root of my repository to tell Travis what to do on every commit to `master`.

```
language: node_js
before_script:
  - npm install -g gatsby-cli
node_js:
  - "10"
script: git config --global user.email $GH_EMAIL 2> /dev/null &&
  git config --global user.name $GH_USERNAME 2> /dev/null &&
  git remote set-url origin "https://${GH_USERNAME}:${GH_TOKEN}@github.com/deborah-digges/deborah-digges.github.io.git" 2> /dev/null &&
  yarn install && yarn run deploy 2> /dev/null
```

The `script` runs the `yarn run deploy` step that I previously used to deploy my site locally. It is doing some extra steps to give Travis CI the right access to push to my GitHub repository.

It tells the `git` client installed on Travis CI who I am.

```
git config --global user.name $GH_USERNAME
git config --global user.email $GH_EMAIL
```

To provide the script push access to my GitHub repository, I embedded my [Github Token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) environment variable in the remote URL.

```
git remote set-url origin "https://${GH_USERNAME}:${GH_TOKEN}@github.com/deborah-digges/
```

Where did these environment variables come from?

### Configuring Travis Environment Variables

I headed to my repository settings and made the following environment variables available to my script.

![Travis Env Variables](https://dev-to-uploads.s3.amazonaws.com/i/0honf0v7zksioox8e385.png)

It took me a few attempts to get this right, but I am proud to say that my site is now being continously deployed to GitHub Pages on every commit to the `master` branch of my repository.

![Travis Failed Attempts](https://dev-to-uploads.s3.amazonaws.com/i/n2pu1tvhp0snzg9qyi7a.png)

This was a lot of work, and in my quest to search for a simpler solution, I will explore using a GitHub Action to continously deploy my site. Stay tuned for more dangerous living!