持续构建需要标识出每次构建的版本,而每次构建的时候人工去修改版本是不现实的。靠程序去添加版本号,有3种可选:1) 顺序流水号;2) 时间戳;3) SVN检出代码的修订版本号

1) 顺序流水号。需要每次构建将上次记录的流水号+1,再更新到版本中去。如果要记录每次构建的版本号,需要提交到代码器,不仅会造成代码修订版本+1,而且在构建时提交东东总是件不爽的事情。

2) 时间戳。对比流水号来说,靠谱多了,就是太长,就算以秒为单位,一天也是86400的增量

3) SVN检出代码时的修订版本号。最靠谱的还是这个,代码有更新,版本号增加,代码没更新,版本号不变。通常情况下,代码不变,构建结果基本上不需要有差异,所以选这个啦!

当然这篇博文的关键不在这里,关键是咋才能让MSBuild在构建的时候去取得版本号,并且替换掉AssemblyInfo.cs中的AssemblyVersion或AssemblyFileVersion。这要靠原生的MSBuild Task似乎是办不到,自己写Task太累。所以找了个第三方的Task:MSBuild Community Tasks。

其实这已经不是第一次接触 MSBuild Community Tasks 了,上次使用它是因为需要在项目构建时将生成的结果打包成压缩文件,所以用到了它的 Zip Task。而这次,需要用到它两个Task:

SvnVersion Task,用来获取代码的SVN修订版本号

FileUpdate,用来更新AssemblyInfo.cs文件

下面是实验环境和代码:

首先是项目目录结构(test.xml就是 MSBuild 构建脚本)

C:.
├─build
│  │  test.xml
│  │
│  └─msbuildtasks
│          MSBuild.Community.Tasks.dll
│          MSBuild.Community.Tasks.Targets
│
└─MyProject└─PropertiesAssemblyInfo.cs

构建脚本只干了一件事件,就是更新 AssemblyInfo.cs 中两个版本号的最后一位(修订版本号)。

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><Import Project="msbuildtasks\MSBuild.Community.Tasks.Targets" /><PropertyGroup><MSBuildCommunityTasksLib>$([MSBUILD]::Unescape(MSBuild.Community.Tasks.dll))</MSBuildCommunityTasksLib></PropertyGroup><Target Name="Test"><ItemGroup><AssemblyInfos Include="..\MyProject\**\AssemblyInfo.cs" /></ItemGroup><SvnVersion LocalPath="."><Output TaskParameter="Revision" PropertyName="Revision" /></SvnVersion><Message Text="Revision: $(Revision)" /><FileUpdate Files="@(AssemblyInfos)"Regex="\(&quot;(\d+\.\d+\.\d+\.)\d+&quot;\)\]"ReplacementText="(&quot;${1}$(Revision)&quot;)]" /></Target>
</Project>

稍稍解释一下脚本:

    <Import Project="msbuildtasks\MSBuild.Community.Tasks.Targets" /><PropertyGroup><MSBuildCommunityTasksLib>$([MSBUILD]::Unescape(MSBuild.Community.Tasks.dll))</MSBuildCommunityTasksLib></PropertyGroup>

这里是引入 MSBuild Community Tasks 的动态库,官方写法,照抄就是了

        <ItemGroup><AssemblyInfos Include="..\MyProject\**\AssemblyInfo.cs" /></ItemGroup>

这里把所有 AssemblyInfo.cs 找出来,这样可以将一个解决方案中多个项目的版本号一起更新了。

        <SvnVersion LocalPath="."><Output TaskParameter="Revision" PropertyName="Revision" /></SvnVersion>

这里很明显就是在取当前代码的SVN修订版本号了,LocalPath指定了取哪个目录的版本号,Output则将取到的修订版本号输出到“Revision”这个属性中,关于Output,可以参考 http://msdn.microsoft.com/zh-cn/library/ms164287.aspx

需要注意的是,在 PATH 路径中可以找到 svnversion 命令。如果没有设置 PATH,可以使用 ToolPath 参数指定 svnversion 所在目录。

        <FileUpdate Files="@(AssemblyInfos)"Regex="\(&quot;(\d+\.\d+\.\d+\.)\d+&quot;\)\]"ReplacementText="(&quot;${1}$(Revision)&quot;)]" />

这部分就是通过正则表达式查找替换版本号了。有时有两点需要注意,一是在写引号的时候,需要用&quot;代替;二是在替换字符串中最好用${1}代替$1这种写法,因为后面的$(Revision)也是数字,如果不用大括号连起来就可能变成 $1123 这样,不能被正确识别,用一大括号就是 ${1}123 这样了,不会出错。

