前言
企业线上环境是.NET Framework,自然使用Windows Server平台。现在需求是要对.NET项目进行自动化持续集成,免得每次手动发布,一台台机器登录,那种痛苦干过的都懂得,繁琐、效率低下、误操作等等。而.Net与Jenkins的结合使用目前要达到完全自动化还是有局限性的,关键是Windows环境,各种命令无法向Linux方便。.NET Core可能会好一些。现有的没办法,得上。
基本组合是Jenkins + Gitlab + Msbuild。实现代码提交、编译、部署。

  • 安装环境与流程
    1) Jenkins是java产品,需安装JDK8,Windows server 2012环境。
    2) .NET项目需.Net Framework支持,这里选择Framework4.6.1。Nuget解决依赖。构建工具Msbuild,基于VS2019下的Msbuild。以上都基于Windows server 2012。刚开始选择server 2008R2,后面构建打包这种问题,困扰2天,果断换。
    3) 代码仓库GitLab。选用Centos7.6。
    4) .Net项目持续集成流程:
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第1张图片
  • Jenkins操作
    1) Jenkins具体安装略,傻瓜式下一步...安装完成。下载见官方网站:https://jenkins.io/download/ ,找到downlaod下载,这里项目基于.Net Freamwork,Jenkins中构建需编译.net程序,方便编译,选择安装Windows版本。
    这里Jenkins安装前,需配置好JDK环境。
    2) 插件安装
    Jenkins安装好后,进入系统管理->插件管理,安装好Msbuild、GitLab、ftp、python等。
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第2张图片
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目
    3) 新建Job
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第3张图片
    4) Job设置
    设置保留构建的天数,和构建最大数量
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第4张图片
    自定义workspace工作空间
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目
    5) 获取Git仓库代码
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第5张图片
    指定Git仓库代码项目分支,这里为测试环境,统一使用dev分支构建。
    主要有以下配置项:
    Repositories URL:git方式获取代码路径,走ssh协议。
    Credentials:授权登录信息,添加凭据。这里使用SSH方式(用户名+私钥方式)登录。需先Jenkins配置SSH方式登录Gitlab。
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第6张图片
    Branches to build:指定分支。
    6) 构建程序配置
    6.1安装插件后,进入系统管理->Global Tool Configuration,找到MSbuild配置选项。
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第7张图片
    这里Path to MABuild配置VS下的MSBuild。不使用C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild目录下的msbuild工具。
    6.2 构建前创建Windows batch command,解决项目软件包依赖,配置Nuget。
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第8张图片
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第9张图片
    需在本地安装好nuget。Windows命令如下:
    "E:\Program Files (x86)\Tools\nuget.exe" restore "E:\jenkins-workspace\APIDataBM-test\BM.BMData.Web\BM.BMData.sln" -ConfigFile "C:\Users\Administrator\AppData\Roaming\NuGet\NuGet.Config" -NoCache

    其中Nuget restore命令是获取项目需要的程序包,解决包的依赖问题。
    7) 构建环境配置
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第10张图片
    选择“Build a Visual Studio project or solution using MSBuild”配置如下:
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第11张图片
    MSBuild Version:之前Global Tool Configuration中配置的版本。
    MSBuild Build File:要构建的解决方案sln文件,也可以是项目.csproj文件。注意都是相对工作的路径。
    Command Line Arguments
    /t:Rebuild 重新生成
    /p:Configuration=Debug 生成Debug模式
    /t:resolveReferences
    /p:WebProjectOutputDir="E:\Publish-web\APIData-Test\web" 构建后sln输出目标目录
    /p:OutputPath="E:\Publish-web\APIData-Test\web\bin" 输出目标的bin目录
    8) 项目config配置
    项目各个环境配置集中存储于Gitlab某个仓库中,开发需对配置更改直接Gitlab中更改,方便统一管理,并对某些敏感信息进行过滤,配置文件安全性增加了。
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目
    Windows batch command的bat文件内容如下:

    @echo off
    cd /d E:\git-config\config-public
    git checkout dev
    git pull origin dev
    echo 选择部署的服务器IP: %1
    xcopy E:\git-config\config-public\test\GroupAPIData\AB\%1 E:\jenkins-workspace\APIDataBK\TEST\AB /exclude:E:\Python-scripts\test\exclude.txt /s /e /h /y
    @echo offnul

    其中变量名表示方式Linux和Windows系统平台方式有区别:
    Windows:%BUILD_ENV% %变量名%
    Linux:${BUILD_ENV} ,也可直接使用 $BUILD_ENV
    从Git Lab仓库中,pull下某个分支的最新配置文件。然后在本地的git config目录下copy配置文件到项目中,其中exclude配置指定无需copy的文件,如隐藏的.gitkeep文件等。
    注:运行Jenkins程序需改成系统administrator账户权限,默认是本地系统账户(system),否则执行到git pull命令是报类似权限问题。
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第12张图片
    9) 参数化构建
    发布构建的服务器是多台情况下,这里选择使用项目参数化方式,Jenkins中找到"This project is parameterized"项,选择“choice parameter”,填写好名称(这个会作为参数后面使用到)、选项(这里根据实际环境用IP)、描述。如下图:
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第13张图片

  • 发布应用
    应用构建成功后,接下来是将构建项目的输出目录copy到应用服务器相应的站点目录中,由于目标的应用服务器都是windows系统,因此无法像linux系统一样通过ssh远程命令操作。目前提供了三种解决方案,使用Ftp直接上传到应用服务器,使用Windows下的Rsync方式,以及Python脚本的方式。
    1) Ftp方式
    1.1 需先Jenkins上安装Ftp插件。同时在发布的目标应用服务器安装配置好Ftp服务。
    安装插件后,进入系统管理->Global Tool Configuration,找到FTP repository hosts配置选项。
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第14张图片
    Porfile Name:随便取个名字,后面Job配置会应用到。
    hostname:Ftp主机名(端口号默认21)
    TimeOut:设置timeout
    Root Repository Path:Ftp服务端跟/目录
    User Name:Ftp用户名
    Password:Ftp密码
    1.2 项目配置
    构建后操作->增加构建后操作步骤->Publish artifacts to FTP
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第15张图片
    FTP site:全局中配置的
    Source:选择发布包路径,即项目构建输出的目录。
    Remote directory:放到远程目标路径(相对于Ftp根目录的路径)
    前提先在要发布的目标服务器上先安装好FTP服务,搭建IIS的ftp站点,作为FTP服务器端,具体安装略。
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第16张图片
    配置完成后,Jenkins上点击构建。
    2) Rsync方式
    2.1 Windows server环境配置使用rsync命令。
    Jenkins的Job配置项构建中,增加构建步骤->Execute Windows batch command
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第17张图片
    2.2 配置rsync
    Windows server中使用rsync命令需要安装配置cwRsync,有Server端和Client端。现在官网已经不免费提供cwRsync Server服务了。应用服务器端安装cwRsync Server,Jenkins服务器配置rsync的Client端。具体cwRsync Server与Client安装略。
    cwRsync Server默认安装下,cwRsync Server端的C:\Program Files (x86)\ICW\rsync.conf文件配置如下:
    uid = 0
    gid = 0
    use chroot = false
    strict modes = false
    hosts allow = *
    log file = rsyncd.log
    port = 873
    [APIData]
    path = /cygdrive/e/Web/APIData-test/web
    secrets file = /cygdrive/c/Program Files (x86)/ICW/rsyncd.secrets
    list = true
    auth users = rsync_user
    read only = false

    cwRsync Client端的rsync命令在Jenkins中的配置如下:
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第18张图片

    "C:\Program Files (x86)\cwRsync\bin\rsync.exe"  -avzP  --progress --delete  --port=873 --password-file="/cygdrive/c/Program Files (x86)/cwRsync/passwd.txt" /cygdrive/e/Publish-web/APIData-Test2/web/  [email protected]::APIData

    配置完成后,Jenkins上点击构建。
    3) Python脚本实现方式
    winRM服务是windows server下PowerShell的远程管理服务。Python脚本可通过连接winRM模块操作windows命令行。
    3.1配置winRM服务
    在被控制windows server上winRM服务操作:
    查看winRM服务状态,默认都是未启动状态,下面命令执行后无任何结果输出,需执行后续步骤进行开启。

    > winrm enumerate winrm/config/listener

    配置winRM服务启动

    > winrm quickconfig

    查看windows的winrm service listener

    > winrm e winrm/config/listener

    winrm service配置auth

    > winrm set winrm/config/service/auth @{Basic="true"}

    配置winrm service 加密方式为允许非加密

    > winrm set winrm/config/service @{AllowUnencrypted="true"}

    3.2配置python脚本
    Job配置项构建中,增加构建步骤->Execute Windows batch command
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第19张图片
    Python脚本如下:

    import winrm
    import os
    import sys
    import time
    env = os.getenv("ENV")
    print('选择发布构建的服务器ENV是:', env)
    if env == '10.10.10.10':
    win2008r2 = winrm.Session('http://10.10.10.10:5985/wsman',auth=('deploy_user','xxxxxx'))
    ip = win2008r2.run_cmd('ipconfig | findstr "10.10.10.10"')
    app_list = win2008r2.run_cmd('C:\\Windows\\System32\\inetsrv\\appcmd.exe list app')
    app_stop = win2008r2.run_cmd('C:\\Windows\\System32\\inetsrv\\appcmd.exe stop site DataapiBM')
    backup = win2008r2.run_cmd('xcopy D:\\Web-prd\\DataapiBM  D:\\Web-prd\\backup\\DataapiBM-%date:~8,2%月%date:~11,2%日%time:~0,2%时%time:~3,2%分%time:~6,2%秒\ /exclude:D:\\Web-prd\\backup\\exclude.txt /ryhs')
    rsync_code = win2008r2.run_cmd('C:\\cwRsync\\bin\\rsync.exe  -vzrtopg  --numeric-ids  --progress  --port=1873 --password-file=/cygdrive/c/cwRsync/passwd.txt

    配置完成后,点击“Build with Parameters”,选择下拉框中对应的服务器节点进行构建。
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第20张图片
    查看构建情况,通过控制台查看:
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目_第21张图片
    Jenkins+GitLab+Msbuild+Python自动化部署.Net项目
    控制台输出构建详细的log信息,如果构建成功,会有个蓝色的圈圈,并且控制台最后输出“Finished: SUCCESS”信息,表示此Job构建成功。相应的如果构建失败,控制台也会输出报错信息。
    自此,项目自动化构建完成。当然其中有些环节还需继续优化。测试比较下来,应用发布这步操作,winRM+Python方式比较灵活方便。