Windows + Jenkins + .NetFramework + SVN 持續部署
環境准備
服務端環境
安裝 Windows 服務器
1、阿里雲購買臨時服務器
2、使用虛擬機安裝
可以使用VMWare、VisualBox等虛擬機管理工具來安裝環境,本教程將使用虛擬機安裝,且 Windows Server 版本為 2016。
Windows Server 2016 安裝包:https://download.microsoft.com/download/B/5/F/B5F1A996-B590-45FD-BA99-DE7E745A0882/14393.0.161119-1705.RS1_REFRESH_SERVER_EVAL_X64FRE_ZH-CN.ISO
安裝 IIS
必須安裝 .net framework 4.6
。
安裝 MSBuild
若要在沒有 Visual Studio 的系統上安裝 MSBuild,請轉到 Visual Studio 下載並向下滾動到“所有下載”,然后展開 “Visual Studio 2019 工具” 。 安裝 Visual Studio 2019 生成工具(包含 MSBuild)
在安裝程序中,確保選擇要為工作負載使用的 MSBuild 工具,然后選擇“安裝”。
其他版本:MSBuild V14.0
安裝 SVN Server 和 SVN Client
SVN Server
1、下載 SVN 安裝包
下載地址:https://www.visualsvn.com/downloads/
根據操作系統版本選擇 32 位或 64 位安裝包,這里選擇 64 位安裝包。
2、創建用戶及 Repository
創建用戶:
創建 Repository:
SVN Client
安裝 Visual SVN
下載地址:https://www.visualsvn.com/downloads/
跟着安裝流程走即可。
安裝 nuget.exe CLI
nuget.exe
CLI(即 nuget.exe
)是適用於 Windows 的命令行實用工具,可提供所有 NuGet 功能;它也可以使用存在一些限制的 Mono 在 Mac OSX 和 Linux 上運行。
要了解如何在 nuget.exe
CLI 中使用基本命令,請參閱使用 nuget.exe CLI 安裝並使用包。
Windows
備注
NuGet.exe 5.0 及更高版本需要 .NET Framework 4.7.2 或更高版本才能執行。
- 請訪問 nuget.org/downloads,並選擇 NuGet 3.3 或更高版本(2.8.6 與 Mono 不兼容)。 始終建議使用最新版。若要將包發布到 nuget.org,版本至少必須是 4.1.0。
- 每次下載都直接下載
nuget.exe
文件。 讓瀏覽器將文件保存到選定文件夾。 此文件不 是安裝程序;如果直接在瀏覽器中運行,就不會看到任何內容。 - 將文件夾添加到
nuget.exe
中放置 PATH 環境變量的位置,這樣就可以從任意位置使用 CLI 工具。
由於我們使用的是 .net framework 4.6,下載 nuget.exe v4.9.4 ,然后放在 C:\nuget
目錄下。
然后再配置環境變量。
驗證效果:
nuget
安裝 .net framework 4.6 Developer Pack
正常情況下,不允許在服務器上安裝開發軟件,而由於需要在服務器上構建項目,那就需要安裝 Developer Pack。
下載地址:https://dotnet.microsoft.com/download/dotnet-framework/net46
客戶端環境
安裝 Visual Studio 及 Visual SVN
1、安裝 Visual Studio 2019
這里安裝 Visual Studio 2019 社區版,大家也可以安裝專業版。
官網下載:https://visualstudio.microsoft.com/zh-hans/vs/
2、安裝 Visual SVN
下載地址:https://www.visualsvn.com/downloads/
跟着安裝流程走即可。
項目准備
1、Checkout 和 項目目錄結構初始化
在本地電腦上,創建目錄 D:\test\helloworld
(你也可以在任意位置創建)
-
將上面 SVN 的倉庫 helloworld 簽出。
-
初始化項目目錄結構,如下:
- build:放構建的 bat 腳本
- lib:放第三方庫
- src:放項目源代碼
- test:放測試代碼
2、創建一個初始項目
3、按 F5 運行,查看效果
4、編寫 MSBuild
在 build 目錄下創建兩個文件。
build.bat:
SET MSBUILD="C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin"
SET APPCMD="C:\WINDOWS\System32\inetsrv\appcmd.exe"
SET YEAR=%date:~0,4%
SET MONTH=%date:~5,2%
SET DAY=%date:~8,2%
SET HOUR=%time:~0,2%
SET MINUTE=%time:~3,2%
SET SECOND=%time:~6,2%
%appcmd% stop site helloworld
%MSBUILD% build.proj /target:Default /property:Rebuild=true;Configuration=Debug;RELEASE=false;PatchVersion=%month: =0%%day: =0%;BuildVersion=%hour: =0%%minute: =0%;SolutionName=src\HelloWorld.sln;DeployDir=..\..\..\websites\helloworld
%appcmd% start site helloworld
這個批處理主要做了3件事:
- 設置變量:SET MSBUILD 等
- 停止/開始IIS站點:appcmd stop[start] site helloworld,更多請查看https://www.cnblogs.com/sharesdk/p/11290597.html
- 構建項目:msbuild build.proj
- /target:Default:表示要執行名字是 Default 的 Target,具體看 build.proj
- /property:表示要傳進 build.proj 的參數,以
key=value
為一對,用分號(;)隔開
build.proj:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Default"
xmlns='http://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="4.0">
<!-- 設置屬性值,后面可以使用 $(...) 來調用 -->
<!-- Condition 表示只有當條件成立,才進行設置,一般作為默認值。如果 msbuild.exe 執行時傳值進來,就不會使用此默認值 -->
<PropertyGroup>
<MajorVersion Condition="$(MajorVersion) == ''">1</MajorVersion>
<MinorVersion Condition="$(MinorVersion) == ''">0</MinorVersion>
<PatchVersion Condition="$(PatchVersion) == ''">0</PatchVersion>
<BuildVersion Condition="$(BuildVersion) == ''">0</BuildVersion>
</PropertyGroup>
<PropertyGroup>
<BuildSolutionDir>$(MSBuildProjectDirectory)\..</BuildSolutionDir>
<SrcDir>$(BuildSolutionDir)\src</SrcDir>
<DeployDir Condition="$(DeployDir) == ''">deploy</DeployDir>
<SolutionName Condition="$(SolutionName) == ''">..\xx.sln</SolutionName>
<Configuration Condition="$(Configuration) == ''">Debug</Configuration>
<!--是否需要重新編譯(會刪除編譯輸出目錄),編譯時間較長-->
<Rebuild Condition="$(Rebuild) == ''">false</Rebuild>
<Version>$(MajorVersion).$(MinorVersion).$(PatchVersion).$(BuildVersion)</Version>
<UnstableTag Condition="$(RELEASE) == ''">-unstable</UnstableTag>
<PackageVersion>$(MajorVersion).$(MinorVersion).$(PatchVersion).$(BuildVersion)</PackageVersion>
<EnvVersion>$(MajorVersion).$(MinorVersion).$(PatchVersion)</EnvVersion>
</PropertyGroup>
<!-- Build依賴順序,即執行順序 -->
<PropertyGroup>
<DoBuildSolutionsDependsOn>
UpdateSVNReporitory;
BuildSolutions;
BackupWebsite;
DeployWebsite;
</DoBuildSolutionsDependsOn>
</PropertyGroup>
<!-- 默認任務 -->
<Target Name="Default" DependsOnTargets="$(DoBuildSolutionsDependsOn)" />
<!-- 從 SVN 更新最新代碼 -->
<Target Name="UpdateSVNReporitory">
<Message Text="*****正在從SVN庫拉取最新代碼*****" Importance="high"/>
<Exec Command="svn update $(BuildSolutionDir)\src" ></Exec>
</Target>
<!--編譯任務-->
<Target Name="BuildSolutions">
<Message Text="*****正在還原引用的程序包*****" Importance="high"/>
<Exec Command="nuget restore $(BuildSolutionDir)\$(SolutionName) "></Exec>
<!--排除web\bin目錄垃圾組件影響-->
<Message Text="*****正在清空站點BIN目錄文件和dist目錄文件*****" Importance="high"/>
<RemoveDir Directories="$(BuildSolutionDir)\src\HelloWorld.Web\bin"></RemoveDir>
<RemoveDir Directories="$(BuildSolutionDir)\lib\dist"></RemoveDir>
<MSBuild Projects="$(BuildSolutionDir)\$(SolutionName) " Targets="Build"
Properties="Configuration=$(Configuration);Version=$(PackageVersion)" ContinueOnError="true"/>
</Target>
<!--備份原站點目錄下的配置文件-->
<Target Name="BackupWebsite">
<Message Text="*****正在備份站點配置文件*****" Importance="high"/>
<Exec Command="XCOPY $(DeployDir)\Web.config $(DeployDir)\backup\ /y" ContinueOnError="true"></Exec>
<!--備份目錄下上傳的圖片文件等資料-->
<!--<Exec Command="XCOPY $(BuildSolutionDir)\$(DeployDir)\files $(BuildSolutionDir)\$(DeployDir)\backup\ /y" ContinueOnError="true"></Exec>-->
</Target>
<!--部署站點任務-->
<Target Name="DeployWebsite">
<!--正在清空原部署站點-->
<Message Text="*****正在清空站點目錄及文件*****" Importance="high"/>
<RemoveDir Directories="$(DeployDir)\bin" ContinueOnError="true"></RemoveDir>
<Message Text="*****正在合並站點文件*****" Importance="high"/>
<Exec Command="XCOPY $(BuildSolutionDir)\src\HelloWorld.Web\App_Data $(BuildSolutionDir)\lib\dist\App_Data\ /y /s /e"></Exec>
<Exec Command="XCOPY $(BuildSolutionDir)\src\HelloWorld.Web\Content $(BuildSolutionDir)\lib\dist\Content\ /y /s /e"></Exec>
<Exec Command="XCOPY $(BuildSolutionDir)\src\HelloWorld.Web\fonts $(BuildSolutionDir)\lib\dist\fonts\ /y /s /e"></Exec>
<Exec Command="XCOPY $(BuildSolutionDir)\src\HelloWorld.Web\Scripts $(BuildSolutionDir)\lib\dist\Scripts\ /y /s /e"></Exec>
<Exec Command="XCOPY $(BuildSolutionDir)\src\HelloWorld.Web\Views $(BuildSolutionDir)\lib\dist\Views\ /y /s /e"></Exec>
<Exec Command="XCOPY $(BuildSolutionDir)\src\HelloWorld.Web\bin $(BuildSolutionDir)\lib\dist\bin\ /y /s /e"></Exec>
<Exec Command="XCOPY $(BuildSolutionDir)\src\HelloWorld.Web\Web.config $(BuildSolutionDir)\lib\dist\ /y /D:m-d-"></Exec>
<Exec Command="XCOPY $(BuildSolutionDir)\src\HelloWorld.Web\favicon.ico $(BuildSolutionDir)\lib\dist\ /y /D:m-d-"></Exec>
<Exec Command="XCOPY $(BuildSolutionDir)\src\HelloWorld.Web\Global.asax $(BuildSolutionDir)\lib\dist\ /y /D:m-d-"></Exec>
<Message Text="*****正在拷貝站點文件*****" Importance="high"/>
<Exec Command="XCOPY $(BuildSolutionDir)\lib\dist $(DeployDir)\ /y /s /e"></Exec>
<Message Text="*****正在還原站點備份組件*****" Importance="high"/>
<Exec Command="XCOPY $(DeployDir)\backup $(DeployDir)\ /y /s /e" ContinueOnError="true"></Exec>
</Target>
</Project>
更多查看官網:https://docs.microsoft.com/zh-cn/visualstudio/msbuild/msbuild-batching?view=vs-2019
關於 XCOPY
的命令請查看:https://www.jianshu.com/p/83e5cb09d55b
注:在構建時,可能會出現 MSBuild 版本問題,看這篇文章解決:https://my.oschina.net/u/3797416/blog/3164082
再把 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VisualStudio\v16.0
(注意 Visual Studio 版本不同,位置不同,這里是 Visual Studio 2019 社區版) 復制到源代碼管理下的 BuildTargets
文件夾。
5、創建站點
在本地電腦創建站點 helloworld
注意:站點路徑,這里與 build.bat 的參數 DeployDir 有關,站點可以放在任意地方,但是需要同時修改 build.bat
的參數 DeployDir
。
6、構建效果
在 build 目錄下打開 cmd 或 powershell
在瀏覽器上打開 http://localhost:5000/
7、提交代碼
將目錄下的所有內容提交到 svn 服務器。
8、服務器簽出代碼
jenkins
什么是 jenkins?
Jenkins 是一個獨立的開源自動化服務器,可用於自動化各種任務,如構建,測試和部署軟件。Jenkins可以通過本機系統包 Docker 安裝,甚至可以通過安裝 Java Runtime Environment 的任何機器獨立運行。
安裝 jenkins
安裝 JDK
下載 JDK8:https://www.oracle.com/cn/java/technologies/javase/javase-jdk8-downloads.html
由於官網下載比較慢,且要登錄才能下載。可以使用以下地址下載:
鏈接:https://pan.baidu.com/s/1vJnHF1OMm_XuLNJvcOkoIg
提取碼:zxin
配置 java
- 新建環境變更 JAVA_HOME
變量名:JAVA_HOME
變量值:C:\Java\jdk1.8.0_281
- 新建/修改 CLASSPATH 變量
變量名:CLASSPATH
變量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
- 修改 Path 變量
新建兩條路徑:
%JAVA_HOME%\bin
%JAVA_HOME%\jre\bin
驗證 java 安裝成功
java -version
下載 jenkins war 包
jenkins 的Web應用程序 ARchive(WAR)文件版本可以安裝在任何支持 java 的操作系統或平台上。
要下載並運行 jenkins 的 WAR 文件版本,請執行以下操作:
- 將最新的穩定Jenkins WAR包 下載到您計算機上的相應目錄。
- 在下載的目錄內打開一個終端/命令提示符窗口到。
- 運行命令java -jar jenkins.war
- 瀏覽 http://localhost:8080 並等到 Unlock Jenkins 頁面出現。
- 繼續使用 Post-installation setup wizard 后面步驟設置向導。
將最新的穩定Jenkins WAR包下載到您計算機上的相應目錄。
Notes:
- 不像在Docker中下載和運行有Blue Ocean的Jenkins,這個過程不會自動安裝Blue Ocean功能, 這將分別需要在jenkins上通過 Manage Jenkins > Manage Plugins安裝。 在Getting started with Blue Ocean有關於安裝Blue Ocean的詳細信息 。.
- 您可以通過
--httpPort
在運行java -jar jenkins.war
命令時指定選項來更改端口。例如,要通過端口9090訪問Jenkins,請使用以下命令運行Jenkins:java -jar jenkins.war --httpPort=9090
配置 jenkins
1、運行 jenkins
cd /jenkins # 切換到 jenkins.war 的目錄
java -jar jenkins.war # 運行,默認是 8080 端口
2、jenkins 初始化
- 輸入密碼
- 選擇 ”安裝推薦插件“
- 等待安裝
- 創建第一個管理員用戶
- 填寫 jenkins url,默認是 http://localhost:8080,可以修改為自己外網的 IP 或者使用域名。
- 進入 jenkins
配置 jenkins svn
- 安裝 svn plugin
- 等待安裝完成
創建構建項目
- 點擊 ”新建 Item“,創建一個 free style 類型項目
- 填寫基本信息
- 設置工作空間
點擊 “高級”,然后設置自定義的工作空間 C:\test\helloworld
。
- 配置源碼管理
填寫 Repository URL,這里使用的是本地的路徑。
選擇/添加 Credentials:
- 配置 ”構建“
選擇 ”Execute Windows batch command“:
cd build
call build.bat
- 點擊保存
立即構建
- 創建站點
- 點擊 "Build Now"
- 點擊 “構建歷史”,再點擊 “控制台輸出”
- 查看到 SUCCSS,表示構建成功
- 在瀏覽器打開 http://localhost:5000
至此,一個簡單的 .net 項目的持續部署配置完成。
如何自動構建
上面的構建是需要手動點擊 "Build Now" 才執行的,正常情況下,我們希望是提交代碼就觸發構建。
由於 SVN 沒有 Github、Gitee等 Git 工具的 push hook 功能,只能曲線求國,通過定時器來觸發,判斷版本號是否有更新。
總結
本教程主要是面向比較傳統的 .net framework 開發方式,將其改造成持續部署。當然了,現在很多都已經在使用 git 系列的代碼管理工具了,后面我們再來說說 .net core + git 的持續部署方式。