【问题标题】:Passing Parameters to Ant from Jenkins Ant Plugin从 Jenkins Ant 插件向 Ant 传递参数
【发布时间】:2015-08-24 16:24:11
【问题描述】:

我在尝试创建一个 Jenkins 项目时观察到一个奇怪的行为,该项目的 Ant 步骤接受任何由 Ant 使用的 String 参数。看起来 Ant 以某种方式接收了一些格式错误的内容作为参数。

首先我登录了安装 Jenkins 的同一系统并编写了一个简单的 ant 构建文件:

<?xml version="1.0"?>
<!--DOCTYPE project PUBLIC "-//ANT//DTD project//EN" "/usr/src/ant/project.dtd"-->
<project name="many-params" default="run">
    <target name="run">
        <echo message="first Param: ${firstparam}"/>
        <echo message="second Param: ${secondparam}"/>
    </target>
</project>

然后我用设置的参数运行 ant 并得到预期的输出:

$ ant -Dfirstparam=A -Dsecondparam=B
Buildfile: /tmp/build-dir/build.xml

run:
     [echo] first Param: A
     [echo] second Param: B

BUILD SUCCESSFUL
Total time: 0 seconds

接下来,我去设置一个项目,在 Jenkins 中做同样的事情。我的 Jenkins 系统规格如下:

  • 操作系统: Linux amd64 2.6.32-504.1.3.el6.x86_64
  • 詹金斯:版本。 1.618
  • JRE Jenkins 正在运行: Oracle 1.7.0_55-b13
  • 蚂蚁插件版本: 1.2
  • 项目使用的 JRE: Oracle 1.6.45 32 位
  • 项目使用的 Ant: 1.8.2

我已经设置了 8 个连续步骤的工作,4 个准备性的 shell 脚本片段,用稍微不同的参数名称(没有分隔符、破折号分隔符、点分隔符)重写 build.xml 和 4 个调用 ant 的 Ant 构建步骤,试图传递相应的参数。

作业目录中准备好的 config.xml 如下所示:

<?xml version='1.0' encoding='UTF-8'?>                                                                                                                                                                                                  
<project>                                                                                                                                                                                                                               
  <actions/>                                                                                                                                                                                                                            
  <description>A simple task to test many parameter setting for jenkins calling ant tasks</description>                                                                                                                                 
  <logRotator class="hudson.tasks.LogRotator">                                                                                                                                                                                          
    <daysToKeep>-1</daysToKeep>                                                                                                                                                                                                         
    <numToKeep>10</numToKeep>                                                                                                                                                                                                           
    <artifactDaysToKeep>-1</artifactDaysToKeep>                                                                                                                                                                                         
    <artifactNumToKeep>-1</artifactNumToKeep>                                                                                                                                                                                           
  </logRotator>                                                                                                                                                                                                                         
  <keepDependencies>false</keepDependencies>                                                                                                                                                                                            
  <scm class="hudson.scm.NullSCM"/>                                                                                                                                                                                                     
  <canRoam>true</canRoam>                                                                                                                                                                                                               
  <disabled>false</disabled>                                                                                                                                                                                                            
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>                                                                                                                                                            
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>                                                                                                                                                                
  <jdk>Oracle Java 1.6.45 32-bit JRE</jdk>                                                                                                                                                                                              
  <triggers/>                                                                                                                                                                                                                           
  <concurrentBuild>false</concurrentBuild>                                                                                                                                                                                              
  <builders>                                                                                                                                                                                                                            
    <hudson.tasks.Shell>                                                                                                                                                                                                                
      <command>echo &quot;STEP 1: Pass parameters with no separators in names&quot;                                                                                                                                                     
cat &gt; build.xml &lt;&lt; EOF                                                                                                                                                                                                         
&lt;?xml version=&quot;1.0&quot;?&gt;                                                                                                                                                                                                   
&lt;!--DOCTYPE project PUBLIC &quot;-//ANT//DTD project//EN&quot; &quot;/usr/src/ant/project.dtd&quot;--&gt;                                                                                                                            
&lt;project name=&quot;many-params&quot; default=&quot;run&quot;&gt;                                                                                                                                                                    
    &lt;target name=&quot;run&quot;&gt;                                                                                                                                                                                                 
        &lt;echo message=&quot;first Param: ${paramfirst}&quot;/&gt;                                                                                                                                                                    
        &lt;echo message=&quot;second Param: ${paramsecond}&quot;/&gt;                                                                                                                                                                  
    &lt;/target&gt;                                                                                                                                                                                                                     
&lt;/project&gt;                                                                                                                                                                                                                        
EOF</command>                                                                                                                                                                                                                           
    </hudson.tasks.Shell>                                                                                                                                                                                                               
    <hudson.tasks.Ant plugin="ant@1.2">                                                                                                                                                                                                 
      <targets>run</targets>                                                                                                                                                                                                            
      <antName>Ant 1.8.2</antName>                                                                                                                                                                                                      
      <properties>paramfirst=A                                                                                                                                                                                                          
