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 的持續部署方式。