Auto-DevOps.gitlab-ci.yml 22.3 KB
Newer Older
1 2 3 4 5 6 7 8
# Auto DevOps
# This CI/CD configuration provides a standard pipeline for
# * building a Docker image (using a buildpack if necessary),
# * storing the image in the container registry,
# * running tests from a buildpack,
# * running code quality analysis,
# * creating a review app for each topic branch,
# * and continuous deployment to production
9
#
10 11
# Test jobs may be disabled by setting environment variables:
# * test: TEST_DISABLED
12
# * code_quality: CODE_QUALITY_DISABLED
13
# * license_management: LICENSE_MANAGEMENT_DISABLED
14 15 16
# * performance: PERFORMANCE_DISABLED
# * sast: SAST_DISABLED
# * dependency_scanning: DEPENDENCY_SCANNING_DISABLED
17
# * container_scanning: CONTAINER_SCANNING_DISABLED
18 19 20 21
# * dast: DAST_DISABLED
# * review: REVIEW_DISABLED
# * stop_review: REVIEW_DISABLED
#
22 23
# In order to deploy, you must have a Kubernetes cluster configured either
# via a project integration, or via group/project variables.
24 25
# AUTO_DEVOPS_DOMAIN must also be set as a variable at the group or project
# level, or manually added below.
26
#
27 28 29
# Continuous deployment to production is enabled by default.
# If you want to deploy to staging first, or enable incremental rollouts,
# set STAGING_ENABLED or INCREMENTAL_ROLLOUT_ENABLED environment variables.
30
# If you want to use canary deployments, set CANARY_ENABLED environment variable.
31 32 33 34 35 36 37
#
# If Auto DevOps fails to detect the proper buildpack, or if you want to
# specify a custom buildpack, set a project variable `BUILDPACK_URL` to the
# repository URL of the buildpack.
# e.g. BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-ruby.git#v142
# If you need multiple buildpacks, add a file to your project called
# `.buildpacks` that contains the URLs, one on each line, in order.
Mark Pundsack's avatar
Mark Pundsack committed
38
# Note: Auto CI does not work with multiple buildpacks yet
39 40 41

image: alpine:latest

42
variables:
43 44
  # AUTO_DEVOPS_DOMAIN is the application deployment domain and should be set as a variable at the group or project level.
  # AUTO_DEVOPS_DOMAIN: domain.example.com
45 46 47 48

  POSTGRES_USER: user
  POSTGRES_PASSWORD: testing-password
  POSTGRES_ENABLED: "true"
Mark Pundsack's avatar
Mark Pundsack committed
49
  POSTGRES_DB: $CI_ENVIRONMENT_SLUG
50

51
  KUBERNETES_VERSION: 1.8.6
52
  HELM_VERSION: 2.10.0
53

54 55
  DOCKER_DRIVER: overlay2

56 57 58 59
stages:
  - build
  - test
  - review
60
  - dast
61 62 63
  - staging
  - canary
  - production
64
  - performance
65 66 67 68
  - cleanup

build:
  stage: build
69
  image: docker:stable-git
70
  services:
71
  - docker:stable-dind
72
  script:
73 74
    - setup_docker
    - build
75 76 77 78
  only:
    - branches

test:
79 80 81 82
  services:
    - postgres:latest
  variables:
    POSTGRES_DB: test
83
  stage: test
84
  image: gliderlabs/herokuish:latest
85
  script:
86 87
    - setup_test_db
    - cp -R . /tmp/app
88 89 90
    - /bin/herokuish buildpack test
  only:
    - branches
91 92 93
  except:
    variables:
      - $TEST_DISABLED
94

95
code_quality:
96
  stage: test
97
  image: docker:stable
98
  allow_failure: true
99
  services:
100
    - docker:stable-dind
101
  script:
102
    - setup_docker
103
    - code_quality
104
  artifacts:
105
    paths: [gl-code-quality-report.json]
106 107
  only:
    - branches
108 109
  except:
    variables:
110
      - $CODE_QUALITY_DISABLED
111

112
license_management:
113
  stage: test
114 115 116 117 118 119 120 121 122
  image: docker:stable
  allow_failure: true
  services:
    - docker:stable-dind
  script:
    - setup_docker
    - license_management
  artifacts:
    paths: [gl-license-management-report.json]
