Moving to a Modern Development Workflow

Lately I’ve been focused a lot on front-end technologies, while ignoring this nagging sensation in the back of my mind that I’m leaving something out. The products are getting better, but my process can be improved.

A modern development project needs a modern development work flow.

Normally I would fire up a local development environment (Vagrant or Docker) and start coding. I test it on different devices and browsers, push my code to a Git repo,  transfer the files to production, and call it a day.

This works OK. If I’m diligent about my testing, things generally work out fine. Well, I don’t know about you, but I’m not perfect…

So, over the course of a weekend I decided to upgrade my development process. The goal was to build a simple web app that converts hex values to RGB, and vice versa.

Here’s what I came up with:

However, I wanted the app to be simple so I could focus more on the build process. My goal was to incorporate some modern tools, technologies, and methodologies.

Admittedly, it’s a bit over-engineered, but I wanted to emulate the environment for a larger project

What the workflow looks like

The project was set up with vue-cli which makes a lot of the set up process trivial. Vue-cli has a pwa template that includes support for service workers and unit testing. Setting up a new project is as simple as:

$ npm install -g vue-cli
$ vue init pwa my-project
$ cd my-project
$ npm install
$ npm run dev

(this assumes you have node and npm installed already)

The next step was to build out the components. This project was relatively simple, so the components did not take long, but they each required some unit tests to be written out as well.

As the app progresses, I can regularly run my tests to make sure nothing breaks. If things look good, I can commit the project with Git. Finally, when I’m finished for the day, I can push all my code to my remote repository on GitLab.

Here’s where it gets fun

GitLab supports continuous integration out of the box. By adding a ‘.gitlab-ci.yml’ file to my project, I can tell GitLab what to do whenever I push to the repo. In my case, I have two sets of directions: test and deploy.

When I push my code up, GitLab will and spin up a very basic server, install my prject and all the dependencies (‘npm install’), and finally run my tests (‘npm run test’). If any test fails, I get notified via email, and nothing else happens. If all tests pass, GitLab will automatically deploy the project to production.

A couple gotchas

The project is hosted with netlify, a great static site hosting service. netlify by default has continuous delivery built in. Once connected with a Git repo, it will listen for any changes and pull up the code any time a commit comes in. This, however, forgoes any testing I have running on GitLab, which is not ideal.

The solution is to delete the default integration (GitLab repo -> Settings -> Integrations). Next, set up a custom webhook in netlify. This is a unique URL I can send a request to so netlify knows when to pull up the latest code.

The final step is to notify netlify when it’s time to pull up the latest round of unit-tested code. Back to the GitLab continuous integration configuration. The deploy stage runs after a successful testing stage. So all we have to do is ping the custom netlify build webhook. It looks something like this:

curl -X POST -d ‘{}’{your custom api token}

Another issue was that my PWA features weren’t working. My static resources were not being cached properly although the service worker was properly configured.

The reason was that netlify will serve static resources form it’s own CDN hosted on AWS. Therefore, the URL where my resources were being served from had been changed. Adding the new URL to the service worker configuration fixed that issue.

That’s about it

Write some code. Push code to the remote repository. Watch the tests pass. Check out the production site.