由于面向接口编程的关系,许多实现往往是动态注入运行,在一个项目中直接引用实现dll编译是不合理的。通常我们会在Post Build Event中添加一些xcopy命令将运行时才需要的dll复制到输出目录。在发布时会带来一些问题,比如:使用Visual Studio自带的Publish功能发布一个Web应用时就不会运行Post Build Event。同样的在基于TFS Build时也存在类似问题。

TFS Build时会根据对应Definition的名称创建两个子目录:Source、Binaries,Binaries下针对Web应用会创建发布目录"_PublishedWebsites",如果想要Post Build Event时将dll复制到对应目录下,最简单的方式就是再添加xcopy命令(这样的命令可能有多条),例如:

xcopy /y /i "$(SolutionDir)BuildEvents\Post-build" "$(TargetDir)_PublishedWebsites\$(TargetName)\bin\"

但是会给开发人员带来歧义、工作量并污染Post Build Event。其实我们想做的就是当MSBuild时的某一个参数值符合要求则执行发布用的命令(这个命令和Post Build Event执行的内容一样,就是$(TargetDir)不同),这时就需要修改项目文件来添加一些自定义的脚本实现该功能。首先在Build Definition的高级选项里添加MSBuild Arguments,例如:

/p:RMS=

由于我的目标是和Release Management Service整合,故使用了该缩写。下面打开项目文件(csproj),开启AfterBuild,并添加一个Exec Task

<Target Name="AfterBuild">
<Exec Command="$(PostBuildEvent)" Condition=" '$(RMS)' == '1' " />
</Target>

上面的命令实际无法达到最终效果,这里自己绕了一个弯路。主要问题在于对PostBuildEvent的理解,其实它也是一个字符串变量,在执行时它内部使用的$(TargetDir)早已被替换,无法再重新计算结果。例如:

<Target Name="AfterBuild" Condition=" '$(RMS)' == '1' ">
<PropertyGroup>
<TargetDir>$(TargetDir)_PublishedWebsites\$(TargetName)\bin\</TargetDir>
</PropertyGroup>
<Message Text="$(TargetDir)" />
<Exec Command="$(PostBuildEvent)" />
</Target>

TargetDir的值确实产生变化,但PostBuildEvent的值也已经被提前计算,我们无法再让它被动态计算一次。幸好MSBuild 4.0以上版本允许我们使用一部分.NET代码来修改这些变量,我们只需调用System.String的Replace方法即可,参考如下:

<Target Name="AfterBuild">
<Exec Command="$(PostBuildEvent.Replace(&quot;$(TargetDir)&quot;, &quot;$(TargetDir)_PublishedWebsites\$(TargetName)\bin\&quot;))" Condition=" '$(RMS)' == '1' " />
</Target>

通过上面的方法就可以将Web应用完整发布,并结合Release Management Service实现持续集成。