123 124
  only:
    - branches
125 126 127 128
  except:
    variables:
      - $LICENSE_MANAGEMENT_DISABLED

129 130
performance:
  stage: performance
131
  image: docker:stable
132 133
  allow_failure: true
  services:
134
    - docker:stable-dind
135
  script:
136
    - setup_docker
137 138 139 140
    - performance
  artifacts:
    paths:
    - performance.json
141
    - sitespeed-results/
142 143 144 145
  only:
    refs:
      - branches
    kubernetes: active
146 147 148
  except:
    variables:
      - $PERFORMANCE_DISABLED
149

150
sast:
151
  stage: test
152
  image: docker:stable
153
  allow_failure: true
154
  services:
155
    - docker:stable-dind
156
  script:
157 158
    - setup_docker
    - sast
159 160
  artifacts:
    paths: [gl-sast-report.json]
161 162
  only:
    - branches
163 164 165
  except:
    variables:
      - $SAST_DISABLED
166

167
dependency_scanning:
168
  stage: test
169
  image: docker:stable
170 171
  allow_failure: true
  services:
172
    - docker:stable-dind
173 174 175 176 177
  script:
    - setup_docker
    - dependency_scanning
  artifacts:
    paths: [gl-dependency-scanning-report.json]
178 179
  only:
    - branches
180 181 182
  except:
    variables:
      - $DEPENDENCY_SCANNING_DISABLED
183

184
container_scanning:
185
  stage: test
186
  image: docker:stable
187 188
  allow_failure: true
  services:
189
    - docker:stable-dind
190 191
  script:
    - setup_docker
192
    - container_scanning
193
  artifacts:
194
    paths: [gl-container-scanning-report.json]
195 196
  only:
    - branches
197 198 199
  except:
    variables:
      - $CONTAINER_SCANNING_DISABLED
200

201
dast:
202
  stage: dast
203
  allow_failure: true
204
  image: registry.gitlab.com/gitlab-org/security-products/zaproxy
205 206 207
  variables:
    POSTGRES_DB: "false"
  script:
Fabio Busatto's avatar
Fabio Busatto committed
208
    - dast
209 210
  artifacts:
    paths: [gl-dast-report.json]
211 212 213 214 215
  only:
    refs:
      - branches
    kubernetes: active
  except:
216 217 218 219
    refs:
      - master
    variables:
      - $DAST_DISABLED
220

221 222 223
review:
  stage: review
  script:
224 225 226 227 228 229
    - check_kube_domain
    - install_dependencies
    - download_chart
    - ensure_namespace
    - install_tiller
    - create_secret
Alessio Caiazza's avatar
Alessio Caiazza committed
230
    - deploy
231
    - persist_environment_url
232 233
  environment:
    name: review/$CI_COMMIT_REF_NAME
234
    url: http://$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_SLUG.$AUTO_DEVOPS_DOMAIN
235
    on_stop: stop_review
236 237
  artifacts:
    paths: [environment_url.txt]
238
  only:
239 240 241
    refs:
      - branches
    kubernetes: active
242
  except:
243 244 245 246
    refs:
      - master
    variables:
      - $REVIEW_DISABLED
247 248 249 250 251 252

stop_review:
  stage: cleanup
  variables:
    GIT_STRATEGY: none
  script:
253 254
    - install_dependencies
    - delete
255 256 257 258 259 260
  environment:
    name: review/$CI_COMMIT_REF_NAME
    action: stop
  when: manual
  allow_failure: true
  only:
261 262 263
    refs:
      - branches
    kubernetes: active
264
  except:
265 266 267 268
    refs:
      - master
    variables:
      - $REVIEW_DISABLED
269

270
# Keys that start with a dot (.) will not be processed by GitLab CI.
271 272 273 274
# Staging and canary jobs are disabled by default, to enable them
# remove the dot (.) before the job name.
# https://docs.gitlab.com/ee/ci/yaml/README.html#hidden-keys

275
# Staging deploys are disabled by default since
276 277
# continuous deployment to production is enabled by default
# If you prefer to automatically deploy to staging and
278 279
# only manually promote to production, enable this job by setting
# STAGING_ENABLED.
280

