Building a custom Google Data Studio connector from A-Z. Part 4 — Continuous Integration

Welcome to the last and final part of my tutorial! In the previous one I showed you how to unit test your connector using Jest framework, generate code coverage and check the code quality using eslint. Now you’ll learn how to automate all this stuff using a CI platform. In this article I’ll be using CircleCI, however these steps should be pretty similar for other tools like Semaphore or Travis.

What we’ll do in this article is we’ll:

  • Make CircleCI run the unit test suite on every new commit
  • Run eslint checks automatically
  • Generate the code coverage and send it to codecov.io
  • After successful build push the new code to Google Scripts

The build part

Simple build setup

Now if I commit the file and push the master branch to GitHub the build will start automatically:

Image for post
Image for post
First successful build!

Eslint & code coverage

- run:
name: "Lint the code"
command: yarn lint
- run:
name: "Run tests (with coverage)"
command: yarn coverage

Now whenever any of eslint’s rules are violated the build will fail with appropriate output:

Image for post
Image for post
Oops, I’ve violated the rules :O

Send the coverage to CodeCov

Image for post
Image for post
CodeCov badge

First I, of course, registered and setup my repository in CodeCov’s interface. Then, basing on this document, hoped that CircleCI will somehow automagically send the coverage to CodeCov. This didn’t really happen :D

The solution wasn’t really that hard — it turned out that there’s an npm package that does the thing I need, so I only had to:

  1. Add CODECOV_TOKEN to my CircleCI project
Image for post
Image for post

2. Add the following step to the .circleci/config.yml file

- run:
name: "Send coverage to CodeCov"
command: yarn add --dev codecov && ./node_modules/.bin/codecov

The deployment part

Prepare the deployment script

As you may remember I’ve already setup the “Production” deployment back then. We’ll now write a script that’s gonna do the following things:

  1. Push the code to Google Scripts
  2. Create a new script version
  3. Modify the “Production” deployment to point at the newly created version

Here’s how the bash script I invented looks like:

The deployment bash script

Run the script on CircleCI

First let’s add a new script to our package.json file: "deploy-production": "./deploy.sh 'Production'".

Then we’ll need to allow CircleCI job modify our Google Script. If you haven’t done it before run clasp login in src folder and login using your Google credentials. Clasp will create a .clasprc.json file containing access tokens to Google services in your home directory.

I haven’t found any better way of doing Google authentication on the CI side than just copying the contents of your local file to the CI application. In case of CircleCI we’ll need to add a new environment variable in our CircleCI project and call it CLASPRC. The value of the variable should simply be the content of your local clasprc.json file.

Last thing is adding the deployment step to our .circleci/config.yml file so that:

  • It writes the content of CLASPRC variable to ~/.clasprc.json file
  • It runs the deploy.sh script we wrote before
  • It runs the deploy step only after a successful master branch build

Our final config file looks like this:

Check the results!

Image for post
Image for post
Deploy in progress

The job completed successfully. Now if we verify the result in Google Scripts interface we’ll see that indeed — a new version was created:

Image for post
Image for post
New version is here

And the “Production” deployment points at the newly created version:

Image for post
Image for post
Updated “Production” deployment

Summary

You may say that doing all these things I did in parts 3 and 4 is an overkill for such a small application and… you may probably be right. However, when your connector gets more advanced you’ll quickly notice that manual debugging and deployments take a looot of time. I’m pretty sure that after a week of such “manual” development you’ll waste as much time on debugging as I did on writing unit tests and setting up the CI :)

Hope you learned a lot during this series of posts and that it’ll help you develop great products.

As always you can check the full code of this part in my GitHub repository or test the connector using this link.

If you liked the series do not hesitate to 👏!

Full stack developer @Leadfeeder. Working on random stuff in my free time.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store