使用 msbuild,如何构建一次然后使用多个转换配置文件发布?
Using msbuild, how can I build once and then publish with multiple transform profiles?
我有一个可以使用 msbuild
构建的 .net 解决方案,并成功生成了一个带有 PublishProfile.pubxml
转换的部署包,用于部署到单个 Web 服务器。
我需要为不同的环境构建和生成部署包,这些环境使用各种 .pubxml
配置文件设置为转换。
我知道我可以单独构建每个配置文件,将更改注入构建的风险可以忽略不计,但时间和 space 没有必要消费。无论如何,我最终只会保留其中一个,并且只是将每个转换中的唯一 web.config
复制到它们自己的部署包的文件夹中(如果不清楚,很抱歉,很高兴澄清)。
我正在寻找类似这个伪代码的东西,我知道它在语法上是不正确的,但应该明白这一点:
// step 1
msbuild myapp.csproj target=Build
// step 2
foreach ($profile in $profileList) {
msbuild myapp.csproj outputdir="releaseDir/$profile" target=Publish publishProfile=$profile
}
我在 Jenkins 上下文中工作,不能使用 Visual Studio 函数,除非它们作为命令行选项可用。
我也拼命尝试让 msdeploy
工作,我认为这可能会简化其中的一些,但对于我来说,我无法让它与 [=17= 一起工作] 选项,这实际上是我想在我的环境中使用的唯一方法。有关那场特殊斗争的详细信息 here.
提前致谢!
更新 1:,但正如我在评论中所说,它仍在创建多个部署包,占用大量 space 并且不是必需的。我真正想要的是一种使用单个构建工件并创建 Web.config 文件的多个转换的方法。然后在部署时,复制构建工件和适当的配置文件。那会 真的 是 build-once/deploy-many!
FWIW,这是我使用上面的 link 得出的代码:
function Initialize-Build {
$ErrorActionPreference = 'Stop'
$appName = 'myApp'
$projsToBuild = 'Ui', 'DataService'
$projPath = "$appName/$appName"
$buildPath = 'obj/Release/Package/'
$releasePath = 'Release-Packages'
$commonArgs = '/p:Configuration=Release',
'/nologo',
'/verbosity:quiet'
}
function Invoke-Build {
foreach ($proj in $projsToBuild) {
$projName = $proj -eq 'Ui' ? 'WebUi' : $proj
$p = "$projPath.$proj/$appName.$projName.csproj"
$buildArgs = '/t:Clean,Build',
'/p:AutoParameterizationWebConfigConnectionStrings=False'
Write-Output "Building $p"
msbuild $p @commonArgs @buildArgs
if ($LASTEXITCODE) { exit 1 }
}
}
function Invoke-Transform {
$xformArgs = "/p:deployOnBuild=True", "/p:Targets=Publish"
foreach ($proj in $projsToBuild) {
$p = "$projPath.$proj/$appName.$projName.csproj"
$pubProfiles = 'Dev', 'QA', 'UAT', 'Prod'
foreach ($prof in $pubProfiles) {
Write-Output "Building $p ($prof)"
$pubProfileArg = "/p:PublishProfile=$prof"
msbuild $p @commonArgs @xformArgs $pubProfileArg
if ($LASTEXITCODE) { exit 1 }
}
}
}
. Initialize-PrivLogBuild
Invoke-Build
Invoke-Transform
我意识到我并没有问对问题。当我开始搜索 msbuild 转换帖子时,我找到了一种方法来完成我需要的事情。
我着手更新我正在使用 AfterBuild
目标构建的应用程序的 .csproj 文件。
需要 4 个转换,每个转换都有自己的 .config 文件作为转换源。幸运的是,这些文件已经由应用程序开发人员创建。
这是我最终得到的代码,位于 .csproj 文件的末尾,在 </project>
标记内。为了减少路径和文件名的重复,我创建了 configDir
和 xformFile
属性。我喜欢这种模式,因为它易于扩展且通用!
<!-- all the rest of the .csproj above this -->
<UsingTask TaskName="TransformXml"
AssemblyFile="$(MSBuildExtensionsPath32)/Microsoft/VisualStudio/v16.0/Web/Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild">
<PropertyGroup>
<configDir>../../Release-Packages/configs</configDir>
<xformFile>Web.config</xformFile>
</PropertyGroup>
<MakeDir Directories="$(configDir)" />
<TransformXml Source="$(xformFile)"
Transform="Web.Dev.config"
Destination="$(configDir)/$(AssemblyName).$(xformFile).DEV" />
<TransformXml Source="$(xformFile)"
Transform="Web.QA.config"
Destination="$(configDir)/$(AssemblyName).$(xformFile).QA" />
<TransformXml Source="$(xformFile)"
Transform="Web.Prod.config"
Destination="$(configDir)/$(AssemblyName).$(xformFile).Prod" />
<TransformXml Source="$(xformFile)"
Transform="Web.UAT.config"
Destination="$(configDir)/$(AssemblyName).$(xformFile).UAT" />
</Target>
</Project>
非常感谢这些帖子为这个解决方案指明了道路
- https://dougrathbone.com/blog/2011/09/14/using-custom-webconfig-transformations-in-msbuild
- How do I use custom variables in MSBuild scripts?
- https://github.com/sayedihashimi/sayed-samples/blob/master/TransformMultipleWebConfigs/transform.proj
- https://www.locktar.nl/general/use-config-transforms-when-debugging-your-web-application/
- https://johan.driessen.se/posts/Applying-MSBuild-Config-Transformations-to-any-config-file-without-using-any-Visual-Studio-extensions/
- https://bartlomiejmucha.com/en/blog/msbuild/how-to-extend-msbuild-publish-pipeline-to-apply-transform-files/
我有一个可以使用 msbuild
构建的 .net 解决方案,并成功生成了一个带有 PublishProfile.pubxml
转换的部署包,用于部署到单个 Web 服务器。
我需要为不同的环境构建和生成部署包,这些环境使用各种 .pubxml
配置文件设置为转换。
我知道我可以单独构建每个配置文件,将更改注入构建的风险可以忽略不计,但时间和 space 没有必要消费。无论如何,我最终只会保留其中一个,并且只是将每个转换中的唯一 web.config
复制到它们自己的部署包的文件夹中(如果不清楚,很抱歉,很高兴澄清)。
我正在寻找类似这个伪代码的东西,我知道它在语法上是不正确的,但应该明白这一点:
// step 1
msbuild myapp.csproj target=Build
// step 2
foreach ($profile in $profileList) {
msbuild myapp.csproj outputdir="releaseDir/$profile" target=Publish publishProfile=$profile
}
我在 Jenkins 上下文中工作,不能使用 Visual Studio 函数,除非它们作为命令行选项可用。
我也拼命尝试让 msdeploy
工作,我认为这可能会简化其中的一些,但对于我来说,我无法让它与 [=17= 一起工作] 选项,这实际上是我想在我的环境中使用的唯一方法。有关那场特殊斗争的详细信息 here.
提前致谢!
更新 1:
FWIW,这是我使用上面的 link 得出的代码:
function Initialize-Build {
$ErrorActionPreference = 'Stop'
$appName = 'myApp'
$projsToBuild = 'Ui', 'DataService'
$projPath = "$appName/$appName"
$buildPath = 'obj/Release/Package/'
$releasePath = 'Release-Packages'
$commonArgs = '/p:Configuration=Release',
'/nologo',
'/verbosity:quiet'
}
function Invoke-Build {
foreach ($proj in $projsToBuild) {
$projName = $proj -eq 'Ui' ? 'WebUi' : $proj
$p = "$projPath.$proj/$appName.$projName.csproj"
$buildArgs = '/t:Clean,Build',
'/p:AutoParameterizationWebConfigConnectionStrings=False'
Write-Output "Building $p"
msbuild $p @commonArgs @buildArgs
if ($LASTEXITCODE) { exit 1 }
}
}
function Invoke-Transform {
$xformArgs = "/p:deployOnBuild=True", "/p:Targets=Publish"
foreach ($proj in $projsToBuild) {
$p = "$projPath.$proj/$appName.$projName.csproj"
$pubProfiles = 'Dev', 'QA', 'UAT', 'Prod'
foreach ($prof in $pubProfiles) {
Write-Output "Building $p ($prof)"
$pubProfileArg = "/p:PublishProfile=$prof"
msbuild $p @commonArgs @xformArgs $pubProfileArg
if ($LASTEXITCODE) { exit 1 }
}
}
}
. Initialize-PrivLogBuild
Invoke-Build
Invoke-Transform
我意识到我并没有问对问题。当我开始搜索 msbuild 转换帖子时,我找到了一种方法来完成我需要的事情。
我着手更新我正在使用 AfterBuild
目标构建的应用程序的 .csproj 文件。
需要 4 个转换,每个转换都有自己的 .config 文件作为转换源。幸运的是,这些文件已经由应用程序开发人员创建。
这是我最终得到的代码,位于 .csproj 文件的末尾,在 </project>
标记内。为了减少路径和文件名的重复,我创建了 configDir
和 xformFile
属性。我喜欢这种模式,因为它易于扩展且通用!
<!-- all the rest of the .csproj above this -->
<UsingTask TaskName="TransformXml"
AssemblyFile="$(MSBuildExtensionsPath32)/Microsoft/VisualStudio/v16.0/Web/Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild">
<PropertyGroup>
<configDir>../../Release-Packages/configs</configDir>
<xformFile>Web.config</xformFile>
</PropertyGroup>
<MakeDir Directories="$(configDir)" />
<TransformXml Source="$(xformFile)"
Transform="Web.Dev.config"
Destination="$(configDir)/$(AssemblyName).$(xformFile).DEV" />
<TransformXml Source="$(xformFile)"
Transform="Web.QA.config"
Destination="$(configDir)/$(AssemblyName).$(xformFile).QA" />
<TransformXml Source="$(xformFile)"
Transform="Web.Prod.config"
Destination="$(configDir)/$(AssemblyName).$(xformFile).Prod" />
<TransformXml Source="$(xformFile)"
Transform="Web.UAT.config"
Destination="$(configDir)/$(AssemblyName).$(xformFile).UAT" />
</Target>
</Project>
非常感谢这些帖子为这个解决方案指明了道路
- https://dougrathbone.com/blog/2011/09/14/using-custom-webconfig-transformations-in-msbuild
- How do I use custom variables in MSBuild scripts?
- https://github.com/sayedihashimi/sayed-samples/blob/master/TransformMultipleWebConfigs/transform.proj
- https://www.locktar.nl/general/use-config-transforms-when-debugging-your-web-application/
- https://johan.driessen.se/posts/Applying-MSBuild-Config-Transformations-to-any-config-file-without-using-any-Visual-Studio-extensions/
- https://bartlomiejmucha.com/en/blog/msbuild/how-to-extend-msbuild-publish-pipeline-to-apply-transform-files/