qifa03 当前位置:首页>qifa03>正文

qifa03

发布时间:2019-03-19

原标题:.NET项目从CI到CD-Jenkins_Pipeline的应用

如遇【线上娱乐站】不能自动打开,请复制 http://da8.us 到浏览器,注册自动送8-88试 ̶̶̶̶̶̶̶̶̶̶玩 ̷̷̷̷̷̷̷̷̷̷金。体验各种类的线上PT/DT/MG/PNG ̶̶̶̶̶̶̶̶̶̶老 ̷̷̷̷̷̷̷̷̷̷虎 ̷̷̷̷̷̷̷̷̷̷机、 ̷̷̷̷̷̷̷̷̷̷真* ̷̷̷̷̷̷̷̷̷̷人* ̶̶̶̶̶̶̶̶̶̶百* ̶̶̶̶̶̶̶̶̶̶家 ̷̷̷̷̷̷̷̷̷̷*乐*游戏等免费试玩、优惠活动,7*24小时专业服务

.NET项目从CI到CD-Jenkins_Pipeline的应用


一、罗里吧嗦

最近迁移了服务器,顺道完善下服役了一两年的Jenkins服务,主要是把Slave搭建起来,还有等等。本文只是我对Jenkins Pipeline的一些自己的理解与应用,欢迎指出错误,欢迎交流高级应用

二、运行环境

Jenkins:

  1. master:阿里云Windows_2016_x64
  2. Slave1:京东云Windows_2008_r2_x64
  3. Slave2:阿里云Windows_2008_r2_x86

版本管理器:自建的git服务器,使用gogs

.NET项目:使用VS2017新建的一个web mvc项目与一个windows service项目,项目上传至git服务器

一些辅助工具:

  1. 7-zip:作为压缩 解压
  2. ossutil:阿里云oss服务工具
  3. nuget:还原解决方案引用包
  4. MSBuild:编译项目

三、开始

首先新建.NET项目,新建一个web项目与windows service项目,步骤略

其次,在自行安装Jenkins,步骤略


新建Jenkins项目,类型选择Pipeline,命名为JenkinsPipelineProject

整体流程如下

start->检出代码->还原引用包->编译->打包->上传OSS->分发slave->发布web->发布Service->end

各步骤:

检出代码:使用内置的工具进行代码的检出,如我使用的是git

还原引用包:使用nuget.exe对解决方案进行引用包还原,包源可选国内节点,国内节点下载速度框

编译:此处进行了两次编译,一次编译web,一次编译Service

打包:并行进行,对编译步骤得到的文件进行打包(使用7zip),存放于本地路径上,打包时,会删除相关配置文件,配置文件为手动更新

上传OSS:对刚打包好的更新包进行上传,因两台服务器处于阿里云内网,所以采用阿里云的OSS,更新速度快

分发Slave:根据配置的节点,进行更新web和service操作

发布web:首先从OSS下载文件下来, 停止站点(非停止IIS),使用7zip进行解压文件,更新文件,更新完毕后启动站点,如有多台服务器需要更新,则并行执行,互不干扰

发布Service:首先从OSS下载文件下来,停止对应的windows服务,卸载对应的windows服务,如若失败,则进行强制删除windows服务,之后使用7zip进行文件的解压更新,更新完毕后安装服务,并启动服务

以下为具体的Pipeline代码

注:

  1. 代码中所需的配置为我自己本身项目需要,如若更改,可根据自己项目进行定制
  2. 代码中一些敏感的配置已用xxxx代替
  3. 仅用于参考

 

//编译服务器设置start
def buildNodeSettings = [:]
buildNodeSettings.node = "阿里云Windows_2008_r2_x86"//编译服务器节点设置
buildNodeSettings.gitUrl = "https://xxx/JenkinsPipelineProject.git"//git地址
buildNodeSettings.gitBarnches = "*/master" //分支
buildNodeSettings.slnFile = "JenkinsPipelineProject.sln" //Nuget还原解决方案名

