jenkins+git+.net core實現自動釋出

2022-12-22 18:00:08

一、前言

       繼上篇介紹jenkins過去2年多了,最近整理了一下,希望這篇能介紹到一些更實用的方法和知識。

  本次使用的jenkins版本是2.375.1、jdk 17、WinRAR、git;釋出時,可以選擇生產、測試並替換相應的組態檔,並做站點目錄的切換。

二、搭建釋出環境

安裝jenkins及所需外掛,本文用到的外掛如下:

    1. Active Choices Plug-in:
    2. Build With Parameters
    3. Gitee Plugin
    4. Hidden Parameter plugin
    5. Pipeline
    6. Pipeline: Stage View Plugin
    7. PowerShell plugin
    8. Workspace Cleanup
    9. Persistent Parameter Plugin
    10. Credentials Binding

 三、建立、設定jenkins任務

  1. 建立任務之前,先把後續可能用的憑據設定好,例如git賬號、svn賬號、gitee的token等資訊,憑據新增方式:點選Manage Jenkins 進入到管理介面,在Security 找到Manage Credentials點選進入該功能,預設第一個列表是沒有資料的
  2. 點選第二個列表的「全域性」,進入到下方介面,
  3. 繼續點選右上方的 Add Credentials,進入新增介面,裡面預設選擇Username with password,輸入相應的賬號密碼即可。如果選擇Gitee API  令牌(token)需要進入Gitee中設定私人令牌。
  4. 點選左側選單的新建Item,輸入任務名稱,選擇Pipeline

     

     

    referenced parameters 填寫的是參照引數的名稱

       

     四、流水線設定

    這步最為重要了,先選擇Pipeline script,在這裡可以寫構建指令碼,如果對流水線語法不熟悉的可以點選下方的流水線語法,點選後會開啟新的頁面,裡面可以根據需求去生成指令碼,十分的好用。 

    流水線指令碼裡我主要是做了這幾件事:

      1. 簽出程式碼到指定的目錄下;
      2. 執行編譯、打包、上傳、修改iis目錄和應用程式池
      3. 清理工作空間
    Pipeline程式碼
     pipeline {
        agent any
        //checkoout 可以考慮使用並行的方式
        stages {
            //簽出程式碼
            stage('checkout') {
                steps {
                  checkout([
    				  $class: 'GitSCM', branches: [[name: '*/master']], 
    				  extensions: 
    				  [
    					[$class: 'RelativeTargetDirectory', relativeTargetDir: './DeployConfig'],//簽出到指定目錄
    					[$class: 'SparseCheckoutPaths', sparseCheckoutPaths: [[path: 'config/']]]//簽出原始碼指定資料夾
    				  ], 
    				  userRemoteConfigs: [[credentialsId: GitId, url: ConfigGit]]
    			  ])
    			  checkout([
    				  $class: 'GitSCM', branches: [[name: '*/master']], 
    				  extensions: 
    				  [
    					[$class: 'RelativeTargetDirectory', relativeTargetDir: './DeployScript'],//簽出到指定目錄
    					[$class: 'SparseCheckoutPaths', sparseCheckoutPaths: [[path: 'lr_bat/']]]//簽出原始碼指定資料夾
    				  ], 
    				  userRemoteConfigs: [[credentialsId: GitId, url: ConfigGit]]//credentialsId為上一步設定的憑據ID
    			  ])
    			  checkout([
    				  $class: 'GitSCM', branches: [[name: '*/master']], 
    				  extensions: 
    				  [
    					[$class: 'RelativeTargetDirectory', relativeTargetDir: './DeployCode']//簽出專案原始碼
    				  ], 
    				  userRemoteConfigs: [[credentialsId: GitId, url: GitLR]]
    			  ])
                }
            }
            //執行編譯、打包、上傳、部署IIS等指令碼
            stage('build') {
                steps {
    				echo 'build....'
    				bat """ cd /d "./DeployScript/lr_bat"
    				call deploy_%Environment%.bat %IP% %Environment% ${JOB_NAME} ${WORKSPACE} %BuildPath% %SolutionName% %GitLR% No %UploadPackage%  """
                }
            }
            //清理工作目錄
            stage('clean'){
                steps{
                    echo 'clean....'
                    cleanWs()
                }
            }
        }
    }

        簽出程式碼指令碼不難,下面重點說一下第二步。

     五、編譯、打包、上傳、修改IIS

    這一步使用批次處理(也稱bat)命令指令碼去處理專案編譯、編譯產物打包、包上傳伺服器、設定IIS站點。每一段批次處理命令都可以單獨建立一個bat檔案,然後使用一個統一的入口bat檔案依次呼叫即可:call  xxx.bat 引數1  引數2 ....

    bat程式碼說明
    //bat """ cd /d "./DeployScript/lr_bat" call deploy_%Environment%.bat %IP% %Environment% ${JOB_NAME} 
    //${WORKSPACE} %BuildPath% %SolutionName% %GitLR% No No """
    //cd "xxxx" 是切換到xxxx目錄,call deploy_%Environment%.bat 是執行 deploy_SIT(SIT是選擇的釋出環境)bat指令碼;
    //%IP% 是Jenkins中自定義的引數,${JOB_NAME}是Jenkins內建的變數,${WORKSPACE}是當前Jenkins的工作空間。
    //在bat指令碼中,接收引數可以這麼寫:set IP=%1,%0 這個引數一般是bat指令碼檔名。

    在deploy_xxx.bat檔案中首先是設定我們需要用的引數,例如:接收傳進來的引數;設定編譯產物目錄、釋出的版本號、指令碼地址、解決方案路徑等

    這些基礎工作做完後,就可以進行後續步驟了。

    1. .net core程式碼編譯
      @echo off&setlocal EnableDelayedExpansion
      ::====  %1 evn %2 jobname %3 svn version %4 sonar
      //編譯產物存放地址
      set outPath= D:\JenkinspProduct\%2\%3 
      //建立目錄
      ::mkdir %outPath%
      //切換到程式碼根目錄
      cd ..\..\DeployCode\原始碼目錄\
      
      echo 還原nuget包
      dotnet restore -s https://api.nuget.org/v3/index.json
      
      echo 編碼原始碼
      //編碼原始碼並輸出到%outPath%  -o就是 -output 的縮寫
      dotnet publish -c Release -o %outPath% 
      exit /b
    2. net framework程式碼編譯
      ::%1 JobName %2 Svn Version %3 BuildPath %4 SolutionName
      @echo off&setlocal EnableDelayedExpansion
      
      set outPath=E:\JenkinspProduct\%1\%2
      
      echo restore nuget
      cd ..\..\DeployCode\原始碼目錄\
      .nuget\NuGet.exe restore "%4" -source "https://api.nuget.org/v3/index.json"
      
      echo build project
      
      msbuild "%3" /m 
                  /t:Rebuild 
                  /t:ResolveReferences;Compile 
                  /t:_CopyWebApplication 
                  /p:Configuration=Release 
                  /p:WebProjectOutputDir=%outPath% 
                  /p:OutputPath=%outPath%\bin 
                  /p:SolutionDir=..\
      exit /b
    3. 打包編譯產物
      @echo off&setlocal EnableDelayedExpansion
      ::====  %1 evn %2 jobname %3 svn version %4 WORKSPACE
      
      set localPath=D:\JenkinspProduct\zip\%2\%3.zip //壓縮包全路徑
      set binPath=D:\JenkinspProduct\%2\%3  //編譯產物目錄
      set configPath=%4\\DeployConfig\config\%2_config\%1 //組態檔目錄
      
      if exist %binPath% ( 
      echo 開始打包
      ) else ( 
      echo ERROR : %2 編譯產物不存在
      exit 1
      ) 
      
      echo 替換%Environment%環境組態檔
      xcopy %configPath% %binPath% /e /y
      
      echo 校驗壓縮包是否存在
      if exist %localPath% ( 
      goto Deletezip
      ) else ( goto Next) 
      
      :Deletezip
      echo 刪除壓縮包%localPath%.zip
      del %localPath%
      
      :Next
      echo 開始壓縮產物 
      mkdir D:\JenkinspProduct\zip\%2
      echo %localPath%
      echo %binPath% 
      //這裡需要安裝WinRAR,且設定到系統環境變數中,如果不配環境變數的話,WinRAR 需要替換成"安裝路徑/WinRAR.exe"
      WinRAR  a -r -ep1 -m1 %localPath% %binPath%
      echo 壓縮完成
      
      set err=%errorlevel%
      exit /b
    4. 編譯產物上傳
      //使用FTP上傳的話,需要在目標伺服器上搭建一個FTP站點
      @echo off&setlocal EnableDelayedExpansion
      ::==== %1 ip  %2  evn %3 jobname %4 git version
      echo 開始上傳ftp至應用伺服器%1
      //本次未修改ftp的預設埠,測試時修改了埠,不管多大的檔案都上傳不上去,各種設定都檢查了一遍還是未解決,最後放棄了
      set localPath= E:\JenkinspProduct\zip\%3\%4.zip
      set ftpip=%1
      set username=賬號
      set password=密碼
      set ftpPath=.\%3
      Echo open %ftpip% >ftp.up
      Echo %username%>>ftp.up
      Echo %password%>>ftp.up
      Echo mkdir %ftpPath%>>ftp.up
      Echo Cd %ftpPath% >>ftp.up
      Echo binary>>ftp.up
      Echo put %localPath%>>ftp.up
      Echo bye>>ftp.up
      FTP -s:ftp.up
      del ftp.up /q
      del %localPath%
      
      set err=%errorlevel%
      exit /b
    5. 最後是修改IIS,因為是遠端釋出,所以需要用到遠端執行命令工具psexec,但是該工具需要伺服器開放445埠且需要開啟Admin$共用(一般是預設開啟),但是一般的雲伺服器服務商只允許在區域網記憶體取,公網大部分都是遮蔽的(阿里雲是),所以在deploy_xxx.bat檔案中最後就是 psexec \\%1 -u 管理員賬號  -p  密碼 -c -f %batPath%\iisweb_%2.bat %2 %3 %SVN_REVISION% -d
    6. 修改IIS
      ::====%1 evn %2 jobname %3 GIT_REVISION
      ::@set "sitePath=%~dp0"
      ::@set "sitePathDer=%~d0"
      ::@set "sitePath=%cd%"
      //壓縮包檔案路徑
      @set "zipPath=D:\\JenkinspProduct\zip\%2\%3.zip"
      //站點目錄
      @set "sitePath=D:\%1\%2"
      //站點檔案目錄
      @set "siteFilePath=D:\%1\%2\%3\"
      
      echo zipPath: %zipPath% 
      echo sitePath: %sitePath% 
      echo siteFilePath: %sitePathDer%
      //建立站點目錄
      mkdir %sitePath%
       
      echo 準備解壓
      "C:\Program Files\WinRAR\WinRAR.exe" x -y "%zipPath%" "%sitePath%"
      echo 解壓完成
      
      :更改當前目錄及其所有子目錄中指定檔案的
      @echo Access Configuration start...
      cacls %siteFilePath% /t /e /g everyone:f 
      @echo Access Configuration finished...
      echo=
      
      :應用程式池名稱 
      @set ApplicationPool_Name="%2"
      
      :應用程式池.NETCLR版本  範例:""->無受控程式碼,"v4.0","v2.0"
      ::可以考慮設定輸入引數
      @set ApplicationPool_NETCLRVersion=""
      
      :IISWeb站點名稱
      @set WebSiteName="%2" 
      
      :IIS站點埠
      @set WebSitePort="8081"
      
      :啟用32位元應用程式;預設:false;支援 true 或者 false;
      @set Enable32BitAppOnWin64="false"
      
      @echo off 
      echo= 
      @echo ---------------------------------------------------
      @echo Start Deploy WebSite %WebSiteName% 
      echo= 
      
      :新建應用程式池
      @echo Create IIS ApplicationPool start...
      @C:\Windows\System32\inetsrv\appcmd.exe add apppool /name:%ApplicationPool_Name% /managedRuntimeVersion:%ApplicationPool_NETCLRVersion% /Enable32BitAppOnWin64:%Enable32BitAppOnWin64%
      @echo Create IIS ApplicationPool finished...
      echo= 
      
      :新建IIS站點
      @echo Create IIS Web Site start...
      @C:\Windows\System32\inetsrv\appcmd.exe add site /name:%WebSiteName% /bindings:http/*:%WebSitePort%: /applicationDefaults.applicationPool:%ApplicationPool_Name% /physicalPath:%siteFilePath%
      @echo Create IIS Web Site finished...
      echo= 
      
      :停止IIS站點
      @echo stop WebSite start...
      @C:\Windows\System32\inetsrv\appcmd.exe stop site %WebSiteName%
      @echo stop WebSite finished...
      echo= 
      
      :啟動IIS站點
      @echo Restart WebSite start...
      @C:\Windows\System32\inetsrv\appcmd.exe start site %WebSiteName%
      @echo Restart WebSite finished...
      echo= 
       
      @echo Finished Deploy WebSite %WebSiteName%
      echo= 
      @echo ---------------------------------------------------
      echo= 
      exit /b
    7. 該指令碼稍作修改即可實現多伺服器釋出

     六、總結

          專案發布工作結束了,中間也踩了很多坑,查閱資料和請教同事後也都解決了。下一步是研究如何釋出到linux伺服器上和使用docker的相關做法,有成果了繼續分享。