version: 2.1

defaults: &defaults
  parameters:
    react-dist-tag:
      description: The dist-tag of react to be used
      type: string
      default: stable
  environment:
    # expose it globally otherwise we have to thread it from each job to the install command
    REACT_DIST_TAG: << parameters.react-dist-tag >>
  working_directory: /tmp/material-ui
  docker:
    - image: circleci/node:10
# CircleCI has disabled the cache across forks for security reasons.
# Following their official statement, it was a quick solution, they
# are working on providing this feature back with appropriate security measures.
# https://discuss.circleci.com/t/saving-cache-stopped-working-warning-skipping-this-step-disabled-in-configuration/24423/21
#
# restore_repo: &restore_repo
#   restore_cache:
#     key: v1-repo-{{ .Branch }}-{{ .Revision }}

commands:
  install_js:
    steps:
      - run:
          name: View install environment
          command: |
            node --version
            yarn --version
      - run:
          name: Resolve react version
          command: |
            node scripts/use-react-dist-tag
            # log a patch for maintainers who want to check out this change
            git --no-pager diff HEAD
      - restore_cache:
          keys:
            - v2-yarn-sha-{{ checksum "yarn.lock" }}
            - v2-yarn-sha-
      - run:
          name: Install js dependencies
          command: yarn
  prepare_chrome_headless:
    steps:
      - run:
          name: Install dependencies for Chrome Headless
          # From https://github.com/GoogleChrome/puppeteer/blob/811415bc8c47f7882375629b57b3fe186ad61ed4/docs/troubleshooting.md#chrome-headless-doesnt-launch
          command: |
            sudo apt-get update
            sudo apt-get install -y --force-yes gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget

jobs:
  checkout:
    <<: *defaults
    steps:
      - checkout
      - install_js
      - run:
          name: Should not have any git not staged
          command: git diff --exit-code
      - run:
          name: Check for duplicated packages
          command: yarn deduplicate
      - save_cache:
          key: v2-yarn-sha-{{ checksum "yarn.lock" }}
          paths:
            - ~/.cache/yarn/v4
  test_unit:
    <<: *defaults
    steps:
      - checkout
      - install_js
      - run:
          name: Tests fake browser
          command: yarn test:coverage
      - run:
          name: Check coverage generated
          command: |
            if ! [[ -s coverage/lcov.info ]]
            then
              exit 1
            fi
      - run:
          name: material-ui-icons
          command: |
            # latest commit
            LATEST_COMMIT=$(git rev-parse HEAD)

            # latest commit where packages/material-ui-icons was changed
            FOLDER_COMMIT=$(git log -1 --format=format:%H --full-diff packages/material-ui-icons)

            if [ $FOLDER_COMMIT = $LATEST_COMMIT ]; then
              echo "changes, let's run the tests"
              yarn workspace @material-ui/icons build:typings
              yarn workspace @material-ui/icons test:built-typings
            else
              echo "no changes"
            fi
      - run:
          name: Coverage
          command: bash <(curl -s https://codecov.io/bash) -Z -C $CIRCLE_SHA1
  test_static:
    <<: *defaults
    steps:
      - checkout
      - install_js
      - run:
          name: '`yarn prettier` changes committed?'
          command: yarn prettier check-changed
      - run:
          name: Generate PropTypes
          command: yarn proptypes --disable-cache
      - run:
          name: '`yarn proptypes` changes committed?'
          command: git diff --exit-code
      - run:
          name: Generate the documentation
          command: yarn docs:api
      - run:
          name: '`yarn docs:api` changes committed?'
          command: git diff --exit-code
      - run:
          name: Lint
          command: yarn lint:ci
      - run:
          name: '`yarn extract-error-codes` changes committed?'
          command: |
            yarn extract-error-codes
            git diff --exit-code
      - run:
          name: Lint JSON
          command: yarn --silent jsonlint
  test_types:
    <<: *defaults
    steps:
      - checkout
      - install_js
      - run:
          name: Transpile TypeScript demos
          command: yarn docs:typescript:formatted --disable-cache
      - run:
          name: '`yarn docs:typescript:formatted` changes committed?'
          command: git add -A && git diff --exit-code --staged
      - run:
          name: Tests TypeScript definitions
          command: yarn typescript
  test_types_next:
    <<: *defaults
    steps:
      - checkout
      - run:
          name: Resolve typescript version
          environment:
            TYPESCRIPT_DIST_TAG: next
          command: |
            node scripts/use-typescript-dist-tag
            # log a patch for maintainers who want to check out this change
            git --no-pager diff HEAD
      - install_js
      - run:
          name: Tests TypeScript definitions
          command: |
            # ignore build failures
            # it's expected that typescript@next fails since the lines of the errors
            # change frequently. This build is monitored regardless of its status
            set +e
            # we want to see errors in all packages.
            # without --no-bail we only see at most a single failing package
            yarn typescript --no-bail
            exit 0
  test_browser:
    <<: *defaults
    steps:
      - checkout
      - install_js
      - prepare_chrome_headless
      - run:
          name: Tests real browsers
          command: yarn test:karma
      - store_artifacts:
          # hardcoded in karma-webpack
          path: /tmp/_karma_webpack_
          destination: artifact-file
      - run:
          name: Can we generate the @material-ui/core umd build?
          command: yarn workspace @material-ui/core build:umd
      - run:
          name: Test umd release
          command: yarn test:umd
  test_regressions:
    <<: *defaults
    docker:
      - image: circleci/node:10
      - image: selenium/standalone-chrome:3.11.0
    steps:
      - checkout
      - install_js
      - run:
          name: Visual regression tests
          command: |
            DOCKER_TEST_URL=http://$(ip addr show lo | grep "inet\b" | awk '{print $2}' | cut -d/ -f1):3090 yarn test:regressions
            yarn argos
workflows:
  version: 2
  pipeline:
    jobs:
      - checkout
      - test_unit:
          requires:
            - checkout
      - test_static:
          requires:
            - checkout
      - test_types:
          requires:
            - checkout
      - test_browser:
          requires:
            - checkout
      - test_regressions:
          requires:
            - test_unit
            - test_static
            - test_types
            - test_browser
  react-next:
    triggers:
      - schedule:
          cron: '0 0 * * *'
          filters:
            branches:
              only:
                - master
    jobs:
      - test_unit:
          react-dist-tag: next
      - test_browser:
          react-dist-tag: next
      - test_regressions:
          requires:
            - test_unit
            - test_browser
          react-dist-tag: next
  typescript-next:
    triggers:
      - schedule:
          cron: '0 0 * * *'
          filters:
            branches:
              only:
                - master
    jobs:
      - test_types_next
