version: 2.1

parameters:
  is_pr:
    type: boolean
    default: false

orbs:
  # The python orb contains a set of prepackaged CircleCI configuration you can use repeatedly in your configuration files
  # Orb commands and jobs help you with common scripting around a language/tool
  # so you dont have to copy and paste it everywhere.
  # See the orb documentation here: https://circleci.com/developer/orbs/orb/circleci/python
  python: circleci/python@1.4
  node: circleci/node@4.7.0
  # poetry: frameio/poetry@0.21.0
  swissknife: roopakv/swissknife@0.59.0
  docker: circleci/docker@2.0.2
  docker-cache: cci-x/docker-registry-image-cache@0.2.0
  codecov: codecov/codecov@3.2.2

workflows:
  pull-request:
    when: << pipeline.parameters.is_pr >>
    jobs:
      - build-frontend
      - test
  build-test-publish:
    unless: << pipeline.parameters.is_pr >>
    jobs:
      - build-frontend:
          filters:
            tags:
              only: /.*/
      - test:
          requires:
            - build-frontend
          filters:
            tags:
              only: /.*/
      - build:
          requires:
            - test
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/
      - publish-pypi:
          requires:
            - build
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/
      - publish-github-release:
          requires:
            - build
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/
      - docker/publish: &docker-push
          name: "docker/publish-release"
          dockerfile: docker/Dockerfile_with_frontend
          after_checkout:
            - attach_workspace:
                at: .
            - restore_cache:
                key: frontend_build_res-{{ checksum "frontend.hash" }}
          requires:
            - test
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/
          context:
            - docker
          image: $CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME
          cache_from: "$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:${CIRCLE_TAG}"
          tag: latest,${CIRCLE_TAG}
          update-description: true
          docker-username: DOCKERHUB_USERNAME
          docker-password: DOCKERHUB_PASSWORD
      - docker/publish:
          <<: *docker-push
          name: "docker/publish-debug"
          filters:
            tags:
              ignore: /.*/
          tag: ${CIRCLE_BRANCH//\//-}
          cache_from: "$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:${CIRCLE_BRANCH}"
      - docker/publish:
          <<: *docker-push
          dockerfile: docker/Dockerfile_with_frontend_sentry
          name: "docker/publish-sentry"
          tag: sentry,${CIRCLE_TAG//\//-}-sentry
          cache_from: "$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:sentry"
      - docker/publish:
          <<: *docker-push
          name: "docker/publish-debug-sentry"
          dockerfile: docker/Dockerfile_with_frontend_sentry
          filters:
            branches:
              only: [main, dev]
            tags:
              ignore: /.*/
          tag: ${CIRCLE_BRANCH//\//-}-sentry
          cache_from: "$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME:${CIRCLE_BRANCH}-sentry"

jobs:
  build-frontend:
    docker:
      - image: cimg/node:16.13.0
    steps:
      - checkout
      - run:
          name: Get hash of frontend code
          command: |
            find ./admin-frontend/src -type f -exec md5sum {} + | LC_ALL=C sort > frontend.hash
            md5sum ./admin-frontend/yarn.lock >> frontend.hash
            cat frontend.hash
      - persist_to_workspace:
          root: .
          paths:
            - "frontend.hash"
      - restore_cache:
          key: frontend_build_res-{{ checksum "frontend.hash" }}
      - run:
          name: Check cache
          command: |
            if [ -f ./src/plugins/nonebot_bison/admin_page/dist/index.html ]; then
              echo "frontend cache exists"
              circleci-agent step halt
            else
              echo "no such cache, build will begin"
            fi
      - node/install-packages:
          app-dir: ./admin-frontend
          pkg-manager: yarn
      - run:
          name: yarn build
          working_directory: ./admin-frontend
          command: yarn build
      - save_cache:
          paths:
            - ./src/plugins/nonebot_bison/admin_page/dist/
          key: frontend_build_res-{{ checksum "frontend.hash" }}
  test:
    docker:
      - image: cimg/python:3.9
    environment:
      BISON_SKIP_BROWSER_CHECK: true
    #   BISON_BROWSER: wsc://localhost:3000
    steps:
      - checkout
      # - run: sed -e '41,45d' -i pyproject.toml
      - python/install-packages:
          pkg-manager: poetry
      # - run:
      #     name: Install browser
      #     command: poetry run playwright install-deps && poetry run playwright install chromium
      - run:
          name: Coverage test
          command:
            poetry run pytest --cov-report html --cov-report xml --cov=./src/plugins/nonebot_bison --junitxml=test-results/junit.xml
            -k 'not compare and not render'
      - store_test_results:
          path: test-results
      - run:
          name: Collect coverage
          command: poetry run coverage html --include='src/*'
      - codecov/upload:
          file: coverage.xml
      - store_artifacts:
          path: htmlcov
  build:
    docker:
      - image: cimg/python:3.9
    steps:
      - checkout
      - attach_workspace:
          at: .
      - restore_cache:
          key: frontend_build_res-{{ checksum "frontend.hash" }}
      - run: poetry build
      - store_artifacts:
          path: "dist"
      - persist_to_workspace:
          root: .
          paths:
            - "dist"
  publish-pypi:
    docker:
      - image: cimg/python:3.9
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          command: poetry publish -u $PYPI_USERNAME -p $PYPI_PASSWORD || echo "Already pushed to pypi"
          name: Publish to Pypi

  publish-github-release:
    docker:
      - image: circleci/golang:1.17
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: Publish to Github Release
          command: |
            go install github.com/tcnksm/ghr@latest
            ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} \
              -delete ${CIRCLE_TAG} -n ${CIRCLE_TAG} -b $(git log --format=%B -n 1 $CIRCLE_SHA1) ./dist