Jenkins持續集成學習-Windows環境進行.Net開發1


Jenkins持續集成學習-Windows環境進行.Net開發


目錄

Jenkins持續集成學習-Windows環境進行.Net開發1
Jenkins持續集成學習-Windows環境進行.Net開發2
Jenkins持續集成學習-Windows環境進行.Net開發3
Jenkins持續集成學習-Windows環境進行.Net開發4
Jenkins持續集成學習-搭建jenkins問題匯總

前言

本文探究在.net環境下的持續集成環境研究並使用。關於為什么使用Jenkins,可以參考一下jenkins持續集成原理

目標

學習jenkins的基本使用,完成以下2點任務。

  1. 搭建jenkins任務完成自動編譯。
  2. 自動從nuget上獲取需要的包。

使用Jenkins

安裝

Jenkins官網下載安裝包,進行安裝。安裝完成后會自動打開一個頁面。默認是網站是localhost:8080。若端口已被占用則需要修改成別的端口。
具體安裝問題可以看這里淺談.net jenkins svn下自動化集成環境安裝 搭建 配置
主要是安裝完后需要安裝.net的環境的一些插件及svn(或git)等相關插件。

根據官網描述是需要安裝java環境的

添加.net環境配置

安裝完后如果要在.net環境使用,在MSBuild插件安裝完的前提下。配置msbuild.exe的路徑。這樣jenkins就能通過msbuild來編譯.net項目了。具體配置可以可以參考《為 Jenkins 配置 .NET 持續集成環境》

我本地的jenkins的全局配置配的MSBuild也為14.0

安裝了不同版本的VS的MSBuild版本可能不一樣。

2.png

部署

我們通過VS先新建一個控制台項目.net framework4.5的項目,項目名稱叫做JenkinsTest。在Program.cs中簡單的輸出hello world

static void Main(string[] args)
{
    Console.WriteLine("Hello World!");
}

程序目錄如下


│  JenkinsTest.sln
│
└─JenkinsTest
    │  App.config
    │  JenkinsTest.csproj
    │  Program.cs
    │
    └─Properties
            AssemblyInfo.cs

編譯通過后將項目上傳到SVN上,我在我本地建了SVN的服務,並增加了用戶名和密碼分別為test。

1.png

新建項目

3.png
創建一個名為test的自由風格軟件項目。
4.png
我本地使用的是SVN,因此選擇Subversion,輸入SVN的路徑。Local module directory為SVN獲取代碼的路徑。.表示獲取到jenkins的根目錄下。
5.png
首次創建的時候需要創建SVN的登錄憑據,在Credentials項點擊Add添加一個新的憑據,類型就選擇Username with password即可,id需要輸入一個唯一憑據標識。
6.png
Build Environment下勾選Add timestamps to the Console Output,這樣可以顯示時間戳。
7.png
Build選擇MSBuild的版本,這個版本在全局配置設置過,在這里就可以顯示出來。MSBuild Build File輸入需要編譯的程序集文件名。在Command Line Arguments輸入編譯的參數,我們編譯成Realse版本。完成后點擊保存即可。具體MSBuild指令不做具體探究,有什么問題直接可以看官方文檔
點擊立即構建就會自動編譯,完成就會顯示一個結果
8.png
9.png
點擊#1即可調轉到該次編譯的詳細信息中,在左側點擊Console Output可以看到編譯的過程日志。
10.png

