From 0281c554635046d7af267b7016b6e8bba7f365d5 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Wed, 15 Jan 2020 17:57:27 +0300 Subject: [PATCH] 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 --- .env.tpl | 1 - .eslintignore | 1 + .gitlab-ci.yml | 209 +++++++++++++++++++++++++ .prettierignore | 2 + .travis.yml | 69 -------- config.js | 1 - deploy_rsa.enc | Bin 3392 -> 0 bytes package.json | 1 + packages/app/services/logger/logger.ts | 5 +- tests-e2e/cypress.json | 3 +- webpack.config.js | 1 - yarn.lock | 58 ++++++- 12 files changed, 272 insertions(+), 79 deletions(-) create mode 100644 .gitlab-ci.yml delete mode 100644 .travis.yml delete mode 100644 deploy_rsa.enc diff --git a/.env.tpl b/.env.tpl index b2b1b94..b4e11dd 100644 --- a/.env.tpl +++ b/.env.tpl @@ -7,4 +7,3 @@ GA_ID=UA-XXXXX-Y API_HOST=https://dev.account.ely.by VERSION=dev -ENVIRONMENT=dev diff --git a/.eslintignore b/.eslintignore index 4fad398..c1f9da0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ build dll node_modules +cache diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..4f0320d --- /dev/null +++ b/.gitlab-ci.yml @@ -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 diff --git a/.prettierignore b/.prettierignore index eee9316..d77e7a4 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,7 @@ build dll +node_modules +cache *.jpg *.png *.gif diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 483b177..0000000 --- a/.travis.yml +++ /dev/null @@ -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 diff --git a/config.js b/config.js index 27f73da..b6c1fab 100644 --- a/config.js +++ b/config.js @@ -6,7 +6,6 @@ const { env } = process; module.exports = { version: env.VERSION || env.NODE_ENV, - environment: env.ENVIRONMENT || env.NODE_ENV, apiHost: env.API_HOST || 'https://dev.account.ely.by', ga: env.GA_ID && { id: env.GA_ID }, sentryDSN: env.SENTRY_DSN, diff --git a/deploy_rsa.enc b/deploy_rsa.enc deleted file mode 100644 index ed282b2b6988feb68d2ce4cb8fb4ab82d20e77d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3392 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 WxY;5X6er#At|RocAD#{|u !isTest, dataCallback: data => { diff --git a/tests-e2e/cypress.json b/tests-e2e/cypress.json index 1dba5eb..c033cd3 100644 --- a/tests-e2e/cypress.json +++ b/tests-e2e/cypress.json @@ -1,5 +1,6 @@ { "baseUrl": "http://localhost:8080", "testFiles": ["**/*.test.ts"], - "chromeWebSecurity": false + "chromeWebSecurity": false, + "projectId": "uftjbg" } diff --git a/webpack.config.js b/webpack.config.js index bcfc73e..a926e89 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -87,7 +87,6 @@ const webpackConfig = { }), new webpack.EnvironmentPlugin({ NODE_ENV: process.env.NODE_ENV, - APP_ENV: config.environment || process.env.NODE_ENV, __VERSION__: config.version || '', }), new HtmlWebpackPlugin({ diff --git a/yarn.lock b/yarn.lock index 357654c..54f598c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1353,6 +1353,38 @@ resolved "https://registry.yarnpkg.com/@formatjs/macro/-/macro-0.2.6.tgz#eb173658d803416a43210778b2f5c04c5a240bb6" 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": version "16.11.0" 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" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/node@*": - version "12.12.22" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.22.tgz#b8d9eae3328b96910a373cf06ac8d3c5abe9c200" - integrity sha512-r5i93jqbPWGXYXxianGATOxTelkp6ih/U0WVnvaqAvTqM+0U6J3kw6Xk6uq/dWNRkEVw/0SLcO5ORXbVNz4FMQ== +"@types/node@*", "@types/node@^12.0.0": + version "12.12.24" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.24.tgz#d4606afd8cf6c609036b854360367d1b2c78931f" + integrity sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug== "@types/normalize-package-data@^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" integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= -core-js@^2.4.0: +core-js@^2.4.0, core-js@^2.6.5: version "2.6.11" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== @@ -12007,6 +12039,11 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: 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: version "5.5.12" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" @@ -13798,6 +13835,17 @@ w3c-hr-time@^1.0.1: dependencies: 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: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"