5

We are trying to cache all Gradle dependencies for our Android build job.

This is the current approach that is failing:

- restore_cache:
    key: android-build-{{ checksum "android/build.gradle" }}-{{ checksum  "android/app/build.gradle" }}
- save_cache:
    paths:
      - ~/.gradle
    key: android-build-{{ checksum "android/build.gradle" }}-{{ checksum  "android/app/build.gradle" }}
oxfist
  • 749
  • 6
  • 22
Sibelius Seraphini
  • 5,303
  • 9
  • 34
  • 55
  • 1
    Define "failing". – Abhijit Sarkar Nov 05 '18 at 11:38
  • it is not saving the cache, it is always creating again and again – Sibelius Seraphini Nov 05 '18 at 17:56
  • The cache is working for me using a static key, and I'm saving `.gradle` and `.m2`. Do you really need a dynamic key? CircleCI doesn't explain how the cache works, but there doesn't seem to be anything dynamic in `.gradle` to warrant generating a dynamic key. If your Gradle wrapper version changes, it won't be found in the `restore_cache` step, will be downloaded, and the cache will be updated in the `save_cache` step. – Abhijit Sarkar Nov 05 '18 at 20:08

2 Answers2

2

There's a sample Android configuration by Circle CI themselves here as well as a step-by-step walkthrough of the attributes.

version: 2
jobs:
  build:
    working_directory: ~/code
    docker:
      - image: circleci/android:api-25-alpha
    environment:
      JVM_OPTS: -Xmx3200m
    steps:
      - checkout
      - restore_cache:
          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}
#      - run:
#         name: Chmod permissions #if permission for Gradlew Dependencies fail, use this. 
#         command: sudo chmod +x ./gradlew
      - run:
          name: Download Dependencies
          command: ./gradlew androidDependencies
      - save_cache:
          paths:
            - ~/.gradle
          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}
      - run:
          name: Run Tests
          command: ./gradlew lint test
      - store_artifacts:
          path: app/build/reports
          destination: reports
      - store_test_results:
          path: app/build/test-results

It's worth noting that we experienced some issues when utilising the cache due to submodules, but the above should work for simpler repositories.

Jake Lee
  • 7,549
  • 8
  • 45
  • 86
1

Place build steps between restore_cache and save_cache.

If your project is multi-module/-level hash all build scripts and use it as key to proper capture dependencies:

  - run:
      name: Hash dependency info
      command: |
        mkdir -p build
        md5sum gradle.properties settings.gradle build.gradle **/build.gradle >build/deps.md5
  - restore_cache:
      key: gradle-{{ checksum "build/deps.md5" }}
  - run:
      name: Build and deploy
      command: >
        bash ./gradlew
        build artifactoryPublish
  - save_cache:
      key: gradle-{{ checksum "build/deps.md5" }}
      paths:
        - ~/.gradle/caches
        - ~/.gradle/wrapper
gavenkoa
  • 45,285
  • 19
  • 251
  • 303
  • It is not working fine, the `checksum "build/deps.md5"` returns different key everytime on different CircleCI Jobs. Does it check to create/modify file date? In other case I don't understand why it returns different keys for the same file content – Jc Miñarro Nov 05 '18 at 08:36
  • 1
    @JcMiñarro That means order of files isn't stable or you alter build files each build (like bump version). – gavenkoa Nov 05 '18 at 09:41
  • 2
    Thanks @gavenkoa I have review my `deps.md5` outputs and yes, it stored md5 sum on different order. What I was doing was the following command: `find . -name "*.gradle" -type f | xargs md5sum > build/deps.md5` But it return files in different order on every job, so what I did is to sort the find output with the following command: `find . -name "*.gradle" -type f | sort | xargs md5sum > build/deps.md5` Thanks for your help – Jc Miñarro Nov 05 '18 at 12:35