version: 2.1

executors:
  sb_node_14_classic:
    parameters:
      class:
        description: The Resource class
        type: enum
        enum: ['small', 'medium', 'medium+', 'large', 'xlarge']
        default: 'medium'
    working_directory: /tmp/storybook
    docker:
      - image: cimg/node:14.19
        environment:
          NODE_OPTIONS: --max_old_space_size=3076
    resource_class: <<parameters.class>>
  sb_node_14_browsers:
    parameters:
      class:
        description: The Resource class
        type: enum
        enum: ['small', 'medium', 'medium+', 'large', 'xlarge']
        default: 'medium'
    working_directory: /tmp/storybook
    docker:
      - image: cimg/node:14.19-browsers
        environment:
          NODE_OPTIONS: --max_old_space_size=3076
    resource_class: <<parameters.class>>
  sb_cypress_8_node_14:
    parameters:
      class:
        description: The Resource class
        type: enum
        enum: ['small', 'medium', 'medium+', 'large', 'xlarge']
        default: 'medium'
    working_directory: /tmp/storybook
    docker:
      # ⚠️ The Cypress docker image is based on Node.js one so be careful when updating it because it can also
      # cause an upgrade of Node.js version too. Cypress 8.5 image is based on Node.js 14
      - image: cypress/included:8.7.0
        environment:
          NODE_OPTIONS: --max_old_space_size=3076
    resource_class: <<parameters.class>>

orbs:
  git-shallow-clone: guitarrapc/git-shallow-clone@2.0.3
  browser-tools: circleci/browser-tools@1.4.0

commands:
  ensure-pr-is-labeled-with:
    description: 'A command looking for the labels set on the PR associated to this workflow and checking it contains the label given as parameter'
    parameters:
      label:
        type: string
    steps:
      - run:
          name: Check if PR is labeled with "<< parameters.label >>"
          command: |
            apt-get -y install jq

            PR_NUMBER=$(echo "$CIRCLE_PULL_REQUEST" | sed "s/.*\/pull\///")
            echo "PR_NUMBER: $PR_NUMBER"

            API_GITHUB="https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME"
            PR_REQUEST_URL="$API_GITHUB/pulls/$PR_NUMBER"
            PR_RESPONSE=$(curl -H "Authorization: token $GITHUB_TOKEN_STORYBOOK_BOT_READ_REPO" "$PR_REQUEST_URL")


            if [ $(echo $PR_RESPONSE | jq '.labels | map(select(.name == "<< parameters.label >>")) | length') -ge 1 ] ||
               ( [ $(echo $PR_RESPONSE | jq '.labels | length') -ge 1 ] && [ "<< parameters.label >>" == "*" ])
            then
              echo "🚀 The PR is labelled with '<< parameters.label >>', job will continue!"
            else
              echo "🏁 The PR isn't labelled with '<< parameters.label >>' so this job will end at the current step."
              circleci-agent step halt
            fi