TFS Build做Web应用持续集成发布的一个技巧的更多相关文章

  1. docker+headless+robotframework+jenkins实现web自动化持续集成

    在Docker环境使headless实现web自动化持续集成 一.制作镜像 原则:自动化测试基于基础制作镜像 命令:docker run --privileged --name=$1 --net=ho ...

  2. Web API 持续集成:PostMan+Newman+Jenkins(图文讲解)

    本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 上篇文章我们已经完成了API测试工具选型,接下来是一系列周期性的开发 ...

  3. postman+jenkins+newman做接口测试的持续集成

    为何要做接口自动化测试的持续集成? 1. 接口相对稳定,改动少,比起GUI自动化测试来说性价比更加高些,不容易出现GUI自动化那种掉到维护脚本的坑里. 2. 接口测试比较简单,一个规范的接口,测试只需 ...

  4. (转)Jenkins2.0 Pipeline 插件执行持续集成发布流程 - git -资料 - 不错的文档

    1.Jenkins 2.0 的精髓是 Pipeline as Code Jenkins 2.0 的精髓是 Pipeline as Code,是帮助 Jenkins 实现 CI 到 CD 转变的重要角色 ...

  5. Jenkins+SVN+tomcat持续集成发布

    有代码更新后重新打包到tomcat再发布,是不是很烦? 看了下面的东西你就不会烦了. SVN或者git等代码版本控制工具不说了,如果是本地开发,也可以安装一个svn server端 jenkins下载 ...

  6. jenkins(8): 实战jenkins+gitlab持续集成发布php项目(代码不需要编译)

    一. jenkins 的配置 1.前提条件安装了GitLab Plugin (源码管理使用),GitLab Hook(gitlab webhook需要) Manage Jenkins--->Ma ...

  7. Docker学习笔记五:Docker生成jenkins容器,支持Java Web项目持续集成、持续部署

    一.创建jenkins容器: 1.拉取jeknin镜像 sudo docker pull jenkins 2.创建一个jenkins目录 sudo mkdir /jenkins 3.在jenkins目 ...

  8. 在TFS持续集成(持续发布)中执行Telnet任务

    Telnet是一种在因特网或局域网上使用虚拟终端连接,提供双向交互式文本通信设备的协议. 它是最早的互联网通讯协议之一.自1969年启用以来,已经经过了将近50年时间,在开放式的操作系统中拥有广泛的用 ...

  9. (转载)持续集成(第二版)[来自:Martin Fowler]

    转载自:iTech的博客 持续集成(第二版) 作者:Martin Fowler 译者:雷镇 持续集成 是一种软件开发实践.在持续集成中,团队成员频繁集成他们的工作成果,一般每人每天至少集成一次,也可以 ...

随机推荐

  1. linux下redis的安装和集群搭建

    一.redis概述 1.1.目前redis支持的cluster特性: 1):节点自动发现. 2):slave->master 选举,集群容错. 3):Hot resharding:在线分片. 4 ...

  2. Ruby gem: Mac 系统下的安装与更新

    官方链接:https://rubygems.org/pages/download#formats 下载安装: 1.点击上面链接进入到官网,从顶部的链接下载压缩包: 2.解压缩到指定文件夹,并通过 “c ...

  3. jsTree 插件

    html代码 <div id="jstree1"></div> js代码: <script src="__STATIC__/h5/js/jq ...

  4. curl教程2

    上篇介绍了curl的基本用法和简单例子,这篇有包含下载,上传,断点续传等的技巧,一并也mark一下吧. 原文:http://blog.csdn.net/apoxlo/article/details/2 ...

  5. nginx配置ThinkPHP配置

    配置时注意红色部分 server { listen 8888 default_server; #listen [::]:80 default_server; server_name _; root / ...

  6. Npm基本指令(转)

    一些常用的 npm 指令 當你設定好 node.js 的開發環境後, 是時候來把下面這些常用的 npm 指令給摸熟了. 將套件於全域安裝. 全域安裝的套件通常只是為了執行檔而已. $ npm inst ...

  7. 如何将会员名单加入LINE@生活圈?

    如何将会员名单加入LINE@生活圈? 我要如何将会员名单加入LINE@生活圈呢?答案是没有办法利用LINE@生活圈直接加入会员名单,LINE@生活圈是许可式行销,必须由LINE好友主动将LINE@生活 ...

  8. 理解linux 块, i节点

    https://blog.csdn.net/zdf19/article/details/54424880 https://www.cnblogs.com/hnrainll/archive/2012/0 ...

  9. LINQ to Entities does not recognize the method 'Int32 ToInt32(System.String)' method, and this method cannot be translated into a store expression

    if (!string.IsNullOrEmpty(FarmWorkId)) { data = data.Where(p => p.TypeId == Convert.ToInt32(FarmW ...

  10. ubuntu 13.04 nginx.conf 配置详解

    1.nginx.conf 文件,路径为:/etc/nginx/agin.conf #使用的用户和组 user www-data; #指定工作衍生进程数(一般等于CPU总核数或总核数的两倍) worke ...