Gitlab实现CI/CD,集成钉钉消息推送

文章目录

  • (一)概念简介
    • 什么是CI/CD?
    • 什么是DevOps?
    • 做CI/CD,有什么好处?
  • (二)实现CI
    • 配置Ranner
    • .gitlab-ci.yml文件
  • (三)代码评审
    • 安装SonarQube
    • 集成Gitlab
  • (四)实现CD
  • (五)钉钉消息推送

(一)概念简介

什么是CI/CD?

  • 软件产业不成熟的时候,一个软件从零开始到最终交付,大概包括:规划、编码、构建、测试、发布、部署和维护。一个人可以完成上述所有工作。但随着软件的复杂度不断攀升,就开始出现了精细化分工。除了软件开发工程师之外,还有软件测试工程师,以及软件运维工程师。分工后对应的流程就变成了:开发–>测试–>部署,将整个流程细分之后,也就缩小了每个节点所需要的时间,大家各司其职,从而可以使整个软件的开发周期缩短,而且变得频繁,这也就是所谓的 “敏捷开发”, 那如何支撑敏捷开发呢?就要说到CI/CD了。
  • CI : Continuous Integration(持续集成)
  • CD : Continuous Delivery(持续交付)或Continuous Deployment(持续部署)
  • 这里所说的持续,其实就是反复不间断执行,并且加速这个过程。这就是敏捷开发,持续的走这一套流程:开发->测试->部署,相比于周期较长的瀑布式开发,这样提高了产品版本迭代的速度,也提高了开发团队的工作效率。
  • 随之而来带来的问题就是,开发和运维之间的矛盾,敏捷开发对开发人员固然是好,因为可以及时检验自己代码的正确性,但是对于运维人员来说并不友好,在运维眼中,稳定比一切都重要,版本更新,意味着要打破这个稳定状态。这就是开发与运维之间的矛盾,DevOps就可以很好的解决这个问题。

什么是DevOps?

  • Development(开发)Operations(运维)两个词的组合,可以将它理解为一组过程,或者是一种思想。
  • DevOps就是打破开发人员和运维人员直接的壁垒,通过自动化流程来使得软件开发过程更加快捷和可靠。目前市场中也出现了这个工种:DevOps工程师
  • DevOps不仅仅是简单的将Dev和Ops两个团队合并,而是彼此介入对方的工作,运维人员可以在早期开发的时候介入开发过程,了解所使用的架构以及技术,可以制定相应的技术方案,开发人员也可以参与到系统的部署中,提出优化建议
  • DevOps这一概念是2009年提出来的,但是最近几年才火起来的,主要是因为虚拟化技术和容器这几年应用的很广泛了,而这两者,为DevOps提供了很好的前提条件。
    Gitlab实现CI/CD,集成钉钉消息推送_第1张图片

做CI/CD,有什么好处?

  • CI/CD是为了敏捷开发诞生的产物,敏捷开发可以更早的发现产品的问题,而不是等到所有功能都做完之后,再来审查这个产品哪里有不合适的地方。
  • 那我目前所经历的流程举例。公司在所CI/CD之前的开发流程是这样的:开发人员在自己的分支开发完成之后,提交到gitlab上,并提mearge requestmaster主分支上,然后开发老大来进行代码的审查reviewreview之后,再由老大去mearge到主分支上,接着再去服务器上执行脚本,重新部署服务,这样一套下来,花费的时间就很多,因为不老大忙的很。而且由于是人工审查代码,有的时候看不出来哪里有问题,一到真正编译的时候就报错了。这个过程是很耗费时间,且效率低下的。
  • 有了CI/CD之后,这个流程就变得自动化,利用工具做CI/CD,基本上都是一样的原理:当指定的某个分支有代码mearge过来的时候,就会触发CI/CD,最基础的步骤就是单元测试,以及自动构建。这个过程中一旦出现一点错,都会失败,所以对代码规范的要求极高。但是这样无感式的测试与构建,节省了大量的时间,也提高了开发效率。

