9 DOCKER_VERSION: '19.03.0'
10 # We don't use the default CI_REGISTRY_IMAGE variable because the security release process on dev.gitlab.org needs to target the gitlab.com registry.
11 # https://gitlab.com/gitterHQ/webapp/-/merge_requests/1952#note_386372016
12 GITTER_CI_REGISTRY_IMAGE: registry.gitlab.com/gitterhq/webapp
17 .if-merge-request: &if-merge-request
18 if: '$CI_MERGE_REQUEST_IID'
20 .if-develop-branch: &if-develop-branch
21 if: '$CI_COMMIT_BRANCH == "develop"'
23 .if-master-branch: &if-master-branch
24 if: '$CI_COMMIT_BRANCH == "master"'
26 .if-release-branch: &if-release-branch
27 if: '$CI_COMMIT_BRANCH =~ /^release\/.*$/'
29 .if-hotfix-branch: &if-hotfix-branch
30 if: '$CI_COMMIT_BRANCH =~ /^hotfix\/.*$/'
32 .if-mr-source-renovate-branch: &if-mr-source-renovate-branch
33 if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^renovate\/.*$/'
38 .if-not-canonical-project: &if-not-canonical-project
40 # - https://gitlab.com/gitterHQ/webapp
41 # - https://dev.gitlab.org/gitlab/gitter/webapp
42 if: '$CI_PROJECT_PATH != "gitterHQ/webapp" && $CI_PROJECT_PATH != "gitlab/gitter/webapp"'
44 .if-schedule: &if-schedule
45 if: '$CI_PIPELINE_SOURCE == "schedule"'
49 # For merge requests, create a pipeline.
50 - <<: *if-merge-request
51 # For `develop` branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
52 - <<: *if-develop-branch
53 # For `master` branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
54 - <<: *if-master-branch
55 # For `release/*` branch, create a pipeline.
56 - <<: *if-release-branch
57 # For tags, create a pipeline.
64 .use-docker-in-docker:
65 image: docker:${DOCKER_VERSION}
67 - docker:${DOCKER_VERSION}-dind
69 DOCKER_DRIVER: overlay2
70 DOCKER_HOST: tcp://docker:2375
71 DOCKER_TLS_CERTDIR: ''
73 # See https://gitlab.com/gitlab-com/www-gitlab-com/-/issues/7019 for tag descriptions
81 # Don't run this job for forks since it should only be run from the canonical project.
82 - <<: *if-not-canonical-project
84 - <<: *if-release-branch
85 - <<: *if-hotfix-branch
87 .webapp_variables: &webapp_variables
88 FF_NETWORK_PER_BUILD: 1
91 SYNAPSE_SERVER_NAME: my.matrix.host
92 SYNAPSE_CONFIG_PATH: /data/gitlab-ci-homeserver.yaml
95 - &webapp_service_mongo
96 name: $GITTER_CI_REGISTRY_IMAGE/mongo:latest
98 - &webapp_service_redis
101 - &webapp_service_elasticsearch
102 name: $GITTER_CI_REGISTRY_IMAGE/elasticsearch:latest
104 - &webapp_service_neo4j
107 - &webapp_service_synapse
108 name: $GITTER_CI_REGISTRY_IMAGE/synapse:latest
112 image: $GITTER_CI_REGISTRY_IMAGE:latest
116 - npm config set prefer-offline true
117 - npm config set cache ./npm_cache
118 # Only copy the cache from the Docker container if the cache from GitLab CI is not in place
119 - '[[ -d ./npm_cache ]] || mv /npm_cache ./npm_cache'
120 # Install the npm dependencies from scratch to avoid the `graceful-fs` problem from multiple npm installs.
121 # (old gulp 3 dependency problem with Node.js v14)
122 # Otherwise, it will throw `ReferenceError: primordials is not defined`.
123 # See https://stackoverflow.com/a/58394828/796832
125 # We're trying to make this fast by using npm cache.
127 # Cache modules in between jobs
128 # Based on https://docs.gitlab.com/ee/ci/caching/#cache-nodejs-dependencies
130 # CI_COMMIT_REF_SLUG is the branch or tag name in lowercase
131 key: ${CI_COMMIT_REF_SLUG}
137 stage: build_unit_test
139 - "echo 'TODO: Skip validation for now because we have new eslint failures'"
141 # TODO: This should be part of `make validate` -> `gulpfile-linter`
142 # but the prettier API doesn't easily allow glob checking and I want
143 # to re-use the scripts that GitLab has, https://gitlab.com/gitlab-org/gitlab-ce/issues/57010
144 - npm run prettier -- --check "**/*.{js,vue}"
149 <<: *webapp_variables
150 NODE_ENV: test-docker
151 stage: build_unit_test
153 - *webapp_service_mongo
154 - *webapp_service_redis
155 - *webapp_service_elasticsearch
156 - *webapp_service_neo4j
157 - *webapp_service_synapse
171 <<: *webapp_variables
172 ENABLE_FIXTURE_ENDPOINTS: 1
173 DISABLE_GITHUB_API: 1
174 NODE_ENV: test-docker
175 # "fake" dbus address to prevent errors
176 # https://github.com/SeleniumHQ/docker-selenium/issues/87
177 # via https://hub.docker.com/r/cypress/browsers/dockerfile
178 # #oom-chrome-cypress
179 DBUS_SESSION_BUS_ADDRESS: /dev/null
181 # Run the on Gitter internal runner so our Cypress video doesn't have gaps/freezing,
182 # see https://github.com/cypress-io/cypress/issues/4722#issuecomment-526313109
183 # Maybe in the future, Cypress will detect and give a warning when this happens,
184 # see https://github.com/cypress-io/cypress/issues/5061
187 # Don't run this job for forks since it uses the 'internal' runner.
188 - <<: *if-not-canonical-project
190 - <<: *if-mr-source-renovate-branch
194 # install Chromebrowser
195 # via https://hub.docker.com/r/cypress/browsers/dockerfile
196 # We are using Chrome because of OOM issues #oom-chrome-cypress, see https://github.com/cypress-io/cypress/issues/350#issuecomment-633700002
197 - apt-get install -y wget gnupg
198 - wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
199 - echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list
200 - apt-get update -q -y
201 - apt-get install -y dbus-x11 google-chrome-stable
202 - rm -rf /var/lib/apt/lists/*
203 # Cypress dependencies https://docs.cypress.io/guides/guides/continuous-integration.html#Dependencies
204 - apt-get update -q -y
205 - apt-get --yes install libgtk2.0-0 libgtk-3-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
206 # Create `output/assets/js/vue-ssr-server-bundle.json`
208 # Start the server and wait for it to come up
210 - npm start > logs/server-output.txt 2>&1 & node test/e2e/support/wait-for-server.js http://localhost:5000
212 # We are using Chrome because of OOM issues #oom-chrome-cypress, see https://github.com/cypress-io/cypress/issues/350#issuecomment-633700002
213 - npm run test-e2e-run -- --browser chrome --headless
219 - test/e2e/screenshots
226 stage: build_unit_test
228 # While testing the deploment, you can use cached artifacts instead of packaging every time which is slow
229 #- (apt-get update && apt-get install unzip && curl -Ls https://gitlab.com/gitterHQ/webapp/-/jobs/60049410/artifacts/download -o previous-artifacts.zip && unzip previous-artifacts.zip) || (make package)
234 - output/assets.tar.gz
235 - output/app/ASSET_TAG
236 - output/app/GIT_COMMIT
242 stage: build_unit_test
244 - <<: *if-master-branch
247 stats__cube__enabled: 'false'
248 stats__statsd__enabled: 'false'
251 - npm run build-android-assets
252 - npm run build-ios-assets
259 image: $GITTER_CI_REGISTRY_IMAGE/deploy-build-image:latest
267 extends: .distribute_job
269 # Don't run this job for forks since it should only be run from the canonical project.
270 - <<: *if-not-canonical-project
272 - <<: *if-develop-branch
274 DIST_S3_URL: s3://gitter-deployments/gitter-webapp/beta
276 distribute_beta_staging:
277 extends: .distribute_job
279 # Don't run this job for forks since it should only be run from the canonical project.
280 - <<: *if-not-canonical-project
284 DIST_S3_URL: s3://gitter-deployments/gitter-webapp/beta-staging
291 DIST_S3_URL: s3://gitter-deployments/gitter-webapp/staging
294 extends: .distribute_job
296 # Don't run this job for forks since it should only be run from the canonical project.
297 - <<: *if-not-canonical-project
301 DIST_S3_URL: s3://gitter-deployments/gitter-webapp/prod
304 extends: .use-docker-in-docker
311 - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
312 - docker build -t $GITTER_CI_REGISTRY_IMAGE/app:$CI_COMMIT_REF_SLUG -f Dockerfile-app-base .
313 - docker push $GITTER_CI_REGISTRY_IMAGE/app:$CI_COMMIT_REF_SLUG
316 extends: .use-docker-in-docker
321 - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
322 - docker build -t $GITTER_CI_REGISTRY_IMAGE/deploy-build-image:latest scripts/docker/deploy-build-image/
323 - docker push $GITTER_CI_REGISTRY_IMAGE/deploy-build-image:latest
327 image: $GITTER_CI_REGISTRY_IMAGE/deploy-build-image:latest
332 - eval $(ssh-agent -s)
333 # add ssh key stored in SSH_PRIVATE_KEY variable to the agent store
334 - ssh-add <(echo "$DEPLOY_KEY_ANSIBLE_REPO")
335 - ssh-add <(echo "$INTERNAL_GITTER_NETWORK_SSH_KEY")
337 - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
338 # Make the infra tools available (like Ansible)
339 - git clone git@gitlab.com:gitlab-com/gl-infra/gitter-infrastructure.git
340 - ANSIBLE_DIR=$(cd gitter-infrastructure/ansible && pwd) && echo $ANSIBLE_DIR
341 - mkdir -p /root && echo "$ANSIBLE_VAULT_PASS" > /root/.vault_pass
343 - internal # This has to be within the Gitter network
350 # Don't run this job for forks since it uses the 'internal' runner.
351 - <<: *if-not-canonical-project
353 - <<: *if-develop-branch
355 - cd $ANSIBLE_DIR && ansible-playbook -i beta --vault-password-file "/root/.vault_pass" playbooks/gitter/webapp-deploy.yml
358 url: https://beta.gitter.im
363 - distribute_beta_staging
365 # Don't run this job for forks since it uses the 'internal' runner.
366 - <<: *if-not-canonical-project
371 - cd $ANSIBLE_DIR && ansible-playbook -i beta --vault-password-file "/root/.vault_pass" playbooks/gitter/webapp-staging-deploy.yml
374 url: https://beta.gitter.im?gitter_next=true
383 - cd $ANSIBLE_DIR && ansible-playbook -i prod --vault-password-file "/root/.vault_pass" playbooks/gitter/webapp-staging-deploy.yml
386 url: https://gitter.im?gitter_next=true
393 # Don't run this job for forks since it uses the 'internal' runner.
394 - <<: *if-not-canonical-project
399 - cd $ANSIBLE_DIR && ansible-playbook -i prod --vault-password-file "/root/.vault_pass" playbooks/gitter/webapp-deploy.yml
402 url: https://gitter.im
405 extends: .use-docker-in-docker
410 - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
411 - docker build -t $GITTER_CI_REGISTRY_IMAGE:latest .
412 - docker push $GITTER_CI_REGISTRY_IMAGE:latest
415 extends: .use-docker-in-docker
420 - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
421 - docker build -t $GITTER_CI_REGISTRY_IMAGE/mongo:latest scripts/docker/mongo-image/
422 - docker push $GITTER_CI_REGISTRY_IMAGE/mongo:latest
425 extends: .use-docker-in-docker
430 - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
431 - docker build -t $GITTER_CI_REGISTRY_IMAGE/elasticsearch:latest scripts/docker/elasticsearch-image/
432 - docker push $GITTER_CI_REGISTRY_IMAGE/elasticsearch:latest
435 extends: .use-docker-in-docker
440 - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
441 - docker build -t $GITTER_CI_REGISTRY_IMAGE/synapse:latest scripts/docker/matrix/synapse/
442 - docker push $GITTER_CI_REGISTRY_IMAGE/synapse:latest
445 extends: .use-docker-in-docker
451 # GitLab access token with api access
452 #RENOVATE_GITLAB_TOKEN: xxx
453 # GitHub access token for getting release notes of package updates,
454 # https://github.com/renovatebot/renovate/blob/master/docs/self-hosting.md#githubcom-token-for-release-notes
455 #RENOVATE_GITHUB_TOKEN: xxx
456 RENOVATE_CONFIG_FILE: renovate-config.js
458 - docker run -e GITLAB_TOKEN="$RENOVATE_GITLAB_TOKEN" -e GITHUB_COM_TOKEN="$RENOVATE_GITHUB_TOKEN" -v $PWD/renovate.json:/usr/src/app/renovate.json -v $PWD/renovate-config.js:/usr/src/app/config.js renovate/renovate:13 gitterHQ/webapp
461 # =========================================================
463 - template: Security/SAST.gitlab-ci.yml
464 - template: Security/DAST.gitlab-ci.yml
465 - template: Security/Dependency-Scanning.gitlab-ci.yml
466 - template: Security/Container-Scanning.gitlab-ci.yml
467 - template: Security/Secret-Detection.gitlab-ci.yml
472 SECURE_LOG_LEVEL: debug
474 gemnasium-dependency_scanning:
483 DOCKERFILE_PATH: Dockerfile-app-base
485 CI_APPLICATION_REPOSITORY: $GITTER_CI_REGISTRY_IMAGE/app
486 CI_APPLICATION_TAG: $CI_COMMIT_REF_SLUG
491 SAST_EXCLUDED_PATHS: '/test/**,**/*-test.js,/scripts,/build-scripts'
509 <<: *webapp_variables
510 NODE_ENV: test-docker
511 DAST_WEBSITE: http://webapp-server:5000/
512 # Pass-through webapp secrets from our project-level secret variables
513 web__sessionSecret: '${web__sessionSecret}'
514 web__statePassphrase: '${web__statePassphrase}'
515 ws__superClientPassword: '${ws__superClientPassword}'
516 web__messageSecret: '${web__messageSecret}'
517 email__unsubscribeNotificationsSecret: '${email__unsubscribeNotificationsSecret}'
518 integrations__secret: '${integrations__secret}'
519 github__statePassphrase: '${github__statePassphrase}'
520 twitteroauth__consumer_key: '${twitteroauth__consumer_key}'
521 twitteroauth__consumer_secret: '${twitteroauth__consumer_secret}'
522 gitlaboauth__client_id: '${gitlaboauth__client_id}'
523 gitlaboauth__client_secret: '${gitlaboauth__client_secret}'
524 gitlab__public_token_pool: '${gitlab__public_token_pool}'
525 github__client_id: '${github__client_id}'
526 github__client_secret: '${github__client_secret}'
527 github__user_client_id: '${github__user_client_id}'
528 github__user_client_secret: '${github__user_client_secret}'
529 github__anonymous_app__client_id: '${github__anonymous_app__client_id}'
530 github__anonymous_app__client_secret: '${github__anonymous_app__client_secret}'
531 tokens__anonymousPassword: '${tokens__anonymousPassword}'
533 # Used to communicate with the other services and share the other hostnames we can connect to
534 # See https://gitlab.com/gitlab-org/gitlab-runner/issues/1042#note_144420147
535 - cp /etc/hosts "${CI_PROJECT_DIR}/"
537 - name: $GITTER_CI_REGISTRY_IMAGE/app:$CI_COMMIT_REF_SLUG
539 # Used to communicate with the other services and share the other hostnames we can connect to
540 # See https://gitlab.com/gitlab-org/gitlab-runner/issues/1042#note_144420147
545 'while [ ! -f /$CI_PROJECT_DIR/hosts ]; do sleep 1; done && cat /$CI_PROJECT_DIR/hosts > /etc/hosts && node web.js',
547 - *webapp_service_mongo
548 - *webapp_service_redis
549 - *webapp_service_elasticsearch
550 - *webapp_service_neo4j
551 - *webapp_service_synapse
554 extends: .use-docker-in-docker