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

[Sergiy Mokienko] Continuous Integration in Android

[Sergiy Mokienko] Continuous Integration in Android

Presentation from GDG DevFest Ukraine 2016.
Learn more at: https://devfest.gdg.org.ua

Google Developers Group Lviv

September 10, 2016
Tweet

More Decks by Google Developers Group Lviv

Other Decks in Technology

Transcript

  1. #dfua Background 5 years of android development 7 + projects

    on a market Previously GDG Chapter lead in Nikolaev Love IoT
  2. #dfua Build server Open Sourced Plugins Free Easy setUp Scripts

    support Build agents Variety of build triggers VCS support Remote test Run Poor git support Plugins No default support for build agents You have pay for it
  3. #dfua TeamCity Build configuration - Script supports -Attach several VCS

    roots -Build dependencies between jobs - Select branch for build - Schedule triggers - Repository manipulations
  4. #dfua Version naming int majorVersion = MAJOR_VERSION as int
 int

    minorVersion = MINOR_VERSION as int
 int bugFixVersion = BUG_VERSION as int
 String teamCityBuildVersion = (System.getenv("BUILD_NUMBER") ?: "0")
 versionCode majorVersion * 100000000 + minorVersion * 1000000 + bugFixVersion * 10000 + (jenkinsBuildVersion as Integer)
 versionName "" + majorVersion + "." + minorVersion + "." + bugFixVersion + "-" + jenkinsBuildVersion
  5. #dfua gradle.properties MAJOR_VERSION = 1
 MINOR_VERSION = 19
 BUG_VERSION =

    0
 COMPILE_SDK_VERSION=23
 BUILD_TOOLS_VERSION=23.0.2
 MIN_SDK_VERSION=16
 TARGET_SDK_VERSION=23
 SNAPSHOT=true
 SNAPSHOT_ANALYTICS=false
 AUTOTEST=false
 CONNECTION_TEST=false
 MIXPANEL_QA_KEY=297559187fbc0957bec746de0c45a1b2
 BRANDS_DIR=brands
 BRAND=internal
 SERVER_PROJECT_ID=429963794797
 LEVERATE_PASSWORD=leverate2011
  6. #dfua gradle.properties String snapshot = (Boolean.valueOf(getProperty('SNAPSHOT').toString())) ? "Boolean.parseBoolean(\"true\")" : "false"


    buildConfigField 'boolean', 'SNAPSHOT', snapshot
 
 String snapshotAnalytics = (Boolean.valueOf(getProperty('SNAPSHOT_ANALYTICS').toString())) ? "Boolean.parseBoolean(\"true\")" : "false"
 buildConfigField 'boolean', 'SNAPSHOT_ANALYTICS', snapshotAnalytics
 
 String autotest = (Boolean.valueOf(getProperty('AUTOTEST').toString())) ? "Boolean.parseBoolean(\"true\")" : "false"
 buildConfigField 'boolean', 'AUTOTEST', autotest
 
 String connectionTest = (Boolean.valueOf(getProperty('CONNECTION_TEST').toString())) ? "Boolean.parseBoolean(\"true\")" : "false"
 buildConfigField 'boolean', 'CONNECTION_TEST', connectionTest
 
 String mixPanelDebugKey = ("\"" + getProperty('MIXPANEL_QA_KEY').toString() + "\"")
 buildConfigField 'String', 'MIXPANEL_QA_KEY', mixPanelDebugKey
  7. #dfua Email Notification <TeamCity data directory>/config/_notifications/ Including ERRORS from the

    log <#list build.buildLog.messages[1..] as message><#-- skipping the first message (it is a root node)--> <#if message.status == "ERROR" || message.status == "FAILURE" > ${message.text} </#if> </#list>
  8. #dfua Email Notification <TeamCity data directory>/config/_notifications/ <p>Build artifacts:</p> <#list build.artifactsDirectory.listFiles()

    as file> <a href="${webLinks.getDownloadArtefactUrl(build.buildTypeExternalId, build.buildId, file.name)}">${file.name}</a> ($ {file.length()}B)<br/> </#list>
  9. #dfua Unit test Merge to any feature branch On every

    pull request JUnit tests only Lint inspections Test report Lint report Cancel PullRequest if test fails
  10. #dfua Merge On Every PullRequest: Feature branch -> dev Hot

    fix -> master UI Tests on device Test report Cancel PullRequest if test fails
  11. #dfua Nightly build Scheduled Every night on dev branch Runs

    full Test run of All test suits on all relevant Test report Notifies all team with results Notifies all team with results
  12. #dfua Debug deployment Triggered on every pull request: Feature branch

    -> dev Builds debug version of the application Upload debug.apk to your debug build delivery cloud debug .apk
  13. #dfua Debug deployment Triggered manually Builds release version of your

    application Creates a tag with release version Uploads release.apk to google play release.apk
  14. #dfua Release deployment Triggered manually Builds release version of your

    application Creates a tag with release version Uploads release.apk to google play release.apk
  15. #dfua Debug deployment if (project.hasProperty("deployGateToken")) {
 apply plugin: 'deploygate'
 


    deploygate {
 userName = "username"
 token = project.property("deployGateToken")
 }
 
 apks {
 release {
 sourceFile = file('build/outputs/apk/sirix-debug-' + android.defaultConfig.versionName + '.apk')
 }
 }
 }
  16. #dfua Release deployment apply plugin: 'com.github.triplet.play'
 
 play {
 serviceAccountEmail

    = 'your-service-account-email'
 pk12File = file('key.p12')
 track = 'production|betta|alpha'
 uploadImages = true
 }
  17. #dfua Summary Use correct tools Make your tests fast Automate

    build delivery everywhere Use good VCS Use cross platform tools Give gradle a chance Automate you release cycle
  18. #dfua Resource https://www.jetbrains.com/teamcity/documentation/ http://square.github.io/spoon/ http://nvie.com/posts/a-successful-git-branching-model/ https://github.com/Tapadoo/TCSlackNotifierPlugin https://github.com/Triple-T/gradle-play-publisher https://deploygate.com/?locale=en https://get.fabric.io/ https://www.sonatype.com/nexus-repository-sonatype

    http://cyrilmottier.com/2014/12/09/a-story-of-software-development-methodologies/ https://www.reddit.com/r/androiddev/comments/3ig3gm/show_us_your_gradle_tasks/ https://medium.com/@jordanjoz/streamlining-eeros-android-build-process-6a870ef40a89#.1psxvs5kq https://medium.com/fuzz/getting-the-most-out-of-crashlytics-380afb703876#.5vyv6s5hc