developing android plugin
play

developing android plugin android - PowerPoint PPT Presentation

developing android plugin android team lead TFS Android


  1. developing android plugin Сергей Боиштян

  2. обо мне android преподаю team lead разработчик в TFS Android член один программного один из ведущих архитектор из организаторов комитета #AndroidDevPodcast « Mosdroid » « Mobius » 2

  3. о чем поговорим о проблеме о том как связать task o том как писать для которой мне из своего plugin plugin понадобился plugin со сторонними 3

  4. предисловие например сделать apk для тестирования появилось много ответственностей связанных с процессом я стал «Лидом»/ «Архитектором» 4

  5. сделать сборку тестировщику саму сборку не просто понять, что сделать просто: тестировать на сборке • задача и сборка не связаны • сделать apk • может быть несколько сборок • залить в hockeyapp, Beta параллельно 5

  6. алгоритм решения 1 2 3 4 перевести проставить отправить сделать apk задачи внутри в hockeyapp, versionname, в нужный задач beta versioncode, статус версию archivename для связи связать с со сборкой версией 6

  7. алгоритм решения apk JIRA hockeyAPP версия статус c вязать apk в задачах задач c версией 7

  8. проблемы нет явного триггера для действия много шагов можно заболеть легко забыть что - нибудь 8

  9. 9

  10. когда «накипело» начал искать оказалось, что их и было то, которое решения много я взял за основу 10

  11. решение, взятое за основу есть специальная ветка в git задачи меняют а pk попадает статус в hockeyApp она собирает apk versionName, versionCode проставляются в нее попадают в задаче изменения versioncode — триггерится versionname teamcity сборка на ci берется buildnumber из локального файла 11

  12. алгоритм решения инкремент commit versionCode git teamcity проставить в задаче APK versioncode, versionCode=buildNumber versionname versionName= из файла поменять статус задачам hockeyAPP JIRA 12

  13. недостатки решения для инкремента versionCode = триггерим версии нужно синтетический вручную сделать commit buildNumber 13

  14. что я улучшил что позволило автоматизировать изменил инкремент версии триггер, для формирования сборки 14

  15. инкремент версии: формат формат — Semantic Versioning Specification MAJOR.MINOR.PATCH 1.0.0-rc1 1.1.1-rc2 1.2.3-beta 15

  16. инкремент версии: хранение git tag -a 1.0.0-rc1 - m ‘message’ • не ломает историю • легче добавить/удалить на remote • своя система прав 16

  17. триггер инкремента версии когда появились задачи в нужном статусе в JIRA 17

  18. реализация инкремента версии доработал https://github.com/gladed/gradle-android-git-version реализовал инкремент Из 1.1.0 -rc10 в 1.1.1 -rc1 Из 1.1.1 -rc1 в 1.1.1 -rc2 Из 1.1.10 -rc2 в 1.2.1 -rc1 18

  19. реализация инкремента версии добавил: • запись в tag • push tag в remote 19

  20. мое решение инкремент versionCode появление задач в Jira teamcity проставить в задаче apk versioncode, versionCode= git tag versionname versionName= git tag поменять статус задачам hockeyAPP JIRA 20

  21. автоматизируем ➔ bash ➔ fastline (ruby) ➔ gradle ➔ etc. 21

  22. почему gradle? возможность писать нативная система плагинная на java, kotlin, scala :? сборки система но кого я обманываю groovy 22

  23. знакомство build script build script plugin writer plugin writer app developer writer writer plugin writer 23

  24. gadle plugin легко шарить легче поддерживать легче тестировать 24

  25. структура плагина ➔ это gradle проект ➔ build.gradle ➔ plugin class ➔ descriptor ➔ one or more tasks ➔ extension 25

  26. структура плагина plugin extention task descriptor build.gradle 26

  27. структура плагина apply plugin: 'groovy' apply plugin: 'idea' repositories { mavenCentral() } dependencies { compile localGroovy() compile gradleApi() compile 'commons-io:commons-io:2.4' testCompile 'junit:junit:4.12' } 27

  28. plugin class c оздание c вязь c оздание extension с build chain task 28

  29. plugin class class HockeyAppPlugin implements Plugin<Project> { void apply(Project project) { project.extensions.create('hockeyapp', HockeyAppPluginExtension, project) if (project.plugins.hasPlugin(AppPlugin)) { AppExtension android = project.android android.applicationVariants.all { variant -> def taskName = "upload${variant.name.capitalize()}ToHockeyApp" def uploadTask = project.tasks.create(taskName, HockeyAppUploadTask) uploadTask.group = 'HockeyApp' uploadTask.dependsOn variant.assemble } } } } 29

  30. plugin class — create task class HockeyAppPlugin implements Plugin<Project> { void apply(Project project) { project.extensions.create('hockeyapp', HockeyAppPluginExtension, project) if (project.plugins.hasPlugin(AppPlugin)) { AppExtension android = project.android android.applicationVariants.all { variant -> def taskName = "upload${variant.name.capitalize()}ToHockeyApp" def uploadT adTas ask = projec ect.tas asks.cr creat ate(tas askNam ame, Hockey eyAp AppUp UploadT adTas ask) uploadTask.group = 'HockeyApp' uploadTask.dependsOn variant.assemble } } } } 30

  31. plugin class — extention class HockeyAppPlugin implements Plugin<Project> { void apply(Project project) { projec ect.ex exten ension ions.cre creat ate('hock ockey eyapp app', Hockey ckeyAppPlug uginE nExtens xtension on) //... } } } 31

  32. plugin class — связь с build chain class HockeyAppPlugin implements Plugin<Project> { void apply(Project project) { project.extensions.create('hockeyapp', HockeyAppPluginExtension, project) if (project.plugins.hasPlugin(AppPlugin)) { AppExtension android = project.android android.applicationVariants.all { variant -> def taskName = "upload${variant.name.capitalize()}ToHockeyApp" def uploadTask = project.tasks.create(taskName, HockeyAppUploadTask) uploadTask.group = 'HockeyApp' upload adTask Task.de depe pends ndsOn On variant iant.asse semb mble le } } } 32 }

  33. task class HockeyAppUploadTask extends DefaultTask { @TaskAction def upload() throws IOException { //... } 33

  34. task — group name class HockeyAppPlugin implements Plugin<Project> { void apply(Project project) { project.extensions.create('hockeyapp', HockeyAppPluginExtension, project) if (project.plugins.hasPlugin(AppPlugin)) { AppExtension android = project.android android.applicationVariants.all { variant -> def taskName = "upload${variant.name.capitalize()}ToHockeyApp" def uploadTask = project.tasks.create(taskName, HockeyAppUploadTask) upload adTask Task.gro group up = 'Hocke ckeyApp' p' } } } } 34

  35. extension for users hockeyapp { notify = 1 status = 2 notesType = 0 releaseType = 0 teamCityLog = true repositoryUrl = '' variantToApplicationId = [] } 35

  36. extention class class HockeyAppPluginExtension { def Object outputDirectory def File symbolsDirectory = null def String apiToken = null def Map<String, String> variantToApiToken = null def Map<String, String> variantToNotes = null def String status = 2 def String strategy = "add" def String notify = 0 def Map<String, String> variantToNotify = null //... } 36

  37. find extention HockeyAppPluginExtension hockeyApp = project.hockeyapp 37

  38. descriptor implementation-class=de.felixschulze.gradle.HockeyAppPlugin apply plugin: ‘descriptor file name’ 38

  39. подключение к своему проекту In build.gradle apply plugin: ‘descriptor file name' hockeyapp { //... } 39

Recommend


More recommend