281
staging:
282 283 284 285 286 287 288 289 290 291 292
  stage: staging
  script:
    - check_kube_domain
    - install_dependencies
    - download_chart
    - ensure_namespace
    - install_tiller
    - create_secret
    - deploy
  environment:
    name: staging
293
    url: http://$CI_PROJECT_PATH_SLUG-staging.$AUTO_DEVOPS_DOMAIN
294
  only:
295 296 297
    refs:
      - master
    kubernetes: active
298 299
    variables:
      - $STAGING_ENABLED
300

301 302 303
# Canaries are also disabled by default, but if you want them,
# and know what the downsides are, you can enable this by setting
# CANARY_ENABLED.
304

305
canary:
306 307 308 309 310 311 312 313 314 315 316
  stage: canary
  script:
    - check_kube_domain
    - install_dependencies
    - download_chart
    - ensure_namespace
    - install_tiller
    - create_secret
    - deploy canary
  environment:
    name: production
317
    url: http://$CI_PROJECT_PATH_SLUG.$AUTO_DEVOPS_DOMAIN
318 319
  when: manual
  only:
320 321 322
    refs:
      - master
    kubernetes: active
323 324
    variables:
      - $CANARY_ENABLED
325

326
.production: &production_template
327 328
  stage: production
  script:
329 330 331 332 333 334
    - check_kube_domain
    - install_dependencies
    - download_chart
    - ensure_namespace
    - install_tiller
    - create_secret
Alessio Caiazza's avatar
Alessio Caiazza committed
335
    - deploy
336
    - delete canary
337
    - delete rollout
338
    - persist_environment_url
339 340
  environment:
    name: production
341
    url: http://$CI_PROJECT_PATH_SLUG.$AUTO_DEVOPS_DOMAIN
342 343
  artifacts:
    paths: [environment_url.txt]
344 345 346 347 348 349 350 351 352 353

production:
  <<: *production_template
  only:
    refs:
      - master
    kubernetes: active
  except:
    variables:
      - $STAGING_ENABLED
354
      - $CANARY_ENABLED
355
      - $INCREMENTAL_ROLLOUT_ENABLED
356 357 358 359

production_manual:
  <<: *production_template
  when: manual
360
  allow_failure: false
361
  only:
362 363 364
    refs:
      - master
    kubernetes: active
365 366
    variables:
      - $STAGING_ENABLED
Fabio Busatto's avatar
Fabio Busatto committed
367
      - $CANARY_ENABLED
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
  except:
    variables:
      - $INCREMENTAL_ROLLOUT_ENABLED

# This job implements incremental rollout on for every push to `master`.

.rollout: &rollout_template
  stage: production
  script:
    - check_kube_domain
    - install_dependencies
    - download_chart
    - ensure_namespace
    - install_tiller
    - create_secret
    - deploy rollout $ROLLOUT_PERCENTAGE
    - scale stable $((100-ROLLOUT_PERCENTAGE))
    - delete canary
    - persist_environment_url
  environment:
    name: production
    url: http://$CI_PROJECT_PATH_SLUG.$AUTO_DEVOPS_DOMAIN
  artifacts:
    paths: [environment_url.txt]

rollout 10%:
  <<: *rollout_template
  variables:
    ROLLOUT_PERCENTAGE: 10
397
  when: manual
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
  only:
    refs:
      - master
    kubernetes: active
    variables:
      - $INCREMENTAL_ROLLOUT_ENABLED

rollout 25%:
  <<: *rollout_template
  variables:
    ROLLOUT_PERCENTAGE: 25
  when: manual
  only:
    refs:
      - master
    kubernetes: active
    variables:
      - $INCREMENTAL_ROLLOUT_ENABLED

rollout 50%:
  <<: *rollout_template
  variables:
    ROLLOUT_PERCENTAGE: 50
  when: manual
  only:
    refs:
      - master
    kubernetes: active
    variables:
      - $INCREMENTAL_ROLLOUT_ENABLED

rollout 100%:
  <<: *production_template
  when: manual
432
  allow_failure: false
433 434 435 436 437 438
  only:
    refs:
      - master
    kubernetes: active
    variables:
      - $INCREMENTAL_ROLLOUT_ENABLED
439 440 441