buildNodeSettings.buildFileForWeb ="JenkinsPipelineProjectWeb\JenkinsPipelineProjectWeb.csproj" //msbulid编译文件名 web
buildNodeSettings.msbuildArgForWeb = "/t:Rebuild /p:Configuration=Release;PublishProfile=FolderProfile;DeployOnBuild=true" //msbulid参数 web
buildNodeSettings.publishOutputForWeb = "\JenkinsPipelineProjectWeb\bin\Release\PublishOutput" //编译后发布的路径 web
buildNodeSettings.publishFileNameForWeb = env.JOB_NAME + "/Build-Web-" +env.BUILD_NUMBER + ".7z"  //文件名 
buildNodeSettings.delFilesForWeb = ["Web.config","Web.Debug.config","Web.Release.config"] as String[]  //需要删除的文件

buildNodeSettings.buildFileForService ="JenkinsPipelineProject.sln" //msbulid编译文件名 Service
buildNodeSettings.msbuildArgForService = "/t:Rebuild /p:Configuration=Release" //msbulid参数 Service
buildNodeSettings.publishOutputForService = "\JenkinsPipelineProjectWindowsService\bin\Release" //编译后发布的路径 Service
buildNodeSettings.publishFileNameForService = env.JOB_NAME + "/Build-Service-" +env.BUILD_NUMBER + ".7z"  //文件名 
buildNodeSettings.delFilesForService = ["*.config"] as String[]  //需要删除的文件

buildNodeSettings.updateServerPath = "D:\WebRoot\update\public_html\"//更新服务器存放包地址
//编译服务器设置end

def webNodeSetting = [:]
webNodeSetting.node = "阿里云Windows_2008_r2_x86" //Web服务器节点
webNodeSetting.downloadPath = "C:\Jenkins\download\"//更新包下载地址
webNodeSetting.publishPath = "D:\WebRoot\JenkinsPipelinePorject\Web" //web服务器网站根目录
webNodeSetting.webApplicationName = "JenkinsPipelinePorject"//web站点名称

def webNodeSetting2 = [:]
webNodeSetting2.node = "master" //Web服务器节点
webNodeSetting2.downloadPath = "C:\JenkinsDownload\"//更新包下载地址
webNodeSetting2.publishPath = "D:\WebRoot\JenkinsPipelinePorject\Web" //web服务器网站根目录
webNodeSetting2.webApplicationName = "JenkinsPipelinePorject"//web站点名称

def webNodeSetting3 = [:]
webNodeSetting3.node = "京东云Windows_2008_r2_x64" //Web服务器节点
webNodeSetting3.downloadPath = "C:\Jenkins\download\"//更新包下载地址
webNodeSetting3.publishPath = "C:\WebRoot\JenkinsPipelinePorject\Web" //web服务器网站根目录
webNodeSetting3.webApplicationName = "JenkinsPipelinePorject"//web站点名称

def serviceNodeSetting = [:]
serviceNodeSetting.node = "阿里云Windows_2008_r2_x86"
serviceNodeSetting.downloadPath = "C:\Jenkins\download\"//更新包下载地址
serviceNodeSetting.publishPath = "D:\WebRoot\JenkinsPipelinePorject\Service" //Service Windows Service存放路径
serviceNodeSetting.serviceName = "JenkinsPipelineProject"//服务名称
serviceNodeSetting.serviceFileName = "JenkinsPipelineProjectWindowsService.exe" //服务的文件名,相对publishPath的路径

def serviceNodeSetting2 = [:]
serviceNodeSetting2.node = "master"
serviceNodeSetting2.downloadPath = "C:\Jenkins\download\"//更新包下载地址
serviceNodeSetting2.publishPath = "D:\WebRoot\JenkinsPipelinePorject\Service" //Service Windows Service存放路径
serviceNodeSetting2.serviceName = "JenkinsPipelineProject"//服务名称
serviceNodeSetting2.serviceFileName = "JenkinsPipelineProjectWindowsService.exe" //服务的文件名,相对publishPath的路径

def serviceNodeSetting3 = [:]
serviceNodeSetting3.node = "京东云Windows_2008_r2_x64"
serviceNodeSetting3.downloadPath = "C:\Jenkins\download\"//更新包下载地址
serviceNodeSetting3.publishPath = "C:\WebRoot\JenkinsPipelinePorject\Service" //Service Windows Service存放路径
serviceNodeSetting3.serviceName = "JenkinsPipelineProject"//服务名称
serviceNodeSetting3.serviceFileName = "JenkinsPipelineProjectWindowsService.exe" //服务的文件名,相对publishPath的路径

