version: 2.1

aliases:
  - &checkout_cunningham
    checkout:
      path: ~/cunningham

  - &restore_node_modules
    restore_cache:
      name: Restore node_modules cache
      keys:
        - v1-front-dependencies-{{ checksum "~/cunningham/yarn.lock" }}

jobs:
  lint-git:
    docker:
      - image: cimg/python:3.11
    working_directory: ~/cunningham
    steps:
      - checkout:
          path: ~/cunningham
      - run:
          name: Check absence of fixup commits
          command: |
            ! git log origin/main..HEAD | grep 'fixup!'
      - run:
          name: Install gitlint
          command: |
            pip install --user requests gitlint
      - run:
          name: lint commit messages added to main
          command: |
            ~/.local/bin/gitlint --commits origin/main..HEAD

  # Check that renovate configuration file is valid
  check-renovate-configuration:
    docker:
      - image: renovate/renovate
        auth:
          username: $DOCKER_USER
          password: $DOCKER_PASS
    working_directory: ~/cunningham
    steps:
      - *checkout_cunningham
      - run:
          name: Run renovate-config-validator command
          command: renovate-config-validator

  # ---- Codebase -----
  build:
    docker:
      - image: cimg/node:20.16
    working_directory: ~/cunningham
    steps:
      - *checkout_cunningham
      - *restore_node_modules
      # If the yarn.lock file is not up-to-date with the package.json file,
      # using the --frozen-lockfile should fail.
      - run:
          name: Install dependencies
          command: yarn install --frozen-lockfile
      - run:
          name: Build packages
          # Symlinks to bins in the monorepo are not created by yarn, so we need to do it manually.
          command: |
            ln -sf ../../packages/tokens/dist/bin/Main.js node_modules/.bin/cunningham &&
            yarn build
      - persist_to_workspace:
          root: ~/cunningham
          paths:
            - apps/demo/dist
            - packages/tokens/dist
            - packages/react/dist
      - save_cache:
          paths:
            - ./node_modules
            - ./apps/demo/node_modules
            - ./packages/eslint-config-custom/node_modules
            - ./packages/react/node_modules
            - ./packages/tokens/node_modules
          key: v1-front-dependencies-{{ checksum "yarn.lock" }}
  lint:
    docker:
      - image: cimg/node:20.16
    working_directory: ~/cunningham
    steps:
      - *checkout_cunningham
      - *restore_node_modules
      - run:
          name: Run linter over all workspaces
          command: yarn lint

  test:
    docker:
      - image: cimg/node:20.16
    parallelism: 4
    resource_class: large
    working_directory: ~/cunningham
    steps:
      - *checkout_cunningham
      - *restore_node_modules
      - attach_workspace:
          at: ~/cunningham
      - run:
          name: Run test suites over all workspaces
          command: yarn test-ci

  # ---- Internationalization ----
  crowdin-upload:
    docker:
      - image: crowdin/cli:3.10.0
        auth:
          username: $DOCKER_USER
          password: $DOCKER_PASS
    working_directory: ~/cunningham
    steps:
      - *checkout_cunningham
      - run:
          name: upload translation files to crowdin
          command: crowdin upload sources -c crowdin/config.yml

  # ---- Deploy ----
  publish-storybook:
    docker:
      - image: cimg/node:20.16
    working_directory: ~/cunningham
    steps:
      - add_ssh_keys:
          fingerprints:
            - "5e:86:38:27:26:f2:1b:7f:4b:36:99:38:63:d9:2b:75"
      - *checkout_cunningham
      - *restore_node_modules
      - attach_workspace:
          at: ~/cunningham
      - run:
          name: Publish storybook
          command: |
            git config user.email "funmoocbot@users.noreply.github.com"
            git config user.name "FUN MOOC bot"
            yarn deploy-ghpages
  publish-packages:
    docker:
      - image: cimg/node:20.16
        auth:
          username: $DOCKER_USER
          password: $DOCKER_PASS
    working_directory: ~/cunningham
    steps:
      - add_ssh_keys:
          fingerprints:
            - "5e:86:38:27:26:f2:1b:7f:4b:36:99:38:63:d9:2b:75"
      - *checkout_cunningham
      - *restore_node_modules
      - attach_workspace:
          at: ~/cunningham
      - run:
          name: Authenticate with registry
          command: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/cunningham/.npmrc
      - run:
          name: Init Git identity in order to allow changeset to create tags
          command: |
            git config user.email "funmoocbot@users.noreply.github.com"
            git config user.name "FUN MOOC bot"
      - run:
          name: Publish package as public if package version are bumped
          command: yarn changeset publish
      - run:
          name: Push release tags if some were created
          command: git push --follow-tags origin HEAD
workflows:
  version: 2.1

  cunningham:
    jobs:
      # Git jobs
      #
      # Check validity of git history
      - lint-git:
          filters:
            tags:
              only: /.*/
      # Check Renovate
      - check-renovate-configuration:
          filters:
            tags:
              only: /.*/
      # ---- Internationalization ----
      - crowdin-upload:
          filters:
            branches:
              only:
                - main
          requires:
            - build
      # ---- Codebase ----
      - build:
          filters:
            tags:
              only: /.*/
      - lint:
          filters:
            tags:
              only: /.*/
          requires:
            - build
      - test:
          filters:
            tags:
              only: /.*/
          requires:
            - build
            - lint
      - publish-storybook:
          filters:
            branches:
              only:
                - main
          requires:
            - test
      - publish-packages:
          filters:
            branches:
              only:
                - main
          requires:
            - build
            - lint
            - test
