【问题标题】:How do I build from a Git repository subdirectory with Jenkins & Ant?如何使用 Jenkins 和 Ant 从 Git 存储库子目录构建?
【发布时间】:2012-05-15 13:02:58
【问题描述】:

我已将 Jenkins CI 配置为与 GitHub 一起使用。它成功填充了我的 ${workspace} 但我要构建的实际项目位于 repo 的子目录中:

https://github.com/androidfu/CodeExamples

从 Jenkins 中调用 Ant 表明它找不到 build.xml。嗯,那是因为 build.xml 实际上存在于 ${workspace}/DeveloperDebugPreferences 中。

【问题讨论】:

    标签: android git ant jenkins gitosis


    【解决方案1】:

    您可以为 Ant 配置构建文件以在 Jenkins 中使用。如果您正在浏览 Jenkins 服务器上的作业,您可以选择配置,然后选择 Ant 目标下方的高级选项。

    如果您想编辑您的 config.xml 文件,您应该会看到类似这样的构建设置:

    <builders>
      <hudson.tasks.Ant>
        <targets>your_target_name</targets>
        <buildFile>${workspace}/DeveloperDebugPreferences/build.xml</buildFile>
      </hudson.tasks.Ant>
    </builders>
    

    【讨论】:

    • 好答案,但硬编码 config.xml 代替特定的 JOB。我会说这不是一个好习惯。
    【解决方案2】:

    我想更进一步,创建一个在提交到 Git 时启动的构建系统,它会检查代码,构建它并通过 SSH 发布它。此外,我希望在文件名中标记构建的提交。第一步是使用 git 中的 post-receive 和本地安装的 Jenkins 启动构建过程。如果它是远程的,您需要指定一个 URL 并使用 wget 或 curl。作为参考,这是我们的Git branching model


    Git 后接收

    # 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。由于该服务器仅托管 git 和 Jenkins,并且 Eclipse 和 Xcode 环境安装在 Mac Mini 上,我们将其用作构建服务器,Jenkins 被配置为使用带有证书的 SSH 进行登录。 Jenkins 服务器通过 SSH 连接到构建服务器,签出代码,构建代码,然后通过 SSH 将结果发送到我们的软件架。唯一特殊的部分是使这项工作起作用的 Ant build.xml 部分。

    在 Build - Execute Shell - 我们放置的命令

    ~/android-sdks/tools/android update project -p "$WORKSPACE/OurProject" 
    

    在调用 Ant 下

    -buildfile "$WORKSPACE/OurProject/build.xml" clean debug
    

    ant.properties

    这是我们放置有关用于签署二进制文件的密钥库的信息的地方。

    key.store=ourProject.keystore
    key.alias=release
    key.store.password=aBigSecret
    key.alias.password=aBigSecret
    

    build.xml

    因此,在项目 build.xml 中,我们覆盖了几个目标,以使 git 提交哈希出现在文件名中。例如,OurProject 1.0.0 (deadbeef)-release.apk。构建完成后,Jenkins 将文件复制到我们的软件架。

    <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');
    

    总之,这个系统提供了一个完整的构建系统,它允许您将特定的二进制文件追溯到特定的提交。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-22
      • 1970-01-01
      • 2015-05-15
      相关资源
      最近更新 更多