Как выполнить сборку из подкаталога репозитория Git с помощью Jenkins & Ant?
У меня есть Jenkins CI, настроенный для работы с GitHub. Он успешно заполняет мое $ {workspace}, но фактический проект, который я хочу построить, находится в подкаталоге repo:
Https://github.com/androidfu/CodeExamples
Вызов Ant изнутри Дженкинса утверждает, что он не может найти build.XML. Ну, это потому что строят.xml фактически существует в ${workspace} / DeveloperDebugPreferences.
2 ответов:
Вы можете настроить файл сборки для использования Ant в Jenkins. Если вы просматриваете задание на вашем сервере Jenkins, вы можете выбрать Configure, а затем расширенный вариант под вашей целью Ant.
Если вы предпочитаете редактировать свой файл
config.xml, Вы должны увидеть настройки сборки примерно так:<builders> <hudson.tasks.Ant> <targets>your_target_name</targets> <buildFile>${workspace}/DeveloperDebugPreferences/build.xml</buildFile> </hudson.tasks.Ant> </builders>
Я хотел пойти немного дальше и сделать систему сборки, которая начиналась с фиксации в Git, которая проверяла бы код, собирала его и публиковала через SSH. Кроме того, я хотел, чтобы коммит для сборки был помечен в имени файла. Первым шагом является запуск процесса сборки с использованием post-receive в git и локально установленного Jenkins. Если бы он был удаленным, вам нужно было бы указать URL-адрес и использовать wget или curl. Для справки это нашамодель ветвления Git .
Git post-receive
# This must be read using read because the values are passed on # STDIN not as command-line arguments. read OLDREV NEWREV REFNAME BRANCH=${REFNAME#refs/heads/} . /usr/share/doc/git-core/contrib/hooks/post-receive-email if [ ${BRANCH} == "master" ]; then /usr/local/bin/jenkins-start "Our Project - Android - Releases" elif [ ${BRANCH} == "develop" ]; then /usr/local/bin/jenkins-start "Our Project - Android - Development" fiДженкинс
Сторона разработки вещей в основном идентична релизам, но вместо master мы строим на фиксации в ветке develop. Так как на этом сервере размещены только git и Jenkins, а среды Eclipse и Xcode установлены на Mac Mini, который мы используем в качестве сервера сборки, Jenkins настроен на использование SSH с сертификатами для входа. Сервер Дженкинса SSHs к серверу сборки, проверяет код, строит код, и SSHs результат к нашему готовое программное обеспечение. Единственная особая часть - это муравьиная сборка.xml часть, которая делает эту работу.
Под командой Build-Execute Shell ставим
~/android-sdks/tools/android update project -p "$WORKSPACE/OurProject"При Вызове Ant
-buildfile "$WORKSPACE/OurProject/build.xml" clean debugМуравей.свойства
Здесь мы размещаем информацию о хранилище ключей для подписи двоичного файла.
key.store=ourProject.keystore key.alias=release key.store.password=aBigSecret key.alias.password=aBigSecretПостроить.xml
Итак, в проекте build.xml мы переопределяем несколько целевых объектов, чтобы хэш git commit появился в имени файла. Например, OurProject 1.0.0 (deadbeef) - освобождение.АПК. После того как это сделано Дженкинс копирует файл на компьютер.
<target name="-set-debug-files" depends="-set-mode-check"> <exec executable="git" outputproperty="git.revision" failifexecutionfails="false" errorproperty=""> <arg value="rev-parse"/> <arg value="--short"/> <arg value="HEAD"/> </exec> <xpath input="AndroidManifest.xml" expression="/manifest/@android:versionName" output="android.app.version.name" default="Unknown" /> <property name="out.packaged.file" location="${out.absolute.dir}/${ant.project.name}-debug-unaligned.apk" /> <property name="out.final.file" location="${out.absolute.dir}/${ant.project.name}-${android.app.version.name} (${git.revision})-debug.apk" /> <property name="build.is.mode.set" value="true" /> </target> <target name="-set-release-mode" depends="-set-mode-check"> <exec executable="git" outputproperty="git.revision" failifexecutionfails="false" errorproperty=""> <arg value="rev-parse"/> <arg value="--short"/> <arg value="HEAD"/> </exec> <xpath input="AndroidManifest.xml" expression="/manifest/@android:versionName" output="android.app.version.name" default="Unknown" /> <property name="out.packaged.file" location="${out.absolute.dir}/${ant.project.name}-release-unsigned.apk" /> <property name="out.final.file" location="${out.absolute.dir}/${ant.project.name}-${android.app.version.name} (${git.revision})-release.apk" /> <property name="build.is.mode.set" value="true" /> <!-- record the current build target --> <property name="build.target" value="release" /> <property name="build.is.instrumented" value="false" /> <!-- release mode is only valid if the manifest does not explicitly set debuggable to true. default is false. --> <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:debuggable" output="build.is.packaging.debug" default="false"/> <!-- signing mode: release --> <property name="build.is.signing.debug" value="false" /> <!-- Renderscript optimization level: aggressive --> <property name="renderscript.opt.level" value="${renderscript.release.opt.level}" /> <if condition="${build.is.packaging.debug}"> <then> <echo>*************************************************</echo> <echo>**** Android Manifest has debuggable=true ****</echo> <echo>**** Doing DEBUG packaging with RELEASE keys ****</echo> <echo>*************************************************</echo> </then> <else> <!-- property only set in release mode. Useful for if/unless attributes in target node when using Ant before 1.8 --> <property name="build.is.mode.release" value="true"/> </else> </if> </target>Полка Программного Обеспечения
Это просто общедоступная веб-страница, где PHP-скрипт отображает сборки в порядке дат.
Таким образом, эта система предоставляет полную систему сборки и позволяет отслеживать конкретный двоичный файл до конкретной фиксации.<?php require('header.html'); ?> <h2>All builds</h2> <table> <?php $dir = dirname($_SERVER[SCRIPT_FILENAME]); $filenames = scandir($dir); $files = array(); $fileTimes = array(); $j = 0; $n = count($filenames); for ($i = 0; $i < $n; $i++) { $filename = $filenames[$i]; if ( is_file($filename) && pathinfo($filename, PATHINFO_EXTENSION) == "apk" ) { $time = filemtime($filename); $files[$j] = array("name"=>$filename, "time"=>$time ); $fileTimes[$j] = $time; $j++; } } array_multisort($fileTimes, SORT_DESC, $files); $tablerow_classes = array("t0", "t1"); $current_class = 0; $m = count($files); for ( $i = 0; $i < $m; $i++ ) { $name = $files[$i]["name"]; $time = date ("d/m/Y H:i:s", $files[$i]["time"]); $class = $tablerow_classes[$current_class]; $current_class++; if ( $current_class > 1 ) { $current_class = 0; } echo "<tr class=\"$class\"><td><a href=\"$name\">$name</a></td><td>$time<br /></tr>"; } ?> </table> <?php require('footer.html');
Comments