Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pro builds in your small startup (Berlindroid 2...

Nelson Osacky
November 29, 2017

Pro builds in your small startup (Berlindroid 29-Nov-2017)

How we scaled our build system at Zenjob.

Nelson Osacky

November 29, 2017
Tweet

More Decks by Nelson Osacky

Other Decks in Technology

Transcript

  1. About me • Android developer since before Uni • New

    to Berlin - Started working in September • Formerly at Square in San Francisco • Worked on Reader Experience, Square Register and build systems: Buck
  2. Why Travis? • Other engineering teams at Zenjob teams were

    already using it • Integrates easily with GitHub • Good Android examples and documentation • There’s a million options, this isn’t really the point.
  3. How to add Travis? language: android jdk: - oraclejdk8 android:

    components: - tools - platform-tools - tools - build-tools-25.0.0 - android-26 script: ./gradlew assemble check notifications: email: false cache: directories: - $HOME/.gradle
  4. Next step: Boot emulator before_install: 
 - start emulator install:

    ./gradlew assemble before_script: android-wait-for-emulator script: ./gradlew check connectedCheck
  5. before_install: # Install the system image. - sdkmanager “system-images;android-19;default;armeabi-v7a" #

    Create and start emulator for the script. # Meant to race the install task. - echo no | avdmanager create avd --force -n test -k "system- images;android-19;default;armeabi-v7a" - $ANDROID_HOME/emulator/emulator -avd test -no-audio -no-window &
  6. Hard to debug • Button isn’t visible? Why? • No

    screenshots • Spoon doesn’t support AGP 3.0 (yet) • Screenshot on failure is tricky • Unsolved problem
  7. Make the tests faster • Replace SystemClock.sleep() in tests with

    Espresso idling resources • Replace real API calls with mock API calls • Make mock API calls return instantly
  8. • AWS Device Lab failed with cryptic error and no

    support • AWS Device Lab $10/hr • Firebase Test Lab $1/hr virtual and $5/hr real devices
  9. Why faster? • Do not have to download or install

    emulator • Emulator doesn’t slow down the rest of the build • Tests are now run on faster emulator
  10. if [ "$COMPONENT" == "checkstyle" ]; then ./gradlew checkstyle elif

    [ "$COMPONENT" == "unit" ]; then ./gradlew test elif [ "$COMPONENT" == "lint" ]; then ./gradlew lint elif [ "$COMPONENT" == "release" ]; then ./gradlew assembleRelease elif [ "$COMPONENT" == "instrumentation" ]; then ./gradlew assembleDebug assembleAndroidTest .travis/run-ui-tests.sh else echo "This module doesn't exist" exit 1 fi
  11. if [ "$COMPONENT" == "build" ]; then ./gradlew checkstyle check

    assembleRelease elif [ "$COMPONENT" == "instrumentation" ]; then ./gradlew assembleDebug assembleAndroidTest .travis/run-ui-tests.sh else echo "This module doesn't exist" exit 1 fi
  12. before_deploy: # Verify that the apk was signed. - apksigner

    verify -v app/build/outputs/apk/release/app-release.apk # Publish to GitHub releases only on tagged commits. deploy: provider: releases api_key: secure: blah-blah-blah file: - "app/build/outputs/apk/debug/app-debug.apk" - "app/build/outputs/mapping/release/mapping.txt" - "app/build/outputs/apk/release/app-release.apk" skip_cleanup: true on: tags: true condition: $COMPONENT = build # Publish to Google Play after successful deployment to GitHub releases. after_deploy: - ./gradlew publishApkRelease
  13. before_deploy: # Verify that the apk was signed. - apksigner

    verify -v app/build/outputs/apk/release/ app-release.apk
  14. before_deploy: # Verify that the apk was signed. - apksigner

    verify -v app/build/outputs/apk/release/app-release.apk # Publish to GitHub releases only on tagged commits. deploy: provider: releases api_key: secure: blah-blah-blah file: - "app/build/outputs/apk/debug/app-debug.apk" - "app/build/outputs/mapping/release/mapping.txt" - "app/build/outputs/apk/release/app-release.apk" skip_cleanup: true on: tags: true condition: $COMPONENT = build # Publish to Google Play after successful deployment to GitHub releases. after_deploy: - ./gradlew publishApkRelease
  15. # Publish to GitHub releases only on tagged commits. deploy:

    provider: releases api_key: secure: blah-blah-blah file: - "app/build/outputs/apk/debug/app-debug.apk" - "app/build/outputs/mapping/release/mapping.txt" - "app/build/outputs/apk/release/app-release.apk" skip_cleanup: true on: tags: true condition: $COMPONENT = build
  16. before_deploy: # Verify that the apk was signed. - apksigner

    verify -v app/build/outputs/apk/release/app-release.apk # Publish to GitHub releases only on tagged commits. deploy: provider: releases api_key: secure: blah-blah-blah file: - "app/build/outputs/apk/debug/app-debug.apk" - "app/build/outputs/mapping/release/mapping.txt" - "app/build/outputs/apk/release/app-release.apk" skip_cleanup: true on: tags: true condition: $COMPONENT = build # Publish to Google Play after successful deployment to GitHub releases. after_deploy: - ./gradlew publishApkRelease
  17. apply plugin: 'com.github.triplet.play' android { playAccountConfigs { defaultAccountConfig { jsonFile

    = file('keys.json') } } defaultConfig { playAccountConfig = playAccountConfigs.defaultAccountConfig } }
  18. before_deploy: # Verify that the apk was signed. - apksigner

    verify -v app/build/outputs/apk/release/app-release.apk # Publish to GitHub releases only on tagged commits. deploy: provider: releases api_key: secure: blah-blah-blah file: - "app/build/outputs/apk/debug/app-debug.apk" - "app/build/outputs/mapping/release/mapping.txt" - "app/build/outputs/apk/release/app-release.apk" skip_cleanup: true on: tags: true condition: $COMPONENT = build # Publish to Google Play after successful deployment to GitHub releases. after_deploy: - ./gradlew publishApkRelease
  19. # Publish to Google Play after successful deployment to GitHub

    releases. after_deploy: - ./gradlew publishApkRelease
  20. TODOs • Automate bumping version numbers • Run UI tests

    on more real devices with different APIs before release • Move to AWS or another service with faster machines
  21. TODOs • Screenshots on failure ( should be built in)

    • Gradle plugin for Firebase tests • Gradle plugin for Flank (for running locally)
  22. TODOs • Merge on green button • Automate release branch

    cutting • Speed up local builds (Buck?)