jobs:
  build:
    executor:
      class: xlarge
      name: sb_node_14_classic
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - restore_cache:
          name: Restore Yarn cache
          keys:
            - build-yarn-2-cache-v3--{{ checksum "code/yarn.lock" }}
      - run:
          name: Install dependencies
          command: |
            cd code
            yarn install --immutable
      - run:
          name: Install script dependencies
          command: |
            cd scripts
            yarn install --immutable
      - run:
          name: Bootstrap
          command: |
            cd code
            yarn bootstrap --build
            git diff --exit-code
      - save_cache:
          name: Save Yarn cache
          key: build-yarn-2-cache-v3--{{ checksum "code/yarn.lock" }}
          paths:
            - ~/.yarn/berry/cache
      - persist_to_workspace:
          root: .
          paths:
            - code/node_modules
            - scripts/node_modules
            - code/examples
            - code/node_modules
            - code/addons
            - code/frameworks
            - code/lib
            - code/renderers
            - code/presets
  chromatic:
    executor: sb_node_14_browsers
    parallelism: 15
    steps:
      # Keep using default checkout because Chromatic needs some git history to work properly
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: chromatic
          command: |
            cd code
            yarn run-chromatics
  examples:
    executor:
      class: medium+
      name: sb_node_14_browsers
    parallelism: 15
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: examples
          command: |
            cd code
            yarn build-storybooks --all
      - persist_to_workspace:
          root: .
          paths:
            - code/built-storybooks
  publish:
    executor:
      class: medium
      name: sb_node_14_classic
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: running local registry
          command: |
            cd code
            yarn local-registry --publish
      - persist_to_workspace:
          root: .
          paths:
            - .verdaccio-cache
  e2e-tests-extended:
    executor:
      class: medium
      name: sb_cypress_8_node_14
    parallelism: 14
    steps:
      - when:
          condition:
            and:
              - not:
                  equal: [main, << pipeline.git.branch >>]
              - not:
                  equal: [next, << pipeline.git.branch >>]
          steps:
            - ensure-pr-is-labeled-with:
                label: 'run e2e extended test suite'
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: running local registry
          command: |
            cd code
            yarn local-registry --port 6000 --open
          background: true
      - run:
          name: Wait for registry
          command: |
            cd code
            yarn wait-on http://localhost:6000
      - run:
          name: Run E2E (extended) tests
          command: |
            cd code
            yarn test:e2e-framework --clean --all --skip angular --skip angular12 --skip vue3 --skip web_components_typescript --skip cra --skip react
          no_output_timeout: 5m
      - store_artifacts:
          path: /tmp/cypress-record
          destination: cypress
  e2e-tests-core:
    executor:
      class: large
      name: sb_cypress_8_node_14
    parallelism: 8
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Running local registry
          command: |
            cd code
            yarn local-registry --port 6000 --open
          background: true
      - run:
          name: Wait for registry
          command: |
            cd code
            yarn wait-on http://localhost:6000
      - run:
          name: Run E2E (core) tests
          # Do not test CRA here because it's done in PnP part
          # TODO: Remove `web_components_typescript` as soon as Lit 2 stable is released
          command: |
            cd code
            yarn test:e2e-framework vue3 angular130 angular13 angular12 web_components_typescript web_components_lit2 react react_legacy_root_api
          no_output_timeout: 5m
      - run:
          name: prep artifacts
          when: always
          command: zip -r /tmp/storybook-e2e-testing-out.zip /tmp/storybook-e2e-testing
      - store_artifacts:
          path: /tmp/cypress-record
          destination: cypress
      - store_artifacts:
          path: /tmp/storybook-e2e-testing-out.zip
          destination: e2e
  # NOTE: this currently tests each story in docs mode, which doesn't make sense any more as stories
  #   can no longer run in docs mode. Instead we should probably change the test runner to test each
  #   docs entry if you run it in `VIEW_MODE=docs`
  # e2e-tests-sb-docs:
  #   executor:
  #     class: large
  #     name: sb_cypress_8_node_14
  #   parallelism: 2
  #   steps:
  #     - git-shallow-clone/checkout_advanced:
  #         clone_options: '--depth 1 --verbose'
  #     - attach_workspace:
  #         at: .
  #     - run:
  #         name: Running local registry
  #         command: yarn local-registry --port 6000 --open
  #         background: true
  #     - run:
  #         name: Wait for registry
  #         command: yarn wait-on http://localhost:6000
  #     - run:
  #         name: Run smoke tests
  #         command: yarn test:e2e-framework angular_modern_inline_rendering --test-runner --docs-mode
  #         no_output_timeout: 5m
  cra-bench:
    executor:
      class: medium
      name: sb_cypress_8_node_14
    working_directory: /tmp/storybook
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: install playright
          command: |
            cd code
            npx playwright install
      - run:
          name: Running local registry
          command: |
            cd code
            yarn local-registry --port 6000 --open
          background: true
      - run:
          name: Wait for registry
          command: |
            cd code
            yarn wait-on http://localhost:6000
      - run:
          name: set up cra repro, skip tests
          command: |
            cd code
            node ./lib/cli/bin/index.js repro -t cra --e2e ../cra-bench
      - run:
          name: Run @storybook/bench on repro
          command: |
            cd ./cra-bench
            npx @storybook/bench@1.0.0--canary.11.52d1ee7.1 'echo noop' --label cra
  e2e-tests-pnp:
    executor:
      class: medium
      name: sb_cypress_8_node_14
    working_directory: /tmp/storybook
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Running local registry
          command: |
            cd code
            yarn local-registry --port 6000 --open
          background: true
      - run:
          name: Wait for registry
          command: |
            cd code
            yarn wait-on http://localhost:6000
      - run:
          name: run e2e tests cra
          command: |
            cd code
            yarn test:e2e-framework --pnp cra
      # - run:
      #     name: run e2e tests vue
      #     command: yarn test:e2e-framework --pnp sfcVue
      - run:
          name: prep artifacts
          when: always
          command: zip -r /tmp/storybook-e2e-testing-out.zip /tmp/storybook-e2e-testing
      - store_artifacts:
          path: /tmp/cypress-record
          destination: cypress
      - store_artifacts:
          path: /tmp/storybook-e2e-testing-out.zip
          destination: e2e
  e2e-tests-examples:
    executor:
      class: small
      name: sb_cypress_8_node_14
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: running example
          command: |
            cd code
            yarn serve-storybooks
          background: true
      - run:
          name: await running examples
          command: |
            cd code
            yarn await-serve-storybooks
      - run:
          name: cypress run
          command: |
            cd code
            yarn test:e2e-examples
      - store_artifacts:
          path: /tmp/cypress-record
          destination: cypress
  smoke-tests:
    executor:
      class: medium+
      name: sb_node_14_browsers
    environment:
      # Disable ESLint when running smoke tests to improve perf + As of CRA 4.0.3, CRA kitchen sinks are throwing
      # because of some ESLint warnings, related to: https://github.com/facebook/create-react-app/pull/10590
      DISABLE_ESLINT_PLUGIN: 'true'
    parallelism: 16
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: smoke tests
          command: |
            cd code
            yarn smoketest-storybooks --all
  lint:
    executor:
      class: medium
      name: sb_node_14_classic
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Lint
          command: |
            cd code
            yarn lint
  script-unit-tests:
    executor: sb_node_14_browsers
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Test
          command: |
            cd scripts
            yarn test --coverage --runInBand --ci
      - store_test_results:
          path: scripts/junit.xml
  unit-tests:
    executor: sb_node_14_browsers
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Test
          command: |
            cd code
            yarn test --coverage --runInBand --ci
      - store_test_results:
          path: code/junit.xml
      - persist_to_workspace:
          root: .
          paths:
            - code/coverage
  coverage:
    executor:
      class: small
      name: sb_node_14_browsers
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Upload coverage
          command: |
            cd code
            yarn coverage