(二)实现CI

  • 流程简介
  1. 在仓库根目录创建一个.gitlab-ci.yml 文件,定义GitLab runner要做哪些操作。 默认有3个stages阶段: buildtestdeploy
  2. 为该项目指派一个Runner,当有合并请求或者 push的时候,Ranner就会自动开始pipeline(管道操作)。
  3. 当build完成后(返回非零值),会看到pushcommit或者mearge request前面出现一个绿色的对号。 这个功能很方便的检查出本次合并请求是否会导致build失败。

配置Ranner

1. 安装GitLab-Ranner

#在ubuntu server16.04版本下使用命令安装
$ sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64

#授予可执行权限
$ sudo chmod +x /usr/local/bin/gitlab-runner

#创建一个gitlab-ci用户
$ sudo useradd --comment 'GitLabRunner' --create-home gitlab-runner --shell /bin/bash

#安装,并作为服务启动
$ sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner

2. 注册Ranner

  • 执行命令:sudo gitlab-runner register,输入gitlab的urltoken(在Setup a specific Runner manually中找)
  • 启动Rannergitlab-runner start命令不行的话就用gitlab-runner run
  • 启动成功后看:仓库->settings->CI/CD->Ranner Settings->点击Expend,看Ranner是否运行,绿色代表运行中。

.gitlab-ci.yml文件

  • 当有新内容push到仓库后,GitLab会查找是否有.gitlab-ci.yml文件,如果文件存在, Runners 将会根据该文件的内容开始build 本次commit。采用YAML语法, 注意缩进格式是空格,不能用tab键缩进。
  • 这是最基础的脚本文件,还有很多功能集成的话,也可以写入。注意,这个里面的tag是要和ruanner中的tag一样,才能更具项目找到runner去执行pipeline
  • .gitlab-ci.yml示例
stages:
  - build
  - test

before_script:
  - echo "Restoring Packages..."

build_job:
  stage: build
  script:
  - echo "Release build..."
  except:
  - tags

test_job:
  stage: test
  script:
  - echo "Tests run..."
  - cd cds.ci.test
  - gradle test

(三)代码评审

  • SonarQube简介
  • "烂代码"会导致浪费时间,延误进度,后期也不好维护。所以从一开始就要规范出优质代码。有很多代码扫描工具可使用,这里就选择SonarQube
  • 可检查项目代码的漏洞和潜在逻辑问题。提供了丰富的插件,支持多种语言的检测, 如 Java、Python、Groovy、C#、C、C++等几十种编程语言的检测。
  • 检查核心
  1. 是否遵循编程标准:如命名规范,编写的规范等。
  2. 设计是否存在的潜在缺陷:SonarQube通过插件Findbugs、Checkstyle等工具检测代码存在的缺陷。
  3. 代码的重复代码量:SonarQube可以展示项目中存在大量复制粘贴的代码。
  4. 代码中注释的程度:源码注释过多或者太少都不好,影响程序的可读可理解性。
  5. 代码中包、类之间的关系:分析类之间的关系是否合理,复杂度情况。

安装SonarQube

# 1. 获取postgresql的镜像
docker pull postgres

# 2. 启动postgresql
docker run --name postgresDB -e POSTGRES_USER=sonar -e POSTGRES_PASSWORD=sonar -d postgres

# 3. 获取sonarqube的镜像
docker pull sonarqube

# 4. 启动sonarqube
docker run --name sonarqube --link postgresDB -e SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar -p 9000:9000 -d sonarqube

# 5. 将sonar-gitlab-plugin-2.1.0.jar添加到docker中的sonarqube容器中
docker cp sonar-gitlab-plugin-2.1.0.jar sonarqube:/opt/sonarqube/extensions/plugins

# 6. 打开localhost:9000,可以看到ui界面

集成Gitlab

  1. 在build.gradle中添加配置,启动sonarqube插件
  2. 配置sonar系统认证权限信息,以便将分析结果上传到sonar中展示
  3. 运行分析命令:gradle sonarqube,然后就可以在sonarqube页面上看到分析结果。
plugins {
    # plugins段放置位置有要示,放在buildscript段前面会报错,放到文件最末尾也报错,紧跟buildscript放置OK
    #添加插件信息
    id "org.sonarqube" version "2.6-rc1"
}

apply plugin: "org.sonarqube"

subprojects {
    sonarqube {
       # 如果同时存在src/main/java与src/main/test,则要按以下方式设置,如果没有单元测试用例目录test,也可以只填写src
        properties {
            property "sonar.sources", "src/main/java"
        }
    }
}

#配置sonarqube的权限信息
sonarqube{
	properties {
		property "sonar.host.url", "http://192.168.90.58:9000"
		property "sonar.projectName", "${artifactIdParam}"
		property "sonar.projectKey", "${artifactIdParam}"
		property "sonar.projectVersion", "${versionParam}"
        property "sonar.login","admin"
        property "sonar.password","admin"
	}
}

编写.gitlab-ci.yml脚本,增加执行代码审查的脚本

code_review
  stage: test
  script:
  - echo "Start reviewing code"
  - gradle sonarqube  

(四)实现CD

  • 实现自动化部署,就要在.gitlab-ci.yml中指定执行的脚本,与自动化测试类似。
  • 注释:only指定了只有在master分支push的时候才会被执行。tags是对应注册ranner时候的tag。(这相当于唯一标识)
    在实际开发中要通过一个shell脚本来将资源自动部署到指定位置,在script中添加一个脚本:
stages:
  - deploy
deploy:
    stage: deploy
    script:
      - echo "start deploy....."
      - ./deploy.sh
    only:
      - master
    tags:
      - iot
  • script中的deploy是编写的shell脚本,可以实现将要发布的内容自动部署到发布目录下:
#!/bin/bash
deploy_path="/home/..."
project_path="gitlab_ci_cd_test";
judge_path = "$deploy_path/$project_path"
if [ ! -d "$judge_path" ]
then
   project_url="http://XXXXcom/daq/gitlab_ci_cd_test.git"
   git clone $project_path $deploy_path
else
   cd $deploy_path
   git pull
fi

(五)钉钉消息推送

  • 钉钉自定义机器人,获取webhook
  • 编写脚本,在打包构建之后执行
# 前一个命令执行状态判断是成功信息还是失败信息
if [ "$?" -eq "0" ];then
         log "[OK]"
         DEPLOY_SYSTEM="${!YZT_ENV_SERVER_IP2}:${!YZT_ENV_SERVER_PORT2}"
         sendDingTalkSuccessNotifications
else
         logStep ">> $?"
         DEPLOY_SYSTEM="${!YZT_ENV_SERVER_IP2}:${!YZT_ENV_SERVER_PORT2}"
         sendDingTalkErrorNotifications
fi

# 相关脚本
function sendDingTalkErrorNotifications() {
      DEPLOY_STATUS='部署失败!'
      sendDingTalkNotifications
}
function sendDingTalkSuccessNotifications() {
      DEPLOY_STATUS='部署成功!'
      sendDingTalkNotifications
}

# 推送模板发送(模板拼接)
function sendDingTalkNotifications() {
   logStep " STEP 5 - Send Notifications to DingTalk"
   local title="「前端CI/CD」 ${PROJECT_NAME}"
   local text="### ${title} \n #### 构建分支:${CI_COMMIT_REF_NAME} \n #### 构建状态:${DEPLOY_STATUS}\n #### 部署主机:${DEPLOY_SYSTEM} \n #### 提交者:${GITLAB_USER_EMAIL} \n\n\n ##### [流水线 Pipeline #${CI_PIPELINE_ID}](${CI_PROJECT_URL}/pipelines/${CI_PIPELINE_ID}) \n"
   curl POST "$CI_DINGTALK_WEBHOOK_URL" -H 'Content-Type: application/json' -d "{\"msgtype\": \"markdown\",\"markdown\": {\"title\":\"$title\",\"text\": \"$text\"}}"
   # curl POST "$CI_DINGTALK_WEBHOOK_URL" -H 'Content-Type: application/json' -d '{ "msgtype": "markdown", "markdown": {"title":"CI/CD cmp-web","text": "##### 构建分支:test \n Pipelines状态:成功\n ######## [流水线Pipeline #3181](http://git.1ziton.com/front-end/cmp-web/pipelines/3181) \n"}}'
}

function log() {
   echo "$(date):$@"
}

function logStep() {
	echo "$(date):====================================================================================="
        echo "$(date):$@"
	echo "$(date):====================================================================================="
	echo ""
}

你可能感兴趣的:(工具库)