1

我已经为我的项目设置了 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>
}
4

1 回答 1

1

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

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

提供定义域,以免重复两次或更多次:

<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 的下一个域只需将其放入数组中。

一些注意事项:

于 2013-01-30T15:50:23.107 回答