# ---------------------------------------------------------------------------

442
.auto_devops: &auto_devops |
443
  # Auto DevOps variables and functions
444
  [[ "$TRACE" ]] && set -x
445
  auto_database_url=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${CI_ENVIRONMENT_SLUG}-postgres:5432/${POSTGRES_DB}
446 447 448 449 450
  export DATABASE_URL=${DATABASE_URL-$auto_database_url}
  export CI_APPLICATION_REPOSITORY=$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG
  export CI_APPLICATION_TAG=$CI_COMMIT_SHA
  export CI_CONTAINER_NAME=ci_job_build_${CI_JOB_ID}
  export TILLER_NAMESPACE=$KUBE_NAMESPACE
451 452
  # Extract "MAJOR.MINOR" from CI_SERVER_VERSION and generate "MAJOR-MINOR-stable" for Security Products
  export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
453

454
  function registry_login() {
455 456 457 458 459
    if [[ -n "$CI_REGISTRY_USER" ]]; then
      echo "Logging to GitLab Container Registry with CI credentials..."
      docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
      echo ""
    fi
460 461 462 463
  }

  function container_scanning() {
    registry_login
464

465
    docker run -d --name db arminc/clair-db:latest
466
    docker run -p 6060:6060 --link db:postgres -d --name clair --restart on-failure arminc/clair-local-scan:v2.0.1
467
    apk add -U wget ca-certificates
468
    docker pull ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG}
469 470
    wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64
    mv clair-scanner_linux_amd64 clair-scanner
471 472
    chmod +x clair-scanner
    touch clair-whitelist.yml
473 474 475
    retries=0
    echo "Waiting for clair daemon to start"
    while( ! wget -T 10 -q -O /dev/null http://docker:6060/v1/namespaces ) ; do sleep 1 ; echo -n "." ; if [ $retries -eq 10 ] ; then echo " Timeout, aborting." ; exit 1 ; fi ; retries=$(($retries+1)) ; done
476
    ./clair-scanner -c http://docker:6060 --ip $(hostname -i) -r gl-container-scanning-report.json -l clair.log -w clair-whitelist.yml ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} || true
477
  }
478

479
  function code_quality() {
480
    docker run --env SOURCE_CODE="$PWD" \
481 482
               --volume "$PWD":/code \
               --volume /var/run/docker.sock:/var/run/docker.sock \
483
               "registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
484 485
  }

486 487 488 489 490 491 492 493 494 495 496 497
  function license_management() {
    if echo $GITLAB_FEATURES |grep license_management > /dev/null ; then
      # Extract "MAJOR.MINOR" from CI_SERVER_VERSION and generate "MAJOR-MINOR-stable"
      LICENSE_MANAGEMENT_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')

      docker run --volume "$PWD:/code" \
                 "registry.gitlab.com/gitlab-org/security-products/license-management:$LICENSE_MANAGEMENT_VERSION" analyze /code
    else
      echo "License management is not available in your subscription"
    fi
  }

498 499 500
  function sast() {
    case "$CI_SERVER_VERSION" in
      *-ee)
501

502 503 504 505 506 507 508 509
        # Deprecation notice for CONFIDENCE_LEVEL variable
        if [ -z "$SAST_CONFIDENCE_LEVEL" -a "$CONFIDENCE_LEVEL" ]; then
          SAST_CONFIDENCE_LEVEL="$CONFIDENCE_LEVEL"
          echo "WARNING: CONFIDENCE_LEVEL is deprecated and MUST be replaced with SAST_CONFIDENCE_LEVEL"
        fi

        docker run --env SAST_CONFIDENCE_LEVEL="${SAST_CONFIDENCE_LEVEL:-3}" \
                   --volume "$PWD:/code" \
510
                   --volume /var/run/docker.sock:/var/run/docker.sock \
511
                   "registry.gitlab.com/gitlab-org/security-products/sast:$SP_VERSION" /app/bin/run /code
512 513 514 515 516 517 518
        ;;
      *)
        echo "GitLab EE is required"
        ;;
    esac
  }

