BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

使用AppVeyor CI 和PowerShell部署应用

| 作者 Feodor Fitsner 关注 0 他的粉丝 ,译者 陈菲 关注 0 他的粉丝 发布于 2014年3月25日. 估计阅读时间: 21 分钟 | 如何结合区块链技术,帮助企业降本增效?让我们深度了解几个成功的案例。

开头语

关于如何为单一的ASP.NET web应用程序设置持续集成,你可以找到很多文章。这些文章都写到如何通过Web Deploy来构建完美的环境来部署简单、只需稍作修改VS.NET模板的web应用程序。任何东西在这一完美环境下都能顺利进行。

但是,真正部署应用程序的话却并非易事。总是有问题不断出现在以下情况中:当需要在注册表(Registry)或自定义文件夹中配置设置,或者你需要部署到Web集群时。

本文中,我们通过使用PowerShell远程处理(PowerShell remoting)和AppVeyor CI为带有ASP.NET web应用程序和Windows Service的解决方案在其暂存(staging)和产品环境中配置持续集成。

解决方案概述

我们的示例中包含4个项目:

  • DemoApp.Web -ASP.NET应用程序,前端
  • DemoApp.Web.Tests -使用VisualStudio测试框架的web应用程序单元测试
  • DemoApp.Service -承载WCF服务的Windows service,后端
  • DemoApp.Service.Tests -使用NUnit框架的Windows service单元测试

该示例应用程序的代码库托管于BitBucket

我们到底将如何部署?

我们遇到的第一个问题就是如何部署Windows service?我们没有针对Windows service的“发布”菜单,也没有相应的配置转换。根本没法用Web Deploy。为了自动化项目的部署,我们将使用PowerShell部署框架 - AppRolla。

AppRolla利用PowerShell远程处理在目标机器上执行部署任务。部署任务将下载应用程序包,解包,更新配置设置,然后创建或更新应用程序网站及pool。该应用程序包仅仅是带有应用程序文件夹的压缩包,通过HTTP上传到外部存储。其内部并没有任何特别之处 - 模块写在PowerShell内,很容易查看和修改。

为了让你对PowerShell部署一睹为快,我们现在就建立一个简单web应用程序,并将其部署到服务器上。

整个流程中最具挑战性的部分可能就是设置带有SSL认证的PowerShell远程处理了。我们强烈建议使用HTTPS与远程服务器进行通信,因为所有的数据流量都是加密的。

当你在Windows Azure 上创建新的虚拟机时,PowerShell远程会自动被激活和配置。防火墙将允许PowerShell远程HTTPS端点端口5986,另外我们也将HTTP端点添加到示例服务器上:

如果你需设置其它服务,可以参照该链接里的具体细节:guide on how to configure PowerShell remoting。

为了在实例机器上快速安装IIS7.5,我们使用以下PowerShell命令:

Add-WindowsFeature -Name Web-Default-Doc,Web-Dir-Browsing,Web-Http-Errors,Web-Static-Content,Web-Http-Logging,Web-Stat-Compression,Web-Filtering,Web-Net-Ext,Web-Net-Ext45,Web-Asp-Net,Web-Asp-Net45,Web-ISAPI-Ext,Web-Mgmt-Console

我们创建带有“Hello world”的简单Web应用程序,然后将其部署到示例服务器。

创建一个新的SimpleWebApp-1.0.zip压缩包,将带有第一版本的default.aspx存档起来。

现在,我们需要将该应用程序压缩包上传到外部存储,这样目标服务器就能通过HTTP来对其访问。该服务器可以是启用了FTP的web服务器,Amazon S3或Azure blob存储。对于该示例,我们使用DropBox。它为DropBox文件夹下所有项目提供公共的下载链接。

将该SimpleWebApp-1.0.zip拷贝到你的DropBox文件夹中,然后右击文件夹,选择“Share DropBox link”。在浏览器中打开该链接,然后拷贝“Download”键的URL。

打开PowerShell的控制台“As administrator”,将执行政策(execution policy)改成为允许远程PowerShell脚本:

Set-ExecutionPolicy RemoteSigned

安装AppRolla.psl模块(将被安装到用户配置文件中):

(new-object Net.WebClient).DownloadString("https://raw.github.com/AppVeyor/AppRolla/master/install.ps1") | iex

将AppRolla模块导入到当前会话中:

Import-Module AppRolla

AppRolla有两组cmdlets:配置和部署。通过配置cmdlets定义应用程序和环境。

紧接着,添加新的“SimpleWebApp”应用程序,该应用程序只带有单一的“website”角色:

New-Application SimpleWebApp

