经过近2年折腾,基于TFS的Devops主线工程大体落地完毕。
在此大体回忆下中间的各种历程。

开始之前简单说下什么是TFS(Team Foundation Server)。

TFS是微软推出的一款ALM(Application Lifecycle Management)管理工具。

透过TFS你将能获取到从代码版本管理->项目管理->持续集成->自动发布->自动测试等一系列软件生命周期在内的全家桶功能,它也有一个云端版称之为VSTS。

VSTS/TFS=Github+Trello/TeamBition/Tower/Jira/Rally/RTC+QC/TestLink+Jenkins。

TFS不仅是个存代码的,

TFS不仅是个存代码的,

TFS不仅是个存代码的,

重要的事情说三次。只用TFS来存放代码的就相当于6000块买个iPhone当着200块的诺基亚功能机在用,暴殄天物。

本文将会说:TFS在我们组里对提升我们组Devop所起到的作用和各种历程。

本文将不会说:如何对TFS进行具体配置。

希望该文章可以帮助到在用TFS或者希望用TFS的团队或者个人。

第0章--历史

刚到公司的时候,那一年是2015年,作为一名开发小白的我刚加入战局。

此时公司是基于TFS2010使用TFVC来进行代码管理,基于Jira进行项目管理,无自动打包/发布,无自动测试。

首先作为一个有志青年,在这个以SVN为代表的集中式代码管理已经日趋没落而git蒸蒸日上的年代,对和SVN一脉相承的TFVC自然是不屑一顾。

而且还用着5年前的TFS2010…那个界面:

一看就不想用.已经完全不符合时代潮流的UI.

而同时期的TFS2015:

明显就更现代化,更加的User Experience。

然后遂用着VSTS(那会儿还叫Visual Studio Online)里的git进行代码管理,当然这对我司是不合规矩的,不过一方面自己手头负责的是新项目(新建项目开始的那种),另一方面也只是个临时方案。

当然与此同时也向老大申请,看看能否搞个TFS2015来…毕竟要紧跟时代潮流。

第1章--推广git

后面在老大的协助下,终于弄来了我们自己的TFS2015,然后当然第一步新将原VSTS里的代码迁过去,然后自己就基于上面happy的coding。

然后后续其他项目也逐渐迁移到新的TFS服务器上。

因为新的项目集合都基于git来做代码版本管控,这中间有几个问题:

①如何说服已经习惯了TFVC工作流程的其他同事使用上git;

②在git上如何做代码管控。

要说这个问题前先说说为什么我自己喜欢用git:

首先我觉得在技术选型上一定要避免因为这个是最流行/最新所以我就要用它的这种形而上学主义,我们要用一个产品,一定要明白它是什么,以及它是为了解决什么问题而诞生的,只有这样才能选到合适的产品(注意:是合适,而不是”最好”)。

我个人是个BYOD主义者(自带设备上班),一方面是客观上公司电脑战斗渣(起码现在升级后还是机械盘,俺主力的微软亲儿子4好歹是个全固态),另一方面被BYOD思想给洗脑了,在另一方面还能方便随时随地加个班…

git的离线提交对我而言是个相当强有力的功能存在。

另外和集中式管控的每次提交都要做策略不同,我个人更倾向于每次提交无需任何策略检查,而是在pull request阶段在做策略的”打包式代码管控”。

在另外的就是git的分支,让分支这个功能从此变得唾手可得..

基于上述理由所以我选择了git。

然后就是对原有同事的”普法”了,其中一个比较头疼的问题是git的commit和push这2个概念经常说不清,虽然现在的我也不见得就能说清,毕竟TFVC的时候点下提交就真的上服务器了,而现在你”提交”了不算数,还要在同步(sync)或者推送(push)一下才可以。

在另外就是启用了pull request来管理需要开发/发布的代码,同时也是初步引入了”代码审查“的概念:每次pull request都需要非本人之外至少一人同意:

然后因为git的分支使用起来特别方便,之后协同开发也变得更加方便,因为各自都在各自的分支里进行独立开发。