node(buildNodeSettings.node) {

    def msbuild=tool name: "MSBuildTool V14.0", type: "msbuild" //编译工具名称与地址
    buildNodeSettings.publishOutputForWeb  = env.WORKSPACE + buildNodeSettings.publishOutputForWeb 
    buildNodeSettings.publishOutputForService  = env.WORKSPACE + buildNodeSettings.publishOutputForService 
    
    stage("Check Out")
    {
        echo "检出项目"
        checkout([$class: "GitSCM", branches: [[name: buildNodeSettings.gitBarnches]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "xxxxxx", url: buildNodeSettings.gitUrl]]])
    }
    
    stage("Nuget Restore")
    {
        echo " 还原nuget "
        echo "${env.nuget} restore "" + env.WORKSPACE + "/" + buildNodeSettings.slnFile + "" -ConfigFile "" + env.config + "" -NoCache"
        bat env.nuget + " restore "" + env.WORKSPACE + "/" + buildNodeSettings.slnFile + "" -ConfigFile "" + env.config + "" -NoCache"
    }
        
    stage("Bulid")
    {
        echo " 编译项目"
        echo "Bulid Web"
        bat """ + msbuild + "" " + buildNodeSettings.msbuildArgForWeb + " "" + env.WORKSPACE + "/" + buildNodeSettings.buildFileForWeb + """
        echo "Bulid Service"
        bat """ + msbuild + "" " + buildNodeSettings.msbuildArgForService + " "" + env.WORKSPACE + "/" + buildNodeSettings.buildFileForService + """
    }

    stage("Pack") {
        parallel PackWeb:{
            echo "删除相关配置文件"
            buildNodeSettings.delFilesForWeb.each{
                echo "删除文件:" + it
                def filepath =""" + buildNodeSettings.publishOutputForWeb.replace("/","\") + "\" + it + """
                bat "if exist "+ filepath +" del " + filepath
            }
            echo " 发布到更新系统"
            bat "if not exist "" + buildNodeSettings.updateServerPath + env.JOB_NAME + "" md "" + buildNodeSettings.updateServerPath + env.JOB_NAME + """
            bat """ + env.zip + """+ " a -r "" + buildNodeSettings.updateServerPath + buildNodeSettings.publishFileNameForWeb + "" "" + buildNodeSettings.publishOutputForWeb + "\*""
            echo "压缩完成"
            echo "上传oss"
            bat env.oss + " -c " + env.ossconfig + " cp "" + buildNodeSettings.updateServerPath + buildNodeSettings.publishFileNameForWeb + "" "oss://xxxx/" + buildNodeSettings.publishFileNameForWeb +"""
        },
        PackService:{
            echo "删除相关配置文件"
            buildNodeSettings.delFilesForService.each{
                echo "删除文件:" + it
                def filepath =""" + buildNodeSettings.publishOutputForService.replace("/","\") + "\" + it + """
                bat "if exist "+ filepath +" del " + filepath
            }
            echo " 发布到更新系统"
             bat "if not exist "" + buildNodeSettings.updateServerPath + env.JOB_NAME + "" md "" + buildNodeSettings.updateServerPath + env.JOB_NAME + """
            bat """ + env.zip + """+ " a -r "" + buildNodeSettings.updateServerPath + buildNodeSettings.publishFileNameForService + "" "" + buildNodeSettings.publishOutputForService + "\*""
            echo "压缩完成"
            echo "上传oss"
            bat env.oss + " -c " + env.ossconfig + " cp "" + buildNodeSettings.updateServerPath + buildNodeSettings.publishFileNameForService + "" "oss://xxxx/" + buildNodeSettings.publishFileNameForService +"""
        }
    }

    stage("Clear")
    {
        echo "清理工作目录"
        deleteDir()
    }
}

