æçµçã«ãJenkinsãã«ãã¢ãŒãã£ãã¡ã¯ãããããŠã³ããŒãå¯èœãªããã¹ãã®å®äºã«é¢ããã¬ããŒããšçœ²åæžã¿ã®apkãã¡ã€ã«ãåãåããŸãã
èªåã¢ã»ã³ããªãã»ããã¢ããããããã®èŠä»¶
- Jenkins Essentialãã©ã°ã€ã³
- Android Emulatorãã©ã°ã€ã³
- Gitãã©ã°ã€ã³ïŒgitã䜿çšããå ŽåïŒ
- è€æ°ã®SCMãã©ã°ã€ã³ïŒè€æ°ã®ãªããžããªãæäœããããïŒ
- Xvncãã©ã°ã€ã³ïŒXãµãŒããŒããµãŒããŒã«ã€ã³ã¹ããŒã«ãããŠããªãå Žåã«ãšãã¥ã¬ãŒã¿ãŒãå®è¡ããããïŒ
- Android SDK
ãã¡ãããããŠã³ããŒãããŠãã ãã ã ã»ã¯ã·ã§ã³ä»ã®ãã©ãããã©ãŒã ã®ããŠã³ããŒã-> SDKããŒã«ã®ã¿ - ã°ã©ãã«
ããããã¢ãŒã«ã€ããããŠã³ããŒãã㊠ïŒgradle-**-bin.zipïŒã/ usr / local / libã«è§£åããããšããå§ãããŸã - ç°å¢å€æ°
ANDROID_HOME = / usr / local / lib / android / sdk
GRADLE_HOME = / usr / local / lib / gradle-1.8
JAVA_HOME = / usr / lib / jvm / jdk1.7.0_03
PATH = $ PATHïŒ$ ANDROID_HOME / toolsïŒ$ ANDROID_HOME / platform-toolsïŒ$ JAVA_HOME / binïŒ$ GRADLE_HOME / bin
- ãšãã¥ã¬ãŒã¿ãå®è¡ããã©ã€ãã©ãª
Jenkinsã64ãããOSã§å®è¡ãããå Žåãia32-libsã©ã€ãã©ãªãè¿œå ããå¿ èŠããããŸããè¿œå ããªããšããšãã¥ã¬ãŒã¿ãŒãèµ·åããŸããã
sudo apt-get install ia32-libs
ãã¹ãŠã®èŠä»¶ãæºããããããã»ããã¢ããã«é²ã¿ãŸã
ç§ã®ä»äºã§ã¯Eclipseã䜿çšããŠããããããããžã§ã¯ãã«ã¯ãããã°ãgradleãããžã§ã¯ãïŒandroidStudioã®äœæãªã©ïŒã«å žåçã§ã¯ãªãå€ãæ§é ããããŸãã ãããžã§ã¯ãã®å€èŠ³ã«åºã¥ããŠãããã«äŸã瀺ããŸãã
ãããžã§ã¯ã | -res | -src |-ã¢ã»ãã | -libs | -testsïŒåäœãã¹ããå«ããããžã§ã¯ããå«ããã©ã«ããŒïŒ | -src | -res | -AndroidManifest.xml | -AndroidManifest.xml | -build.gradle | -gradle.properties
ã«ã¹ã¿ãã€ãº
ãŸããéåžžã®ãããžã§ã¯ããã»ããã¢ããããŸãã æåã®ã¹ãããã¯ããããžã§ã¯ãã®ã«ãŒãã«build.gradleãã¡ã€ã«ãäœæããããšã§ã
buile.gradle
ãã¹ããå®è¡ããã«ã¯ãandroid.sourceSetsã®instrumentTestã»ã¯ã·ã§ã³ãæå®ããã ãã§ååã§ãããã®ã»ã¯ã·ã§ã³ã«ã¯ããã¹ããããžã§ã¯ãå
ã®ãã©ã«ããŒãžã®ãã¹ã瀺ãããŸãã Gradleãæ±ã£ããšãããŠããããã¹ããå®è¡ããã«ã¯ãå¥ã®ã¿ã¹ã¯ãäœæããsourceSetsã§å¥ã®ãšã³ããªãäœæããããã«å¿ããŠjunitãè¿œå ããå¿
èŠããããšããèšäºãè€æ°ãããŸããã äžè¬ã«ãç§ã¯ããã«æéãç¡é§ã«ããã ãã§ããã¹ãŠãã¯ããã«ç°¡åã§ãã
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.6+' } } apply plugin: 'android' android { compileSdkVersion 18 buildToolsVersion "18.1.1" defaultConfig { minSdkVersion 8 targetSdkVersion 18 testPackageName "com.project.tests" testInstrumentationRunner "android.test.InstrumentationTestRunner" } sourceSets { main { manifest.srcFile file('AndroidManifest.xml') java.srcDirs = ['src'] resources.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } instrumentTest { java.srcDirs = ['tests/src'] manifest.srcFile file('tests/AndroidManifest.xml') java.srcDirs = ['tests/src'] resources.srcDirs = ['tests/src'] res.srcDirs = ['tests/res'] assets.srcDirs = ['tests/assets'] } } dependencies { compile fileTree(dir: 'libs', include: '*.jar') } // if(project.hasProperty("debugSigningPropertiesPath") && project.hasProperty("releaseSigningPropertiesPath")) { // File debugPropsFile = new File(System.getenv('HOME') + "/" + project.property("debugSigningPropertiesPath")) File releasePropsFile = new File(System.getenv('HOME') + "/" + project.property("releaseSigningPropertiesPath")) if(debugPropsFile.exists() && releasePropsFile.exists()) { Properties debugProps = new Properties() debugProps.load(new FileInputStream(debugPropsFile)) Properties releaseProps = new Properties() releaseProps.load(new FileInputStream(releasePropsFile)) // signingConfigs { debug { storeFile file(debugPropsFile.getParent() + "/" + debugProps['keystore']) storePassword debugProps['keystore.password'] keyAlias debugProps['keyAlias'] keyPassword debugProps['keyPassword'] } release { storeFile file(releasePropsFile.getParent() + "/" + releaseProps['keystore']) storePassword releaseProps['keystore.password'] keyAlias releaseProps['keyAlias'] keyPassword releaseProps['keyPassword'] } } buildTypes { debug { signingConfig signingConfigs.debug } release { signingConfig signingConfigs.release } } } } }
ã¢ããªã±ãŒã·ã§ã³ãžã®çœ²åãæ åœããæ§æã®éšåã以äžã«èª¬æããŸãã æ§æãäœæããããJenkinsã®æ§æã«é²ã¿ãŸãã
ãžã§ã³ãã³ã¹ã®ã»ããã¢ãã
æåã®ã¹ãããã¯ããããžã§ã¯ãã§ãªããžããªãæå®ããããšã§ãã 次ã«ã2ã€ã®ãªãã·ã§ã³ã®ãããããéžæããå¿ èŠããããã«ãäžã«Androidãšãã¥ã¬ãŒã¿ãŒãå®è¡ãéžæããå¿ èŠããããŸããæ¢åã®ãšãã¥ã¬ãŒã¿ãŒã®ååãæå®ããããæ°ãããšãã¥ã¬ãŒã¿ãŒãéå§ãããã©ã¡ãŒã¿ãŒãæå®ããŸãã åæã«ã ãšãã¥ã¬ãŒã¿ãŠã£ã³ããŠã衚瀺ããé ç®ã«ãã§ãã¯ãå ¥ãããŸãŸã«ããŸãã
次ã®ã¹ãããã¯ã Invoke Gradleã¹ã¯ãªããã¢ã»ã³ããªã¹ããããè¿œå ãã Gradleã«å¿ èŠãªã³ãã³ããæå®ããããšã§ãã ãã¹ãããã«ãããŠå®è¡ããã«ã¯ãbuildãšconnectedCheckãæå®ããã ãã§ã