而且自此我们每次发布后都会按照当时发布日期拉一个分支出来作为备份分支,用于做各种临时更新所需要的处理:

阶段总结,由于引入了git给我们带来了:

①更方便大家协同合作开发,现在每个人都有自己的开发分支来开发自己负责的功能;

②更方便拉取备份分支,从此我们组在处理临更这件事上更加游刃有余;

③引入了Pull Request和最原始的代码审核。

第2章--引入最初的自动发布

从第0章的历史里已经写到,原来我们是没有任何自动发布的工具或者套路的,我们的一个常规发布流程是:先开发好,然后用vs的”右键->publish”生成一个发布包(文件夹),然后提交到svn,在告知qa的同事拿包更新到测试环境。

首先这个流程繁琐而又浪费时间,其次还经常出错,而且时而还发生比如某人的代码没合并进去之类的恶性问题,无论是我们开发组还是qa组都对这个苦不堪言,于是自动发布被提上优先处理的日程。

最初版本的自动发布的想法只是简单的将vs里的”右键->publish”自动化。

首先我们知道vs的publish是可以支持发布到远程服务器的:

我只要在target location填入目标服务器的共享文件夹地址且我服务器有权限访问目标服务器的话,那么就可以直接发布上去:

对应的在tfs里的Build Solution步骤里的MS Build参数里只要填上发布的对应配置文件,就能将上述过程变得自动化。

但这套方案有如下几个问题:

①被发布的机器一定要有共享文件夹配置;

②Build Agent到被发布的机器一定要有访问对应共享文件夹的权限(要事先弄好);

③每次发布其实都是从代码库里将代码拖出来再重新编译的,如果比对版本的话各个环境的dll版本都是不匹配的..(最起码文件创建时间铁定不一样)。

这就导致配置这套要被发布的机器和BuildAgent同时都要做不同程度的配置,而且这个明显对后期无论BuildAgent的增加或者是被发布的服务器增加都不是个好事,但毕竟第一步,有好过没有,先上了再说。

另外一点是我们正规做法是提交代码时候都是不能带dll的,所以现在本地引用dll的形式在自动发布的时候都很容易会出现问题(别跟我说将dll提交到版本管控里)。

也因此我们首次将nuget作为一个必须项引入进来,在此之前nuget虽然也有但是都是属于想用就用,不想用就本地dll这样的方式。

由于自动发布的需要,我们不再允许本地引用dll而要求所有外部依赖必须通过nuget服务器来进行管理。

同时,QA组同时也对这个流程上提出意见,他们要求上测试环境必须要他们同意才可以而不是开发说想什么时候上就什么时候上(不然我就配置个Trigger搞持续集成了)。

于是我们新引入了QA分支的概念。

QA分支只有QA组的同事有pull request的审核权限,如下图这样的配置:

QA分支只要同意后就会自动触发Demo环境(第一个测试环境)的自动发布(通过Trigger实现),后续testing环境和预发布环境也只会基于QA分支的代码来进行。

然后试用一段时间下来,有自动发布的项目在发布上的问题明显减少了很多,而且QA同事花在更新包到测试环境上所需时间也明显降低。

阶段总结:

①引入了自动发布;

②引入了QA分支,明确了发布上的流程;

③将nuget作为引用外部dll的唯一选择,统一外部依赖的管理。

第3章 自动发布的优化

此时微软发布了TFS2015Update2,相关更新内容可以参考 TFS2015Update2更新日志。

其中最重要的一点是:

引入了Release Management的功能,以前这是作为一个独立产品的现在作为一个子功能整合到了TFS里,然后又在我们老大协助上让运维那边升级了TFS到Update2之后,就着手怎么让我们也用上“Release”的功能。

另外一点是这个版本开始TFS也有了自己的Store,从此走上了可以装各种扩展的日子了

首先我理解的Release和原先已有的Build应该是这样子的:

先通过Build将代码变成dll,然后找个地方存起来,之后就通过Release发布到各个环境,由于Release只是充当一个“复制dll+配置“的功能,而dll都是最初那个Build生成的,所以各环境下的dll应该都是一样的。

