version: "2.1"

# Parameters. {{{

parameters:

    # Bump this to reset all caches.
    cache_epoch:
      type: integer
      default: 4

# }}}

# Executors. {{{

executors:

  base: &BASE_EXE
    docker:
      - image: koreader/kobase:0.5.3-22.04

  # Emulators. {{{

  emu_gcc_ninja:
    <<: *BASE_EXE
    environment: &EMU_ENV_LST
      EMULATE_READER: "1"
      KODEBUG: ""
      CC: "gcc"

  emu_gcc_ninja_debug:
    <<: *BASE_EXE
    environment:
      <<: *EMU_ENV_LST
      KODEBUG: "1"

  emu_clang_ninja:
    docker:
      - image: koreader/kobase-clang:0.4.5-22.04
    environment:
      <<: *EMU_ENV_LST
      KODEBUG: ""
      USE_CLANG: "1"

  # }}}

  # Platforms. {{{

  android-arm: &ANDROID_EXE
    docker:
      - image: koreader/koandroid:0.9.5-22.04
    environment:
      TARGET: "android"

  android-x86:
    <<: *ANDROID_EXE
    environment:
      TARGET: "android"
      ANDROID_ARCH: "x86"

  cervantes:
    docker:
      - image: koreader/kocervantes:0.4.5-22.04
    environment:
      TARGET: "cervantes"

  kindle: &KINDLE_EXE
    docker:
      - image: koreader/kokindle:0.4.5-22.04
    environment:
      TARGET: "kindle"

  kindlehf:
    <<: *KINDLE_EXE
    environment:
      TARGET: "kindlehf"

  kindle-legacy:
    <<: *KINDLE_EXE
    environment:
      TARGET: "kindle-legacy"

  kobo:
    docker:
      - image: koreader/kokobo:0.4.5-22.04
    environment:
      TARGET: "kobo"

  pocketbook:
    docker:
      - image: koreader/kopb:0.5.5-22.04
    environment:
      TARGET: "pocketbook"

  sony-prstux:
    docker:
      - image: koreader/kodeb:0.2.5-22.04
    environment:
      TARGET: "sony-prstux"

  # }}}

# }}}

# Jobs. {{{