構建過程分析
  1. 先從SVN獲取代碼

    16:21:55 由用戶 jake 啟動
    16:21:55 構建中 在工作空間 D:\Program Files (x86)\Jenkins\workspace\test 中
    16:21:55 Updating https://jakepc/svn/JenkinsTest/trunk/JenkinsTest at revision '2019-01-18T16:21:55.792 +0800' --quiet
    16:21:55 Using sole credentials test/****** (本地svn服務器) in realm ‘<https://jakepc:443> VisualSVN Server’
    16:21:55 At revision 3
    
  2. 調用MSBuild命令進行編譯,這里會查找我們全局配置的MSBuild.exe執行我們在創建時輸入的Command Line Arguments指令。

    16:21:56 Path To MSBuild.exe: C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe
    16:21:56 Executing the command cmd.exe /C " "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /t:Build /p:Configuration=Release JenkinsTest.csproj " && exit %%ERRORLEVEL%% from D:\Program Files (x86)\Jenkins\workspace\test
    16:21:56 [test] $ cmd.exe /C " "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /t:Build /p:Configuration=Release JenkinsTest.csproj " && exit %%ERRORLEVEL%%
    
  3. 編譯完成,顯示警告,錯誤和結果

    ...
    16:21:57 _CopyAppConfigFile:
    16:21:57   正在將文件從“App.config”復制到“bin\Release\JenkinsTest.exe.config”。
    16:21:57 CopyFilesToOutputDirectory:
    16:21:57   正在將文件從“obj\Release\JenkinsTest.exe”復制到“bin\Release\JenkinsTest.exe”。
    16:21:57   JenkinsTest -> D:\Program Files (x86)\Jenkins\workspace\test\bin\Release\JenkinsTest.exe
    16:21:57   正在將文件從“obj\Release\JenkinsTest.pdb”復制到“bin\Release\JenkinsTest.pdb”。
    16:21:57 已完成生成項目“D:\Program Files (x86)\Jenkins\workspace\test\JenkinsTest.csproj”(Build 個目標)的操作。
    16:21:57 
    16:21:57 已成功生成。
    16:21:57     0 個警告
    16:21:57     0 個錯誤
    16:21:57 
    16:21:57 已用時間 00:00:01.22
    16:21:59 Finished: SUCCESS
    

通過以上三步驟,實際和我們自己使用VS編譯過程也是一樣的。

增加依賴dll

上面我們創建了一個最簡單的項目,並通過jenkins獲取並編譯成功了,下面我們增加項目復雜性,增加其他依賴項。

新建一個jenkins.Common的類庫。我們把HelloWorld的字符串通過該類庫獲取到,然后主項目進行輸出。
增加HelloWolrdHelper類獲取字符串

public class HelloWolrdHelper
{
    public static string GetString()
    {
        return "Hello World!";
    }
}

修改原項目

static void Main(string[] args)
{
    Console.WriteLine(HelloWolrdHelper.GetString());
    Console.ReadKey();
}

11.png

然后提交代碼到SVN后在jenkins再次構建,結構如下。


│  JenkinsTest.sln
│
├─Jenkins.Common
│  │  HelloWolrdHelper.cs
│  │  Jenkins.Common.csproj
│  │
│  └─Properties
│          AssemblyInfo.cs
│
└─JenkinsTest
    │  App.config
    │  JenkinsTest.csproj
    │  Program.cs
    │
    └─Properties
            AssemblyInfo.cs

構建一下,編譯成功了,MSBuild會根據csproj文件內的依賴關系編譯其他程序集。
15.png

生成啟動時間為 2019/1/18 17:16:03。
17:16:03 項目“D:\Program Files (x86)\Jenkins\workspace\test\JenkinsTest\JenkinsTest.csproj”在節點 1 上(Build 個目標)。
17:16:03 PrepareForBuild:
17:16:03   正在創建目錄“bin\Release\”。
17:16:03   正在創建目錄“obj\Release\”。
17:16:03 項目“D:\Program Files (x86)\Jenkins\workspace\test\JenkinsTest\JenkinsTest.csproj”(1)正在節點 1 上生成“D:\Program Files (x86)\Jenkins\workspace\test\Jenkins.Common\Jenkins.Common.csproj”(2) (默認目標)。
17:16:03 PrepareForBuild:
17:16:03   正在創建目錄“bin\Release\”。
17:16:03   正在創建目錄“obj\Release\”。
17:16:03 GenerateTargetFrameworkMonikerAttribute:
17:16:03 正在跳過目標“GenerateTargetFrameworkMonikerAttribute”,因為所有輸出文件相對於輸入文件而言都是最新的。

增加Nuget依賴

新建一個Jenkins.Core項目,並生成Nuget包上傳到Nuget服務器上。

關於Nuget如何打包可以看我之前的博客NuGet的使用、部署、搭建私有服務,這里不做討論。

為了簡單起見,創建一個和Jenkins.Common程序集一樣的輸出HelloWorld的方法,但是為了作為區分,分別略作修改。
Jenkins.Common的代碼

public class HelloWolrdHelper
{
    public static string GetString()
    {
        return "Hello World! Jenkins.Common";
    }
}

Jenkins.Core的代碼

public class HelloWolrdHelper
{
    public static string GetString()
    {
        return "Hello World! Jenkins.Core";
    }
}

程序結構如下

│  JenkinsTest.sln
│
├─.nuget
│      NuGet.Config
│      NuGet.exe
│      NuGet.targets
│
├─Jenkins.Common
│  │  HelloWolrdHelper.cs
│  │  Jenkins.Common.csproj
│  │
│  └─Properties
│          AssemblyInfo.cs
│
├─Jenkins.Core
│  │  HelloWorldHelper.cs
│  │  Jenkins.Core.csproj
│  │  Jenkins.Core.sln
│  │
│  └─Properties
│          AssemblyInfo.cs
│
└─JenkinsTest
   │  App.config
   │  JenkinsTest.csproj
   │  packages.config
   │  Program.cs
   │
   └─Properties
           AssemblyInfo.cs

注意:Jenkins.Core我放到一個單獨的項目中打包的。原本我是放到原項目一起。但是Nuget似乎有個bug,導致編譯通不過。

20.png

因為控制台項目更新的時候會向JenkinsTest.csproj文件寫入nuget包還原的指令


 <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
  </Target>

而中解決方案的目錄是在上一層目錄<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>,最終編譯的時候會校驗pacakges是否存在已下載的包。通過路徑$(SolutionDir)\packages\下查找,即..\\packages\。多了一個\導致存在包仍然報錯查找不到,最終編譯不過。

上傳nuget包

17.png

然后從Nuget本地nuget服務器上獲取。

18.png

Program的代碼增加新的helloworld輸出


class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(HelloWolrdHelper.GetString());
        Console.WriteLine(Jenkins.Core.HelloWolrdHelper.GetString());
        Console.ReadKey();
    }
}

重新編譯項目后上傳代碼到SVN后再次到Jenkins上構建項目。

19.png

可以看到構建失敗了,去看下具體失敗原因。

正在將文件從“obj\Release\Jenkins.Common.pdb”復制到“bin\Release\Jenkins.Common.pdb”。
12:51:14 已完成生成項目“D:\Program Files (x86)\Jenkins\workspace\test\Jenkins.Common\Jenkins.Common.csproj”(默認目標)的操作。
12:51:14 ResolveAssemblyReferences:
12:51:14   主引用“Jenkins.Core, Version=0.2.0.0, Culture=neutral, processorArchitecture=MSIL”。
12:51:14 C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(1820,5): warning MSB3245: 未能解析此引用。未能找到程序集“Jenkins.Core, Version=0.2.0.0, Culture=neutral, processorArchitecture=MSIL”。請檢查磁盤上是否存在該程序集。 如果您的代碼需要此引用,則可能出現編譯錯誤。 [D:\Program Files (x86)\Jenkins\workspace\test\JenkinsTest\JenkinsTest.csproj]
12:51:14           用於 SearchPath“{HintPathFromItem}”。
12:51:14           已考慮使用“..\packages\Jenkins.Core.0.2.0\lib\net45\Jenkins.Core.dll”,但它不存在。
12:51:14           用於 SearchPath“{TargetFrameworkDirectory}”。
12:51:14           已考慮使用“C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Jenkins.Core.winmd”,但它不存在。
12:51:14           已考慮使用“C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Jenkins.Core.dll”,但它不存在
...
12:51:14 Program.cs(15,22): error CS0234: The type or namespace name 'Core' does not exist in the namespace 'Jenkins' (are you missing an assembly reference?) [D:\Program Files (x86)\Jenkins\workspace\test\JenkinsTest\JenkinsTest.csproj]
12:51:14 已完成生成項目“D:\Program Files (x86)\Jenkins\workspace\test\JenkinsTest\JenkinsTest.csproj”(Build 個目標)的操作 - 失敗。
12:51:15 
12:51:15 生成失敗。
12:51:15 
12:51:15 “D:\Program Files (x86)\Jenkins\workspace\test\JenkinsTest\JenkinsTest.csproj”(Build 目標) (1) ->
12:51:15 (ResolveAssemblyReferences 目標) -> 
12:51:15   C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(1820,5): warning MSB3245: 未能解析此引用。未能找到程序集“Jenkins.Core, Version=0.2.0.0, Culture=neutral, processorArchitecture=MSIL”。請檢查磁盤上是否存在該程序集。 如果您的代碼需要此引用,則可能出現編譯錯誤。 [D:\Program Files (x86)\Jenkins\workspace\test\JenkinsTest\JenkinsTest.csproj]
12:51:15 
12:51:15 
12:51:15 “D:\Program Files (x86)\Jenkins\workspace\test\JenkinsTest\JenkinsTest.csproj”(Build 目標) (1) ->
12:51:15 (CoreCompile 目標) -> 
12:51:15   Program.cs(15,22): error CS0234: The type or namespace name 'Core' does not exist in the namespace 'Jenkins' (are you missing an assembly reference?) [D:\Program Files (x86)\Jenkins\workspace\test\JenkinsTest\JenkinsTest.csproj]
12:51:15 
12:51:15     1 個警告
12:51:15     1 個錯誤
12:51:15 
12:51:15 已用時間 00:00:01.43
12:51:15 Build step 'Build a Visual Studio project or solution using MSBuild' marked build as failure
12:51:16 Finished: FAILURE

一開始會去..\packages\Jenkins.Core.0.2.0\lib\net45\Jenkins.Core.dll獲取,但是因為沒有包,后面就去遍歷其他目錄獲取,最終都沒有找到包導致編譯失敗。因此我們需要使用nuget,在MSBuild編譯之前將包下載下來。

為了方便我將nuget一同上傳到SVN上,SVN的程序目錄如下

│  JenkinsTest.sln
│
├─.nuget
│      NuGet.Config
│      NuGet.exe
│      NuGet.targets
│
├─Jenkins.Common
│  │  HelloWolrdHelper.cs
│  │  Jenkins.Common.csproj
│  │
│  └─Properties
│          AssemblyInfo.cs
│
└─JenkinsTest
   │  App.config
   │  JenkinsTest.csproj
   │  packages.config
   │  Program.cs
   └─Properties
           AssemblyInfo.cs

由於Jenkins.Core可以理解為第三方依賴,不是和JenkinsTest放一起。

在Build配置中新增一項批處理命令,執行nuget包還原。如圖拖動到編譯之前。
21.png

根據我們目錄結構調用".nuget/nuget.exe" restore JenkinsTest.sln命令使用nuget進行包還原。

由於.nuget目錄帶有.因此需要用雙引號引起來執行。

再次編譯仍然失敗了。可以通過日志看到已經在編譯前已經執行了腳本,但是沒有從我們想要的地方獲取包。


13:26:47 No changes for https://jakepc/svn/JenkinsTest/trunk/JenkinsTest since the previous build
13:26:47 [test] $ cmd /c call C:\WINDOWS\TEMP\jenkins8156278399083484284.bat
13:26:47 
13:26:47 D:\Program Files (x86)\Jenkins\workspace\test>".nuget/nuget.exe" restore JenkinsTest.sln 
13:26:47 MSBuild auto-detection: using msbuild version '15.9.21.664' from 'D:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\bin'.
13:26:48 Restoring NuGet package Jenkins.Core.0.2.0.
13:26:49   GET https://api.nuget.org/v3-flatcontainer/jenkins.core/0.2.0/jenkins.core.0.2.0.nupkg
13:26:49   NotFound https://api.nuget.org/v3-flatcontainer/jenkins.core/0.2.0/jenkins.core.0.2.0.nupkg 191ms
13:26:49 警告: Unable to find version '0.2.0' of package 'Jenkins.Core'.
13:26:49   C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\: Package 'Jenkins.Core.0.2.0' is not found on source 'C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\'.
13:26:49   https://api.nuget.org/v3/index.json: Package 'Jenkins.Core.0.2.0' is not found on source 'https://api.nuget.org/v3/index.json'.
13:26:49 
13:26:49 警告: Unable to find version '0.2.0' of package 'Jenkins.Core'.
13:26:49   C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\: Package 'Jenkins.Core.0.2.0' is not found on source 'C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\'.
13:26:49   https://api.nuget.org/v3/index.json: Package 'Jenkins.Core.0.2.0' is not found on source 'https://api.nuget.org/v3/index.json'.
13:26:49 
13:26:49 
13:26:49 Errors in packages.config projects
13:26:49     Unable to find version '0.2.0' of package 'Jenkins.Core'.
13:26:49       C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\: Package 'Jenkins.Core.0.2.0' is not found on source 'C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\'.
13:26:49       https://api.nuget.org/v3/index.json: Package 'Jenkins.Core.0.2.0' is not found on source 'https://api.nuget.org/v3/index.json'.
13:26:49 
13:26:49 NuGet Config files used:
13:26:49     D:\Program Files (x86)\Jenkins\workspace\test\.nuget\NuGet.Config
13:26:49     C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\NuGet\NuGet.Config
13:26:49     C:\Program Files (x86)\NuGet\Config\Microsoft.VisualStudio.Offline.config
13:26:49 
13:26:49 Feeds used:
13:26:49     https://api.nuget.org/v3/index.json
13:26:49     C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\
13:26:49 
13:26:49 D:\Program Files (x86)\Jenkins\workspace\test>exit 1 
13:26:49 Build step '執行 Windows 批處理命令' marked build as failure
13:26:50 Finished: FAILURE
指定nuget包下載源地址。

找到Nuget.exe的配置Nuget.Config,在configuration節點內增加packageSources節點。


  <packageSources>
    <add key="Jake Package source" value="http://127.0.0.1:10080/nuget" />
  </packageSources>

再次編譯,終於編譯成功了,日志如下。

13:38:08 No changes for https://jakepc/svn/JenkinsTest/trunk/JenkinsTest since the previous build
13:38:08 [test] $ cmd /c call C:\WINDOWS\TEMP\jenkins5326599668058283263.bat
13:38:08 
13:38:08 D:\Program Files (x86)\Jenkins\workspace\test>".nuget/nuget.exe" restore JenkinsTest.sln 
13:38:08 MSBuild auto-detection: using msbuild version '15.9.21.664' from 'D:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\bin'.
13:38:09 Restoring NuGet package Jenkins.Core.0.2.0.
13:38:09 Adding package 'Jenkins.Core.0.2.0' to folder 'D:\Program Files (x86)\Jenkins\workspace\test\packages'
13:38:09 Added package 'Jenkins.Core.0.2.0' to folder 'D:\Program Files (x86)\Jenkins\workspace\test\packages'
13:38:09 
13:38:09 NuGet Config files used:
13:38:09     D:\Program Files (x86)\Jenkins\workspace\test\.nuget\NuGet.Config
13:38:09     C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\NuGet\NuGet.Config
13:38:09     C:\Program Files (x86)\NuGet\Config\Microsoft.VisualStudio.Offline.config
13:38:09 
13:38:09 Feeds used:
13:38:09     C:\WINDOWS\system32\config\systemprofile\.nuget\packages\
13:38:09     http://127.0.0.1:10080/nuget
13:38:09     https://api.nuget.org/v3/index.json
13:38:09     C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\
13:38:09 
13:38:09 Installed:
13:38:09     1 package(s) to packages.config projects
13:38:09 
13:38:09 D:\Program Files (x86)\Jenkins\workspace\test>exit 0 
13:38:09 Path To MSBuild.exe: C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe
13:38:09 Executing the command cmd.exe /C " "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /t:Build /p:Configuration=Release JenkinsTest/JenkinsTest.csproj " && exit %%ERRORLEVEL%% from D:\Program Files (x86)\Jenkins\workspace\test
13:38:09 [test] $ cmd.exe /C " "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /t:Build /p:Configuration=Release JenkinsTest/JenkinsTest.csproj " && exit %%ERRORLEVEL%%

結語

通過N次嘗試,最終完成了.Net開發下Jenkins進行持續集成。總結起來如下:

  1. 安裝Java環境,由於我本地已有java環境,因此該步驟跳過。
  2. 安裝MSBuild,由於我本地已安裝過VS,因此該步驟跳過。
  3. 下載Nuget,由於我本地已安裝VS,同時已安裝過Nuget,因此該步驟跳過。
  4. 安裝Jenkins,並安裝MSbuild插件。
  5. 修改Jenkins的MSBuild插件的配置。
  6. 新建一個工程,修改配置
    • 選擇源碼管理,我本地是SVN,因此選擇SVN(增加登錄憑據)
    • 增加windows批處理腳本用於Nuget下載庫包。(在Nuget.Config中增加自己的包服務地址)
    • 增加MSBuild編譯VS的項目

通過以上步驟,基本就完成了自動編譯的功能。但是光編譯還是不夠的,最終還要完成自動跑單元測試,下一篇博客再進行研究。

參考文檔

  1. Jenkins部署.net自動化構建
  2. 為 Jenkins 配置 .NET 持續集成環境
  3. 淺談.net jenkins svn下自動化集成環境安裝 搭建 配置
  4. jenkins持續集成原理
  5. Jenkins結合.net平台工具之Nuget
  6. Make Jenkins aware of custom NuGet Package Source

20191127212134.png
微信掃一掃二維碼關注訂閱號傑哥技術分享
本文地址:https://www.cnblogs.com/Jack-Blog/p/10291612.html
作者博客:傑哥很忙
歡迎轉載,請在明顯位置給出出處及鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM