version: 2.1 ### ABOUT # # This configuration powers our Circleci.io integration # # Note: # Netlify works independently from this configuration to # create pull request previews and to update `https://docs.ohif.org` ### ## https://github.com/cypress-io/circleci-orb ## orbs: codecov: codecov/codecov@1.0.5 cypress: cypress-io/cypress@3.3.1 executors: cypress-custom: description: | Single Docker container used to run Cypress Tests docker: - image: cimg/node:<< parameters.node-version >>-browsers parameters: node-version: default: '18.16.1' description: | The version of Node to run your tests with. type: string defaults: &defaults docker: - image: cimg/node:18.18 environment: TERM: xterm # Enable colors in term QUICK_BUILD: true working_directory: ~/repo jobs: ### # Workflow: PR_CHECKS ### UNIT_TESTS: <<: *defaults resource_class: large steps: # Update yarn - run: yarn -v - run: node --version # Checkout code and ALL Git Tags - checkout - restore_cache: name: Restore Yarn and Cypress Package Cache keys: # when lock file changes, use increasingly general patterns to restore cache - yarn-packages-{{ checksum "yarn.lock" }} - yarn-packages- - run: name: Install Dependencies command: yarn install --frozen-lockfile - save_cache: name: Save Yarn Package Cache paths: - ~/.cache ## Cache yarn and Cypress key: yarn-packages-{{ checksum "yarn.lock" }} # RUN TESTS - run: name: 'JavaScript Test Suite' command: yarn run test:unit:ci # platform/app - run: name: 'VIEWER: Combine report output' command: | viewerCov="/home/circleci/repo/platform/app/coverage" touch "${viewerCov}/reports" cat "${viewerCov}/clover.xml" >> "${viewerCov}/reports" echo "\<<\<<\<< EOF" >> "${viewerCov}/reports" cat "${viewerCov}/lcov.info" >>"${viewerCov}/reports" echo "\<<\<<\<< EOF" >> "${viewerCov}/reports" - codecov/upload: file: '/home/circleci/repo/platform/app/coverage/reports' flags: 'viewer' # PLATFORM/CORE - run: name: 'CORE: Combine report output' command: | coreCov="/home/circleci/repo/platform/core/coverage" touch "${coreCov}/reports" cat "${coreCov}/clover.xml" >> "${coreCov}/reports" echo "\<<\<<\<< EOF" >> "${coreCov}/reports" cat "${coreCov}/lcov.info" >> "${coreCov}/reports" echo "\<<\<<\<< EOF" >> "${coreCov}/reports" - codecov/upload: file: '/home/circleci/repo/platform/core/coverage/reports' flags: 'core' ### # Workflow: DEPLOY ### BUILD: <<: *defaults resource_class: large steps: # Checkout code and ALL Git Tags - checkout - restore_cache: name: Restore Yarn and Cypress Package Cache keys: # when lock file changes, use increasingly general patterns to restore cache - yarn-packages-{{ checksum "yarn.lock" }} - yarn-packages- - run: name: Install Dependencies command: yarn install --frozen-lockfile - save_cache: name: Save Yarn Package Cache paths: - ~/.cache ## Cache yarn and Cypress key: yarn-packages-{{ checksum "yarn.lock" }} # Build & Test - run: name: 'Perform the versioning before build' command: node ./version.mjs - run: name: 'Build the OHIF Viewer' command: yarn run build no_output_timeout: 45m - run: name: 'Upload SourceMaps, Send Deploy Notification' command: | # export FILE_1=$(find ./build/static/js -type f -name "2.*.js" -exec basename {} \;) # export FILE_MAIN=$(find ./build/static/js -type f -name "main.*.js" -exec basename {} \;) # export FILE_RUNTIME_MAIN=$(find ./build/static/js -type f -name "runtime~main.*.js" -exec basename {} \;) # curl https://api.rollbar.com/api/1/sourcemap -F source_map=@build/static/js/$FILE_1.map -F access_token=$ROLLBAR_TOKEN -F version=$CIRCLE_SHA1 -F minified_url=https://$GOOGLE_STORAGE_BUCKET/static/js/$FILE_1 # curl https://api.rollbar.com/api/1/sourcemap -F source_map=@build/static/js/$FILE_MAIN.map -F access_token=$ROLLBAR_TOKEN -F version=$CIRCLE_SHA1 -F minified_url=https://$GOOGLE_STORAGE_BUCKET/static/js/$FILE_MAIN # curl https://api.rollbar.com/api/1/sourcemap -F source_map=@build/static/js/$FILE_RUNTIME_MAIN.map -F access_token=$ROLLBAR_TOKEN -F version=$CIRCLE_SHA1 -F minified_url=https://$GOOGLE_STORAGE_BUCKET/static/js/$FILE_RUNTIME_MAIN curl --request POST https://api.rollbar.com/api/1/deploy/ -F access_token=$ROLLBAR_TOKEN -F environment=$GOOGLE_STORAGE_BUCKET -F revision=$CIRCLE_SHA1 -F local_username=CircleCI # Persist :+1: - persist_to_workspace: root: ~/repo paths: - platform/app/dist - Dockerfile - version.txt - commit.txt - version.json # just to make sure later on we can publish them BUILD_PACKAGES_QUICK: <<: *defaults resource_class: large steps: - run: yarn -v # Checkout code and ALL Git Tags - checkout - attach_workspace: at: ~/repo # Use increasingly general patterns to restore cache - restore_cache: name: Restore Yarn and Cypress Package Cache keys: - yarn-packages-{{ checksum "yarn.lock" }} - yarn-packages- - run: name: Install Dependencies command: yarn install --frozen-lockfile - save_cache: name: Save Yarn Package Cache paths: - ~/.cache/yarn key: yarn-packages-{{ checksum "yarn.lock" }} - run: name: Avoid hosts unknown for github command: | rm -rf ~/.ssh mkdir ~/.ssh/ echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config git config --global user.email "danny.ri.brown+ohif-bot@gmail.com" git config --global user.name "ohif-bot" - run: name: Authenticate with NPM registry command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc - run: name: build half of the packages (to avoid out of memory in circleci) command: | yarn run build:package-all - run: name: build the other half of the packages command: | yarn run build:package-all-1 ### # Workflow: RELEASE ### NPM_PUBLISH: <<: *defaults resource_class: large steps: - run: yarn -v # Checkout code and ALL Git Tags - checkout - attach_workspace: at: ~/repo # Use increasingly general patterns to restore cache - restore_cache: name: Restore Yarn and Cypress Package Cache keys: - yarn-packages-{{ checksum "yarn.lock" }} - yarn-packages- - run: name: Install Dependencies command: yarn install --frozen-lockfile - save_cache: name: Save Yarn Package Cache paths: - ~/.cache/yarn key: yarn-packages-{{ checksum "yarn.lock" }} - run: name: Avoid hosts unknown for github command: | rm -rf ~/.ssh mkdir ~/.ssh/ echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config git config --global user.email "danny.ri.brown+ohif-bot@gmail.com" git config --global user.name "ohif-bot" - run: name: Authenticate with NPM registry command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc - run: name: build half of the packages (to avoid out of memory in circleci) command: | yarn run build:package-all - run: name: build the other half of the packages command: | yarn run build:package-all-1 - run: name: increase min time out command: | npm config set fetch-retry-mintimeout 20000 - run: name: increase max time out command: | npm config set fetch-retry-maxtimeout 120000 - run: name: publish package versions command: | node ./publish-version.mjs - run: name: Again set the NPM registry (was deleted in the version script) command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc - run: name: publish package dist command: | node ./publish-package.mjs - persist_to_workspace: root: ~/repo paths: - . DOCKER_RELEASE_PUBLISH: <<: *defaults resource_class: large steps: - attach_workspace: at: ~/repo - setup_remote_docker: docker_layer_caching: false - run: name: Build and push Docker image from the release branch command: | # This file will exist if a new version was published by # our command in the previous job. if [[ ! -e version.txt ]]; then exit 0 else # Remove npm config rm -f ./.npmrc # Set our version number using vars export IMAGE_VERSION=$(cat version.txt) export IMAGE_VERSION_FULL=v$IMAGE_VERSION echo $IMAGE_VERSION echo $IMAGE_VERSION_FULL # Build our image, auth, and push docker build --tag ohif/app:$IMAGE_VERSION_FULL --tag ohif/app:latest . echo $DOCKER_PWD | docker login -u $DOCKER_LOGIN --password-stdin docker push ohif/app:$IMAGE_VERSION_FULL docker push ohif/app:latest fi DOCKER_BETA_PUBLISH: <<: *defaults resource_class: large steps: - attach_workspace: at: ~/repo - setup_remote_docker: docker_layer_caching: false - run: name: Build and push Docker image from the master branch (beta releases) command: | echo $(ls -l) # This file will exist if a new version was published by # our command in the previous job. if [[ ! -e version.txt ]]; then echo "don't have version txt" exit 0 else echo "Building and pushing Docker image from the master branch (beta releases)" rm -f ./.npmrc # Set our version number using vars export IMAGE_VERSION=$(cat version.txt) export IMAGE_VERSION_FULL=v$IMAGE_VERSION echo $IMAGE_VERSION echo $IMAGE_VERSION_FULL # Build our image, auth, and push echo "starting docker build" docker build --tag ohif/app:$IMAGE_VERSION_FULL . echo $DOCKER_PWD | docker login -u $DOCKER_LOGIN --password-stdin echo "starting docker push" docker push ohif/app:$IMAGE_VERSION_FULL fi # This is copied from the Cypress orb since the default for cypress/run is node 16 and # we migrated to 18 CYPRESS_CUSTOM_RUN: description: | A single, complete job to run Cypress end-to-end tests in your application. executor: cypress-custom parallelism: << parameters.parallelism >> parameters: cypress-cache-key: default: cypress-cache-{{ arch }}-{{ checksum "package.json" }} description: Cache key used to cache the Cypress binary. type: string cypress-cache-path: default: ~/.cache/Cypress description: | By default, this will cache the '~/.cache/Cypress' directory so that the Cypress binary is cached. You can override this by providing your own cache path. type: string cypress-command: default: npx cypress run description: Command used to run your Cypress tests type: string include-branch-in-node-cache-key: default: false description: | If true, this cache will only apply to runs within the same branch. (Adds -{{ .Branch }}- to the node cache key) type: boolean install-browsers: default: false description: | Cypress runs by default in the Electron browser. Use this flag to install additional browsers to run your tests in. This is only needed if you are passing the `--browser` flag in your `cypress-command`. This parameter leverages the `circleci/browser-tools` orb and includes Chrome and FireFox. If you need additional browser support you can set this to false and use an executor with a docker image that includes the browsers of your choosing. See https://hub.docker.com/r/cypress/browsers/tags type: boolean install-command: default: '' description: Overrides the default NPM command (npm ci) type: string node-cache-version: default: v1 description: Change the default node cache version if you need to clear the cache for any reason. type: string package-manager: default: npm description: Select the default node package manager to use. NPM v5+ Required. enum: - npm - yarn - yarn-berry type: enum parallelism: default: 4 description: | Number of Circle machines to use for load balancing, min 1 (requires `parallel` and `record` flags in your `cypress-command`) type: integer post-install: default: '' description: | Additional commands to run after running install but before verifying Cypress and saving cache. type: string start-command: default: '' description: Command used to start your local dev server for Cypress to tests against type: string working-directory: default: '' description: Directory containing package.json type: string resource_class: large steps: - cypress/install: cypress-cache-key: << parameters.cypress-cache-key >> cypress-cache-path: << parameters.cypress-cache-path >> include-branch-in-node-cache-key: << parameters.include-branch-in-node-cache-key >> install-browsers: << parameters.install-browsers >> install-command: << parameters.install-command >> node-cache-version: << parameters.node-cache-version >> package-manager: << parameters.package-manager >> post-install: << parameters.post-install >> working-directory: << parameters.working-directory >> - cypress/run-tests: cypress-command: << parameters.cypress-command >> start-command: << parameters.start-command >> working-directory: << parameters.working-directory >> workflows: PR_CHECKS: jobs: - BUILD_PACKAGES_QUICK: filters: branches: ignore: master - UNIT_TESTS: requires: - BUILD_PACKAGES_QUICK - CYPRESS_CUSTOM_RUN: name: 'Cypress Tests' context: cypress matrix: parameters: start-command: - yarn run test:data && yarn run test:e2e:serve install-browsers: - true cypress-command: - 'npx wait-on@latest http://localhost:3000 && cd platform/app && npx cypress run --record --browser chrome --parallel' package-manager: - 'yarn' cypress-cache-key: - 'yarn-packages-{{ checksum "yarn.lock" }}' cypress-cache-path: - '~/.cache/Cypress' requires: - BUILD_PACKAGES_QUICK # PR_OPTIONAL_VISUAL_TESTS: # jobs: # - AWAIT_APPROVAL: # type: approval # # Update hub.docker.org # - cypress/run: # name: 'Generate Percy Snapshots' # executor: cypress/browsers-chrome76 # browser: chrome # pre-steps: # - run: 'rm -rf ~/.yarn && yarn -v && yarn global add wait-on' # yarn: true # store_artifacts: false # working_directory: platform/app # build: # yarn test:data && npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js # yarn run build # # start server --> verify running --> percy + chrome + cypress # command: yarn run test:e2e:dist # cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}' # no-workspace: true # Don't persist workspace # post-steps: # - store_artifacts: # path: platform/app/cypress/screenshots # - store_artifacts: # path: platform/app/cypress/videos # requires: # - AWAIT_APPROVAL # Our master branch deploys to viewer-dev.ohif.org, the viewer.ohif.org is # deployed from the release branch which is more stable and less frequently updated. DEPLOY_MASTER: jobs: - BUILD: filters: branches: only: master - NPM_PUBLISH: requires: - BUILD - DOCKER_BETA_PUBLISH: requires: - NPM_PUBLISH # Our release branch deploys to viewer.ohif.org and is more stable and less # frequently updated after being tested in the staging environment. DEPLOY_RELEASE: jobs: - BUILD: filters: branches: only: /^release\/.*/ - HOLD_FOR_APPROVAL: type: approval requires: - BUILD - NPM_PUBLISH: requires: - HOLD_FOR_APPROVAL - DOCKER_RELEASE_PUBLISH: requires: - NPM_PUBLISH ### # Unit and E2E tests have already run for PR_CHECKS # Re-running should not gain us any confidence here ### # RELEASE: # jobs: # - NPM_PUBLISH: # filters: # branches: # only: master # - DOCS_PUBLISH: # filters: # branches: # only: master # # Update base branch snapshots # # and record a Cypress dashboard test run # - cypress/run: # name: 'Generate Percy Snapshots' # executor: cypress/browsers-chrome76 # browser: chrome # pre-steps: # - run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v && yarn global # add wait-on' # Use yarn latest # yarn: true # store_artifacts: false # working_directory: platform/app # build: # npx cross-env QUICK_BUILD=true APP_CONFIG=config/e2e.js yarn run # build # # start server --> verify running --> percy + chrome + cypress # command: yarn run test:e2e:dist # cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}' # no-workspace: true # Don't persist workspace # post-steps: # - store_artifacts: # path: platform/app/cypress/screenshots # - store_artifacts: # path: platform/app/cypress/videos # - store_test_results: # path: platform/app/cypress/results # filters: # branches: # only: master # - DOCKER_MASTER_PUBLISH: # requires: # - NPM_PUBLISH