Add-WebsiteRole SimpleWebApp Web -PackageURL "<your-dropbox-download-link>"

在服务器上定义“示例”环境(在提示出现后,输入示例服务器的管理员证明 - 后面将有详细讲解):

New-Environment demo

Add-EnvironmentServer demo "appveyor-demo.cloudapp.net" -Credential (Get-Credential)

将“SimpleWebApp”应用程序作为版本1.0部署到“示例”环境上:

New-Deployment SimpleWebApp 1.0 -to demo

(点击图片放大)

就这样!你已经通过PowerShell将你的Web应用程序发布到示例服务器上了:

现在,我们修改一下页面内容,然后部署一个新的示例应用程序版本。我们将“Hello,World!”改成“Hello, world2.0!”。随后,创建新的SimpleWebApp-1.1.zip文件将修改好的default.aspx文件存档,再次上传到DropBox。

更新“website”角色,将其压缩包的URL修改为新的值:

Set-WebsiteRole SimpleWebApp Web -PackageUrl <public-URL-of-SimpleWebApp-1.1>

然后部署新版本1.1:

New-Deployment SimpleWebApp 1.1 -to demo

从日志可以看出,每次部署都会在本地:\applications\<application-name>\<role-name>\<version>中生成新的文件夹。默认情况下,目标服务器上可以保留5个部署版本,因此应用程序可以很容易地回滚到上一版本:

Restore-Deployment SimpleWebApp -on demo

从示例环境中删除所有应用程序部署:

Remove-Deployment SimpleWebApp -from demo

整个过程,我们都使用简单且简洁的命令来完成所有工作!

使用AppVeyor CI持续构建

 

AppVeyor CI是为Windows开发人员设计的基于云的持续集成和部署平台。它有自己的服务器,因此不需要安装或配置。就算需要,配置起来也非常简单。另外,AppVeyor CI对开源项目是免费的。

为了在AppVeyor CI中设置工程,其代码源必须托管于在线源代码控制库上,比如:GitHub、BitBucket或Kiln。它支持Git和Mercurial。

在我们示例中,我们使用托管于BitBucket的Mercurial库。对商业项目来说,BitBucket相当实用,它免费地提供无限制的私有库。

启用NuGet存储

如果你的解决方案依赖于NuGet管理包,不要忘了启用NuGet restore来自动下载构建服务器上的各种程序包。可以使用如何启用NuGe包存储这一指导来确保在.Nuget文件夹中的NuGet.exe已经添加到库里了。

添加新项目

我们可以先从创建新项目开始:

一旦新项目建成,新的web hook就会自动添加到项目库中,为新构建拉开序幕。

构建配置和配置交换

当通过Web Deploy部署时,配置交换在应用程序配置过程中是一个关键。对于每个需要部署的环境,都需定义新的VS.NET解决方案配置,然后使用配置转换生成web.config,它带有数据库链接字符及其它应用程序针对每个环境特定的设置。该方法看起来可行,却有一系列问题:

• 类似数据库链接字符这样的敏感数据存储于源代码控制中。

• 配置转换应用于构建过程,每当项目部署到新环境中,都需要重新构建配置转换。

当用AppVeyor部署时,配置转换非常有用,但并非是必需的。默认情况下,VS会产生两种配置:Debug和Release,大多数情况下,这种形式完全OK。Debug配置用于本地开发,而Release配置则用于CI流程生成可以部署到任何环境的包。配置转换应该“真正地”用于转换配置文件结构,比如:禁用“Debug”标识;启用自定义错误;或启用Autofac更换模式等适用于所有环境的常见设置。

我们现在就可以开始改变Release设置页面中的项目构建配置:

AppVeyor提供三种构建方案:

  • Visual Studio方案 - 运行MSBuild于VS.NET解决方案或工程文件(如果没有指定,首先查找第一个.sln或.*proj文件),还有将所有项目构建结果以工件形式打包。
  • MSBuild - 根据自己的规定运行MSBuild,允许在“Packaging”页面上定义自定义的构建工件。
  • Script - 运行特定PowerShell脚本或批文件。为管理构建流程及其结果提供最大化的自由。

组件版本

每个新项目构建都会收到新的版本号,该版本号的格式规定于“General”页面下。

AppVeyor默认提供Windows style versioning(major.minor.{build}.revision),但是你也可以运用其它任意版本风格,比如:SemVer(major.minor.patch.{build})。

当启用“Update assembly version attributes”时,AppVeyor会将解决方案目录下的所有AssemblyInfo.*文件设置成当前版本。

执行测试

