写点什么

使用 AppVeyor CI 和 PowerShell 部署应用

  • 2014-03-24
  • 本文字数:5279 字

    阅读完需:约 17 分钟

开头语

关于如何为单一的 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 “

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

复制代码
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\\\中生成新的文件夹。默认情况下,目标服务器上可以保留 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 Stagingappveyor-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.” updates connection string with name in “connectionStrings”section.
  • Setting with name “AppSettings.” updates “AppSettings” value with 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 )关注我们,并与我们的编辑和其他读者朋友交流。

2014-03-24 03:167140
用户头像

发布了 39 篇内容, 共 13.3 次阅读, 收获喜欢 2 次。

关注

评论

发布
暂无评论
发现更多内容

实时数据引擎系列(一): 新鲜的数据流

tapdata

数据库 hadoop Tapdata 实时数据引擎 OLTP

iOS App注入SDK调试

GrowingIO技术专栏

ios sdk 逆向 注入sdk

这份Github神仙笔记覆盖了90%以上的Java面试题,带你所向披靡

Java~~~

Java spring 架构 面试 微服务

裸辞闭关62天,啃下这些分布式技术笔记,有幸通过阿里Java岗P6面试

Java~~~

Java 架构 面试 分布式 高可用

如何动手做出一个 CPU

Java 编程 架构 cpu 电脑

阿里技术大牛终于分享出了解决我多年困扰的微服务开发架构文档

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

阿里资深架构师熬夜纯手写的238页微服务容器化开发实战笔记

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

百度世界大会2021: 与时代共振,AI让生活更好

百度大脑

人工智能

基于java springboot vue uniapp商城源码(毕设)

清风

Java uniapp 商城项目 毕业设计

智能量化交易系统搭建|量化交易APP系统源码开发

量化系统19942438797

量化交易 智能量化

Web端实现RTC视频特效的解决方案

网易云信

终于学完了阿里P8架构师7年心血整理总结的微服务实战文档

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

金九银十你打算用什么硬核技能噎死面试官呢?附Java面试核心笔记

Java~~~

Java spring 架构 面试 微服务

腾讯T8面试官纯手打总结Java888道高频面试真题笔记+Java面试金典

Java~~~

Java 架构 面试 算法 JVM

“古老”茶产业碰上“年轻”区块链,能否擦出新火花?

旺链科技

区块链 产业 茶叶

智能CRM销氪强势崛起, CRM赛道变数几何?

ToB行业头条

CRM

【Vue2.x 源码学习】第四十篇 - 组件部分 - 组件的生命周期

Brave

源码 vue2 8月日更

四十四本iOS开发书籍资料,务必赶紧保存!

iOSer

微信公众号 ios开发 iOS书籍 iOS公众号

5秒到1秒,记一次效果“非常”显著的性能优化

Java 编程 架构 性能优化 计算机

数字货币量化交易平台源码搭建|量化交易所自动交易软件开发

Geek_23f0c3

去中心化交易所系统开发 量化跟单 合约量化

Python代码阅读(第13篇):检测列表中的元素是否都一样

Felix

Python 编程 Code Programing 阅读代码

带你破解DDOS攻击的原理

网络安全学海

黑客 网络安全 信息安全 渗透测试 漏洞挖掘

网络安全产品之堡垒机介绍以及应用案例

行云管家

网络安全 数据安全 堡垒机 成功案例

85W美团架构师分享深入解析Java虚拟机HotSpot文档

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

Swift 与 Objective-C:您应该为下一个 iOS 移动应用选择哪个语言?

iOSer

ios objective-c swift ios开发

那些年用星环产品解决的业务难点…

星环科技

征文 星环科技

Reality Capture 初探

空城机

3D渲染 3D模型 8月日更 Reality Capture

备战92天终入阿里,这份Java后端开发者面试技能笔记功不可没,共勉

Java~~~

Java spring 架构 面试 微服务

面试侃集合 | ArrayBlockingQueue篇

码农参上

队列 8月日更

都2021年了,你还在用Jenkins?赶快看看这些替代方案吧

编程菌

Java 编程 程序员 计算机 技术宅

地表最强:iOS安全黑宝书中文版来袭

博文视点Broadview

使用AppVeyor CI 和PowerShell部署应用_DevOps & 平台工程_Feodor Fitsner_InfoQ精选文章