msbuild构建时用SVN修改版本号代替AssemblyVersion的Revision版本号相关推荐

  1. [问题]DotNet 项目如何实现在构建时 Build 号自动增加?

    [问题]DotNet 项目如何实现在构建时 Build 号自动增加? 继续昨天的问题,今天在Google上找了一下,没有找到很好的方案. 目前找到的解决方案有以下几种: 1.使用一个地三方的 VS.N ...

  2. Flutter framework在线上构建时的包大小优化

    混合开发线上构建之flutter包大小优化 前景 打包flutter flutter引擎包的来源 缩减fluter framework大小 总结 前景 因为项目要使用jenkins线上构建,所以整个项 ...

  3. oracle数据库imp导入失败提示:“不是有效的导出文件, 标头验证失败”解决方法,修改dmp文件里oracle数据库版本号方法

    报错信息如下,该报错主要是因为原来导出时的数据库版本和现有的数据库版本不匹配所致. C:\Users\Administrator>imp ncc2005zdh_0602/ufida file=D ...

  4. msbuild构建步骤_如何按照以下步骤构建最终的AI聊天机器人

    msbuild构建步骤 by Paul Pinard 保罗·皮纳德(Paul Pinard) 如何按照以下步骤构建最终的AI聊天机器人 (How to build the ultimate AI ch ...

  5. 构建时预渲染:网页首帧优化实践

    前言 自JavaScript诞生以来,前端技术发展非常迅速.移动端白屏优化是前端界面体验的一个重要优化方向,Web 前端诞生了 SSR .CSR.预渲染等技术.在美团支付的前端技术体系里,通过预渲染提 ...

  6. cmake(13):构建时设置预处理宏定义以及add_compile_definitions命令详解

    目录 1. 说明 1.1 无参宏 1.2 有参宏 2. 使用示例 3. 命令解析 add_compile_definitions 命令 add_definitions 命令 参考链接 1. 说明 宏定 ...

  7. msbuild构建步骤_使用并行构建和多核CPU的MSBuild进行更快的构建

    msbuild构建步骤 UPDATE: I've written an UPDATE on how to get MSBuild building using multiple cores from ...

  8. svn 服务器忽略文件夹,关于构建自动化:SVN checkout忽略文件夹

    我可以忽略svn checkout上的文件夹吗? 我需要在我的构建服务器上的结帐时忽略DOCs文件夹. 编辑:忽略外部不是一个选项. 我有一些我需要的外部因素. 看看这个:stackoverflow. ...

  9. 我在React Native中构建时获得的经验教训

    by Amanda Bullington 通过阿曼达·布林顿(Amanda Bullington) 我在React Native中构建时获得的经验教训 (Lessons I learned while ...

最新文章

  1. 使用nc传输文件和目录【转】
  2. Linux数据报文接收发送总结1
  3. UOJ#37. 【清华集训2014】主旋律
  4. c语言 子进程,子Shell和子进程
  5. Mono for Android 优势与劣势
  6. linux nm命令_Linux的networkmanager
  7. 【信号检测】基于隐马尔可夫模型HMM算法实现睡眠状态检测matlab代码
  8. 华南理工计算机电路基础试题,华南理工计算机电路基础模拟考试题
  9. Java Web实战详细教程(二)第一个Java Web项目+JSP模板设置
  10. 红外测距模块工作原理_红外测温仪方案工作原理
  11. windows: 关于MsMpEng.exe导致“弹出USB大容量存储设备时出问题”
  12. 重装系统找不到固态_安装Win10系统没有固态硬盘(双硬盘找不到固态硬盘)怎么解决?...
  13. 如何在H3C路由器使用ACL来管理网络安全
  14. 01 复杂度分析(上):时间、空间复杂度讲解
  15. 网店工商信息图片文字提取
  16. Unity触发检测和碰撞检测
  17. php android 微信支付,Android_Android实现微信支付功能,开发Android APP微信支付功能, - phpStudy...
  18. 电路专用计算机,基于AD977A的专用计算机数据采集电路的设计实现
  19. SpringMVC全注解开发
  20. vite打包报错EPERM: operation not permitted

热门文章

  1. vue 判断两对象是否一致_你的.vue文件就已经是你的文档了
  2. linux搭建mcpe服务器_Ubuntu Linux下搭建Minecraft我的世界服务器
  3. php里push的用法,php array_push函数怎么用?
  4. java fx border_JavaFx UI控件与代码间的绑定方法
  5. cron 每10分钟执行一次_早餐儿子最爱它,简单卷一卷,10分钟做一大盘,三天两头吃一次...
  6. 【Java基础篇】你真的了解构造器吗?
  7. hbase 页面访问_HBase
  8. 室内定位算法_001:室内定位算法技术咨询服务工作室简介(更新)
  9. 潜流式湿地计算_人工湿地计算书
  10. ethtool用法 linux_Linux命令之Ethtool用法详解