然后经过调整后(删掉有的没的只留下必要的)一个典型的Build的步骤是这个样子的:

然后Release的步骤大概是这样:

这里不会详情阐述上述截图的意思,具体的配置可以参考微软官方文档Build for Asp.NetDeploy to Windows VM

到现在我们的自动发布就变成类似这样:

注意中间的格子,灰色代表对应环境没执行发布动作,而绿色则是发布过且发布成功,对应还有黄色(发布了但部分成功)和红色(发布失败)。

然后我们项目发布过程到达了哪个阶段现在也能一目了然而不是总是跑过去问QA:”现在发布到哪里了,testing上了吗?”。

在这套自动发布上了之后没多久,我惊讶发现在Release里的”IIS Web App Deployment”的Task有这么一个东西:

虽然我英语不好,不过字里行间隐约猜到它应该是可以在部署期间替换某些参数(猜测跟Vs发布时候的那个Transform那样)。

以前我们发布的时候都要求排除掉web.config的,因为像是数据库链接字符串,在各个环境下都不一样,然后就各个环境web.config实现准备好,发布时候不发布web.config这样的方式来解决。

这有个问题是我们经常更新nuget包的时候其实它是会动web.config的,然后这种变动每次在SVN包里写个txt告诉QA怎么改(你能想象QA们在一堆xml里找到你需要的节点然后做对应修改的痛苦么?)。

类似这样子:

后面运维那边提出将“环境相关”的web.config抽取出独立的config文件来作为不更新的部分,web.config整体就作为发布的一部分每次都更新,大体拆分的Web.Config的拆分可以参考 使用 ConfigSource 特性 拆分 Web.config 文件

但我总归觉得这种事情应该要能更“自动化”的解决,而且一个文件如果长久不发布后面万一真要变的时候谁会想的起还有这码事?然后就去研究那个”Web Deploy Parameter File“。

发觉只要指定一个xml文件然后在IIS部署阶段Web Deploy就会用对应配置文件替换掉你站点里的所有指定配置文件(没错,是所有,不局限于web.config)。

它的文件定义大概是这样子的:

后面投入使用后也反馈良好,自此之后我们开发将web.config也作为发布文件发布上去,然后每次发布的时候会透着这个文件在部署阶段自动转换注入数据库链接字符串或者某些appsetting。

自此做了这套方案的项目,基本上没有通过一个txt的形式告诉QA怎么改配置文件了。

阶段总结:

①升级了TFS获得了Release Management功能以及支持商店功能;

②将自动发布拆分了Build和Release两个步骤,更规范的自动发布流程;

③通过Release我们开发能清楚知道现在测试到什么阶段;

④web.config为代表的发布配置自动化。

大总结

经历过上述折腾,现在我们基本从封建时代阶段步入工业革命时代,引入了git(特别是它的分支功能),引入了自动化发布。

整体让我们组进入初步现代化的阶段。

之后将会讲讲我们组基于TFS如何来做代码分析,整合监控,NetCore的支持等,敬请期待..

