workflow: rules: # NOTE: don't run pipeline if commit is a Merge/Pull-Request - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' when: 'never' # Otherwise: - when: 'always' variables: version: '0.0.$CI_PIPELINE_IID' k8sVersion: '1.20.5' stages: - build - test - deploy - release job_build-image: stage: build tags: - docker-privileged image: docker:20.10.12 services: - name: docker:20.10.12-dind script: - docker-compose build --file "server/Containerfile" --tag "${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}" "./" # NOTE: push image to local registry so that it can be accessed in subsequent jobs - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY} - docker push "${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}" after_script: - docker image rm --force "${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}" job_test-image: stage: test tags: - docker-privileged image: docker:20.10.12 services: - name: docker:20.10.12-dind alias: containerhost variables: # NOTE: some random port that hopefully is free on the runner outerPort: '38080' before_script: - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY} - docker pull "${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}" script: - docker run --detach --publish "${outerPort}:8080" --name "${CI_PROJECT_ID}-${CI_PIPELINE_IID}" "${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}" - | attempts=1 while (wget "http://containerhost:${outerPort}" 2>&1 || true) | grep 'Connection refused' && [ "${attempts}" -lt 5 ]; do sleep 1 && echo sleeping attempts=$((attempts + 1)) done - (wget --no-cache --quiet --output-document - "http://containerhost:${outerPort}/health" | docker run --rm --interactive stedolan/jq -e '.status == "pass"') || (echo 'Test failed' && exit 1) after_script: # NOTE: clean up after test run (stop and remove container) - docker rm --force "${CI_PROJECT_ID}-${CI_PIPELINE_IID}" job_deploy-new-version: stage: deploy needs: - job_build-image - job_test-image tags: - docker image: name: quay.io/bitnami/kubectl:1.20.5 entrypoint: [''] script: - VERSION="${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}" - IMAGE="${CI_REGISTRY_IMAGE}:${VERSION}" - DEPLOYMENT_MANIFEST=$(sed -e "s,{{image}},${IMAGE},g" ./infra/deployment.yaml.tmpl) - echo "${DEPLOYMENT_MANIFEST}" | kubectl apply --kubeconfig ${SECRET_KUBECONFIG_PATH} --namespace devops-lecture-showcase --filename - job_create-release: stage: release only: - stable needs: - job_build-image tags: - docker-privileged image: docker:20.10.12 services: - name: docker:20.10.12-dind before_script: - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY} - docker pull "${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}" script: - VERSION=$(cat ./src/package.json | docker run --interactive stedolan/jq --raw-output '.version') - docker tag "${CI_REGISTRY_IMAGE}:${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}" "${CI_REGISTRY_IMAGE}:${VERSION}" - docker push "${CI_REGISTRY_IMAGE}:${VERSION}" - git tag "v${VERSION}" && git push origin "v${VERSION}" after_script: - docker image rm --force $(docker images --format '{{.Repository}}{{.Tag}}' | grep '${CI_REGISTRY_IMAGE}') job_deploy-new-release: only: - stable tags: - docker-privileged image: docker:20.10.12 services: - name: docker:20.10.12-dind script: - VERSION=$(cat ./src/package.json | docker run --interactive stedolan/jq --raw-output '.version') - IMAGE="${CI_REGISTRY_IMAGE}:${VERSION}" - DEPLOYMENT_MANIFEST=$(sed -e "s/{{image}}/${IMAGE}/g" infra/deployment.yaml.tmpl) - echo "${DEPLOYMENT_MANIFEST}" | docker run --rm --volume ${SECRET_KUBECONFIG_PATH}:/.kube/config quay.io/bitnami/kubectl:1.20.5 apply --namespace devops-lecture-showcase --filename - job_update-infra: stage: deploy rules: - changes: - infra/* tags: - docker image: name: quay.io/bitnami/kubectl:1.20.5 entrypoint: [''] script: - kubectl apply --kubeconfig ${SECRET_KUBECONFIG_PATH} --namespace devops-lecture-showcase --filename ./infra