循环访问Cruisecontrol.net中的参数值

时间:2012-11-05 07:58:19

标签: continuous-integration cruisecontrol.net

我为我的项目设置了Cruisecontrol构建,我需要在多个环境中运行。这就是我目前使用的:

<parameters>
    <selectParameter>
        <name>Environment1</name>
        <display>Environment1</display>
        <allowedValues>
            <value name="No">No</value>
        <value name="Yes">Yes</value>
        </allowedValues>
    </selectParameter>
    <selectParameter>
        <name>Environment2</name>
        <display>Environment2</display>
        <allowedValues>
            <value name="No">No</value>
        <value name="Yes">Yes</value>
        </allowedValues>
    </selectParameter>
    <selectParameter>
        <name>Environment3</name>
        <display>Environment3</display>
        <allowedValues>
            <value name="No">No</value>
        <value name="Yes">Yes</value>
        </allowedValues>
    </selectParameter>
</parameters>

<conditional>
    <conditions>
    <compareCondition value1="Environment1" evaluation="equal" value2="Yes" />
    </conditions>
    <tasks>
        <msbuild>
            <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
            <workingDirectory>$[DirectoryOfBuildScript]</workingDirectory>
            <projectFile>MSBuild.proj</projectFile>
            <buildArgs>/v:n /p:Environment=Environment1;Version=$[BuildVersion];</buildArgs>
            <targets>Deploy</targets>
            <timeout>3000</timeout>
            <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:\Program Files\CruiseControl.NET\webdashboard\bin\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        </msbuild>
    </tasks>
</conditional>

<conditional>
    <conditions>
    <compareCondition value1="Environment2" evaluation="equal" value2="Yes" />
    </conditions>
    <tasks>
        <msbuild>
            <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
            <workingDirectory>$[DirectoryOfBuildScript]</workingDirectory>
            <projectFile>MSBuild.proj</projectFile>
            <buildArgs>/v:n /p:Environment=Environment2;Version=$[BuildVersion];</buildArgs>
            <targets>Deploy</targets>
            <timeout>3000</timeout>
            <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:\Program Files\CruiseControl.NET\webdashboard\bin\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        </msbuild>
    </tasks>
</conditional>

<conditional>
    <conditions>
    <compareCondition value1="Environment3" evaluation="equal" value2="Yes" />
    </conditions>
    <tasks>
        <msbuild>
            <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
            <workingDirectory>$[DirectoryOfBuildScript]</workingDirectory>
            <projectFile>MSBuild.proj</projectFile>
            <buildArgs>/v:n /p:Environment=Environment3;Version=$[BuildVersion];</buildArgs>
            <targets>Deploy</targets>
            <timeout>3000</timeout>
            <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:\Program Files\CruiseControl.NET\webdashboard\bin\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        </msbuild>
    </tasks>
</conditional>

如您所见,只有环境名称在所有条件语句中都不同。有没有办法让我通过循环选定的环境名称来推广我的构建调用(版本不会有所不同)。像这样:

// Conceptually I want a for loop which iterates through the selected environments
foreach(environmentName in selectedEnvironments)
{
    <tasks>
        <msbuild>
            <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
            <workingDirectory>$[DirectoryOfBuildScript]</workingDirectory>
            <projectFile>MSBuild.proj</projectFile>
            <buildArgs>/v:n /p:Environment=environmentName;Version=$[BuildVersion];</buildArgs>
            <targets>Deploy</targets>
            <timeout>3000</timeout>
            <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:\Program Files\CruiseControl.NET\webdashboard\bin\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        </msbuild>
    </tasks>
}

1 个答案:

答案 0 :(得分:1)

我会考虑为这些东西使用预处理器。似乎预处理器中存在for-each元素,尽管我没有在任何地方看到它。但CCNet资源中的测试显示了如何使用它。

关于这个问题,我创建了一个类似的概念证明,我认为你应该能够轻松地适应你的条件。我只是提供要ping的域列表,而不是构建某些环境。

将域名作为 define 提供,以免重复两次或更多次:

<cb:define name="domains">
    ['facebook', 'twitter', 'wired']
</cb:define>

然后以相同的方式定义参数:

<cb:define name="paramDef">
    <selectParameter>
        <name>$(domainName)</name>
        <display>$(domainName)</display>
        <allowedValues>
            <value name="No">No</value>
            <value name="Yes">Yes</value>
        </allowedValues>
    </selectParameter>
</cb:define>

......和任务:

<cb:define name="condTask">         
    <conditional>
        <conditions>
            <compareCondition>
                <value1>$[$(domainName)]</value1>
                <value2>Yes</value2>
                <evaluation>Equal</evaluation>
                <ignoreCase>true</ignoreCase>
            </compareCondition>
        </conditions>
        <tasks>
            <exec executable="ping">
                <buildArgs>$(domainName).com</buildArgs>
            </exec>
        </tasks>
    </conditional>
</cb:define>

(注意 value1 中的奇怪构造 - 它匹配名称,然后计算该名称的值)

现在我们已经掌握了一切,所以我们可以生成我们需要的东西。 对于参数:

<parameters>
    <cb:for-each iterator-name="i" iterator-expr="$(domains)">
        <cb:scope domainName="$(i)">    
            <cb:paramDef />
        </cb:scope>
    </cb:for-each>
</parameters>

......和任务相同:

<tasks>
    <cb:for-each iterator-name="i" iterator-expr="$(domains)">
        <cb:scope domainName="$(i)">    
            <cb:condTask />
        </cb:scope>
    </cb:for-each>
</tasks>

就是这样。我需要ping的下一个域只需将其放入 domains 数组。

一些注意事项: