A
A
Anton2018-12-25 18:53:40
GitLab
Anton, 2018-12-25 18:53:40

How to properly build/roll out tagged apps/containers separately from untagged ones in gitlab ci?

Below is the gitlab-ci.yml that builds/tests/rolls out the application/containers.
There is code duplication due to the fact that to build a tagged and untagged version, build a tagged and untagged image, roll out to a tagged and untagged image / container.
You can use anchors to make the code smaller.
But maybe there is another - more correct way to build / roll out tagged applications / containers separately from untagged ones in gitlab ci?
They suggest using SHA commit instead of tag

variables:
  KUBE_PROJECT_ID: zzzz
  ARTIFACT_NAME: ${CI_PROJECT_NAME}-${CI_JOB_NAME}
  NAMESPACE: zzzz
  build_img: maven:3.5.3-jdk-8
  pgsql_img: zzzz
  deploy_img: zzzz
  MAVEN_OPTS: "-Djava.awt.headless=true -Dmaven.repo.local=.m2/repository"
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode --errors --fail-at-end --show-version"
  REF_NAME: 9-devs
  JOB_NAME: dev
  PG_SERVER: "db-$CI_COMMIT_REF_SLUG-postgresql"
  PG_PORT: "5432"
  PG_DB: zzzz
  PG_USER: zzzz
  PG_PASS: zzzz
  CI_REGISTRY_IMAGE: "docker-registry-zzzz"
  CI_REGISTRY_USER: zzzz
  CI_REGISTRY: "docker-registry-zzz"

stages:
  - build
  - test
  - release
  - postgres_cleanup
  - build-tag
  - dockerize
  - deploy
  - deploy-tag

cache:
  paths:
    - .m2/repository
  key: "$CI_COMMIT_REF_NAME"

.download_artifact:
  before_script: &download_artifact
    - if ; then export REF_NAME=$PRODUCTION_TAG JOB_NAME="production"; elif ; then REF_NAME="master" JOB_NAME="staging"; fi
    - helm init --client-only

build:
  stage: build
  image: "$build_img"
  artifacts:
    paths:
    - assembly/target
    expire_in: 1 day
  script:
    - 'mvn $MAVEN_CLI_OPTS clean package -Dmaven.test.skip=true -P app'
  tags:
    - docker-only
    - inet

.test_template: &test_template
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker build --pull -t "$CI_REGISTRY_IMAGE/$CI_PROJECT_NAME/$CI_JOB_NAME:$CI_COMMIT_REF_SLUG" .
    - docker run --name "$CI_PROJECT_NAME"-db-"$CI_PIPELINE_ID"-"$CI_JOB_NAME" -d "$pgsql_img"
    - docker run --name "$CI_PROJECT_NAME"-"$CI_PIPELINE_ID"-"$CI_JOB_NAME" --link "$CI_PROJECT_NAME"-db-"$CI_PIPELINE_ID"-"$CI_JOB_NAME":db -d "$CI_REGISTRY_IMAGE/$CI_PROJECT_NAME/$CI_JOB_NAME:$CI_COMMIT_REF_SLUG" java -jar app.jar
    - docker logs "$CI_PROJECT_NAME"-"$CI_PIPELINE_ID"-"$CI_JOB_NAME"
    - sleep 60
  after_script:
    - docker rm -f -v "$CI_PROJECT_NAME"-"$CI_PIPELINE_ID"-"$CI_JOB_NAME" "$CI_PROJECT_NAME"-db-"$CI_PIPELINE_ID"-"$CI_JOB_NAME"
    - docker rmi -f "$CI_REGISTRY_IMAGE/$CI_PROJECT_NAME/$CI_JOB_NAME:$CI_COMMIT_REF_SLUG"

test_containers:
  stage: test
  <<: *test_template
  script:
    - TEST=`docker exec --tty "$CI_PROJECT_NAME"-"$CI_PIPELINE_ID"-"$CI_JOB_NAME" wget -qO /dev/stdout http://localhost:8088/version`
    - echo $TEST
    - if ; then echo "Error - $TEST" && exit 254; else echo OK; exit 0; fi
  tags:
  - docker
  only:
  - branches

unit_test:
  stage: test
  image: "$build_img"
  dependencies:
    - build
  script:
    - 'mvn $MAVEN_CLI_OPTS test'
  tags:
    - docker-only
    - inet

it_unit_test:
  stage: test
  image: "$build_img"
  dependencies:
    - build
  services:
    - name: "$pgsql_img"
      alias: db
  script:
    - mvn $MAVEN_CLI_OPTS test -P intTests
  tags:
    - docker-only
    - inet

