version: 2.1

aliases:
  - &restore-yarn-cache
    key: v2-yarn-cache-{{ checksum "yarn.lock" }}

  - &save-yarn-cache
    paths:
      - ~/.yarn/berry/cache
    key: v2-yarn-cache-{{ checksum "yarn.lock" }}

  - &artifact_babel
    path: ~/babel/packages/babel-standalone/babel.js

  - &artifact_babel_min
    path: ~/babel/packages/babel-standalone/babel.min.js

  - &test262_workdir
    working_directory: ~/babel/babel-test262-runner

  - &artifact_test262_tap
    path: ~/test262.tap

  - &artifact_test262_xunit
    path: ~/test-results

  - &artifact_test262_diff_tap
    path: ~/diff.tap

executors:
  node-executor:
    docker:
      - image: cimg/node:current
    working_directory: ~/babel
  # e2e-vue-cli test requires chromium
  node-browsers-executor:
    docker:
      - image: cimg/node:current-browsers
    working_directory: ~/babel
  # e2e-jest test requires python
  node-python-executor:
    docker:
      - image: cimg/python:3.9-node
    working_directory: ~/babel

jobs:
  build-standalone:
    executor: node-executor
    steps:
      - checkout
      - restore_cache: *restore-yarn-cache
        # Builds babel-standalone with the regular Babel config
        # test-ci-coverage doesn't test babel-standalone, as trying to gather coverage
      - run: IS_PUBLISH=true make -j build-standalone-ci
        # data for a JS file that's several megabytes large is bound to fail. Here,
        # we just run the babel-standalone test separately.
      - run: yarn jest "\-standalone/test"
      - store_artifacts: *artifact_babel
      - store_artifacts: *artifact_babel_min
      - save_cache: *save-yarn-cache

  test262:
    executor: node-executor
    steps:
      - checkout
      - run:
          name: Sync with latest main branch (only on PRs)
          command: |
            if [ -n "$CIRCLE_PULL_REQUEST" ]
            then
              # $CIRCLE_PR_NUMBER is not always defined:
              # https://support.circleci.com/hc/en-us/articles/360047521451-Why-is-CIRCLE-PR-NUMBER-empty-
              git fetch origin refs/pull/${CIRCLE_PULL_REQUEST##*/}/merge
              git checkout -qf FETCH_HEAD
            fi
      - restore_cache: *restore-yarn-cache
      - run:
          name: Build Babel
          command: BABEL_ENV=test make bootstrap
      - run:
          name: Setup Test Runner
          command: |
            git clone --depth=1 --recurse-submodules https://github.com/babel/babel-test262-runner
            cd babel-test262-runner
            npm ci
            npm i tap-mocha-reporter --save-dev
            node lib/download-node
      - run:
          name: Download main branch Test262 artifact
          command: node lib/download-main-artifact ~/test262-main.tap
          <<: *test262_workdir
      - run:
          name: Run Test262
          command: BABEL_PATH=.. node lib/run-tests I_AM_SURE | tee ~/test262.tap
          <<: *test262_workdir
      - store_artifacts: *artifact_test262_tap
      - run:
          name: Output Test262 results
          command: |
            cat ~/test262.tap | $(npm bin)/tap-mocha-reporter spec || true
          <<: *test262_workdir
      - run:
          name: Compare previous main branch & current job results
          command: |
            mkdir -p ~/test-results/test262
            node lib/compare-results ~/test262-main.tap ~/test262.tap | tee ~/diff.tap
          <<: *test262_workdir
      - store_artifacts: *artifact_test262_diff_tap
      - run:
          name: Output comparison results and report to CircleCI
          command: |
            mkdir -p ~/test-results/test262
            cat ~/diff.tap | $(npm bin)/tap-merge | $(npm bin)/tap-mocha-reporter xunit | tee ~/test-results/test262/results.xml
          <<: *test262_workdir
      - store_test_results: *artifact_test262_xunit
      - save_cache: *save-yarn-cache

  publish-verdaccio-babel-8-breaking:
    executor: node-executor
    steps:
      - checkout
      - restore_cache: *restore-yarn-cache
      - run: BABEL_8_BREAKING=true ./scripts/integration-tests/publish-local.sh
      - persist_to_workspace:
          root: /tmp/verdaccio-workspace
          paths:
            - storage
            - htpasswd
      - save_cache: *save-yarn-cache

  e2e-breaking-babel:
    executor: node-executor
    steps:
      - checkout
      - attach_workspace:
          at: /tmp/verdaccio-workspace
      - run: BABEL_8_BREAKING=true ./scripts/integration-tests/e2e-babel.sh

  e2e-breaking-create-react-app:
    executor: node-executor
    steps:
      - checkout
      - attach_workspace:
          at: /tmp/verdaccio-workspace
      - run: BABEL_8_BREAKING=true ./scripts/integration-tests/e2e-create-react-app.sh

  e2e-breaking-vue-cli:
    executor: node-browsers-executor
    steps:
      - checkout
      - attach_workspace:
          at: /tmp/verdaccio-workspace
      - run:
          # vue-cli uses puppeteer, and it depends on the libXss.so.1 shared library
          name: Install Headless Chrome dependencies
          command: sudo apt-get install -yq libxss1
      - run: BABEL_8_BREAKING=true ./scripts/integration-tests/e2e-vue-cli.sh

  e2e-breaking-jest:
    executor: node-python-executor
    steps:
      - checkout
      - attach_workspace:
          at: /tmp/verdaccio-workspace
      - run: BABEL_8_BREAKING=true ./scripts/integration-tests/e2e-jest.sh

workflows:
  version: 2
  build-standalone:
    jobs:
      - build-standalone
  test262:
    jobs:
      - test262:
          filters:
            branches:
              only:
                - main
                - next-8-dev
                - next-8-rebased
          context: babel-test262
  test262-pr:
    jobs:
      - approve-test262-run:
          type: approval
          filters:
            branches:
              ignore:
                - main
                - master
                - next-8-dev
                - next-8-rebased
      - test262:
          requires:
            - approve-test262-run
          filters:
            branches:
              ignore:
                - main
                - master
                - next-8-dev
                - next-8-rebased
          context: babel-test262

  e2e-breaking:
    jobs:
      - publish-verdaccio-babel-8-breaking:
          filters:
            branches:
              only: [main, next-8-dev, next-8-rebased]
      - e2e-breaking-babel:
          requires:
            - publish-verdaccio-babel-8-breaking
      - e2e-breaking-create-react-app:
          requires:
            - publish-verdaccio-babel-8-breaking
      - e2e-breaking-vue-cli:
          requires:
            - publish-verdaccio-babel-8-breaking
      - e2e-breaking-jest:
          requires:
            - publish-verdaccio-babel-8-breaking

  e2e-breaking-pr:
    jobs:
      - approve-e2e-breaking-run:
          type: approval
          filters:
            branches:
              ignore: [main, next-8-dev, next-8-rebased]
      - publish-verdaccio-babel-8-breaking:
          requires:
            - approve-e2e-breaking-run
      - e2e-breaking-babel:
          requires:
            - publish-verdaccio-babel-8-breaking
      - e2e-breaking-create-react-app:
          requires:
            - publish-verdaccio-babel-8-breaking
      - e2e-breaking-vue-cli:
          requires:
            - publish-verdaccio-babel-8-breaking
      - e2e-breaking-jest:
          requires:
            - publish-verdaccio-babel-8-breaking
