Using GitLab to build, test and deploy modern front end applications

0: The project

1: Configure Firebase

2: Setup GitLab

  • install — install all dependencies from NPM
  • build — build the code
  • quality — run eslint, unit tests with Jest and end-2-end test with Cypress
  • deploy — deploy the code to firebase
  • audit — Run lighthouse against deployed code
linting:
stage: quality
script:
- npm run lint

2.1: Install step

install:
stage: install
script:
- npm install
artifacts:
name: "artifacts"
untracked: true
expire_in: 30 mins
paths:
- .npm/
- node_modules/

2.2: Build

build:
stage: build
script:
- CI=false npm run build
artifacts:
paths:
- build
expire_in: 30 mins
dependencies:
- install

2.3: Quality

test:unit:
stage: quality
script:
- npm run test:coverage
dependencies:
- install
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
"e2e": "CYPRESS_baseUrl=http://localhost:3333 npx cypress run",
"e2e:ci": "npx start-server-and-test serve:e2e http://localhost:3333 e2e",
"serve:e2e": "node_modules/.bin/sirv build --quiet --single --port 3333",
test:e2e:
stage: quality
image: cypress/browsers:chrome69
dependencies:
- install
- build
script:
- npm run e2e:ci
artifacts:
paths:
- cypress/screenshots
- cypress/videos
expire_in: 1 day

2.4: Deploy

.deploy:
stage: deploy
before_script:
- npm install -g firebase-tools
- (if [ -d "build" ]; then echo ok; else exit "no build folder, try to run pipeline again"; fi);
script:
- firebase deploy --token $FIREBASE_TOKEN --non-interactive --only hosting:$ENV
when: manual
deploy_to_prod:
environment:
name: prod
url: $PROD_URL
extends: .deploy
variables:
ENV: prod
only:
refs:
- master

2.5: Audits

.lighthouse:
image: markhobson/node-chrome
stage: audit
before_script:
- npm i -g lighthouse
script:
- lighthouse --chrome-flags="--headless --no-sandbox" $LIGHTHOUSE_TEST_URL --output html --output-path ./report.html
artifacts:
paths:
- ./report.html
expire_in: 1 month
when: manual
  • Artifacts can take disk space, so set an expiration limit
  • Short expiration limit means sometimes you need to re-run the pipeline again if you want to deploy later in 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
Stoyan Delev

Stoyan Delev

web developer obsessed by making web better ( focused on web perf and a11y )