stage("Publish Web")
{
    parallel publishWeb1:{
        node(webNodeSetting.node)
        {
            echo "发布web"
            echo "更新文件"
            echo "更新文件下载地址为:http://xxxx/" + buildNodeSettings.publishFileNameForWeb
            echo "下载文件"
            bat env.oss + " -c " + env.ossconfig + " cp  "oss://xxxx/" + buildNodeSettings.publishFileNameForWeb + "" " + webNodeSetting.downloadPath
            echo "文件下载完成"
            echo "停止站点"
            bat "C:\Windows\System32\inetsrv\appcmd.exe stop site "" + webNodeSetting.webApplicationName + """
            bat """ + env.zip + "" x ""+ webNodeSetting.downloadPath + buildNodeSettings.publishFileNameForWeb + "" -y -o"" + webNodeSetting.publishPath + """
            echo "启动站点"
            bat "C:\Windows\System32\inetsrv\appcmd.exe start site "" + webNodeSetting.webApplicationName+ """
        }
    },
    publishWeb2:{
        node(webNodeSetting2.node)
        {
            echo "发布web"
            echo "更新文件"
            echo "更新文件下载地址为:http://xxxx/" + buildNodeSettings.publishFileNameForWeb
            echo "下载文件"
            bat env.oss + " -c " + env.ossconfig + " cp  "oss://xxxx/" + buildNodeSettings.publishFileNameForWeb + "" " + webNodeSetting2.downloadPath
            echo "文件下载完成"
            echo "停止站点"
            bat "C:\Windows\System32\inetsrv\appcmd.exe stop site "" + webNodeSetting2.webApplicationName + """
            bat """ + env.zip + "" x ""+ webNodeSetting2.downloadPath + buildNodeSettings.publishFileNameForWeb + "" -y -o"" + webNodeSetting2.publishPath + """
            echo "启动站点"
            bat "C:\Windows\System32\inetsrv\appcmd.exe start site "" + webNodeSetting2.webApplicationName+ """
        }
    },
    publishWeb3:{
        node(webNodeSetting3.node)
        {
            withEnv(["oss=C:\Tools\oss\ossutil.exe", "ossconfig=C:\Tools\oss\config"]) {//需要手动设置变量
                echo "发布web"
                echo "更新文件"
                echo "更新文件下载地址为:http://xxxx/" + buildNodeSettings.publishFileNameForWeb
                echo "下载文件"
                bat env.oss + " -c " + env.ossconfig + " cp  "oss://xxxx/" + buildNodeSettings.publishFileNameForWeb + "" " + webNodeSetting3.downloadPath
                echo "文件下载完成"
                echo "停止站点"
                bat "C:\Windows\System32\inetsrv\appcmd.exe stop site "" + webNodeSetting3.webApplicationName + """
                bat """ + env.zip + "" x ""+ webNodeSetting3.downloadPath + buildNodeSettings.publishFileNameForWeb + "" -y -o"" + webNodeSetting3.publishPath + """
                echo "启动站点"
                bat "C:\Windows\System32\inetsrv\appcmd.exe start site "" + webNodeSetting3.webApplicationName+ """
            }
        }
    }
}

