version: 2.1

orbs:
  browser-tools: circleci/browser-tools@1.4.1

aliases:
  - &docker-node-image
    - image: cimg/node:18.15

  - &docker-node-browsers-image
    - image: cimg/node:18.15-browsers
      environment:
        CHROME_BIN: "/usr/bin/google-chrome"

  - &restore-node-modules-cache
    name: Restore node_modules cache
    key: v7-yarn-deps-{{ checksum "yarn.lock" }}

  - &restore-yarn-cache
    name: Restore yarnpkg cache
    key: v7-yarn-cache

  - &save-node-modules-cache
    name: Save node_modules cache
    paths:
      - node_modules
    key: v7-yarn-deps-{{ checksum "yarn.lock" }}

  - &save-yarn-cache
    name: Save yarnpkg cache
    paths:
      - ~/.cache/yarn
    key: v7-yarn-cache

references:
  reports_path: &reports_path
    path: ./reports

jobs:
  checkout-code:
    docker: *docker-node-image
    steps:
      - checkout
      - restore_cache: *restore-yarn-cache
      - restore_cache: *restore-node-modules-cache
      - run: yarn install --non-interactive --cache-folder ~/.cache/yarn
      - run:
          name: Check if yarn.lock changed during install
          command: git diff --exit-code
      - save_cache: *save-node-modules-cache
      - save_cache: *save-yarn-cache
      - persist_to_workspace:
          root: "."
          paths: [packages/*/node_modules]

  clean-lockfile:
    docker: *docker-node-image
    steps:
      - checkout
      - restore_cache: *restore-node-modules-cache
      - run: ./scripts/verifyCleanLockfile.sh

  compile:
    docker: *docker-node-image
    resource_class: large
    steps:
      - checkout
      - restore_cache: *restore-node-modules-cache
      - attach_workspace: { at: "." }
      - run: yarn compile
      - persist_to_workspace:
          root: "."
          paths:
            - packages/*/lib
            - packages/*/src/generated
            - packages/icons/src/generated-icons

  format-check:
    docker: *docker-node-image
    environment:
      JUNIT_REPORT_PATH: reports
      NODE_ENV: test
    steps:
      - checkout
      - restore_cache: *restore-node-modules-cache
      - attach_workspace: { at: "." }
      - run: yarn format-check

  lint:
    docker: *docker-node-image
    resource_class: large
    environment:
      JUNIT_REPORT_PATH: reports
      NODE_ENV: test
    steps:
      - checkout
      - restore_cache: *restore-node-modules-cache
      - attach_workspace: { at: "." }
      - run: mkdir -p ./reports/eslint ./reports/stylelint
      # types and lint rules should already be compiled since this job depends on the 'compile' job
      - run: yarn lint
      - store_test_results: { path: ./reports }
      - store_artifacts: { path: ./reports }

  dist:
    docker: *docker-node-image
    resource_class: large
    environment:
      NODE_ENV: test
    steps:
      - checkout
      - restore_cache: *restore-node-modules-cache
      - attach_workspace: { at: "." }
      - run: yarn dist
      - persist_to_workspace:
          root: "."
          paths: [packages/*/lib, packages/*/dist]

  test-node-libs:
    docker: *docker-node-image
    environment:
      JUNIT_REPORT_PATH: reports
    parallelism: 2
    steps:
      - checkout
      - restore_cache: *restore-node-modules-cache
      - attach_workspace: { at: "." }
      - run: mkdir -p ./reports
      - run:
          command: |
            case $CIRCLE_NODE_INDEX in \
            0) yarn lerna run --scope "@blueprintjs/eslint-plugin" test ;; \
            1) yarn lerna run --scope "@blueprintjs/stylelint-plugin" test ;; \
            esac
          when: always
      - store_test_results: { path: ./reports }
      - store_artifacts: { path: ./reports }

  test-react-16: &test-react
    docker: *docker-node-browsers-image
    environment:
      JUNIT_REPORT_PATH: reports
      NODE_ENV: test
    parallelism: 8
    steps:
      - checkout
      - restore_cache: *restore-node-modules-cache
      - attach_workspace: { at: "." }
      - browser-tools/install-chrome
      - browser-tools/install-chromedriver
      - run:
          name: Verify Chrome browser installed
          command: |
            google-chrome --version
            chromedriver --version
      - run: mkdir -p ./reports
      - run:
          # split karma tests into containers because they can take up a lot of memory
          # running them in one container caused Karma to time out frequently
          # see https://github.com/palantir/blueprint/issues/3616
          command: |
            case $CIRCLE_NODE_INDEX in \
            0) yarn lerna run test:typeCheck ;; \
            1) yarn lerna run --scope "@blueprintjs/core" test:karma ;; \
            2) yarn lerna run --scope "@blueprintjs/datetime" test:karma ;; \
            3) yarn lerna run --scope "@blueprintjs/datetime2" test:karma ;; \
            4) yarn lerna run --scope "@blueprintjs/popover2" test:karma ;; \
            5) yarn lerna run --scope "@blueprintjs/select" test:karma ;; \
            6) yarn lerna run --scope "@blueprintjs/table" test:karma ;; \
            7) yarn lerna run --scope "@blueprintjs/timezone" test:karma ;; \
            esac
          when: always
      - store_test_results: { path: ./reports }
      - store_artifacts: { path: ./reports }

  test-iso-react-16: &test-iso
    docker: *docker-node-image
    environment:
      JUNIT_REPORT_PATH: reports
    steps:
      - checkout
      - restore_cache: *restore-node-modules-cache
      - attach_workspace: { at: "." }
      - run: mkdir ./reports
      - run: yarn lerna run test:iso
      - store_test_results: { path: ./reports }
      - store_artifacts: { path: ./reports }

  deploy-preview:
    docker: *docker-node-image
    steps:
      - checkout
      - restore_cache: *restore-node-modules-cache
      - attach_workspace: { at: "." }
      - store_artifacts: { path: packages/docs-app/dist }
      - store_artifacts: { path: packages/landing-app/dist }
      - store_artifacts: { path: packages/table-dev-app/dist }
      - store_artifacts: { path: packages/demo-app/dist }
      - run: ./scripts/submit-preview-comment.sh

  deploy-npm:
    docker: *docker-node-image
    steps:
      - checkout
      - restore_cache: *restore-node-modules-cache
      - attach_workspace: { at: "." }
      - run: ./scripts/publish-npm-semver-tagged

workflows:
  version: 2
  compile_lint_test_dist_deploy:
    jobs:
      - checkout-code
      - clean-lockfile:
          requires: [checkout-code]
      - compile:
          requires: [checkout-code]
      - format-check:
          requires: [checkout-code]
      - lint:
          requires: [compile]
      - dist:
          requires: [compile]
      - test-node-libs:
          requires: [compile]
      - test-react-16:
          requires: [compile]
      - test-iso-react-16:
          requires: [compile]
      - deploy-preview:
          requires: [dist]
      - deploy-npm:
          requires:
            [
              dist,
              lint,
              test-node-libs,
              test-react-16,
              test-iso-react-16,
            ]
          filters:
            branches:
              only:
                - develop
                - next
                - /^release\/.*/