TFS在项目中Devops落地进程(上)的更多相关文章

  1. TFS在项目中DevOps落地进程(下)

    紧接上篇 TFS在项目中Devops落地进程(上) 再接着说TFS相关之前先插入一个番外篇,虽然跟TFS关系不大但跟DevOps关系很大,觉得有必要在此乱入一下. 番外篇--监控之Applicatio ...

  2. vue项目中阻止浏览器返回上一页

    vue项目中在某个页面阻止浏览器返回上一页,适用移动端.PC端. 使用场景例如: 首页 与 A页面     来回跳转,那样点击浏览器返回时也会来回跳转,本想当页面在首页的时候就不再返回了,所以这个时候 ...

  3. Java项目中的下载 与 上传

    使用超级链接下载,一般会在浏览器中直接打开,而不是出现下载框 如果要确保出现下载框下载文件,则需要设置response中的参数: 1是要设置用附件的方式下载 Content-Disposition: ...

  4. ssm项目中KindEditor的图片上传插件,浏览器兼容性问题

    解决办法: 原因:使用@ResponseBody注解返回java对象,在浏览器中是Content-Type:application/json;charset=UTF-8 我们需要返回字符串(Strin ...

  5. ASP.NET WEB API 帮助文档引用单独项目中的DTO,见面上不显示字段注释问题解决办法

    StackOverFlow上的解决办法: 问题地址

  6. 项目中使用的图片上传方法,base64存本地

    //生成健康报告 public function uploadJkbg(Request $r) { $data = $r->all(); $jkbg['jkbg_ctime'] = time() ...

  7. 如何在 ETL 项目中统一管理上百个 SSIS 包的日志和包配置框架

    一直准备写这么一篇有关 SSIS 日志系统的文章,但是发现很难一次写的很完整.因为这篇文章的内容可扩展的性太强,每多扩展一部分就意味着需要更多代码,示例和理论支撑.因此,我选择我觉得比较通用的 LOG ...

  8. [转]在iOS项目中使用CorePlot框架

    转载地址:http://blog.csdn.net/llfjfz/article/details/7849190#comments Core Plot是OS X和IOS下的一个开源图形库,它提供数据的 ...

  9. 将 Net 项目升级 Core项目经验:(二)修复迁移后Net Standard项目中的错误

    修复迁移后Net Standard项目中的错误 接上一章,项目编译结果如下: 解决依赖dll引用 在Net Framework项目的引用如下: 各引用和作用: log4net(1.10.0.0) 用于 ...

随机推荐

  1. cs224d 自然语言处理作业 problem set3 (一) 实现Recursive Nerual Net Work 递归神经网络

    1.Recursive Nerual Networks能够更好地体现每个词与词之间语法上的联系这里我们选取的损失函数仍然是交叉熵函数 2.整个网络的结构如下图所示: 每个参数的更新时的梯队值如何计算, ...

  2. JQ重复注册问题

    开发中常常会碰到事件重复注册,简单总结一下解决方法. (1)bind注册事件 $('...').unbind().bind('...',function(){}) (2)live注册事件 $('... ...

  3. 渣渣学QT

    初学QT,自己的一些小总结,错误之处,望大神指点一二: 1,添加资源文件时想应用在界面的背景,但是发现用不了,后来才知道是没有"构建"?应该是要在构建之后才将所添加的资源文件真正的 ...

  4. oracle排序的几种方法

    1.创建数据库表 CREATE TABLE USER_INFO(  USERID      VARCHAR2(10 BYTE)                 NOT NULL,  USERNAME  ...

  5. 编写 WPF DataGrid 列模板,实现更好的用户体验

    Julie Lerman 下载代码示例 最近我在为一个客户做一些 Windows Presentation Foundation (WPF) 方面的工作. 虽然我提倡使用第三方工具,但有时也会避免使用 ...

  6. riot.js教程【一】简介

    Riotjs简介 Riotjs是一款简单的.优雅的.组件化UI前端开发框架: 他支持自定义标签(custom tags),拥有令人愉悦的语法,优雅的API和非常小的体积: 为什么需要一个新的界面库 前 ...

  7. oracle开启一个用户

    我的工具,PL/SQL Developer(其他工具大同小意) 1.用系统管理员账号登入数据库    账号是:sys,   connect as:sysdba  登入进入如下页面. 2.查看所有用户( ...

  8. Bootstrap表格样式(附源码文件)--Bootstrap

    1.表格默认样式 <h4>表格默认样式</h4><table><!--默认样式--> <tr><th>序号</th> ...

  9. JavaEE 对象的串行化(Serialization)

    什么情况下需要序列化 a)当你想把的内存中的对象写入到硬盘的时候:b)当你想用套接字在网络上传送对象的时候:c)当你想通过RMI传输对象的时候:再稍微解释一下:a)比如说你的内存不够用了,那计算机就要 ...

  10. Java 线程并发

    http://www.yesky.com/9/1899009.shtml http://zhidao.baidu.com/link?url=-xZ9JLo5x4bvCSVyXb2XhO6TODnBcU ...