paramsecond=B</properties>                                                                                                                                                                                                              
    </hudson.tasks.Ant>                                                                                                                                                                                                                 
    <hudson.tasks.Shell>                                                                                                                                                                                                                
      <command>rm build.xml
echo
echo &quot;STEP 2: Pass parameters with separated by dashes in names&quot;
cat &gt; build.xml &lt;&lt; EOF
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;!--DOCTYPE project PUBLIC &quot;-//ANT//DTD project//EN&quot; &quot;/usr/src/ant/project.dtd&quot;--&gt;
&lt;project name=&quot;many-params&quot; default=&quot;run&quot;&gt;
    &lt;target name=&quot;run&quot;&gt;
        &lt;echo message=&quot;first Param: ${param-first}&quot;/&gt;
        &lt;echo message=&quot;second Param: ${param-second}&quot;/&gt;
    &lt;/target&gt;
&lt;/project&gt;
EOF</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Ant plugin="ant@1.2">
      <targets>run</targets>
      <antName>Ant 1.8.2</antName>
      <properties>param-first=A
param-second=B</properties>
    </hudson.tasks.Ant>
    <hudson.tasks.Shell>
      <command>echo
echo &quot;STEP 3: Same, but with parameters on the same line in Ant Plugin step setup&quot;</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Ant plugin="ant@1.2">
      <targets>run</targets>
      <antName>Ant 1.8.2</antName>
      <properties>param-first=A param-second=B</properties>
    </hudson.tasks.Ant>
    <hudson.tasks.Shell>
      <command>rm build.xml
echo
echo &quot;STEP 4: Pass parameters with separated by dots in names&quot;
cat &gt; build.xml &lt;&lt; EOF
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;!--DOCTYPE project PUBLIC &quot;-//ANT//DTD project//EN&quot; &quot;/usr/src/ant/project.dtd&quot;--&gt;
&lt;project name=&quot;many-params&quot; default=&quot;run&quot;&gt;
    &lt;target name=&quot;run&quot;&gt;
        &lt;echo message=&quot;first Param: ${param.first}&quot;/&gt;
        &lt;echo message=&quot;second Param: ${param.second}&quot;/&gt;
    &lt;/target&gt;
&lt;/project&gt;
EOF</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Ant plugin="ant@1.2">
      <targets>run</targets>
      <antName>Ant 1.8.2</antName>
      <properties>param.first=A
param.second=B</properties>
    </hudson.tasks.Ant>
  </builders>
  <publishers/>
  <buildWrappers>
    <hudson.plugins.ws__cleanup.PreBuildCleanup plugin="ws-cleanup@0.26">
      <deleteDirs>false</deleteDirs>
      <cleanupParameter></cleanupParameter>
      <externalDelete></externalDelete>
    </hudson.plugins.ws__cleanup.PreBuildCleanup>
  </buildWrappers>
</project>

构建任务给了我以下输出:

Started by user Alexander Krasnyansky
[EnvInject] - Loading node environment variables.
Building remotely on j03_uk1ps41 (buildslaves) in workspace /var/lib/jenkins03/workspace/akrasnyansky/ManyParams/ant-param-test

Deleting project workspace... done

[ant-param-test] $ /bin/sh -xe /tmp/hudson2203137136163442442.sh
+ echo 'STEP 1: Pass parameters with no separators in names'
STEP 1: Pass parameters with no separators in names
+ cat
[ant-param-test] $ /usr/local/apache-ant-1.8.2/bin/ant -Dparamfirst=A -Dparamsecond=B run
Buildfile: /var/lib/jenkins03/workspace/akrasnyansky/ManyParams/ant-param-test/build.xml

run:
     [echo] first Param: 
     [echo] second Param: 

BUILD SUCCESSFUL
Total time: 0 seconds
[ant-param-test] $ /bin/sh -xe /tmp/hudson5869719507232196626.sh
+ rm build.xml
+ echo

+ echo 'STEP 2: Pass parameters with separated by dashes in names'
STEP 2: Pass parameters with separated by dashes in names
+ cat
[ant-param-test] $ /usr/local/apache-ant-1.8.2/bin/ant -Dparam-first=A -Dparam-second=B run
Buildfile: /var/lib/jenkins03/workspace/akrasnyansky/ManyParams/ant-param-test/build.xml

run:
     [echo] first Param: first
     [echo] second Param: second

BUILD SUCCESSFUL
Total time: 0 seconds
[ant-param-test] $ /bin/sh -xe /tmp/hudson1052316660761572548.sh
+ echo

+ echo 'STEP 3: Same, but with parameters on the same line in Ant Plugin step setup'
STEP 3: Same, but with parameters on the same line in Ant Plugin step setup
[ant-param-test] $ /usr/local/apache-ant-1.8.2/bin/ant "-Dparam-first=A param-second=B" run
Buildfile: /var/lib/jenkins03/workspace/akrasnyansky/ManyParams/ant-param-test/build.xml

