使用 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> 标记内。为了减少路径和文件名的重复,我创建了 configDirxformFile 属性。我喜欢这种模式,因为它易于扩展且通用!

<!-- 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>

非常感谢这些帖子为这个解决方案指明了道路