DotNET Core ASP.NET Core Jenkins Gogs持续构建 持续部署

DotNET Core ASP.NET Core Jenkins Gogs持续构建 持续部署

环境

  1. Jenkins,安装在window(安装在Linux更合适)
  2. Gogs
  3. 服务运行服务器

Jenkins插件

  1. Pipeline
  2. Pipeline: Basic Steps
  3. Pipeline: Build Step
  4. Pipeline: Groovy
  5. Pipeline: Job
  6. Gogs plugin
  7. Git plugin
  8. PowerShell plugin
  9. SSH Pipeline Steps

使用说明

创建任务

流水线任务
第1步 新建任务
  1. 点击首页左上角第一个菜单“新建Item”
  2. 输入名称
  3. 选择流水线
  4. 确认
第2步 配置任务基本信息
  1. 在General界面的“描述”中,添加构建任务描述 ;
  2. 勾选“描述”下方的选择框“Discard old builds”
  3. 设置构建保持策略,在“保持构建的天数”填入数值“7”,在“保持构建的最大个数”填入数字“20”
第3步 配置Gogs Webhook
  1. 点击顶部菜单“Gogs Webhook”
  2. 勾选“Use Gogs secret”,内容不填,如果有内容需要清空
  3. 勾选“在必要的时候并发构建”
第4步 构建触发器
  1. 点击顶部菜单“构建触发器”
  2. 勾选“Build when a change is pushed to Gogs”,即当有新的提交记录时触发构建。
第5步 编写流水线
  1. 将编写好的脚本拷贝到脚本框里(不要直接脚本框里编写,很难编辑),构建脚本参考后文
  2. 保存
第6步 Gogs中配置钩子

其他代码管理工具使用方式类似
http://192.168.4.179:8080/gogs-webhook/?job=任务名字
在这里插入图片描述

附录

服务脚本

脚本如下:

def remote = [:]
	remote.name = 'develop'
	remote.host = '192.168.4.212'
	remote.user = 'root'
	remote.password = 'XXXXXXX'
	remote.allowAnyHosts = true
        

pipeline {
    agent any
    
    environment {
       
        GitUser='Jenkins'
        GitURI='http://192.168.4.84:10080/pst/XXXXX.git'
        SSHIp='192.168.4.212'
        PackageName='user'
        PathName='User'
        PackageFunctionVersion='1.1.5.'
		
        SSHRemoteDir='/root/jenkins_service_package'  //包发送的临时文件夹
        SSH_Publish_image="cd /root/jenkins_service_package;bash /root/jenkins_service_package/install_${PackageName}.sh" //执行打包脚本,脚本需要提前在服务器准备好,脚本参考下文
        
        PublishCommand="dotnet publish .\\src\\Service.${PathName}\\${PathName}Service.Host\\${PathName}Service.Host.csproj -c release -o ${PackageName}"
        RenameCommand="ren ./${PackageName}.zip ('${PackageName}-${PackageFunctionVersion}' + (git rev-parse --short HEAD)+'.zip')"
        PackageMoveComand="move ${PackageName}-* D:/ServicePackage"
                
        SSH_Source="./${PackageName}.zip"
    }
    
    options { 
        disableConcurrentBuilds() //不并行编译
    }
    
    stages {
        stage('Source') {
            steps{
                git credentialsId: GitUser,branch: 'develop', url: GitURI
            }
        }
     
        stage('Parallel Stage'){
            parallel{
                stage("Check Project"){
                    when{
                        expression{
                                return checkProjectUpdated("src/Service.${PathName}/")  //这里是一个解决方案中有多个项目,需要判定并构建指定的项目
                            }
                    }
                    stages{
                        stage("Compile Project"){
                           steps{
                               bat "${PublishCommand}"
                               zip dir: "${PackageName}", zipFile: "${PackageName}.zip"
                           }
                        }
                        stage('Publish Project'){
                          steps{
                            sshPut remote: remote, from: "${SSH_Source}", into: "${SSHRemoteDir}"
                            sshCommand remote: remote, command: "${SSH_Publish_image}"
                            }
                        }
                        stage("Package Project"){  //这里是打包并存档
                          steps{      
                             powershell "${RenameCommand}"
                             powershell "${PackageMoveComand}"
                            }
                        }
                    }
                }     
				
            }
        }
    }  
}

@NonCPS
def checkProjectUpdated(prjName){
    //强制构建 
    def userBuild = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause')
    if(userBuild != null && userBuild.size() > 0){
        currentBuild.description = "#${BUILD_NUMBER} 强制构建"
        return true
    }
    
    try{
        def changeLogSets = currentBuild.changeSets
        for (int i = 0; i < changeLogSets.size();i++){
            def entries = changeLogSets[i].items
            for (int j = 0; j < entries.length; j++) {
                def entry = entries[j]
                def files = new ArrayList(entry.affectedFiles)
                for (def file in files) {
                    def isPrjUpdated= file.path.startsWith(prjName)
                    if(isPrjUpdated == true){
                        echo "PrjChecked by ${file}"
                        return true
                    }
                }
            }
        }        
    }catch(ex){
        echo "checkProjectUpdated Error:${ex}"
    }
    echo "项目路径检测未通过-禁止项目构建"
    return false
}

运行服务器构建镜像脚本

服务

需要修改服务名称service_package_name和服务版本service_version,后端脚本示例如下:

#! /bin/bash

//修改服务名称
service_package_name="user"
service_version="v1"

//停止服务,docker-compose文件和构建images的脚本在同一个目录,需要注意
cd ../docker-compose/
docker-compose -p docker-compose -f docker_compose_services_$service_package_name.yml down
docker rm -f bup_service_$service_package_name
docker rmi bup/services_$service_package_name:$service_version

//制作镜像
cd -
rm -rf $service_package_name
unzip $service_package_name.zip -d $service_package_name
cd $service_package_name
docker build -t bup/services_$service_package_name:$service_version . 

//删除临时文件
cd ..
rm -rf $service_package_name
rm -f $service_package_name.zip 

//启动服务
cd ../docker-compose/
docker-compose -p docker-compose -f docker_compose_services_$service_package_name.yml up -d

//删除未引用的镜像
docker images prune

docker-compose文件内容

docker_compose_services_user.yml

version: '3.4'

services: 
  services_basedata:
    image: bup/services_user:v1
    container_name: "bup_services_user"
    restart: always
    ports:
      - "8201:8201"
      - "8202:8202"
      - "8203:8203"
    networks:
      bup_services_network:
        ipv4_address: 172.30.0.4
    volumes:
      - /etc/localtime:/etc/localtime
    environment:
      RpcPort: "8201"
      HttpPort: "8202"
      WSPort: "8203"
      db_connectionstring: "xxxxxxxxxx"
    logging:
      driver: "json-file"
      options:
        max-size: "200M"
        max-file: "10"
networks:
  bup_services_network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.30.0.0/16

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值