jobs:

  # Lint. {{{

  lint:
    executor: base
    resource_class: small
    environment:
      BASH_ENV: "~/.bashrc"
      PARALLEL_JOBS: "1"
    steps:
      - checkout
      - run:
          name: lint
          command: source .ci/lint_script.sh

  # }}}

  # Build & Test. {{{

  build_and_test:
    parameters:
      executor:
        type: executor
      ccache_maxsize:
        type: string
        default: "256M"
      check_ffi_cdecls:
        type: boolean
        default: false
      save_tests:
        type: boolean
        default: false
    executor: << parameters.executor >>
    resource_class: medium
    environment:
      BASH_ENV: "~/.bashrc"
      CCACHE_MAXSIZE: << parameters.ccache_maxsize >>
      CLICOLOR_FORCE: "1"
      MAKEFLAGS: "PARALLEL_JOBS=3 OUTPUT_DIR=build"
    steps:
      # Checkout / fetch. {{{
      - checkout
      - run:
          name: Fetch
          command: make fetchthirdparty
      # }}}
      # Restore / setup caches. {{{
      - run:
          name: Generate cache key
          command: make TARGET= cache-key
      - restore_cache:
          name: Restore build directory
          keys:
            - &CACHE_KEY_BUILD_DIR '<< pipeline.parameters.cache_epoch >>-{{ .Environment.CIRCLE_JOB }}-build-{{ arch }}-{{ checksum "cache-key" }}'
      - restore_cache:
          name: Restore build cache
          keys:
            - &CACHE_KEY_BUILD_CACHE '<< pipeline.parameters.cache_epoch >>-{{ .Environment.CIRCLE_JOB }}-ccache-{{ arch }}-{{ checksum "cache-key" }}'
            - '<< pipeline.parameters.cache_epoch >>-{{ .Environment.CIRCLE_JOB }}-ccache-{{ arch }}-'
      - run:
          name: Setup build cache
          command: |
            set -x
            which ccache
            ccache --version
            ccache --zero-stats
            ccache --show-config
      # }}}
      # Build. {{{
      - run:
          name: Build
          command: test -d build || source .ci/build_script.sh
      - run:
          when: always
          name: Dump build timings
          command: "! test -d build/cmake || make buildstats"
      - run:
          name: Dump binaries runtime path & dependencies
          command: make bininfo
      # }}}
      # Clean & save build cache. {{{
      - run:
          name: Clean build cache
          when: always
          command: |
            set -x
            ccache --cleanup >/dev/null
            ccache --show-stats --verbose
      - save_cache:
          name: Save build cache
          key: *CACHE_KEY_BUILD_CACHE
          paths:
            - /home/ko/.cache/ccache
      # }}}
      # Check FFI cdecls are up-to-date. {{{
      - when:
          condition: << parameters.check_ffi_cdecls >>
          steps:
            - run:
                name: Check FFI cdecls are up-to-date
                command: "! test -d build/cmake || { make ffi && git --no-pager diff --exit-code ffi; }"
      # }}}
      # Trim & save build directory. {{{
      - run:
          name: Trim build directory
          when: always
          command: rm -rf build/{cmake,staging,thirdparty}
      - save_cache:
          name: Save build directory
          key: *CACHE_KEY_BUILD_DIR
          paths:
            - build
      # }}}
      # Tests. {{{
      - run:
          name: Test
          command: source .ci/test_script.sh
      - when:
          condition: << parameters.save_tests >>
          steps:
              - store_test_results:
                  name: Store tests results
                  path: test-results.xml
              - store_artifacts:
                  name: Upload tests results to artifacts
                  path: test-results.xml
      # }}}

  # }}}

# }}}

# Workflows. {{{

workflows:

  version: 2

  lint_build_test:

    jobs:

      - lint

      # Emulators. {{{

      - build_and_test:
          name: emu_gcc_ninja
          executor: emu_gcc_ninja
          filters:
            branches:
              only: master
          requires:
            - lint
          save_tests: true

      - build_and_test:
          name: emu_gcc_ninja_debug
          executor: emu_gcc_ninja_debug
          requires:
            - lint
          ccache_maxsize: "512M"
          check_ffi_cdecls: true
          save_tests: true

      - build_and_test:
          name: emu_clang_ninja
          executor: emu_clang_ninja
          requires:
            - lint
          save_tests: true

      # }}}

      # Platforms. {{{

      - build_and_test:
          name: android-arm
          executor: android-arm
          requires:
            - emu_gcc_ninja_debug

      - build_and_test:
          name: android-x86
          executor: android-x86
          filters:
            branches:
              only: master
          requires:
            - emu_gcc_ninja_debug

      - build_and_test:
          name: cervantes
          executor: cervantes
          requires:
            - emu_gcc_ninja_debug
          check_ffi_cdecls: true

      - build_and_test:
          name: kindle
          executor: kindle
          requires:
            - emu_gcc_ninja_debug
          check_ffi_cdecls: true

      - build_and_test:
          name: kindlehf
          executor: kindlehf
          requires:
            - emu_gcc_ninja_debug
          check_ffi_cdecls: true

      - build_and_test:
          name: kindle-legacy
          executor: kindle-legacy
          requires:
            - emu_gcc_ninja_debug

      - build_and_test:
          name: kobo
          executor: kobo
          requires:
            - emu_gcc_ninja_debug
          check_ffi_cdecls: true

      - build_and_test:
          name: pocketbook
          executor: pocketbook
          requires:
            - emu_gcc_ninja_debug
          check_ffi_cdecls: true

      - build_and_test:
          name: sony-prstux
          executor: sony-prstux
          requires:
            - emu_gcc_ninja_debug
          check_ffi_cdecls: true

      # }}}

# }}}

# vim: foldmethod=marker foldlevel=0
