Gitlab CI Example Pipeline File

Gitlab CI file to deploy Spring application with MongoDB using Helm to OpenShift

## variables
.env-dev: &env-dev
  OPENSHIFT_URL: ${OPENSHIFT4_URL_NONPROD}
  OPENSHIFT_TOKEN: ${OPENSHIFT4_TOKEN_DEV}
  OPENSHIFT_PROJECT: "poi-lim-dev"
 
## rules
# This job will only run on the master branch
.on-master: &on-master $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $GITLAB_USER_EMAIL != "weblate@company.com"
 
# branches with 'feature/' prefix
.on-feature: &on-feature $CI_COMMIT_BRANCH =~ /^feature\/.+/i
 
## caching
.cache: &npm_cache
  key:
    files: # compute the cache key from the lock file
      - frontend/package-lock.json
  paths:
    - frontend/.npm
 
## helper functions
.docker-init: &docker-init
  - docker login -u ${DOCKER_REGISTRY_USER} -p ${DOCKER_REGISTRY_PASSWORD} ${DOCKER_REGISTRY_URL}
 
.docker-tag: &docker-tag
  - echo "docker pull ${DOCKER_IMG}:${DOCKER_TAG_OLD}"
  - docker pull ${DOCKER_IMG}:${DOCKER_TAG_OLD}
  - echo "tag ${DOCKER_IMG}:${DOCKER_TAG_OLD} ${DOCKER_IMG}:${DOCKER_TAG_NEW}"
  - docker tag ${DOCKER_IMG}:${DOCKER_TAG_OLD} ${DOCKER_IMG}:${DOCKER_TAG_NEW}
  - echo "docker push ${DOCKER_IMG}:${DOCKER_TAG_NEW}"
  - docker push ${DOCKER_IMG}:${DOCKER_TAG_NEW}
 
.helm-init: &helm-init
  - helm3 repo add company ${HELM_REPO_URL} --username ${HELM_REPO_USER} --password ${HELM_REPO_PASSWORD}
  - helm3 repo add bitnami ${CHART_REPO_BITNAMI}
  - helm3 repo update
 
.helm-deploy: &helm-deploy
  # deploy database
  - cd ${CHART_DB_DIR}
  - helm3 upgrade ${HELM_CLI_OPTS}
    --namespace ${OPENSHIFT_PROJECT} ${LIM_PROJECT}-mongodb
    -f values.yaml
    ${HELM_ARGS}
    bitnami/mongodb --version "${CHART_DB_VERSION}"
  # deploy web application
  - cd - && cd ${CHART_LIM_DIR}
  - helm3 upgrade ${HELM_CLI_OPTS}
    --namespace ${OPENSHIFT_PROJECT} ${LIM_PROJECT}
    -f values.yaml
    ${HELM_ARGS}
    my-web-application --set appVersion="${RELEASE_VERSION}"
 
## jobs
build:
  stage: build
  needs:
    - job: init
  cache: *npm_cache
  rules:
    - if: $SKIP_BUILD || $DEPLOY
      when: never
    - if: *on-master
    - if: *on-feature
  services:
    - docker:stable-dind
  before_script:
    - *docker-init
  script:
    - mvn clean install
    - mvn sonar:sonar 
    - cd app
    - mvn docker:build docker:push
  artifacts: # upload test artifacts
    when: always
    reports:
      junit: backend/target/surefire-reports/TEST-*.xml
      
  lint:
  stage: build
  needs:
    - job: build
      artifacts: false
  allow_failure: true
  cache: *npm_cache
  rules:
    - if: $SKIP_BUILD || $DEPLOY
      when: never
    - if: *on-master
    - if: *on-feature
  before_script:
    - cd frontend
    - npm ci --cache .npm --prefer-offline --no-audit
  script:
    - npm run lint
  
deploy-feature:
  stage: deploy-feature
  extends: .deploy
  rules:
    - if: $SKIP_DEPLOY_FEATURE || $DEPLOY
      when: never
    - if: *on-master
    - if: *on-feature
  environment:
    name: $CI_COMMIT_REF_NAME
    url: https://$CI_COMMIT_REF_SLUG.my-app.company.com
    on_stop: undeploy-feature
    auto_stop_in: 1 week
  variables:
    <<: *env-dev
    DOCKER_TAG_OLD: ${RELEASE_VERSION}
    DOCKER_TAG_NEW: ${CI_COMMIT_REF_SLUG}-snapshot
    LIM_PROJECT: ${CI_COMMIT_REF_SLUG}
    HELM_CLI_OPTS: "--install --history-max 5"
    HELM_ARGS: "-f values-feature.yaml"
    SPRING_PROFILES: auth-password, auth-ldap
  script:
    # prepare feature configuration
    - sed -i "s/<<RELEASE_NAME>>/${PROJECT}/g" ${CHART_DB_DIR}/values-feature.yaml
    - sed -i "s/<<RELEASE_NAME>>/${PROJECT}/g" ${CHART_LIM_DIR}/values-feature.yaml
    - sed -i "s/<<DOCKER_IMG>>/${DOCKER_TAG_NEW}/g" ${CHART_LIM_DIR}/values-feature.yaml
    - sed -i "s/<<SPRING_PROFILES>>/${SPRING_PROFILES}/g" ${CHART_LIM_DIR}/values-feature.yaml
    - *docker-tag
    - *helm-deploy