Thank You and Android build example

android
docker
2.0

#1

I recently migrated from v1 to v2, and I wanted to thank you guys for the awesome work:
I got my Android builds on Circle CI down from 20+ minutes to ~3 minutes!
v1: https://circleci.com/gh/AnySoftKeyboard/AnySoftKeyboard/304
v2: https://circleci.com/gh/AnySoftKeyboard/AnySoftKeyboard/350

This is in part, to finally figuring out how to easily parallelize my unit-test step, but even without parallelism, my builds were down to 8 minutes.

This is my latest circle.yml for Android using Docker:

version: 2
jobs:
  build:
    docker:
      - image: menny/android_ndk:1.6.1a

    working_directory: /opt/workspace/

    environment:
      CODECOV_TOKEN: 1a4cd171-2784-4f48-8a62-0b7ec31e6d7e
      COV_REPORT_LOCATION: app/build/reports/jacoco/testDebugUnitTestCoverage/testDebugUnitTestCoverage.xml
      TERM: dumb
      _JAVA_OPTIONS: "-Xmx1400m -XX:ParallelGCThreads=2 -XX:ConcGCThreads=2 -XX:ParallelGCThreads=2 -Djava.util.concurrent.ForkJoinPool.common.parallelism=2"

    steps:
      - checkout

      - restore_cache:
          key: anysoftkeyboard-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "circle.yml" }}-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}

      - run:
          name: Setup environment
          command: scripts/ci_setup.sh

      - run:
          name: Run Checks
          command: |
            if [ "${CIRCLE_NODE_INDEX}" == "0" ]; then
              ./scripts/ci_check.sh
              BUILD_EXIT_CODE=$?

              mkdir lint_reports || true

              cp -r app/build/reports/ lint_reports/
              cp -r base/build/reports/ lint_reports/
              cp -r jnidictionaryv1/build/reports/ lint_reports/
              cp -r jnidictionaryv2/build/reports/ lint_reports/
              cp -r nextword/build/reports/ lint_reports/

              exit ${BUILD_EXIT_CODE}
            fi

      - store_artifacts:
          path: lint_reports/
          destination: lint_reports/

      - run:
          name: Run Tests
          command: |
            if [ "${CIRCLE_NODE_INDEX}" != "0" ]; then
              export TEST_GROUP_INDEX=$(( ${CIRCLE_NODE_INDEX} - 1 ))
              export TEST_GROUPS_COUNT=$(( ${CIRCLE_NODE_TOTAL} - 1 ))
              echo "Running test group ${TEST_GROUP_INDEX} out of ${TEST_GROUPS_COUNT}..."
              ./scripts/ci_test.sh
              if [[ -f $COV_REPORT_LOCATION ]]; then
                ./scripts/ci_binaries/codecov.sh -X gcov -X coveragepy -f ${COV_REPORT_LOCATION}
              fi
            fi

      - store_artifacts:
          path: app/build/reports/tests/
          destination: tests_reports/

      - store_test_results:
          path: "app/build/test-results/testDebugUnitTest/"

      - deploy:
          name: Deploy to Play Store
          command: |
            if [ "${CIRCLE_BRANCH}" == "master" ] && [ "${CIRCLE_PROJECT_USERNAME}" == "AnySoftKeyboard" ]; then
              ./scripts/ci_deploy.sh $KEYSTORE_FILE_URL $PUBLISH_CERT_FILE_URL
            fi

      - store_artifacts:
            path: app/build/outputs/apk/
            destination: apks/

      - store_artifacts:
            path: app/build/outputs/mapping/
            destination: mapping/

      - save_cache:
                key: anysoftkeyboard-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "circle.yml" }}-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}
                paths:
                  - "~/.gradle/3.4.1"
                  - "~/.gradle/wrapper/dists/gradle-3.4.1-bin"
                  - "~/.gradle/caches/modules-2"
                  - "~/.gradle/buildOutputCleanup"
                  - "~/.m2"

It does build, lint-check, unit-tests (split into 3 groups) and deploy.
I do not use Emulator tests, so the incompatibility of Docker and Android’s emulator is not an issue to me.

All-in-all, it’s great! Thanks.


#2

Wow, that’s extremely motivating!


#3

This is great to see! Would you be willing to share your ./scripts/ci_test.sh script contents so we can see what commands you are running for testing?


#4

It is all open-sourced here https://github.com/AnySoftKeyboard/AnySoftKeyboard
Specifically, this my circle.yml file: https://github.com/AnySoftKeyboard/AnySoftKeyboard/blob/master/circle.yml
and this is the test script: https://github.com/AnySoftKeyboard/AnySoftKeyboard/blob/master/scripts/ci_test.sh
You can see other scripts here: https://github.com/AnySoftKeyboard/AnySoftKeyboard/blob/master/scripts


#5

Hi Menny,

Thanks for the example can you please guide me for the step by step android project setup in circleci for the android project. From the current documentation its hard to get into the steps.

Thanks,


#6

Can you ping me on gitter?


#7