run:
     [echo] first Param: first
     [echo] second Param: second

BUILD SUCCESSFUL
Total time: 0 seconds
[ant-param-test] $ /bin/sh -xe /tmp/hudson4427994032931026249.sh
+ rm build.xml
+ echo

+ echo 'STEP 4: Pass parameters with separated by dots in names'
STEP 4: Pass parameters with separated by dots in names
+ cat
/tmp/hudson4427994032931026249.sh: line 5: <?xml version="1.0"?>
<!--DOCTYPE project PUBLIC "-//ANT//DTD project//EN" "/usr/src/ant/project.dtd"-->
<project name="many-params" default="run">
    <target name="run">
        <echo message="first Param: ${param.first}"/>
        <echo message="second Param: ${param.second}"/>
    </target>
</project>
: bad substitution
Build step 'Execute shell' marked build as failure
Started calculate disk usage of build
Finished Calculation of disk usage of build in 0 seconds
Started calculate disk usage of workspace
Finished Calculation of disk usage of workspace in 0 seconds
Finished: FAILURE

所以这就产生了很多问题:

  1. 为什么在第 1 步根本不打印任何值?
  2. 如何使用字符串值“first”和“second”而不是我在 STEP 2 中提供的“A”和“B”?
  3. 为什么在 STEP 3 中,格式错误的行“-Dparam-first=A param-second=B”(通过在 Jenkins 步骤设置中将两个参数放在同一行产生:param-first=A param-second=B)正常工作以及第 2 步的“-Dparam-first=A -Dparam-second=B”?我应该在这里失败,就像我在 shell 中运行一样。
  4. 第 4 步的点有什么问题?为什么会在此处产生错误的替换错误?

非常感谢您对这些问题的任何建议。

【问题讨论】:

    标签: java ant jenkins


    【解决方案1】:

    您的问题在于重写build.xml。老实说,我不明白你为什么要这样做。但是让我们开始吧。

    tl;dr: 您对 Shell 和 Ant 变量的行为感到困惑:如何对它们进行转义以及当它们未定义时会发生什么。

    您有一个“执行 Shell” 构建步骤,并在那里使用cat 将新内容放入文件中。

    停在那里。要么删除你的其他构建步骤,要么只是在cat 命令之后放置一个巨大的sleep。现在在您的工作区中查看生成的build.xml。你会看到:
    &lt;echo message="first Param: "/&gt;

    如您所见,该回显行中实际上没有参数。因此,当它运行时,它不会打印除文本以外的任何内容,这并不奇怪。为什么会这样?

    1. 您的cat 命令在Shell 中运行。您没有在first Param: ${paramfirst} 中转义参数的美元符号$。因此,在运行时,Shell 将${paramfirst} 视为变量并尝试找到它的值。没有,所以 Shell 用任何内容替换它(如果这是 Ant,Ant 会逐字打印未定义的变量)

    你需要从 Shell 中转义变量,因此写成first Param: \${paramfirst}。这将生成正确的build.xml,一切都将从那里开始。

    2. Allowed characters in linux environment variable namesCan shell variable include - character?
    连字符 - 不是允许的 Shell 变量名称。

    Shell 看到变量定义${ 后会向前看连字符-(因为连字符不能是变量名),并在那里拆分字符串。所以在${param-first} 中,Shell 认为${param 是可变的,-first} 是格式错误的文本。第一个被任何内容替换,其余部分被打印(} 由于 Shell 特性而被消耗)

    3.“Invoke Ant”构建步骤需要key=value 样式的参数,每行一个。然后它将获取每一行,在其前面加上 -D 并将多行串在一起形成最终的命令行。

    所以:

    param-first=A
    param-second=B
    

    变成这样:

    -Dparam-first=A
    -Dparam-second=B
    

    然后串成:-Dparam-first=A -Dparam-second=B

    当你这样做时:

    param-first=A param-second=B
    

    变成这样(记住:每行一个):

    -Dparam-first=A param-second=B
    

    注意只有一个-D,因为它是每行一个参数

    4. Shell 不允许在变量名中使用句点 .。时期。 (双关语)。请参阅 1.2. 的答案。但是,您可以在 Ant 变量名称中使用句点和连字符,但出于一致性原因,我建议您不要这样做。

    【讨论】:

    • 谢谢!即使使用重写的 build.xml,转义美元符号也完全解决了我的问题。我觉得自己像个白痴,没有弄清楚这一点!
    • 不要有这种感觉。在我运行您的配置并查看生成的 build.xml 文件之前,我自己没有发现它
    猜你喜欢
    • 1970-01-01
    • 2012-02-28
    • 1970-01-01
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 2012-10-27
    相关资源
    最近更新 更多