519 520 521 522 523 524 525 526 527 528 529 530 531 532
  function dependency_scanning() {
    case "$CI_SERVER_VERSION" in
      *-ee)
        docker run --env DEP_SCAN_DISABLE_REMOTE_CHECKS="${DEP_SCAN_DISABLE_REMOTE_CHECKS:-false}" \
                   --volume "$PWD:/code" \
                   --volume /var/run/docker.sock:/var/run/docker.sock \
                   "registry.gitlab.com/gitlab-org/security-products/dependency-scanning:$SP_VERSION" /code
        ;;
      *)
        echo "GitLab EE is required"
        ;;
    esac
  }

533 534 535
  function get_replicas() {
    track="${1:-stable}"
    percentage="${2:-100}"
Alessio Caiazza's avatar
Alessio Caiazza committed
536 537 538 539

    env_track=$( echo $track | tr -s  '[:lower:]'  '[:upper:]' )
    env_slug=$( echo ${CI_ENVIRONMENT_SLUG//-/_} | tr -s  '[:lower:]'  '[:upper:]' )

540
    if [[ "$track" == "stable" ]] || [[ "$track" == "rollout" ]]; then
Alessio Caiazza's avatar
Alessio Caiazza committed
541 542
      # for stable track get number of replicas from `PRODUCTION_REPLICAS`
      eval new_replicas=\$${env_slug}_REPLICAS
543 544 545
      if [[ -z "$new_replicas" ]]; then
        new_replicas=$REPLICAS
      fi
Alessio Caiazza's avatar
Alessio Caiazza committed
546 547 548
    else
      # for all tracks get number of replicas from `CANARY_PRODUCTION_REPLICAS`
      eval new_replicas=\$${env_track}_${env_slug}_REPLICAS
549 550 551
      if [[ -z "$new_replicas" ]]; then
        eval new_replicas=\${env_track}_REPLICAS
      fi
Alessio Caiazza's avatar
Alessio Caiazza committed
552
    fi
553 554 555 556 557 558 559 560 561

    replicas="${new_replicas:-1}"
    replicas="$(($replicas * $percentage / 100))"

    # always return at least one replicas
    if [[ $replicas -gt 0 ]]; then
      echo "$replicas"
    else
      echo 1
Alessio Caiazza's avatar
Alessio Caiazza committed
562
    fi
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
  }

  function deploy() {
    track="${1-stable}"
    percentage="${2:-100}"
    name="$CI_ENVIRONMENT_SLUG"

    replicas="1"
    service_enabled="true"
    postgres_enabled="$POSTGRES_ENABLED"

    # if track is different than stable,
    # re-use all attached resources
    if [[ "$track" != "stable" ]]; then
      name="$name-$track"
      service_enabled="false"
      postgres_enabled="false"
    fi

    replicas=$(get_replicas "$track" "$percentage")
Alessio Caiazza's avatar
Alessio Caiazza committed
583

584 585 586 587 588 589
    if [[ "$CI_PROJECT_VISIBILITY" != "public" ]]; then
      secret_name='gitlab-registry'
    else
      secret_name=''
    fi

Alessio Caiazza's avatar
Alessio Caiazza committed
590 591 592 593 594 595
    helm upgrade --install \
      --wait \
      --set service.enabled="$service_enabled" \
      --set releaseOverride="$CI_ENVIRONMENT_SLUG" \
      --set image.repository="$CI_APPLICATION_REPOSITORY" \
      --set image.tag="$CI_APPLICATION_TAG" \
596
      --set image.pullPolicy=IfNotPresent \
597
      --set image.secrets[0].name="$secret_name" \
Alessio Caiazza's avatar
Alessio Caiazza committed
598 599 600 601 602 603 604 605 606 607 608 609
      --set application.track="$track" \
      --set application.database_url="$DATABASE_URL" \
      --set service.url="$CI_ENVIRONMENT_URL" \
      --set replicaCount="$replicas" \
      --set postgresql.enabled="$postgres_enabled" \
      --set postgresql.nameOverride="postgres" \
      --set postgresql.postgresUser="$POSTGRES_USER" \
      --set postgresql.postgresPassword="$POSTGRES_PASSWORD" \
      --set postgresql.postgresDatabase="$POSTGRES_DB" \
      --namespace="$KUBE_NAMESPACE" \
      "$name" \
      chart/
610 611

    kubectl rollout status -n "$KUBE_NAMESPACE" -w "deployment/$name"
Alessio Caiazza's avatar
Alessio Caiazza committed
612 613
  }

614 615 616 617 618 619 620 621 622 623 624
  function scale() {
    track="${1-stable}"
    percentage="${2-100}"
    name="$CI_ENVIRONMENT_SLUG"

    if [[ "$track" != "stable" ]]; then
      name="$name-$track"
    fi

    replicas=$(get_replicas "$track" "$percentage")

625 626 627 628 629 630 631 632
    if [[ -n "$(helm ls -q "^$name$")" ]]; then
      helm upgrade --reuse-values \
        --wait \
        --set replicaCount="$replicas" \
        --namespace="$KUBE_NAMESPACE" \
        "$name" \
        chart/
    fi
633 634
  }

635
  function install_dependencies() {
636
    apk add -U openssl curl tar gzip bash ca-certificates git
637 638
    curl -L -o /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
    curl -L -O https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk
639 640
    apk add glibc-2.28-r0.apk
    rm glibc-2.28-r0.apk
641

642
    curl "https://kubernetes-helm.storage.googleapis.com/helm-v${HELM_VERSION}-linux-amd64.tar.gz" | tar zx
643 644 645
    mv linux-amd64/helm /usr/bin/
    helm version --client

646
    curl -L -o /usr/bin/kubectl "https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl"
647 648
    chmod +x /usr/bin/kubectl
    kubectl version --client
649
  }
650

651
  function setup_docker() {
652
    if ! docker info &>/dev/null; then
653
      if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
654 655 656
        export DOCKER_HOST='tcp://localhost:2375'
      fi
    fi
657
  }
658

659 660
  function setup_test_db() {
    if [ -z ${KUBERNETES_PORT+x} ]; then
661 662 663 664
      DB_HOST=postgres
    else
      DB_HOST=localhost
    fi
665 666
    export DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DB_HOST}:5432/${POSTGRES_DB}"
  }
667

668
  function download_chart() {
669
    if [[ ! -d chart ]]; then
670 671 672
      auto_chart=${AUTO_DEVOPS_CHART:-gitlab/auto-deploy-app}
      auto_chart_name=$(basename $auto_chart)
      auto_chart_name=${auto_chart_name%.tgz}
673
      auto_chart_name=${auto_chart_name%.tar.gz}
674 675 676
    else
      auto_chart="chart"
      auto_chart_name="chart"
677
    fi
678 679 680 681 682 683 684 685 686 687

    helm init --client-only
    helm repo add gitlab https://charts.gitlab.io
    if [[ ! -d "$auto_chart" ]]; then
      helm fetch ${auto_chart} --untar
    fi
    if [ "$auto_chart_name" != "chart" ]; then
      mv ${auto_chart_name} chart
    fi

688 689
    helm dependency update chart/
    helm dependency build chart/
690
  }
691

692 693 694
  function ensure_namespace() {
    kubectl describe namespace "$KUBE_NAMESPACE" || kubectl create namespace "$KUBE_NAMESPACE"
  }
695

696
  function check_kube_domain() {
697
    if [ -z ${AUTO_DEVOPS_DOMAIN+x} ]; then
698
      echo "In order to deploy or use Review Apps, AUTO_DEVOPS_DOMAIN variable must be set"
699
      echo "You can do it in Auto DevOps project settings or defining a variable at group or project level"
700
      echo "You can also manually add it in .gitlab-ci.yml"
701 702 703 704
      false
    else
      true
    fi
705
  }
706

707
  function build() {
708
    registry_login
709

710 711
    if [[ -f Dockerfile ]]; then
      echo "Building Dockerfile-based application..."
712 713 714 715 716 717 718 719 720 721
      docker build \
        --build-arg HTTP_PROXY="$HTTP_PROXY" \
        --build-arg http_proxy="$http_proxy" \
        --build-arg HTTPS_PROXY="$HTTPS_PROXY" \
        --build-arg https_proxy="$https_proxy" \
        --build-arg FTP_PROXY="$FTP_PROXY" \
        --build-arg ftp_proxy="$ftp_proxy" \
        --build-arg NO_PROXY="$NO_PROXY" \
        --build-arg no_proxy="$no_proxy" \
        -t "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" .
722 723
    else
      echo "Building Heroku-based application using gliderlabs/herokuish docker image..."
724 725 726 727 728 729 730 731 732 733 734
      docker run -i \
        -e BUILDPACK_URL \
        -e HTTP_PROXY \
        -e http_proxy \
        -e HTTPS_PROXY \
        -e https_proxy \
        -e FTP_PROXY \
        -e ftp_proxy \
        -e NO_PROXY \
        -e no_proxy \
        --name="$CI_CONTAINER_NAME" -v "$(pwd):/tmp/app:ro" gliderlabs/herokuish /bin/herokuish buildpack build
735 736
      docker commit "$CI_CONTAINER_NAME" "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG"
      docker rm "$CI_CONTAINER_NAME" >/dev/null
737 738
      echo ""

739 740 741 742
      echo "Configuring $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG docker image..."
      docker create --expose 5000 --env PORT=5000 --name="$CI_CONTAINER_NAME" "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" /bin/herokuish procfile start web
      docker commit "$CI_CONTAINER_NAME" "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG"
      docker rm "$CI_CONTAINER_NAME" >/dev/null
743 744 745 746
      echo ""
    fi

    echo "Pushing to GitLab Container Registry..."
747
    docker push "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG"
748
    echo ""
749
  }
750

751
  function install_tiller() {
752
    echo "Checking Tiller..."
753
    helm init --upgrade
754
    kubectl rollout status -n "$TILLER_NAMESPACE" -w "deployment/tiller-deploy"
755 756 757 758 759
    if ! helm version --debug; then
      echo "Failed to init Tiller."
      return 1
    fi
    echo ""
760
  }
761

762
  function create_secret() {
763 764 765 766
    echo "Create secret..."
    if [[ "$CI_PROJECT_VISIBILITY" == "public" ]]; then
      return
    fi
767

768
    kubectl create secret -n "$KUBE_NAMESPACE" \
769
      docker-registry gitlab-registry \
770
      --docker-server="$CI_REGISTRY" \
771 772
      --docker-username="${CI_DEPLOY_USER:-$CI_REGISTRY_USER}" \
      --docker-password="${CI_DEPLOY_PASSWORD:-$CI_REGISTRY_PASSWORD}" \
773 774 775
      --docker-email="$GITLAB_USER_EMAIL" \
      -o yaml --dry-run | kubectl replace -n "$KUBE_NAMESPACE" --force -f -
  }
776

Fabio Busatto's avatar
Fabio Busatto committed
777 778
  function dast() {
    export CI_ENVIRONMENT_URL=$(cat environment_url.txt)
779

Fabio Busatto's avatar
Fabio Busatto committed
780
    mkdir /zap/wrk/
781
    /zap/zap-baseline.py -J gl-dast-report.json -t "$CI_ENVIRONMENT_URL" || true
Fabio Busatto's avatar
Fabio Busatto committed
782 783
    cp /zap/wrk/gl-dast-report.json .
  }
784

785
  function performance() {
786
    export CI_ENVIRONMENT_URL=$(cat environment_url.txt)
787

788
    mkdir gitlab-exporter
789
    wget -O gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/10-5/index.js
790

791
    mkdir sitespeed-results
792

793 794
    if [ -f .gitlab-urls.txt ]
    then
795
      sed -i -e 's@^@'"$CI_ENVIRONMENT_URL"'@' .gitlab-urls.txt
796
      docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.3.1 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results .gitlab-urls.txt
797
    else
798
      docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:6.3.1 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "$CI_ENVIRONMENT_URL"
799
    fi
800

801 802
    mv sitespeed-results/data/performance.json performance.json
  }
803

804 805 806
  function persist_environment_url() {
      echo $CI_ENVIRONMENT_URL > environment_url.txt
  }
807 808 809 810

  function delete() {
    track="${1-stable}"
    name="$CI_ENVIRONMENT_SLUG"
811

812 813 814
    if [[ "$track" != "stable" ]]; then
      name="$name-$track"
    fi
815

816
    if [[ -n "$(helm ls -q "^$name$")" ]]; then
817
      helm delete --purge "$name"
818
    fi
819
  }
820

821 822
before_script:
  - *auto_devops