stage("Publish Service")
{
    parallel publishService1:
    {
        node(serviceNodeSetting.node){
            
            //发布windows service
            echo "发布Service"
            echo "下载文件"
            bat env.oss + " -c " + env.ossconfig + " cp  "oss://xxxx/" + buildNodeSettings.publishFileNameForService + "" " + serviceNodeSetting.downloadPath
            echo "卸载Windows Services"
            try{
                bat "net stop " + serviceNodeSetting.serviceName
                bat env.InstallUtil + " -u " + serviceNodeSetting.serviceName
            }catch(ex)
            {
                echo "卸载失败:" + ex
                try{
                    bat "sc delete " + serviceNodeSetting.serviceName
                }catch(ex2)
                {
                    echo "强制删除失败:" +ex2
                }
            }
            echo "解压文件"
            bat """ + env.zip + "" x ""+ serviceNodeSetting.downloadPath + buildNodeSettings.publishFileNameForService + "" -y -o"" + serviceNodeSetting.publishPath + """
            echo "服务安装"
            bat env.InstallUtil + " " + serviceNodeSetting.publishPath + "\" + serviceNodeSetting.serviceFileName + " /name="+ serviceNodeSetting.serviceName + " /display=" + serviceNodeSetting.serviceName + " /desc=" + serviceNodeSetting.serviceName
            echo "启动服务"
            bat "net start " + serviceNodeSetting.serviceName
            
        }
    },
    publishService2:
    {
        node(serviceNodeSetting2.node){
            
            //发布windows service
            echo "发布Service"
            echo "下载文件"
            bat env.oss + " -c " + env.ossconfig + " cp  "oss://xxxx/" + buildNodeSettings.publishFileNameForService + "" " + serviceNodeSetting2.downloadPath
            echo "卸载Windows Services"
            try{
                bat "net stop " + serviceNodeSetting2.serviceName
                bat env.InstallUtil + " -u " + serviceNodeSetting2.serviceName
            }catch(ex)
            {
                echo "卸载失败:" + ex
                try{
                    bat "sc delete " + serviceNodeSetting2.serviceName
                }catch(ex2)
                {
                    echo "强制删除失败:" +ex2
                }
            }
            echo "解压文件"
            bat """ + env.zip + "" x ""+ serviceNodeSetting2.downloadPath + buildNodeSettings.publishFileNameForService + "" -y -o"" + serviceNodeSetting2.publishPath + """
            echo "服务安装"
            bat env.InstallUtil + " " + serviceNodeSetting2.publishPath + "\" + serviceNodeSetting2.serviceFileName + " /name="+ serviceNodeSetting2.serviceName + " /display=" + serviceNodeSetting2.serviceName + " /desc=" + serviceNodeSetting2.serviceName
            echo "启动服务"
            bat "net start " + serviceNodeSetting2.serviceName
            
        }
    },
    publishService3:
    {
        node(serviceNodeSetting3.node){
            withEnv(["oss=C:\Tools\oss\ossutil.exe", "ossconfig=C:\Tools\oss\config"]) {//需要手动设置变量
                //发布windows service
                echo "发布Service"
                echo "下载文件"
                bat env.oss + " -c " + env.ossconfig + " cp  "oss://xxxx/" + buildNodeSettings.publishFileNameForService + "" " + serviceNodeSetting3.downloadPath
                echo "卸载Windows Services"
                try{
                    bat "net stop " + serviceNodeSetting3.serviceName
                    bat env.InstallUtil + " -u " + serviceNodeSetting3.serviceName
                }catch(ex)
                {
                    echo "卸载失败:" + ex
                    try{
                        bat "sc delete " + serviceNodeSetting3.serviceName
                    }catch(ex2)
                    {
                        echo "强制删除失败:" +ex2
                    }
                }
                echo "解压文件"
                bat """ + env.zip + "" x ""+ serviceNodeSetting3.downloadPath + buildNodeSettings.publishFileNameForService + "" -y -o"" + serviceNodeSetting3.publishPath + """
                echo "服务安装"
                bat env.InstallUtil + " " + serviceNodeSetting3.publishPath + "\" + serviceNodeSetting3.serviceFileName + " /name="+ serviceNodeSetting3.serviceName + " /display=" + serviceNodeSetting3.serviceName + " /desc=" + serviceNodeSetting3.serviceName
                echo "启动服务"
                bat "net start " + serviceNodeSetting3.serviceName
            }
        }
    }
}

 

以上代码对三台服务器上的web和service进行了更新操作,两台阿里云内网,一台京东云

代码说明:

node:节点,Slave,表示在哪个节点中运行
stage:阶段,表示当前阶段,可定义阶段名称
checkout:代码检出
echo:输出信息
bat:执行cmd命令,linux下命令为sh
env:环境变量,有系统定义变量和自定义变量两部分
parallel:表示并行执行步骤
更多详细解释请查看官方文档https://jenkins.io/doc/book/pipeline/

四、看看效果

我们开始构建刚才新建的项目

从gif可以看出,整个流程只耗费了一分钟不到,我们去看看这三台服务器

三台服务器的文件都已更新,并且服务已经启动,证明我们的pipeline代码是可行的

五、补充和改进

  • 这篇文章的代码量过大,语言组织能力有待改进
  • Slave节点的环境变量不能正确读取到,目前只能使用withEnv进行更改环境变量,具体情况publishService3
  • 项目的耦合性太高了,目前编译、打包、发布都在同一个项目中,需要进行项目的拆分
  • 没有加重试机制,一旦某一阶段失败,只能重新运行,有待改进
  • 失败邮件通知,这个目前没有加入

如若有写的不好的地方,请指出

如若有更好的方案,欢迎一起交流

如若有不懂,欢迎咨询,我会告诉你我知道的

本文已同步个人博客,欢迎转载

当前文章://icr8i.html

发布时间:2019-03-19 06:59:43

澳门永利国际平台|首页 澳门真人棋牌_首页 澳门正规博彩50大网站_澳门正规博彩_正规博彩娱乐官方网站 东方彩票网-东方彩票注册-东方彩票手机版 海洋之神海洋财富 - 海洋之神 

责任编辑:纯华戏

随机推荐