version: 2.1

orbs:
  browser-tools: circleci/browser-tools@1.1.3
workflows:
  version: 2
  build_and_test:
    jobs:
      - build_and_unit_test
      - integration_test_readonly:
          requires:
            - build_and_unit_test
      - integration_test_readwrite:
          requires:
            - build_and_unit_test
executors:
  node:
    working_directory: ~/pinafore
    docker:
      - image: cimg/ruby:3.0.3-browsers
  node_and_ruby:
    working_directory: ~/pinafore
    docker:
      - image: cimg/ruby:3.0.3-browsers
      - image: circleci/postgres:12.2
        environment:
          POSTGRES_USER: pinafore
          POSTGRES_PASSWORD: pinafore
          POSTGRES_DB: pinafore_development
          BROWSER: chrome:headless
      - image: circleci/redis:5-alpine
commands:
  install_mastodon_system_dependencies:
    description: Install system dependencies that Mastodon requires
    steps:
      - run:
          name: Install system dependencies
          command: |
            sudo apt-get update
            sudo apt-get install -y \
              ffmpeg \
              fonts-noto-color-emoji \
              imagemagick \
              libicu-dev \
              libidn11-dev \
              libprotobuf-dev \
              postgresql-contrib \
              protobuf-compiler
  install_browsers:
    description: Install browsers and tools
    steps:
      - browser-tools/install-chrome:
          chrome-version: 91.0.4472.114
      - browser-tools/install-chromedriver
      - run:
          name: "Check browser version"
          command: |
            google-chrome --version
  install_node:
    description: Install Node.js
    steps:
      - run:
          name: "Install Node.js"
          # via https://circleci.com/docs/2.0/circleci-images/#notes-on-pinning-images
          command: |
            curl -sSL "https://nodejs.org/dist/v14.21.1/node-v14.21.1-linux-x64.tar.xz" \
            | sudo tar --strip-components=2 -xJ -C /usr/local/bin/ node-v14.21.1-linux-x64/bin/node
      - run:
          name: Check current version of node
          command: node -v

  save_workspace:
    description: Persist workspace
    steps:
      - persist_to_workspace:
          root: .
          paths:
            - .
  load_workspace:
    description: Load workspace
    steps:
      - attach_workspace:
          at: ~/pinafore
  restore_yarn_cache:
    description: Restore yarn cache
    steps:
      - restore_cache:
          name: Restore yarn cache
          key: yarn-v4-{{ checksum "yarn.lock" }}
  save_yarn_cache:
    description: Save yarn cache
    steps:
      - save_cache:
          name: Save yarn cache
          key: yarn-v4-{{ checksum "yarn.lock" }}
          paths:
            - ~/.cache/yarn
  restore_yarn_cache_mastodon:
    description: Restore yarn cache for Mastodon
    steps:
      - restore_cache:
          name: Restore yarn cache for Mastodon
          key: yarn-v4-{{ checksum "mastodon/yarn.lock" }}
  save_yarn_cache_mastodon:
    description: Save yarn cache for Mastodon
    steps:
      - save_cache:
          name: Save yarn cache for Mastodon
          key: yarn-v4-{{ checksum "mastodon/yarn.lock" }}
          paths:
            - ~/.cache/yarn
  restore_bundler_cache:
    description: Restore bundler cache
    steps:
      - restore_cache:
          name: Restore bundler cache
          key: bundler-v4-{{ checksum "mastodon/Gemfile.lock" }}
  save_bundler_cache:
    description: Save bundler cache
    steps:
      - save_cache:
          name: Save bundler cache
          key: bundler-v4-{{ checksum "mastodon/Gemfile.lock" }}
          paths:
            - mastodon/vendor/bundle
  install_mastodon:
    description: Install Mastodon and set up Postgres/Redis
    steps:
      - run:
          name: Clone mastodon
          command: yarn clone-mastodon
      - restore_yarn_cache_mastodon
      - restore_bundler_cache
      - run:
          name: Install mastodon
          command: yarn install-mastodon
      - save_yarn_cache_mastodon
      - save_bundler_cache
      - run:
          name: Wait for postgres to be ready
          command: |
            for i in `seq 1 10`;
            do
              nc -z localhost 5432 && echo Success && exit 0
              echo -n .
              sleep 1
            done
            echo Failed waiting for postgres && exit 1
      - run:
          name: Wait for redis to be ready
          command: |
            for i in `seq 1 10`;
            do
              nc -z localhost 6379 && echo Success && exit 0
              echo -n .
              sleep 1
            done
            echo Failed waiting for redis && exit 1
jobs:
  build_and_unit_test:
    executor: node
    steps:
      - checkout
      - install_node
      - restore_yarn_cache
      - run:
          name: Yarn install
          command: yarn install --immutable
      - save_yarn_cache
      - run:
          name: Lint
          command: yarn lint
      - run:
          name: Copy vercel.json
          command: cp vercel.json vercel-old.json
      - run:
          name: Build
          command: yarn build
      - run:
          name: Check vercel.json unchanged
          command: |
            if ! diff -q vercel-old.json vercel.json &>/dev/null; then
              diff vercel-old.json vercel.json
              echo "vercel.json changed, run yarn build and make sure everything looks okay"
              exit 1
            fi
      - run:
          name: Unit tests
          command: yarn test-unit
      - save_workspace
  integration_test_readonly:
    executor: node_and_ruby
    steps:
      - install_mastodon_system_dependencies
      - install_browsers
      - install_node
      - load_workspace
      - install_mastodon
      - run:
          name: Read-only integration tests
          command: yarn test-in-ci-suite0
  integration_test_readwrite:
    executor: node_and_ruby
    steps:
      - install_mastodon_system_dependencies
      - install_browsers
      - install_node
      - load_workspace
      - install_mastodon
      - run:
          name: Read-write integration tests
          command: yarn test-in-ci-suite1
