How I used GitHub Actions to automate (some) of my deployment

An effort to make my life a bit more easy

This isn’t my terminal, it’s just a picture of it.

To be honest, this will not be impressive to a lot of developers out there. But for me it was an acomplishment and a moment of learning as a developer that consistently feels slow to catch up, not to mention often intimidated & needed a way to ease his own imposter syndrome. For now anyway.

Before I explain, let me show you my old work flow

The old but sort of simple way

Since version 1.x I had decoupled with my backend. Why? Because AWS is far too expensive and this was far simpler, quick & easy.

Let’s break this down a bit on what’s going on here.

  1. Code a new feature or fix.
  2. When these changes are ready I’ll locally run ESLint. If there are any errors it will tell me and I’ll have to repeat this step.
  3. Run End-To-End(E2E) tests locally with Cypress. If this fails then it will also tell me where when and how.
  4. If all checks out, then start generating my build files with npm.
  5. Deploy changes to my local Firebase server. The difference here is that the local server will now preview changes from the build files from step 4, instead of the npm local server which hotloads any changes I make to my .JSX files. At this stage I generally won’t add any new changes. But if I ever change my mind I’ll have to start over from step 1.
  6. The changes look good, so now it’s time to deploy to production.
Firebase also keeps a deployment history so anytime I want to rollback to a previous change I can do that easily at the click of a button.

7. Finally, when Firebase has successfully deployed my new changes I’ll add all my build files and commit them to my private GitHub repository as some means of version control.

For a lot of people with small projects this is generally enough and you probably don’t need to do more. But I wasn’t happy with this at all and for 2 big reasons too:

  1. Deployment and version control are not synchronized at all.
  2. I have to manually perform each step so it’s not really well streamlined. e.g. Running E2E tests locally before building files then deploying to Firebase.

First Solution — Ditch Firebase, migrate to Netlify

I switched hosting to Netlify because I hear it works really well with GitHub. Especially when there is a simple way to automate deployment straight from my pull requests.

Next— GitHub Actions

With GitHub Actions, it’s possible to automate “some” of my workflow. Here is my now updated deployment workflow.

Far from perfect. But for now this is enough. It’s important to note that this is basically done automatically up until some interaction is done in a pull request

Just follow the arrows and refer back to above and it will make sense.

  1. New feature or fix is ready, so commit changes and push them to GitHub.
  2. Create pull request and set my feature branch to be merged to its base master branch.
  3. GitHub Actions will now start to execute and do it’s thing.
  4. Run ESLint and check for formatting errors. (I use the AirBnb JavaScript style guide as the default format by the way.) If this step fails, I get a notification.
  5. Run my E2E tests after GitHub actions has finished the ESLint job. In my GitHub actions .yml file I explictly set any number of machines to run the same tests across multiple copies in parallel. You can do this by setting the machines keyword in your .yml file here then setting the parallel flag to true.

7. When my tests pass Cypress will comment automatically into my pull request the test results as a bot. Here is the case that all tests have passed, telling me the commit number, the OS that was used and the duration of the whole test:

All test cases look good. Good bot!
In the case tests had failed. But don’t feel down, see how it even links to where the test had failed! You even get a screenshot pointing exactly to which part of the test had failed. Awesome!

8. At this stage GitHub Actions has finished it’s list of executions and the Netlify webhook takes over to deploy these changes into a deploy preview. Netlify will provide a randomly generated link for me to preview what has changed. This is basically a staging environment, except without the large overhead of cash about to be invoiced to me like my secondary school teacher with my exam results.

9. I verify my changes and check that the deploy preview shows my changes are in effect.

10. Now that I’m sure my changes are working properly in deploy preview I’ll hit that merge button and move on.

11. After merging, Netlify automatically detects this action and performs production deploy of all my build files. I can off course turn this off and do this in Github Actions but I haven’t a solution to allow deploy preview and perform a production deploy on merge. Probably I need to upgrade to a pro account because this is the only way for me to set up a rule.

At the grand scheme of things, I’ll most likely do this in the next update because this repo is still private and the only people that have access is me and a friend. In terms of best practices, this should not be left alone and it’s especially true in a company.

And that’s it! What do you think? Could be done better/simpler?

Full-Stack Engineer, at one time also officially labelled “Professional Badass”.