release:
  stage: release
  image: "$build_img"
  script:
    - apt-get install -y openssh-client git
    - mkdir -p ~/.ssh
    - echo "$SSH" | tr -d '\r' > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - eval "$(ssh-agent -s)"
    - ssh-add ~/.ssh/id_rsa
    - ssh-keyscan gitlab-zzz >> ~/.ssh/known_hosts
    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
    - git config user.name $PUSH_USER_NAME
    - git config user.email $PUSH_USER_EMAIL
    - git remote set-url origin $SSH_GIT_URL
    - git checkout master
    - git reset --hard origin/master
    - mvn $MAVEN_CLI_OPTS clean release:prepare -Dresume=false -DautoVersionSubmodules=true -DdryRun=false -Dmaven.test.skip=true -DskipITs -DscmCommentPrefix="Release pom [ci skip]"
  only:
    - master
  tags:
    - docker-only
    - inet

build-tag:
  stage: build-tag
  image: "$build_img"
  artifacts:
    paths:
    - assembly/target
    expire_in: 1 day
  script:
    - git checkout master
    - git pull
    - git reset --hard $(git describe --abbrev=0 --tags)
    - 'mvn $MAVEN_CLI_OPTS clean package -Dmaven.test.skip=true -P app'
  only:
    - master
  tags:
    - docker-only
    - inet

build_docker_container_master:
  stage: dockerize
  script:
    - git checkout master
    - git pull
    - export TAG_TO_BUILD=$(git describe --abbrev=0 --tags)
    - test -z "${TAG_TO_BUILD}" && echo "The TAG_TO_BUILD is empty" && exit 1
    - git reset --hard "${TAG_TO_BUILD}"
    - docker login -u "$CI_REGISTRY_USER" -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker build --pull -t "$CI_REGISTRY_IMAGE/$CI_PROJECT_NAME-$CI_COMMIT_REF_SLUG:${TAG_TO_BUILD}" .
    - docker push "$CI_REGISTRY_IMAGE/$CI_PROJECT_NAME-$CI_COMMIT_REF_SLUG:${TAG_TO_BUILD}"
  only:
    - master
  tags:
    - docker

build_docker_container_except_master:
  stage: dockerize
  script:
    - docker login -u "$CI_REGISTRY_USER" -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker build --pull -t "$CI_REGISTRY_IMAGE/$CI_PROJECT_NAME-$CI_COMMIT_REF_SLUG:latest" .
    - docker push "$CI_REGISTRY_IMAGE/$CI_PROJECT_NAME-$CI_COMMIT_REF_SLUG:latest"
  except:
    - master
  tags:
    - docker

deploy: &deploy
  stage: deploy
  image: "$deploy_img"
  before_script: *download_artifact
  script:
    - export KUBECONFIG=./artifacts/admin.conf
    - mkdir yaml
    - for F in *.yaml; do echo "Converting on $F"; envsubst < "$F" > yaml/"$F"; done
    - for F in yaml/*.yaml; do echo "Applying on $F"; kubectl apply -f "$F"; done
    - envsubst < values.yml > values_new.yml
    - >
       helm install stable/postgresql --version 0.9.4 --name db-$CI_COMMIT_REF_SLUG --namespace $NAMESPACE -f values_new.yml ||
       helm upgrade db-$CI_COMMIT_REF_SLUG -f values_new.yml stable/postgresql --version 0.9.4 --namespace $NAMESPACE
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    url: http://$CI_PROJECT_NAME-$CI_COMMIT_REF_SLUG.xx.xx.xx.xx.nip.io
  except:
    - master
  tags:
    - docker

deploy-tag: &deploy
  stage: deploy-tag
  image: "$deploy_img"
  before_script: *download_artifact
  script:
    - export KUBECONFIG=./artifacts/admin.conf
    - mkdir yaml
    - git checkout master
    - git pull
    - export latest_tag=$(git describe --abbrev=0 --tags)
    - for F in *.yaml; do echo "Converting on $F"; envsubst < "$F" > yaml/"$F"; done
    - for F in yaml/*.yaml; do echo "Applying on $F"; kubectl apply -f "$F"; done
    - envsubst < values.yml > values_new.yml
    - >
       helm install stable/postgresql --version 0.9.4 --name db-$CI_COMMIT_REF_SLUG --namespace $NAMESPACE -f values_new.yml ||
       helm upgrade db-$CI_COMMIT_REF_SLUG -f values_new.yml stable/postgresql --version 0.9.4 --namespace $NAMESPACE
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    url: http://$CI_PROJECT_NAME-$CI_COMMIT_REF_SLUG.xx.xx.xx.xx.nip.io
  tags:
    - docker
  only:
    - master

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question