## new workflow
  create-sandboxes:
    executor:
      class: medium+
      name: sb_node_14_browsers
    # parallelism: 15
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Running local registry
          command: |
            cd code
            yarn local-registry --port 6000 --open
          background: true
      - run:
          name: Wait for registry
          command: |
            cd code
            yarn wait-on http://localhost:6000
      - run:
          name: Preparing Sandboxes
          command: |
            mkdir sandbox
            cd code
            yarn multiplex-templates --cadence ci --parallel --script "yarn sandbox --no-link --no-start --no-publish"
      - persist_to_workspace:
          root: .
          paths:
            - sandbox
  

workflows:
  test:
    jobs:
      - build
      - lint:
          requires:
            - build
      - examples:
          requires:
            - build
      - e2e-tests-examples:
          requires:
            - examples
      - smoke-tests:
          requires:
            - build
      - unit-tests:
          requires:
            - build
      - script-unit-tests:
          requires:
            - build
      - coverage:
          requires:
            - unit-tests
      - chromatic:
          requires:
            - examples
      - publish:
          requires:
            - build
      - e2e-tests-extended:
          requires:
            - publish
      - e2e-tests-core:
          requires:
            - publish
      - e2e-tests-pnp:
          requires:
            - publish
      - cra-bench:
          requires:
            - publish

## new workflow
      - create-sandboxes:
          requires:
            - publish
      