æåŸã«ãã¢ã»ã³ããªåŸã«å®è¡ãããã¢ã¯ã·ã§ã³ãè¿œå ããå¿ èŠããããŸãã
1. JUnitãã¹ãçµæã¬ããŒããçºè¡ããŸãïŒãŠããããã¹ãã®å®è¡ã«é¢ããã¬ããŒããçºè¡ããŸãïŒã å®äºãããã¹ãã®ã¬ããŒããå«ãxmlãã¡ã€ã«ã®è¡ã«ã次ã®ãã¹ãèšè¿°ããå¿ èŠããããŸãã
**/build/instrumentTest-results/*/*.xml
Gradleã¯ãhtmlãšxmlã®2çš®é¡ã®ã¬ããŒããäœæããŸãã HTMLã¬ããŒãã¯build / reports / instrumentTests / connected /ãã©ã«ããŒã«ãããŸãããJenkinsã®å Žåã¯xmlã¬ããŒããæå®ããå¿ èŠããããŸãã
2.ã¢ãŒãã£ãã¡ã¯ããã¢ãŒã«ã€ãããŸã ïŒã¢ãŒãã£ãã¡ã¯ãããã³ã³ãã€ã«æžã¿ã®çœ²åæžã¿ã¢ããªã±ãŒã·ã§ã³ãçŽæ¥ããŠã³ããŒãã§ããŸãïŒã ã¢ãŒã«ã€ãã®ãã¡ã€ã«ãã¹ïŒ
**/build/apk/workspace-release.apk
ã¢ããªã±ãŒã·ã§ã³ãžã®çœ²åã«æ»ããŸã
ã¢ããªã±ãŒã·ã§ã³çœ²å
ã¢ããªã±ãŒã·ã§ã³ã«çœ²åããã«ã¯ãkeytoolãŠãŒãã£ãªãã£ã䜿çšããŠããŒãäœæããå¿ èŠããããŸããããã¯ãã¢ããªã±ãŒã·ã§ã³éçºè ã«é¢ããããŒã¿ãä¿åããŸãã äœæããæšæºã³ãã³ãã¯æ¬¡ã®ãšããã§ãã
keytool -genkey -v -alias appAlias -keyalg RSA -keysize 2048 -keystore release.keystore -validity 10000
ãšã€ãªã¢ã¹ãã©ã¡ãŒã¿ã¯åã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšããå¿ èŠããããã¢ããªã±ãŒã·ã§ã³ã«çœ²åãããšãã«æå®ããå¿ èŠããããŸãã
ã»ãã¥ãªãã£äžã®çç±ãããããŒã¯ããŒãžã§ã³ç®¡çã·ã¹ãã ã®äžã«ä¿ç®¡ããªãã§ãã ããã ãã®ããŒããããšãä»ã®ã¢ããªã±ãŒã·ã§ã³ã«çœ²åã§ããŸãããã·ã¹ãã ã¯ãããåäžã®ãã®ãšããŠèªèããŸãã ãããã£ãŠããã¡ã€ã«ã¯CIãµãŒããŒã«çŽæ¥ä¿åããå¿ èŠããããŸãã
ãããã®èæ ®äºé ã«åºã¥ããŠãgradle.propertiesãã¡ã€ã«ããããžã§ã¯ãã«ãŒãã«è¿œå ããŸããã
releaseSigningPropertiesPathã®å€ã¯ãããŒã®ãã©ã¡ãŒã¿ãŒïŒãã¹ã¯ãŒããšãšã€ãªã¢ã¹ïŒãæã€ãã¡ã€ã«ãé 眮ãããŠãããã¹ïŒããŒã ãã£ã¬ã¯ããªã®ã/ .androidSigning /ãåºæºãšããïŒãæããŸãã ãããžã§ã¯ãã®å Žåã次ã®4ã€ã®ãã¡ã€ã«ããã®ãã©ã«ããŒã«ä¿åããå¿ èŠããããŸããreleaseSigningPropertiesPath=.androidSigning/releaseProperties debugSigningPropertiesPath=.androidSigning/debugProperties
release.keystore-ãªãªãŒã¹ãã«ãã¢ããªã±ãŒã·ã§ã³ã®ããŒ
releaseProperties-ãªãªãŒã¹ããŒã®ãã©ã¡ãŒã¿ãŒ
debug.keystore-ã¢ããªã±ãŒã·ã§ã³ã®ãã«ãããããã°ããããã®ããŒ
debugProperties-ãããã°ããŒã®ãã©ã¡ãŒã¿ãŒ
*ããããã£ãã¡ã€ã«ã®ããããã¯ã次ã®æ§é ãæã€å¿ èŠããããŸãã
keystore=- ( ) keystore.password= keyAlias=alias keyPassword=
äŸïŒ
keystore=release.keystore keystore.password=mypassword keyAlias=appAlias keyPassword=mypassword
ãããã®ãã©ã¡ãŒã¿ãŒã¯ãã¹ãŠãããŒã®äœææã«æå®ãããŸãã
ä»ã®ãã¹ãŠã®ã¢ã¯ã·ã§ã³ã¯build.gradleãã¡ã€ã«ã§æå®ãããŸããã Gradleã«ãšã£ãŠäŸ¿å©ãªã®ã¯ãæ§æå ã§éåžžã®Javaã³ãŒããå®è¡ã§ããããšã§ããããã«ãããåæ§ã®çœ²åã¡ã«ããºã ãäœæã§ããŸãã ããã§ãã¢ã»ã³ããªãå®å šã«å®è¡ãã眲åæžã¿ã§ãã¹ãæžã¿ã®ã¢ããªã±ãŒã·ã§ã³ãååŸã§ããŸãã
次ã«ãã©ã€ãã©ãªã¢ããªã±ãŒã·ã§ã³ã䜿çšããã¢ããªã±ãŒã·ã§ã³ãäœæãã2çªç®ã®äŸãèŠãŠã¿ãŸãããã
android-libraryã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯
ç§ã®å Žåããããžã§ã¯ããšãããžã§ã¯ãã©ã€ãã©ãªã¯ç°ãªããªããžããªã«ãããŸãã Jenkinsã®è€æ°ã®ãªããžããªãæäœã§ããããã«ããã«ã¯ãMultiple SCMs Pluginãã©ã°ã€ã³ãã€ã³ã¹ããŒã«ããå¿ èŠããããŸãã æåã®ããšã¯ãåã³gradleã®æ§æãäœæããããšã§ãã æåã®ãã¡ã€ã«ã¯ã©ã€ãã©ãªãããžã§ã¯ãã«ãããŸã
ã©ã€ãã©ãªbuild.gradle
ãããžã§ã¯ãã©ã€ãã©ãªã®äž»ãªéãã¯ãé©çšããããã©ã°ã€ã³ã§ãïŒapply pluginïŒ 'android-library'
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.6.3' } } apply plugin: 'android-library' android { compileSdkVersion 18 buildToolsVersion "19.0.0" defaultConfig { minSdkVersion 8 targetSdkVersion 18 testPackageName "com.project.tests" testInstrumentationRunner "android.test.InstrumentationTestRunner" } sourceSets { main { manifest.srcFile file('AndroidManifest.xml') java.srcDirs = ['src'] resources.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } instrumentTest { manifest.srcFile file('tests/AndroidManifest.xml') java.srcDirs = ['tests/src'] resources.srcDirs = ['tests/src'] res.srcDirs = ['tests/res'] assets.srcDirs = ['tests/assets'] } } dependencies { compile fileTree(dir: 'libs', include: '*.jar') } }
2çªç®ã®æ§æã¯æ¢ã«ãããžã§ã¯ãå ã«ãããŸã
ãããžã§ã¯ãbuild.gradle
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.6.3' } } apply plugin: 'android' android { compileSdkVersion 18 buildToolsVersion "19.0.0" defaultConfig { minSdkVersion 8 targetSdkVersion 18 } sourceSets { main { manifest.srcFile file('AndroidManifest.xml') java.srcDirs = ['src'] resources.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } } dependencies { compile fileTree(dir: 'libs', include: '*.jar') compile project(':MyLibrary') } // if(project.hasProperty("debugSigningPropertiesPath") && project.hasProperty("releaseSigningPropertiesPath")) { // File debugPropsFile = new File(System.getenv('HOME') + "/" + project.property("debugSigningPropertiesPath")) File releasePropsFile = new File(System.getenv('HOME') + "/" + project.property("releaseSigningPropertiesPath")) if(debugPropsFile.exists() && releasePropsFile.exists()) { Properties debugProps = new Properties() debugProps.load(new FileInputStream(debugPropsFile)) Properties releaseProps = new Properties() releaseProps.load(new FileInputStream(releasePropsFile)) // signingConfigs { debug { storeFile file(debugPropsFile.getParent() + "/" + debugProps['keystore']) storePassword debugProps['keystore.password'] keyAlias debugProps['keyAlias'] keyPassword debugProps['keyPassword'] } release { storeFile file(releasePropsFile.getParent() + "/" + releaseProps['keystore']) storePassword releaseProps['keystore.password'] keyAlias releaseProps['keyAlias'] keyPassword releaseProps['keyPassword'] } } buildTypes { debug { signingConfig signingConfigs.debug } release { signingConfig signingConfigs.release } } } } }
次ã«ãJenkinsã§ãªããžããªãæ£ããæå®ããå¿ èŠããããŸãã
åã®äŸãšã¯ç°ãªãããã®å ŽåãããœãŒã¹ç®¡çãã»ã¯ã·ã§ã³ã§ãç¹å®ã®ããŒãžã§ã³ç®¡çã·ã¹ãã ã§ã¯ãªããè€æ°ã®SCMããéžæããå¿ èŠããããŸãã ãã®åŸãã·ã¹ãã ãè¿œå ãããªããžããªãžã®ãã¹ãæå®ã§ããŸãã 1ã€ç®ã¯ãããžã§ã¯ãã§ãªããžããªãæå®ããããšã2ã€ç®ã¯ã©ã€ãã©ãªã§æå®ããããšã§ããäžæ¹ãã©ã€ãã©ãªã䜿çšãããªããžããªã§ã¯ãã³ãŒããé 眮ããããã©ã«ãã®ååãå«ãè¿œå èšå®ããµããã£ã¬ã¯ããªã«ãã§ãã¯ã¢ãŠãããæå®ããå¿ èŠããããŸãã ãã®ãã©ã«ããŒã®ååã¯ãbuild.gradleãã¡ã€ã«å ã®äŸåé¢ä¿ã§æå®ãããããžã§ã¯ãã®ååãšäžèŽããå¿ èŠããããŸãïŒãã®äŸã§ã¯MyLibraryïŒã
compile project(':MyLibrary')
ãããã£ãŠãäœæ¥ãã£ã¬ã¯ããªã¯éåžžã®ãããžã§ã¯ãã®ããã«èŠããã©ã€ãã©ãªãé 眮ãããMyLibraryãã©ã«ãã1ã€ã ãè¿œå ãããŸãã
ä»ã®ãã¹ãŠã®èšå®ã¯ãéåžžã®ãããžã§ã¯ãã®èšå®ãšãŸã£ããåãã§ãã
ããŒãã¹ãšããŠ
ç§ã®ãããžã§ã¯ãã§ã¯ãããŸããŸãªç°å¢ã§äœæ¥ããå¿ èŠããããŸãã ããšãã°ãã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãããŒãžã§ã³ã®å Žåãéçºããã»ã¹äžã«ãèŠæ±ãéä¿¡ããããŒã¿ãåä¿¡ããããã«ããã¹ããµãŒããŒã«ããŒã«ã«ãµãŒããŒã«éä¿¡ããå¿ èŠããããŸãã ãããã£ãŠã3ã€ã®å žåçãªç°å¢devãstageãããã³prodãåºå¥ã§ããŸãã res / values / environment.xmlãã¡ã€ã«ã®ã¢ããªã±ãŒã·ã§ã³ãªãœãŒã¹ã«é 眮ããç°å¢ã«å¿ããèšå®ã«ã¯ãããŒã¿ãé©çšããå¿ èŠãããURLãå«ãŸããŠããŸãã ç¹å®ã®ç°å¢ã®èšå®ãã¡ã€ã«ããdev.xmlãstage.xmlãprod.xmlã®3ã€ã®èšå®ãã¡ã€ã«ãå«ãåå¥ã®ç°å¢ãã©ã«ããŒã«é 眮ããŸãã ã¢ããªã±ãŒã·ã§ã³ãå¿ èŠãªç°å¢ã§åäœããããã«ã¯ãenvironment.xmlã®ä»£ããã«ãããã®ãã¡ã€ã«ã®1ã€ã眮ãæããã ãã§ãã
ãããè¡ãã«ã¯ãJenkinsã§ãã¢ã»ã³ããªã®æåã®ã¹ããããšããŠã·ã§ã«ã³ãã³ãlaunchãè¿œå ãã次ãæå®ããå¿ èŠããããŸãã
cp $WORKSPACE/environment/prod.xml $WORKSPACE/res/values/environment.xml
䟿å©ãªãªã³ã¯
www.gradle.org/docs/current/javadoc-Gradleããã¥ã¡ã³ã
tools.android.com/tech-docs/new-build-system/user-guide technical documentation
tools.android.com/recent/updatingsdkfromcommand-line-ã³ã³ãœãŒã«çµç±ã§Android SDKãæŽæ°ããŸãïŒXããªãå ŽåïŒ
vimeo.com/34436402-gradle wrapperã®åäœã説æãããããª