AppVeyor能通过以下这些测试框架,在assembly中发现和运行测试:

  • MSTest
  • NUnit
  • xUnit

当“测试”步骤被启动时,AppVeyor会分析“out”文档中所有的assembly,来确认它们对所支持的测试框架是否含有相应的引用。如果有,那么所有assembly内的测试将会在相应的测试执行器中运行一遍。所有assembly的测试结果也会集合显示在UI上。

(点击图片放大)

构建.测试.打包!

我们现在开始创建新构建,可以对项目库进行修改或点击“New Build”。

该模拟项目的构建流程会生产两个构建工件:web application和Windows service。将它们下载下来,你会发现其内容就是带有应用文件的常规压缩文档。

由于Windows service包基本上就是其“Bin”文件夹下用于生成web应用包的内容中还需包含的一些步骤:

  1. Web应用应是解决方案的一部分。
  2. 创建应用了“file system”发布方法的新发布配置文件,并发布了使用MSBuild的WAP项目,该配置文件用来确保web.config修改以及其它发布设置的执行。
  3. 将发布的web应用打包为一压缩文件。

构建工件将存储于Geo-redundant云存储中,能通过其独有的专属链接下载。如果想有自己专有的构建工件命名结构,以及允许公共访问的话,可以配置专有存储空间。

成功部署到预生产环境

我们现在开始往staging上配置自动化部署,作为该构建流程的一部分。

该部署应脚本的形式来完成,可以是PowerShell或批处理文件。在项目库的根部创建“部署”文件夹以放置部署脚本。

打开PowerShell命令行,跳转到“部署”文件夹,并执行以下命令下载模板脚本到现有目录:

(new-object Net.WebClient).DownloadString("https://raw.github.com/AppVeyor/Deployment/master/install.ps1") | iex

会有三个脚本被添加:configure.ps1、 project.ps1 和deploy.ps1。

总的说来,我们只需要编辑一个文件就能配置部署:project.psl。该文件定义了我们将要部署的环境。将删除紧接着新staging环境那一行的备注,然后添加模拟服务器:

New-Environment Staging 
Add-EnvironmentServer Staging “appveyor-demo.cloudapp.net”

返回到AppVeyor CI,打开项目设置的“Deployment”页面。

选择“Run deployment script”,并指定脚本路径:

deployment\deploy.ps1

设置以下部署变量:

Environment: Staging   
ServerUsername:    
ServerPassword:    
ApiAccessKey:   
ApiSecretKey: 

ServerUsername和Password用来创建Credential对象以验证PowerShell的远程调用。以下两种情况要求到API关键字:a)阅读项目工件获取项目包的URL;b)验证目标服务器下载工件包。AppVeyor API关键字可以在用户配置的“API Keys”页面下找到。

就这样。接着只要提交“deployment”文件夹,将其推送到项目库就可以开始该部署的新构建了。

如何更新web.config的链接字符?

部署变量通过$variables参数以哈希表形式传递到脚本中。对于项目或角色,如果想启用附加的配置变量,可以在Set-Application, Set-WebsiteRole或Set-ServiceRole cmdlets中使用“Configuration”参数。打开project.ps1,并添加以下语句:

Set-WebsiteRole $projectName DemoApp.Web -Configuration @{   
    “ConnectionStrings.DefaultConnection” = $variables.DefaultConnection   
}

}

然后在部署设置页面上定义“DefaultConnection”变量,用于web应用的链接字符的传递。部署脚本通过web.config为web应用程序应用了角色配置,对Windows应用程序,则通过app.config,运用了以下这些规则:

  • Setting with name “ConnectionStrings.<name>” updates connection string with <name> name in “connectionStrings”section.
  • Setting with name “AppSettings.<name>” updates “AppSettings” value with <name> name.

总结

本文中,我并非试图去低估或淡化其它的Web部署工具,它们可能在你的web应用中得到了很好的应用。但是,如果你的项目已经超出模板化的web应用,而必须部署到集群环境中或你需要更复杂,或对部署流程更多控制的话,那么绝对值得考虑像PowerShell remoting这样替代的解决方案。这对于具有PowerShell技能或使用PSake的开发人员来说,将会特别具有吸引力。

关于作者

Feodor Fitsner是个具有创业精神的.NET开发人员,他接触Windows Web平台已超过10年。Feodor最新项目就是Appveyor CI:专为.NET开发人员设计的主机型持续集成解决方案。在AppVeyor之前,Feodor针对Windows主机开发了DotNetPanel控制面板,之后就职于Microsoft的Azure 部门。

参考英文原文:Deploying it right with AppVeyor CI and PowerShell


感谢陈菲对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT