Gitlab+Jenkins+Artifactory, CI/CD自动构建发布环境搭建使用实践

CI/CD自动构建发布环境搭建使用实践

通过C/C++的cmake工程示例项目,构建Gitlab+Jenkins+Artifactory自动构建发布环境。其中

  • Gitlab提供源码仓库功能,通过webhook自动触发器(trigger)触发Jenkins构建动作
  • Jenkins提供构建发布中心角色,通过从Gitlab拉取源码(Git)、构建(Build)、测试(Test)、发布(Publish)、部署(Deploy), 完成整个CI/CD流程
  • Artifactory提供二进制生成物(tar,zip,deb,exe等)仓库功能,以及每次编译构建详情辅助信息

测试环境

  • Host机器: WSL2(Ubuntu 20.04.2 LTS )
  • 采用docker容器运行服务
    • Gitlab镜像:gitlab/gitlab-ce:latest、
    • Jenkins镜像: jenkins/jenkins:latest
    • Artifactory镜像: docker.binary.io/jfrog/artifactory-oss:latest

安装配置过程中碰到的坑

  • Jenkins内置openjdk11版本,对Gitlab插件太高,需要降到jdk8版本
  • Artifactory TCP端口8081和8082,其中8081是API端口,8082才是Web前端端口,需要将两者都映射出来
  • 新版Jenkins内的Artifactory插件和旧版本配置有较大不同,在Publish时采用直接指定Artifactory服务器地址临时方案
  • Gtilab配置Webhook时,首先需要管理员对网络配置打开webhook网络使能。
  • 如果容器启动过程中异常,用docker logs <容器ID>查看调试日志,基本能找到问题。
  • HOST端volumes映射到容器内,需要保证路径有读写权限

docker-compose.yaml文件

version: "3.2"

services:
   gitlab:
       image: gitlab/gitlab-ce:latest
       container_name: gitlab-container
       restart: always
       environment:
           - GITLAB_SECRETS_DB_KEY_BASE=******
           - GITLAB_HOST=172.26.180.63
           - GITLAB_PORT=10081
           - GITLAB_SSH_PORT=10023
       ports:
           - "10081:80"
           - "10023:22"
       volumes:
       - '/data/gitlab/config:/etc/gitlab'
       - '/data/gitlab/logs:/var/log/gitlab'
       - '/data/gitlab/data:/var/opt/gitlab'
   jenkins:
       image: jenkins/jenkins:latest
       container_name: jenkins-container
       restart: always
       ports:
           - "8081:8080"
           - '50000:50000'
       volumes:
       - '/var/run/docker.sock:/var/run/docker.sock'
       - '/data/jenkins/jenkins_home:/var/jenkins_home'
       environment:
       - "JENKINS_OPTS=--prefix=/jenkins"
       - "JAVA_HOME=/var/jenkins_home/opt/jdk1.8.0_202"
       - "PATH=/var/jenkins_home/opt/jdk1.8.0_202/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
   artifactory:
       image: docker.bintray.io/jfrog/artifactory-oss:latest
       container_name: artifactory-container
       restart: always
       ports:
           - "9081:8081"
           - "9082:8082"
       volumes:
            - '/var/opt/jfrog/artifactory:/var/opt/jfrog/artifactory'

在Jenkins容器中设置环境变量JAVA_HOME和PATH,用jdk8替换openjdk11; Artifactory容器把8081和8082端口都映射出来。Jenkins容器启动后除了安装默认插件外,还需要安装: Gitlab、Cmake、Aritfactory等插件,同时把WSL2作为Jenkins的node节点(slave节点)加到构建节点集合内,通过ssh(用户名/密码)方式登录,并设定其标签(cmake ubuntu), 在WSL2子系统内安装cmake,openjdk, gcc,cppcheck等编译工具套件。


工程

Gitlab工程基于jenkinsexample, 涉及Qt部分被剔除。该工程内含Jenkins构建脚本文件Jenkinsfile,通过改动该文件做实验操作。在Jenkins仪表盘界面可以构建流水线(pipeline)和多分枝流水线(multibranch pipeline)项目,在Gitlab端配置集成Jenkins,可将工程和Jenkins项目进行链接,实现自动触发.

Gitlab+Jenkins+Artifactory, CI/CD自动构建发布环境搭建使用实践_第1张图片

Jenkinsfile文件内容

pipeline {
	agent {
        label 'cmake'
    }

	options {
		buildDiscarder(logRotator(numToKeepStr: '10'))
	}


	parameters {
		booleanParam name: 'RUN_TESTS', defaultValue: true, description: 'Run Tests?'
		booleanParam name: 'RUN_ANALYSIS', defaultValue: true, description: 'Run Static Code Analysis?'
		booleanParam name: 'DEPLOY', defaultValue: true, description: 'Deploy Artifacts?'
		booleanParam name: 'PUBLISH', defaultValue: true, description: 'Publish Artifacts?'
	}

	stages {
        stage('Build') {
            steps {
                cmake arguments: '-DCMAKE_CXX_FLAGS=-g', installation: 'InSearchPath'
                cmakeBuild buildType: 'Release', cleanBuild: true, installation: 'InSearchPath', steps: [[withCmake: true]]
            }
        }

        stage('Test') {
            when {
                environment name: 'RUN_TESTS', value: 'true'
            }
            steps {
                ctest 'InSearchPath'
            }
        }

        stage('Analyse') {
            when {
                environment name: 'RUN_ANALYSIS', value: 'true'
            }
            steps {
                sh label: '', returnStatus: true, script: 'cppcheck . --xml --language=c++ --suppressions-list=suppressions.txt 2> cppcheck-result.xml'
                publishCppcheck allowNoReport: true, ignoreBlankFiles: true, pattern: '**/cppcheck-result.xml'
            }
        }

        stage('Deploy') {
            when {
                environment name: 'DEPLOY', value: 'true'
            }
            steps {
                sh label: '', returnStatus: true, script: '''cp jenkinsexample ~
                cp test/testPro ~'''
            }
        }
        stage('Publish'){
            when {
                environment name: 'PUBLISH', value: 'true'
            }

            steps {
                script{
                 	def server = Artifactory.newServer url: 'http://172.26.180.63:9081/artifactory', username:'admin' , password:'******'
                 	def uploadSpec="""{
                				"files":[
						                    {
						                        "pattern":"jenkinsexample",
						                        "target":"example-project/${BUILD_NUMBER}/",
						                        "props":"XXX=xxx;YYY=yyy"
						                    }
                						]
            			}"""
                	buildInfo = server.upload spec: uploadSpec
                	buildInfo.env.collect()
                	server.publishBuildInfo buildInfo
            	}//script
            }
        }
	}
}

Jenkins的新Pipeline语法和旧版本有一些差异,实践中会碰到一些使用错误,可以查看Jenkins项目的console输出定位出错位置,进行调试; 新版本Artifactory插件和旧版本配置有出入(暂时搞不懂如何使用),这里直接定义了Artifactory服务器!

你可能感兴趣的:(jenkins,ci,docker)