paint-brush
DevOps Shouldn't Be Hard!by@Destiner
573 reads
573 reads

DevOps Shouldn't Be Hard!

by TimurJanuary 9th, 2020
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

GitHub Actions is a feature that allows you to run custom checks and actions each time your remote git repository changes. Two major ways to use it is to run automated checks on our codebase or use it for continuous deployment. As we do all our CD work on our own server, we're most interested in the former. That is, we will leverage GitHub Actions to run tests and other checks to make sure our app is behaving correctly before deploying it. You can sign your webhook requests with JWT or HMAC.
featured image - DevOps Shouldn't Be Hard!
Timur HackerNoon profile picture

About those GitHub Actions

So far we were able to set up a deployment and reporting servers, making a full way from pushing a new commit to updating the app in production. But what can we automate before pushing to master? What if we run a set of checks to make sure our app is behaving correctly before deploying it? That's where GitHub Actions will come handy.

GitHub Actions is a feature that allows you to run custom checks and, well, actions each time your remote git repository changes. Two major ways to use it is to run automated checks on our codebase or use it for continuous deployment. As we do all our CD work on our own server, we're most interested in the former. That is, we will leverage GitHub Actions to run tests and other checks to make sure our codebase is OK.

There are several ways to manage your git workflow. I won't dive too much into it, but it boils down to whether you want to have feature branches, do you differentiate between

develop
and
master
, and whether you deploy your code automatically for each push. I researched this for a while, and here's what made the most sense to me. For context, I'm talking about an individual or a small team working on a small- to mid-size project.

Here's my workflow of choice:

  • there are two branches:
    develop
    and
    master
  • code is pushed to
    develop
  • each push triggers code checks, powered by GH Actions
  • assuming checks passed, new PR is created automatically
  • once PR is pushed to
    master
    , code is deployed
  • you get a notification on the check result

Setting Actions up

We don't need to configure anything to get started. Create a file under

.github/workflows
named
nodejs.yml
and commit it, and GitHub will automatically process it and show
nodejs
workflow under the
Actions
tab.

Our pipeline will consist of three jobs:

build
,
notify
, and
create PR
.

Build

Our build step will consist of 5 commands, running one after another.

  • npm audit
    : runs a security audit of dependencies
  • npm ci
    : makes a clean install of dependencies
  • npm run lint
    : lints your codebase (e.g. ESLint)
  • npm run build
    : builds your app (e.g. Webpack)
  • npm test
    : runs tests (e.g. Jest)

Of course, all the steps are optional. You can add your own checks as well.

Here's the full code of the build job:

build:
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        node-version: [8.x, 10.x, 12.x]
    
    steps:
    - uses: actions/checkout@v1
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - name: npm install, build, and test
      run: |
        npm audit
        npm ci
        npm run lint
        npm run build
        npm test

strategy.matrix
allows us to test our app on multiple Node.js versions in parallel, which is handy.

Notify

Let's now send a webhook to our reporting server upon successful build. Note passing

WEBHOOK_URL
from repository secrets.

notify:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Webhook
        uses: joelwmale/[email protected]
        env:
          WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
          data: "{'app': 'my app', 'success': true}"

Once GitHub executes build, it will trigger a webhook to the specified URL so we can catch it and show some message.

Additionally, you can sign your webhook requests with JWT or HMAC (for example, using this action).

## Create a PR

Finally, let's send PR to master after a successful build. Secrets with

GITHUB_
prefix are provided by GitHub itself, so we don't need to do anything extra here.

master-pr:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Create Pull Request
        uses: repo-sync/[email protected]
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}

The neat thing about this workflow is that you get an overview of all jobs for each PR.

Wrapping up

We made it! We managed to build an entire workflow of deploying an app.

Here's what we achieved.

Each time a new code is pushed:

  1. The codebase is audited to make sure there are no security vulnerabilities
  2. Build tool ensuring there are no build-time errors
  3. Linter is run to make sure code formatted correctly
  4. Tests are run to make sure app behaves correctly
  5. PR is created
  6. We receive a notification

Each time PR is merged to

master
:

  1. CD server updates the app
  2. CD server notifies reporting server
  3. We receive a notification

In other words, all of the boring stuff is done automatically with minimal input from our, developer's, side.

I hope you enjoyed the series! From there, you can continue adding automation to your build and deploy pipelines based on your app requirements.