Skip to content

Instantly share code, notes, and snippets.

@ggolin
Forked from woodcockjosh/.gitlab-ci.yaml
Created July 15, 2020 04:20
Show Gist options
  • Save ggolin/d41b324e0ed519211604498f18f795a3 to your computer and use it in GitHub Desktop.
Save ggolin/d41b324e0ed519211604498f18f795a3 to your computer and use it in GitHub Desktop.
CI+CD pipeline for k8s nodejs deployment with helm
stages:
- test
- docker-build
- version-push
- deploy
variables:
BUMP_VERSION_MESSAGE: "[bump version]"
CD_TO_DEV1_FROM_MASTER: "true"
# Only run when there is [bump version] in the commit message and rev type is a tag or there is not [bump version] in the commit message
workflow:
rules:
- if: $CI_COMMIT_MESSAGE =~ /\[bump version\]/ && $CI_COMMIT_TAG
when: always
- if: $CI_COMMIT_MESSAGE =~ /\[bump version\]/ && $CI_COMMIT_BRANCH == "master"
when: never
- if: $CI_COMMIT_MESSAGE !~ /\[bump version\]/
when: always
.version-validate: &version-validate
- echo $CI_PROJECT_ID
- "latest_tag_json=$(curl -X GET --header \"Private-Token: $SHARED_CI_ACCESS_TOKEN\" \"https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/repository/tags?per_page=1\")"
- echo "$latest_tag_json"
- latest_tag_length=$(echo "$latest_tag_json" | jq '. | length')
- latest_tag_name=
- if [[ $latest_tag_length > 0 ]]; then latest_tag_name=$(echo "$latest_tag_json" | jq -r '.[0].name'); fi;
- package_version=$(jq -r '.version' app/package.json)
- if [[ "$package_version" != "$latest_tag_name" ]]; then echo -e "\e[31mVersion does not match latest tag. Please change version in package.json to '$latest_tag_name'\e[39m"; exit 1; fi
.git-configure: &git-configure
- echo "$GIT_SSH_PK" | base64 -d > id_rsa
- chmod 400 id_rsa
- echo 'ssh -i ./id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $*' > ssh
- chmod +x ssh
- git config --global user.name "$GITLAB_USER_NAME"
- git config --global user.email "$GITLAB_USER_EMAIL"
- git remote set-url origin git@$CI_SERVER_HOST:$CI_PROJECT_PATH.git
test:
image: cryptexlabs/ts-node-ci:1.2.0
stage: test
allow_failure: false
except:
refs:
- tags
script:
- *version-validate
- export NODE_ENV=test
- cd app
- yarn install
- yarn lint
- yarn test
.docker-variables: &docker-variables
DOCKER_TLS_CERTDIR: ""
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375
docker-build:
image: cryptexlabs/ts-node-ci:1.2.0
stage: docker-build
allow_failure: false
needs:
- test
services:
- docker:dind
variables:
<<: *docker-variables
except:
refs:
- tags
script:
- docker build --cache-from $CI_REGISTRY_IMAGE:latest . --tag $CI_REGISTRY_IMAGE:commit-$CI_COMMIT_SHORT_SHA
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- docker push $CI_REGISTRY_IMAGE:commit-$CI_COMMIT_SHORT_SHA
.version-push: &version-push
image: cryptexlabs/ts-node-ci:1.2.0
stage: version-push
needs:
- test
- docker-build
when: manual
allow_failure: false
services:
- docker:dind
only:
refs:
- master
script:
- *version-validate
- *git-configure
- git checkout master
- BASE_DIR=$PWD
- cd app
- yarn version --$INCREMENT_TYPE --no-git-tag-version --no-commit-hooks
- version=$(jq -r '.version' package.json)
- cd $BASE_DIR
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- docker pull $CI_REGISTRY_IMAGE:commit-$CI_COMMIT_SHORT_SHA
- docker tag $CI_REGISTRY_IMAGE:commit-$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE:$version
- docker tag $CI_REGISTRY_IMAGE:commit-$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE:latest
- yq w -i k8s/$CI_PROJECT_NAME/Chart.yaml appVersion "$version"
- yq w -i k8s/$CI_PROJECT_NAME/values.yaml '.nodejs.image.tag' "$version"
- git add k8s/$CI_PROJECT_NAME/Chart.yaml app/package.json
- git commit -m "$BUMP_VERSION_MESSAGE $version"
- git tag $version
- GIT_SSH='./ssh' git push origin $version
- GIT_SSH='./ssh' git push origin master
- docker push $CI_REGISTRY_IMAGE:$version
- docker push $CI_REGISTRY_IMAGE:latest
patch:
<<: *version-push
variables:
INCREMENT_TYPE: patch
<<: *docker-variables
minor:
<<: *version-push
variables:
INCREMENT_TYPE: minor
<<: *docker-variables
major:
<<: *version-push
variables:
INCREMENT_TYPE: major
<<: *docker-variables
.deploy-script: &deploy-script
- >
if [[ -z "$(kubectl get namespace $KUBE_NAMESPACE)" ]]; then
kubectl create namespace $KUBE_NAMESPACE;
fi;
- >
if [[ -z "$(kubectl get secret gitlab-registry --namespace $KUBE_NAMESPACE)" ]]; then
kubectl create secret docker-registry gitlab-registry \
--docker-server=https://registry.gitlab.com \
--docker-username=$CI_REGISTRY_USER \
--docker-password=$SHARED_CI_ACCESS_TOKEN \
--namespace $KUBE_NAMESPACE;
fi;
- >
helm upgrade $CI_PROJECT_NAME k8s/$CI_PROJECT_NAME
--install
--namespace $KUBE_NAMESPACE
--set nodejs.annotations.'app\.gitlab\.com/env'=$CI_ENVIRONMENT_SLUG
--set nodejs.annotations.'app\.gitlab\.com/app'=$CI_PROJECT_PATH_SLUG
--set nodejs.namespace=$KUBE_NAMESPACE
--set nodejs.image.tag=$APP_VERSION
.deploy: &deploy
image:
name: cryptexlabs/helm-yq:3.2.4
entrypoint: [""]
stage: deploy
allow_failure: false
.rev-deploy: &rev-deploy
<<: *deploy
script:
- yq w -i k8s/$CI_PROJECT_NAME/Chart.yaml appVersion "commit-$CI_COMMIT_SHORT_SHA"
- APP_VERSION=commit-$CI_COMMIT_SHORT_SHA
- *deploy-script
.tag-deploy: &tag-deploy
<<: *deploy
script:
- APP_VERSION=$CI_COMMIT_TAG
- *deploy-script
deploy-development-1-ref:
<<: *rev-deploy
rules:
# Makes continuous deployment to dev environment from master
- if: $CI_COMMIT_BRANCH == "master" && $CD_TO_DEV1_FROM_MASTER == "true"
when: always
- if: $CI_COMMIT_BRANCH != "master" && $CI_COMMIT_BRANCH
when: manual
needs:
- test
- docker-build
environment:
name: development.1
deploy-development-1:
<<: *tag-deploy
# Makes continuous deployment to dev environment from all new tags
when: always
only:
refs:
- tags
environment:
name: development.1
deploy-production-1:
<<: *tag-deploy
when: manual
only:
refs:
- tags
environment:
name: production.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment