Replace TravisCI with GitLab CI (#16)

* Add gitlab-ci configuration

* Attempt to fix cypress binary installation cache

* Even more improve caching, add wait-on step to ensure, that web server is ready to run cypress

* Exclude cache directory from linting

* Do not cache yarn's global cache to reduce the size of the cache to upload

* Disable Sentry for e2e tests, enable parallelization for cypress

* Store build artifacts

* Add dev deployment stage

* Try to fix commits association

* Fix sentry-cli param name

* Disable host checking for rsync

* Disable host checking via ssh config

* Add production deployment step

* Fix deployment Sentry notifying, allow performing auto deployment with special commit message

* Make autodeploy [deploy]

* Cleanup test branch refs

* Remove environment definition. Detect it based on the domain name

* Store cache for E2E tests separately
This commit is contained in:
ErickSkrauch 2020-01-15 17:57:27 +03:00 committed by GitHub
parent 4b71e8b12e
commit 0281c55463
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 272 additions and 79 deletions

View File

@ -7,4 +7,3 @@ GA_ID=UA-XXXXX-Y
API_HOST=https://dev.account.ely.by API_HOST=https://dev.account.ely.by
VERSION=dev VERSION=dev
ENVIRONMENT=dev

View File

@ -1,3 +1,4 @@
build build
dll dll
node_modules node_modules
cache

209
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,209 @@
variables:
# To cache both npm modules and Cypress binary we use environment variables
# to point at the folders we can list as paths in "cache" job settings
YARN_CACHE_FOLDER: "$CI_PROJECT_DIR/cache/yarn"
CYPRESS_CACHE_FOLDER: "$CI_PROJECT_DIR/cache/cypress"
default:
image: circleci/node:12
stages:
- prepare
- test
- build
- deploy
# GitLab don't support bash syntax in the "variables" definitions,
# so we use a custom step to define all necessary environment variables
.defineVars: &defineVars |-
export VERSION="${CI_COMMIT_TAG:-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}}"
.installSentry: &installSentry |-
curl -sL https://sentry.io/get-cli/ | bash
.setupSSH: &setupSSH |-
mkdir ~/.ssh
echo -e "Host *\n StrictHostKeyChecking no\n" > ~/.ssh/config
eval $(ssh-agent -s)
echo "$SSH_DEPLOY_KEY" | tr -d '\r' | ssh-add -
###################
# Steps to extend #
###################
.yarnCache:
cache:
key: yarn-cache
paths:
- node_modules
- packages/*/node_modules
policy: pull
.yarnE2ECache:
cache:
key: yarn-e2e-cache
paths:
- cache/cypress
- node_modules
- packages/*/node_modules
- tests-e2e/node_modules
policy: pull
#################
# Prepare stage #
#################
Yarn:
stage: prepare
extends:
- .yarnCache
cache:
policy: pull-push
variables:
CYPRESS_INSTALL_BINARY: 0 # Don't install binary to increase caching performance between jobs
script:
- yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
Yarn E2E:
stage: prepare
extends:
- .yarnE2ECache
cache:
policy: pull-push
script:
- yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
only:
refs:
- master
#################
# Testing stage #
#################
Lint:
stage: test
extends:
- .yarnCache
script:
- yarn lint:check
TypeScript:
stage: test
extends:
- .yarnCache
script:
- yarn ts:check
Jest:
stage: test
extends:
- .yarnCache
script:
- yarn test
Cypress:
stage: test
image: circleci/node:12-buster-browsers
extends:
- .yarnE2ECache
variables:
# Sentry's DSN is provided for build step from repository configuration,
# but it's not necessary to send any logs reports during E2E testing
SENTRY_DSN: ""
script:
- yarn start &
- yarn wait-on http://localhost:8080
- >
yarn --cwd tests-e2e test:ci
--record
--browser chrome
--parallel
parallel: 4
timeout: 5m
allow_failure: true
only:
refs:
- master
###############
# Build stage #
###############
Build:
stage: build
needs:
- Lint
- TypeScript
- Jest
extends:
- .yarnCache
before_script:
- *defineVars
- sudo apt install cpio
script:
- yarn build
# Remove unneeded files
- rm -rf build/messages
- rm -rf build/*.css.map
# Move all source maps to its own directory
- mkdir -p source-maps
- cd build
- find . -name '*.js.map' | cpio -pdm ../source-maps/
- rm -rf *.js.map
- find . -name '*.js' | cpio -pdm ../source-maps/
- cd ..
artifacts:
name: "Production build for $CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA"
paths:
- build
- source-maps
expire_in: 1 week
################
# Deploy stage #
################
.deployJob:
stage: deploy
before_script:
- *defineVars
- *installSentry
- *setupSSH
- sudo apt install rsync
script:
# Send release to the Sentry
- sentry-cli releases new $VERSION
- sentry-cli releases set-commits --commit "elyby/accounts-frontend@${CI_COMMIT_SHA}" $VERSION
- sentry-cli releases files $VERSION upload-sourcemaps source-maps
- rsync -v -a -r --delete-after -e "ssh -J deploy@ely.by:4534 -p 722" build/ "root@${VM_HOST_NAME}:${VM_DEPLOY_PATH}"
# Finalize Sentry's release
- sentry-cli releases deploys $VERSION new -e $CI_ENVIRONMENT_NAME
- sentry-cli releases finalize $VERSION
Deploy dev:
extends:
- .deployJob
environment:
name: Development
variables:
VM_HOST_NAME: playground.ely.local
VM_DEPLOY_PATH: /srv/dev.account.ely.by/frontend
only:
refs:
- master
Deploy prod:
extends:
- .deployJob
stage: deploy
environment:
name: Production
variables:
VM_HOST_NAME: accounts.ely.local
VM_DEPLOY_PATH: /srv/frontend
rules:
- if: '$CI_COMMIT_BRANCH != "master"'
when: never
- if: '$CI_COMMIT_MESSAGE =~ /\[deploy\]/'
when: on_success
- when: manual

View File

@ -1,5 +1,7 @@
build build
dll dll
node_modules
cache
*.jpg *.jpg
*.png *.png
*.gif *.gif

View File

@ -1,69 +0,0 @@
language: node_js
node_js:
- "11"
cache:
yarn: true
directories:
- node_modules
addons:
ssh_known_hosts: account.ely.by
env:
global:
- GA_ID=UA-45299905-3
- SENTRY_CDN="https://95461d4ce6734b088c34fc4272d0a9e6@sentry.io/1463318"
- VERSION="${TRAVIS_TAG:-${TRAVIS_BRANCH}-${TRAVIS_COMMIT:0:7}}"
- FORCE_COLOR=1
script:
- yarn ci:check
- yarn build:quiet
before_deploy:
# Prepare ssh deployment
- openssl aes-256-cbc -K $encrypted_dd5ad7a5f201_key -iv $encrypted_dd5ad7a5f201_iv -in deploy_rsa.enc -out /tmp/deploy_rsa -d
- eval "$(ssh-agent -s)"
- chmod 600 /tmp/deploy_rsa
- ssh-add /tmp/deploy_rsa
# Removing unneeded files
- rm -rf build/messages
- rm -rf build/*.css.map
# Move all source maps to it's own directory
- mkdir -p source-maps
- mv build/*.js.map source-maps/ 2>/dev/null; true
- cp build/*.js source-maps/
# Creating tar.gz and zip archives
- cd build
- tar -zcf ../build.tar.gz --exclude="*.map" *
- zip -rq ../build.zip * -x "*.map"
- cd ..
deploy:
- provider: releases
api_key: "$GITHUB_TOKEN"
file:
- build.tar.gz
- build.zip
skip_cleanup: true
draft: true
on:
branch: master
# - provider: script
# skip_cleanup: true
# script: echo "put -r $TRAVIS_BUILD_DIR/build/* accounts-frontend/" | sftp deploy@account.ely.by
# on:
# branch: master
- provider: script
skip_cleanup: true
script: >
curl -sL https://sentry.io/get-cli/ | bash &&
sentry-cli releases new -p $SENTRY_PROJECT $VERSION &&
sentry-cli releases set-commits --auto $VERSION &&
sentry-cli releases files $VERSION upload-sourcemaps source-maps &&
sentry-cli releases deploys $VERSION new -e "Production"
on:
branch: master

View File

@ -6,7 +6,6 @@ const { env } = process;
module.exports = { module.exports = {
version: env.VERSION || env.NODE_ENV, version: env.VERSION || env.NODE_ENV,
environment: env.ENVIRONMENT || env.NODE_ENV,
apiHost: env.API_HOST || 'https://dev.account.ely.by', apiHost: env.API_HOST || 'https://dev.account.ely.by',
ga: env.GA_ID && { id: env.GA_ID }, ga: env.GA_ID && { id: env.GA_ID },
sentryDSN: env.SENTRY_DSN, sentryDSN: env.SENTRY_DSN,

Binary file not shown.

View File

@ -168,6 +168,7 @@
"unexpected": "^11.12.0", "unexpected": "^11.12.0",
"unexpected-sinon": "^10.5.1", "unexpected-sinon": "^10.5.1",
"url-loader": "^3.0.0", "url-loader": "^3.0.0",
"wait-on": "^3.3.0",
"webpack": "^4.41.5", "webpack": "^4.41.5",
"webpack-bundle-analyzer": "^3.6.0", "webpack-bundle-analyzer": "^3.6.0",
"webpack-cli": "^3.3.10", "webpack-cli": "^3.3.10",

View File

@ -11,7 +11,10 @@ class Logger {
Raven.config(sentryDSN, { Raven.config(sentryDSN, {
logger: 'accounts-js-app', logger: 'accounts-js-app',
level: 'info', level: 'info',
environment: process.env.APP_ENV, environment:
window.location.host === 'account.ely.by'
? 'Production'
: 'Development',
release: process.env.__VERSION__, release: process.env.__VERSION__,
shouldSendCallback: () => !isTest, shouldSendCallback: () => !isTest,
dataCallback: data => { dataCallback: data => {

View File

@ -1,5 +1,6 @@
{ {
"baseUrl": "http://localhost:8080", "baseUrl": "http://localhost:8080",
"testFiles": ["**/*.test.ts"], "testFiles": ["**/*.test.ts"],
"chromeWebSecurity": false "chromeWebSecurity": false,
"projectId": "uftjbg"
} }

View File

@ -87,7 +87,6 @@ const webpackConfig = {
}), }),
new webpack.EnvironmentPlugin({ new webpack.EnvironmentPlugin({
NODE_ENV: process.env.NODE_ENV, NODE_ENV: process.env.NODE_ENV,
APP_ENV: config.environment || process.env.NODE_ENV,
__VERSION__: config.version || '', __VERSION__: config.version || '',
}), }),
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({

View File

@ -1353,6 +1353,38 @@
resolved "https://registry.yarnpkg.com/@formatjs/macro/-/macro-0.2.6.tgz#eb173658d803416a43210778b2f5c04c5a240bb6" resolved "https://registry.yarnpkg.com/@formatjs/macro/-/macro-0.2.6.tgz#eb173658d803416a43210778b2f5c04c5a240bb6"
integrity sha512-DfdnLJf8+PwLHzJECZ1Xfa8+sI9akQnUuLN2UdkaExTQmlY0Vs36rMzEP0JoVDBMk+KdQbJNt72rPeZkBNcKWg== integrity sha512-DfdnLJf8+PwLHzJECZ1Xfa8+sI9akQnUuLN2UdkaExTQmlY0Vs36rMzEP0JoVDBMk+KdQbJNt72rPeZkBNcKWg==
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==
"@hapi/bourne@1.x.x":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a"
integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==
"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0":
version "8.5.0"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.0.tgz#2f9ce301c8898e1c3248b0a8564696b24d1a9a5a"
integrity sha512-7XYT10CZfPsH7j9F1Jmg1+d0ezOux2oM2GfArAzLwWe4mE2Dr3hVjsAL6+TFY49RRJlCdJDMw3nJsLFroTc8Kw==
"@hapi/joi@^15.0.3":
version "15.1.1"
resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7"
integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==
dependencies:
"@hapi/address" "2.x.x"
"@hapi/bourne" "1.x.x"
"@hapi/hoek" "8.x.x"
"@hapi/topo" "3.x.x"
"@hapi/topo@3.x.x":
version "3.1.6"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29"
integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==
dependencies:
"@hapi/hoek" "^8.3.0"
"@hot-loader/react-dom@^16.11.0": "@hot-loader/react-dom@^16.11.0":
version "16.11.0" version "16.11.0"
resolved "https://registry.yarnpkg.com/@hot-loader/react-dom/-/react-dom-16.11.0.tgz#c0b483923b289db5431516f56ee2a69448ebf9bd" resolved "https://registry.yarnpkg.com/@hot-loader/react-dom/-/react-dom-16.11.0.tgz#c0b483923b289db5431516f56ee2a69448ebf9bd"
@ -2161,10 +2193,10 @@
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
"@types/node@*": "@types/node@*", "@types/node@^12.0.0":
version "12.12.22" version "12.12.24"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.22.tgz#b8d9eae3328b96910a373cf06ac8d3c5abe9c200" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.24.tgz#d4606afd8cf6c609036b854360367d1b2c78931f"
integrity sha512-r5i93jqbPWGXYXxianGATOxTelkp6ih/U0WVnvaqAvTqM+0U6J3kw6Xk6uq/dWNRkEVw/0SLcO5ORXbVNz4FMQ== integrity sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug==
"@types/normalize-package-data@^2.4.0": "@types/normalize-package-data@^2.4.0":
version "2.4.0" version "2.4.0"
@ -4411,7 +4443,7 @@ core-js@^1.0.0:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
core-js@^2.4.0: core-js@^2.4.0, core-js@^2.6.5:
version "2.6.11" version "2.6.11"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
@ -12007,6 +12039,11 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies: dependencies:
aproba "^1.1.1" aproba "^1.1.1"
rx@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=
rxjs@^5.0.0-beta.11: rxjs@^5.0.0-beta.11:
version "5.5.12" version "5.5.12"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc"
@ -13798,6 +13835,17 @@ w3c-hr-time@^1.0.1:
dependencies: dependencies:
browser-process-hrtime "^0.1.2" browser-process-hrtime "^0.1.2"
wait-on@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.3.0.tgz#9940981d047a72a9544a97b8b5fca45b2170a082"
integrity sha512-97dEuUapx4+Y12aknWZn7D25kkjMk16PbWoYzpSdA8bYpVfS6hpl2a2pOWZ3c+Tyt3/i4/pglyZctG3J4V1hWQ==
dependencies:
"@hapi/joi" "^15.0.3"
core-js "^2.6.5"
minimist "^1.2.0"
request "^2.88.0"
rx "^4.1.0"
walker@^1.0.7, walker@~1.0.5: walker@^1.0.7, walker@~1.0.5:
version "1.0.7" version "1.0.7"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"