version: 2.1

executors:
  sb_node_16_classic:
    parameters:
      class:
        description: The Resource class
        type: enum
        enum: ['small', 'medium', 'medium+', 'large', 'xlarge']
        default: 'small'
    working_directory: /tmp/storybook
    docker:
      - image: cimg/node:16.17.1
        environment:
          NODE_OPTIONS: --max_old_space_size=3076
    resource_class: <<parameters.class>>
  sb_node_16_browsers:
    parameters:
      class:
        description: The Resource class
        type: enum
        enum: ['small', 'medium', 'medium+', 'large', 'xlarge']
        default: 'small'
    working_directory: /tmp/storybook
    docker:
      - image: cimg/node:16.17.1-browsers
        environment:
          NODE_OPTIONS: --max_old_space_size=3076
    resource_class: <<parameters.class>>
  sb_playwright:
    parameters:
      class:
        description: The Resource class
        type: enum
        enum: ['small', 'medium', 'medium+', 'large', 'xlarge']
        default: 'small'
    working_directory: /tmp/storybook
    docker:
      - image: mcr.microsoft.com/playwright:v1.27.0-focal
        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: large
      name: sb_node_16_classic
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - restore_cache:
          name: Restore Yarn cache
          keys:
            - build-yarn-2-cache-v4--{{ checksum "code/yarn.lock" }}--{{ checksum "scripts/yarn.lock" }}
      - run:
          name: Compile
          command: |
            yarn task --task compile --start-from=auto --no-link --debug
            git diff --exit-code
      - save_cache:
          name: Save Yarn cache
          key: build-yarn-2-cache-v4--{{ checksum "code/yarn.lock" }}--{{ checksum "scripts/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/ui
            - code/renderers
            - code/presets
  publish:
    executor:
      class: small
      name: sb_node_16_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
  cra-bench:
    executor:
      class: medium
      name: sb_playwright
    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 6001 --open
          background: true
      - run:
          name: Wait for registry
          command: |
            cd code
            yarn wait-on http://localhost:6001
      - run:
          name: set up cra repro, skip tests
          command: |
            cd code
            node ./lib/cli/bin/index.js repro-next cra/default-js --output ../../cra-bench
      - run:
          name: Run @storybook/bench on repro
          command: |
            cd ../cra-bench
            rm -rf node_modules
            mkdir node_modules
            npx -p @storybook/bench@0.7.6--canary.14.6702e4f.0 sb-bench 'yarn install' --label cra
      - run:
          name: prep artifacts
          when: always
          command: tar cvzf /tmp/sb-bench.tar.gz ../cra-bench
      - store_artifacts:
          path: /tmp/sb-bench.tar.gz
          destination: sb-bench.tar.gz
  react-vite-bench:
    executor:
      class: medium
      name: sb_playwright
    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 6001 --open
          background: true
      - run:
          name: Wait for registry
          command: |
            cd code
            yarn wait-on http://localhost:6001
      - run:
          name: set up react-vite repro, skip tests
          command: |
            cd code
            node ./lib/cli/bin/index.js repro-next react-vite/default-ts --output ../../react-vite-bench
      - run:
          name: Run @storybook/bench on repro
          command: |
            cd ../react-vite-bench
            rm -rf node_modules
            mkdir node_modules
            npx -p @storybook/bench@0.7.6--canary.14.6702e4f.0 sb-bench 'yarn install' --label react-vite
      - run:
          name: prep artifacts
          when: always
          command: tar cvzf /tmp/sb-bench.tar.gz ../react-vite-bench
      - store_artifacts:
          path: /tmp/sb-bench.tar.gz
          destination: sb-bench.tar.gz
  lint:
    executor:
      class: medium
      name: sb_node_16_classic
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Lint
          command: |
            cd code
            yarn lint
  check:
    executor:
      class: xlarge
      name: sb_node_16_classic
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Check
          command: |
            yarn task --task check --start-from=auto --no-link --debug
            git diff --exit-code
  script-unit-tests:
    executor: sb_node_16_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:
      class: medium+
      name: sb_node_16_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_16_browsers
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Upload coverage
          command: |
            cd code
            yarn coverage
  chromatic-internal-storybooks:
    executor:
      class: medium
      name: sb_node_16_browsers
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Running Chromatic
          command: |
            cd code
            yarn storybook:ui:chromatic
            yarn storybook:blocks:chromatic
      - store_test_results:
          path: test-results
  ## new workflow
  create-sandboxes:
    executor:
      class: medium
      name: sb_node_16_browsers
    parallelism: 9
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Creating Sandboxes
          command: yarn task --task sandbox --template $(yarn get-template ci create) --no-link --start-from=never --junit
      - persist_to_workspace:
          root: .
          paths:
            - sandbox
      - store_test_results:
          path: test-results
  smoke-test-sandboxes:
    executor:
      class: medium
      name: sb_node_16_browsers
    parallelism: 9
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Smoke Testing Sandboxes
          command: yarn task --task smoke-test --template $(yarn get-template ci smoke-test) --no-link --start-from=never --junit
      - store_test_results:
          path: test-results
  build-sandboxes:
    executor:
      class: medium+
      name: sb_node_16_browsers
    parallelism: 9
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Building Sandboxes
          command: yarn task --task build --template $(yarn get-template ci build) --no-link --start-from=never --junit
      - store_test_results:
          path: test-results
      - persist_to_workspace:
          root: .
          paths:
            - sandbox/*/storybook-static
  test-runner-sandboxes:
    executor:
      class: medium
      name: sb_playwright
    parallelism: 8
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Running Test Runner
          command: yarn task --task test-runner --template $(yarn get-template ci test-runner) --no-link --start-from=never --junit
      - store_test_results:
          path: test-results
  chromatic-sandboxes:
    executor:
      class: medium
      name: sb_node_16_browsers
    parallelism: 9
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Running Chromatic
          command: yarn task --task chromatic --template $(yarn get-template ci chromatic) --no-link --start-from=never --junit
      - store_test_results:
          path: test-results
  e2e-sandboxes:
    executor:
      class: medium
      name: sb_playwright
    parallelism: 9
    steps:
      - git-shallow-clone/checkout_advanced:
          clone_options: '--depth 1 --verbose'
      - attach_workspace:
          at: .
      - run:
          name: Running E2E Tests
          command: yarn task --task e2e-tests --template $(yarn get-template ci e2e-tests) --no-link --start-from=never --junit
      - store_test_results:
          path: test-results
      - store_artifacts: # this is where playwright puts more complex stuff
          path: code/playwright-results/
          destination: playwright

workflows:
  test:
    jobs:
      - build
      - lint:
          requires:
            - build
      - check:
          requires:
            - build
      - unit-tests:
          requires:
            - build
      - script-unit-tests:
          requires:
            - build
      - chromatic-internal-storybooks:
          requires:
            - build
      - coverage:
          requires:
            - unit-tests
      - publish:
          requires:
            - build
      - cra-bench:
          requires:
            - publish
      - react-vite-bench:
          requires:
            - publish
      ## new workflow
      - create-sandboxes:
          requires:
            - publish
      # - smoke-test-sandboxes: # disabled for now
      #     requires:
      #       - create-sandboxes
      - build-sandboxes:
          requires:
            - create-sandboxes
      - test-runner-sandboxes:
          requires:
            - build-sandboxes
      - chromatic-sandboxes:
          requires:
            - build-sandboxes
      - e2e-sandboxes:
          requires:
            - build-sandboxes
