default: image: golang:latest stages: - build - lint - test - docker - e2e - deploy - cleanup variables: DOCKER_TLS_CERTDIR: "" NOMAD_SLUG: $NOMAD_PREFIX-$CI_ENVIRONMENT_SLUG IMAGE_NAME_ENV: $DOCKER_REGISTRY/$DOCKER_IMAGE_NAME/$CI_COMMIT_REF_SLUG:$CI_PIPELINE_IID IMAGE_NAME_GENERAL: $DOCKER_REGISTRY/$DOCKER_IMAGE_NAME/$CI_COMMIT_REF_SLUG:latest NOMAD_CI_IMAGE_NAME_ENV: $DOCKER_REGISTRY/nomad-ci/$CI_COMMIT_REF_SLUG:$CI_PIPELINE_IID NOMAD_CI_IMAGE_NAME_GENERAL: $DOCKER_REGISTRY/nomad-ci/$CI_COMMIT_REF_SLUG:latest NOMAD_CI_BASE_IMAGE: $DOCKER_REGISTRY/nomad-ci/main:latest compile: stage: build needs: [] variables: CGO_ENABLED: 0 script: - make build artifacts: paths: - poseidon expire_in: 1 week golangci-lint: stage: lint needs: [] image: golangci/golangci-lint:latest script: - make golangci-lint test: stage: test needs: [] script: - make coverhtml artifacts: paths: - coverage_unit.html expire_in: 1 week expose_as: coverageReport dep-scan: stage: test needs: - compile script: - make trivy-scan-deps artifacts: reports: dependency_scanning: .trivy/gl-scanning-report.json cache: paths: - .trivy/.trivycache/ dockerimage: stage: docker image: $DOCKER_REGISTRY/docker-make:latest services: - name: docker:dind alias: docker needs: - compile - dep-scan - test script: - docker login -u $DOCKER_REGISTRY_USER -p $DOCKER_REGISTRY_PASSWORD $DOCKER_REGISTRY # Prevent pull rate limit but still have normal alpine image in Dockerfile - docker pull $DOCKER_REGISTRY/library/alpine:latest - docker tag $DOCKER_REGISTRY/library/alpine:latest alpine:latest - docker build -t $IMAGE_NAME_ENV -f deploy/poseidon/Dockerfile . # Run vulnerability scan before pushing the image - make trivy-scan-docker DOCKER_TAG=$IMAGE_NAME_ENV - docker push $IMAGE_NAME_ENV - docker tag $IMAGE_NAME_ENV $IMAGE_NAME_GENERAL - docker push $IMAGE_NAME_GENERAL cache: paths: - .trivy/.trivycache/ artifacts: reports: container_scanning: .trivy/gl-scanning-report.json nomadimage: stage: docker image: docker:latest services: - name: docker:dind alias: docker needs: [] script: - cd deploy/nomad-ci - docker login -u $DOCKER_REGISTRY_USER -p $DOCKER_REGISTRY_PASSWORD $DOCKER_REGISTRY - docker pull $DOCKER_REGISTRY/library/golang:latest - docker tag $DOCKER_REGISTRY/library/golang:latest golang:latest # Pull base image to avoid rebuilding every pipeline if nothing changed, prioritize image from branch - docker pull $NOMAD_CI_IMAGE_NAME_GENERAL || docker pull $NOMAD_CI_BASE_IMAGE || true - docker build --cache-from $NOMAD_CI_BASE_IMAGE --cache-from $NOMAD_CI_IMAGE_NAME_GENERAL -t $NOMAD_CI_IMAGE_NAME_ENV -t $NOMAD_CI_IMAGE_NAME_GENERAL . - docker push $NOMAD_CI_IMAGE_NAME_ENV - docker push $NOMAD_CI_IMAGE_NAME_GENERAL test_e2e: image: $NOMAD_CI_IMAGE_NAME_ENV stage: e2e needs: - compile - dep-scan - nomadimage services: - name: docker:dind alias: docker variables: DOCKER_HOST: "tcp://docker:2375" script: # Avoid docker pull limit - docker login -u $DOCKER_REGISTRY_USER -p $DOCKER_REGISTRY_PASSWORD $DOCKER_REGISTRY - docker pull $DOCKER_REGISTRY/openhpi/co_execenv_python:3.8 - docker tag $DOCKER_REGISTRY/openhpi/co_execenv_python:3.8 openhpi/co_execenv_python:3.8 # Setup own Nomad cluster and wait for startup - export NOMAD_ADDR=http://localhost:4646 - nomad agent -dev -log-level=WARN & - sleep 5 # Start Poseidon and wait for it - ./poseidon & - sleep 20 - make e2e-test .start_deployment: &start_deployment image: $NOMAD_CI_IMAGE_NAME_ENV stage: deploy needs: - job: dockerimage artifacts: false - test_e2e before_script: - export NOMAD_NAMESPACE="$NOMAD_SLUG" - nomad namespace apply $NOMAD_NAMESPACE script: - export NOMAD_CACERT_DATA=$(cat $NOMAD_CACERT) # Only replace set env vars - envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < deploy/api.tpl.nomad > deploy/api.nomad # Make sure to set NOMAD_ADDR, NOMAD_SKIP_VERIFY and NOMAD_TOKEN env vars in CI settings appropriately - nomad validate deploy/api.nomad # nomad plan returns 1 if allocation is created or destroyed which is what we want here - nomad plan deploy/api.nomad || [ $? == 1 ] - nomad run deploy/api.nomad artifacts: paths: - deploy/api.nomad expire_in: 1 month expose_as: api-nomad deploy_review: <<: *start_deployment variables: HOSTNAME: $CI_ENVIRONMENT_SLUG.$BASE_DOMAIN environment: name: $CI_COMMIT_REF_SLUG url: http://$CI_ENVIRONMENT_SLUG.$BASE_DOMAIN on_stop: stop_review before_script: - export NOMAD_NAMESPACE="$NOMAD_SLUG" - nomad namespace apply $NOMAD_NAMESPACE only: - branches - tags except: - main when: manual stop_review: # See: # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml stage: cleanup image: $NOMAD_CI_IMAGE_NAME_ENV variables: GIT_STRATEGY: none script: - export NOMAD_NAMESPACE="$NOMAD_SLUG" # Stop all jobs before deleting the namespace - nomad job status | cut -d" " -f1 | tail -n +2 | xargs -n1 nomad stop - nomad namespace delete $NOMAD_NAMESPACE environment: name: $CI_COMMIT_REF_SLUG action: stop needs: [] allow_failure: true only: - branches - tags except: - main when: manual deploy_staging: <<: *start_deployment variables: NOMAD_SLUG: $NOMAD_PREFIX-staging HOSTNAME: staging.$BASE_DOMAIN environment: name: staging url: http://staging.$BASE_DOMAIN only: - main deploy_production: <<: *start_deployment variables: NOMAD_SLUG: $NOMAD_PREFIX-production HOSTNAME: $PRODUCTION_URL environment: name: production url: https://$PRODUCTION_URL only: - main when: manual