如何通过CruiseControl.NET发布ClickOnce应用程序?
我在开发服务器上设置了CruiseControl.NET 1.4版。每当开发人员签入代码时,它都会进行编译。
现在我们在一个可以开始将应用程序提供给测试人员的地方。我们希望使用ClickOnce分发应用程序,其想法是当测试人员去测试应用程序时,他们拥有最新的版本。
我找不到通过CruiseControl.NET实现这一目标的方法。我们正在使用MSBUILD来执行构建。
解决方案
回答
我们要在msbuild中使用ClickOnce清单生成任务。这个过程有点漫长,所以我只想指出几个链接。这是msdn上的参考,并提供了示例文章,希望可以入门。
回答
我们已经完成了这一步,可以为我们提供一些入门指南。
我们应该注意的两件事:
- MSBuild可以为我们生成必要的部署文件。
- MSBuild不会将文件部署到FTP或者UNC共享。我们将需要一个单独的步骤。
要使用MSBuild生成ClickOnce清单,这是我们需要发出的命令:
msbuild /target:publish /p:Configuration=Release /p:Platform=AnyCPU; "c:\yourProject.csproj"
这将告诉MSBuild构建项目并在bin \ Release \ YourProject.publish目录中生成ClickOnce部署文件。
剩下的就是将这些文件复制到FTP / UNC共享/任何位置,一切就绪。
我们可以告诉CruiseControl.NET使用那些MSBuild参数进行构建。
然后,我们将需要CruiseControl.NET构建任务来获取生成的部署文件并将其复制到FTP或者UNC共享。我们为此使用了一个自定义的小型Cconsole程序,但我们也可以轻松地使用Powershell脚本。
回答
我记得去年为我正在从事的ClickOnce项目这样做。我记得花了我一辈子的时间,但事实确实如此。我希望我的脚本要做的是生成一个指向我们的开发环境的不同安装程序,以及一个针对产品的安装程序。不仅如此,我还需要它注入正确的版本信息,以便现有客户可以"意识到"那里有一个新版本,这就是clickOnce的全部重点。
在此脚本中,我们必须用自己的服务器名称等替换。技巧是保存publish.htm和project.publish文件,并根据CC.NET提供的版本注入新的版本号。
这是我的构建脚本的样子:
<target name="deployProd"> <exec program="<framework_dir>\msbuild.exe" commandline="<project>/<project>.csproj /property:Configuration=PublishProd /property:ApplicationVersion=${build.label}.*;PublishUrl=\<prod_location>\binups$\;InstallUrl=\<prod_location>\binups$\;UpdateUrl=\<prod_location>\binups$\;BootstrapperComponentsUrl=\<prod_location>\prereqs$\ /target:publish"/> <copy todir="<project>\bin\PublishProd\<project>.publish"> <fileset basedir="."> <include name="publish.htm"/> </fileset> <filterchain> <replacetokens> <token key="CURRENT_VERSION" value="${build.label}"/> </replacetokens> </filterchain> </copy> </target>
希望这可以帮助
回答
感谢所有帮助。我们实施的最终解决方案从每个答案中都花了一点时间。
我们发现使用简单的批处理文件可以更轻松地处理多个环境。我并不是说这是执行此操作的最佳方法,但是对于我们给定的方案和要求,此方法效果很好。用项目名称补充" Project",并用环境名称补充" Environment"(开发,测试,阶段,生产等)。
这是我们的" ccnet.config"文件的任务区域。
<!-- override settings --> <exec> <executable>F:\Source\Project\Environment\CruiseControl\CopySettings.bat</executable> </exec> <!-- compile --> <msbuild> <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable> <workingDirectory>F:\Source\Project\Environment\</workingDirectory> <projectFile>Project.sln</projectFile> <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs> <targets>Rebuild</targets> <timeout>0</timeout> <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,ThoughtWorks.CruiseControl.MsBuild.dll</logger> </msbuild> <!-- clickonce publish --> <exec> <executable>F:\Source\Project\Environment\CruiseControl\Publish.bat</executable> </exec>
我们会注意到的第一件事是CopySettings.bat运行。这将复制环境的特定设置,例如数据库连接。
接下来,运行标准的MSBUILD任务。任何编译错误都会在此处捕获并按正常方式处理。
最后要执行的是Publish.bat。实际上,这实际上是从命令行再次执行MSBUILD"重建",并且CruiseControl中的参数会自动传递并建立。接下来,MSBUILD被称为"发布"目标。发出重新生成时,将完全相同的参数提供给发布。这样可以使内部版本号保持同步。另外,我们的可执行文件的名称也不同(即ProjectDev和ProjectTest)。我们最终得到不同的版本号和名称,这使ClickOnce可以完成其工作。
Publish.bat的最后一部分将实际文件复制到其新位置。我们不使用publish.htm,因为我们所有的用户都在网络上,我们只是给他们一个桌面上的清单文件的快捷方式,他们可以单击并始终运行具有正确版本的最新可执行文件巡航控制。
这是CopySettings.bat
XCOPY "F:\Source\Project\Environment\CruiseControl\Project\app.config" "F:\Source\Project\Environment\Project" /Y /I /R XCOPY "F:\Source\Project\Environment\CruiseControl\Project\My Project\Settings.Designer.vb" "F:\Source\Project\Environment\Project\My Project" /Y /I /R XCOPY "F:\Source\Project\Environment\CruiseControl\Project\My Project\Settings.settings" "F:\Source\Project\Environment\Project\My Project" /Y /I /R
最后是Publish.bat
C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /target:rebuild "F:\Source\Project\Environment\Project\Project.vbproj" /property:ApplicationRevision=%CCNetLabel% /property:AssemblyName="ProjectEnvironment" /property:PublishUrl="\Server\bin\Project\Environment\" C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /target:publish "F:\Source\Project\Environment\Project\Project.vbproj" /property:ApplicationVersion="1.0.0.%CCNetLabel%" /property:AssemblyVersion="1.0.0.%CCNetLabel%" /property:AssemblyName="ProjectEnvironment" XCOPY "F:\Source\Project\Environment\Project\bin\Debug\app.publish" "F:\Binary\Project\Environment" /Y /I XCOPY "F:\Source\Project\Environment\Project\bin\Debug\app.publish\Application Files" "F:\Binary\Project\Environment\Application Files" /Y /I /S
就像我说的那样,它可能未达到CruiseControl和MSBUILD开发人员想要的正常工作的方式,但是它确实有效。如果我们需要昨天进行此工作,则可能是我们正在寻找的解决方案。祝你好运!
回答
只要能够在CCNET.config msbuild任务中传递$ {CCNetLabel},将是一个很大的改进。