Getting started with Gitlab CI/CD: Eslint
Tags: gitlab, cicd, node, docker
Published: 2019-01-09 21:45:50

---
title: Getting started with Gitlab CI/CD: Eslint
published: true
description: A quick guide to get started with Gitlabs CI/CD by creating an linting Job using shared runners.
tags: gitlab, CI/CD, node, docker
cover_image: https://images.unsplash.com/photo-1531030874896-fdef6826f2f7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1000&h=400&q=80
---

Getting up and running with Gitlab's Continuous Integration can take less than 10 minutes (depending on what you want to do, YMMV) I'm going to show you how:

To begin with - I just want to setup a simple task that will run `eslint` on our code. Luckily for us, we're already half way there.

> Starting from version 8.0, GitLab Continuous Integration (CI) is fully integrated into GitLab itself and is enabled by default on all projects.

If you head on over to a project within Gitlab and click on **Settings** and **CD / CD** (https://gitlab.com/{username}/{project}/settings/ci_cd) you will see a drop down for **Runners**. You should see two columns. **Specific Runner** and **Shared Runners**. Awesome! (You don't have to do anything).

![Runners](https://thepracticaldev.s3.amazonaws.com/i/9byh5332zm8zbt8ni9b4.png)

## Runners

You should have some shared runners available. Shared runners are free to use for public open source projects and limited to 2000 CI minutes per month per group for private projects.

Runners are virtual machines that run jobs specified in a `.gitlab-ci.yml`. This file will tell the runner what jobs to do.

```bash
# At the root of your repository, add the .gitlab-ci.yml file.
$ touch .gitlab-ci.yml
```

Runners use [docker](https://www.docker.com/) to pull an `image` and run our application in a container, so we need to tell it what image to pull, what things to install and what scripts to run.


Since I'm using node, we want to pull that [image from Docker](https://hub.docker.com/_/node/)

```yml
# We're pulling and installing node into our virtual container, neat!
image: node
```

Now we want to add a `stage`. Stages tell the runner what functions to run and when. For example you might have `build`, `test` and `deploy` stages. Stages can have multiple Jobs.

```yml
image: node

stage:
 # I just want to lint, so I will create a "lint" stage
 - lint

# Lets name our Job eslint, because that's what it's doing.
eslint:
 # tell eslint what stage it is. (This could also be build or test for example)
 stage: lint
 # What scripts do we want to run?
 script:
    # install eslint
    - npm i eslint
    # Run eslint
    - node_modules/eslint/bin/eslint.js .
```

Commit the `.gitlab-ci.yml` and push it to gitlab!

Head on over to `https://gitlab.com/{username}/{project}/-/jobs` to see your job in action.

Assuming you have some eslint errors, your job will fail - Woohoo!

![failed-job](https://thepracticaldev.s3.amazonaws.com/i/bx6m849ec4c28k6g61sa.png)
![eslint-errors](https://thepracticaldev.s3.amazonaws.com/i/f5rep0a669na7vhn5pns.png)

![lol](https://media2.giphy.com/media/5VKbvrjxpVJCM/giphy.gif?cid=3640f6095c36689c3370327963701ff7)

### But I have plugins, and presets!

You can simply install these along side the `npm i eslint` statement.

If you have multiple, you can use a backslash `\` to move it onto a new line for a **multiline command**

```yml
image: node

stages:
  - lint

eslint:
  stage: lint
  script:
    # Install eslint
    - |
      npm install eslint \
      eslint-config-airbnb \
      eslint-config-prettier \
      eslint-plugin-flowtype \ # Any ideas on what I might want to do next?
      eslint-plugin-import \
      eslint-plugin-jsx-a11y \
      eslint-plugin-prettier \
      eslint-plugin-react
    # Run eslint
    - node_modules/eslint/bin/eslint.js .
```

Now go and get rid of all your eslint errors and you're on your way to a passing pipeline!

![passed-pipe](https://thepracticaldev.s3.amazonaws.com/i/5s9oin61bmuswpz9fifd.png)
![passed-term](https://thepracticaldev.s3.amazonaws.com/i/d8c13yl6lne4wihgsrd7.png)