物联网架构成长之路(29)-Jenkins环境搭建
0. 说明
哈哈,前面中间插入了一篇Eclipse增加Git插件,在此之前真的没有用过GIT。
1. 运行Jenkins
这里为了方便,还是用Docker方式安装,由于这个是标准的war报,不对Docker Image进行过多的干预,直接使用官方的Jenkins即可
docker pull jenkins/jenkins:lts
写一份docker-compose.yml
version: '3'
services:
jenkins:
image: registry.cn-shenzhen.aliyuncs.com/wunaozai/jenkins
ports:
- 8080:8080
- 50000:50000
volumes:
- /root/workspace/docker/jenkins/data:/var/jenkins_home
2. 运行jenkins
docker-compose启动容器

然后访问宿主机,开始Jenkins安装和配置,安装就不多说了,就是下一步下一步。还有之前的博客也简单的讲解的Jenkins的搭建及使用。安装插件就使用官方默认的就可以了,以后有需要还可以在管理界面上增加。 遇到网速不好的,等一下重试一下就可以了。

Ps: 安装后,如果刷新页面,没有出现登录界面的,重启一下jenkins
进入欢迎界面

3. 本地eclipse关联GitLab仓库、利用Spring Cloud的Eureka测试自动构建
物联网服务注册中心 global-service-eureka
GlobalServiceEurekaApplication.java
@EnableEurekaServer
@SpringBootApplication
public class GlobalServiceEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(GlobalServiceEurekaApplication.class, args);
}
}
application.yml
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:8761/eureka/
在GitLab上创建项目

Eclipse关联项目到GitLab这一步就不做过多说明
4. Jenkins 系统配置
创建前,先标准插件安装,然后我们还需要安装几个插件,在系统管理-插件管理

由于我们使用Maven构建Spring Cloud项目,所以需要增加对应的Maven Plugin。我们还使用了GitLab作为代码版本管理,因此需要安装Gitlab Hook Plugin用来使用提交代码,触发自动构建行为。最后还需要把自动构建的结果通过邮件返回给相关人员,这里又需要Email Extension Plugin。
这一步需要配置Maven,默认的Jenkins Docker Image是有包含了JDK和GIT,所以我们只需要配置Maven。在系统管理-全局工具配置 这个界面,只需要配置Maven工具,使用自动安装。

配置一下GIT帐号密码,在Jenkins-凭证-系统-全局凭证-新增

配置邮件 在Jenkins-系统管理-系统设置
配置Jenkins Locaion

配置E-mail Notification,填入SMTP服务器、邮件后缀,用户名、密码。有些服务器要求SSL、SSL端口有587、465两种,好像可以不填,JavaMail包会自动选择。然后就可以测试发送了。

由于默认的E-mail Notificaion功能比较弱,因此,需要Email Extension Plugin,对应的配置如下

5. Jenkins 任务
创建一个任务、构建一个Maven项目

配置源码管理Git方式,输入对应Repo URL、选择对应的认证凭证,这个在签名一步已经配置了,这里选择就可以。分支就选默认主分支的。

构建触发器,采用Git上有人提交时触发构建

这里将 GitLab Webhook URL,复制到GitLab对应的项目上。注意这里的URL,必须GitLab所在的服务器要能访问到。

下面这个,根据实际构建Goals及Options进行配置,以后可能会通过Maven 直接构建成 Docker Image

下面这个是配置构建成功后,对应执行的操作,以后可能会通过这个脚本,构建成docker Image然后上传到Aliyun Repo

下面这个是配置自定义构建后,把结果发邮件到指定人,最前面的 Project From 要填前面配置的管理,下面的Recipient List可以写邮件接收人

下面的高级,注意下面这个配置才是实际要发送的邮件内容。我们先默认的发送一份邮件测试一下。

一切完成后,点击保存
6. 触发构建
可以在GitLab的Web Hooks 点击 Test Hook 按钮,测试一下是否触发自动构建。

看这里,自动触发构建、等构建完成,对应的邮箱就会收到构建结果。


可以看到这个邮件已经收到了。结果也是显示在邮件里面
7. 自定义邮件格式
初看邮件内容,感觉有点Low,通过下面方式实现自定义邮件内容。在 $JENKINS_HOME 目录下创建 email-templates 文件,创建 wunaozai.html 文件,并写上以下内容,可以通过以下方式预览效果。

wunaozai.html 内容
<STYLE>
BODY, TABLE, TD, TH, P {
font-family:Verdana,Helvetica,sans serif;
font-size:11px;
color:black;
}
h1 { color:black; }
h2 { color:black; }
h3 { color:black; }
TD.bg1 { color:white; background-color:#0000C0; font-size:120% }
TD.bg2 { color:white; background-color:#4040FF; font-size:110% }
TD.bg3 { color:white; background-color:#8080FF; }
TD.test_passed { color:blue; }
TD.test_failed { color:red; }
TD.console { font-family:Courier New; }
</STYLE>
<BODY> <TABLE>
<TR><TD align="right"><IMG SRC="${rooturl}static/e59dfe28/images/32x32/<%= (build.result == null || build.result.toString() == 'SUCCESS') ? "blue.gif" : build.result.toString() == 'FAILURE' ? 'red.gif' : 'yellow.gif' %>" />
</TD><TD valign="center"><B style="font-size: 200%;">BUILD ${build.result ?: 'SUCCESSFUL'}</B></TD></TR>
<TR><TD>URL</TD><TD><A href="${rooturl}${build.url}">${rooturl}${build.url}</A></TD></TR>
<TR><TD>Project:</TD><TD>${project.name}</TD></TR>
<TR><TD>Date:</TD><TD>${it.timestampString}</TD></TR>
<TR><TD>Duration:</TD><TD>${build.durationString}</TD></TR>
<TR><TD>Cause:</TD><TD><% build.causes.each() { cause -> %> ${cause.shortDescription} <% } %></TD></TR>
</TABLE>
<BR/> <!-- CHANGE SET -->
<% def changeSets = build.changeSets
if(changeSets != null) {
def hadChanges = false %>
<TABLE width="100%">
<TR><TD class="bg1" colspan="2"><B>CHANGES</B></TD></TR>
<% changeSets.each() { cs_list ->
cs_list.each() { cs ->
hadChanges = true %>
<TR>
<TD colspan="2" class="bg2"> Revision <B><%= cs.metaClass.hasProperty('commitId') ? cs.commitId : cs.metaClass.hasProperty('revision') ? cs.revision :
cs.metaClass.hasProperty('changeNumber') ? cs.changeNumber : "" %></B> by
<B><%= cs.author %>: </B>
<B>(${cs.msgAnnotated})</B>
</TD>
</TR>
<% cs.affectedFiles.each() { p -> %>
<TR>
<TD width="10%"> ${p.editType.name}</TD>
<TD>${p.path}</TD>
</TR>
<% }
}
} if(!hadChanges) { %>
<TR><TD colspan="2">No Changes</TD></TR>
<% } %>
</TABLE>
<BR/>
<% } %> <!-- ARTIFACTS -->
<% def artifacts = build.artifacts
if(artifacts != null && artifacts.size() > 0) { %>
<TABLE width="100%">
<TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
<TR>
<TD>
<% artifacts.each() { f -> %>
<li>
<a href="${rooturl}${build.url}artifact/${f}">${f}</a>
</li>
<% } %>
</TD>
</TR>
</TABLE>
<BR/>
<% } %> <!-- MAVEN ARTIFACTS -->
<%
try {
def mbuilds = build.moduleBuilds
if(mbuilds != null) { %>
<TABLE width="100%">
<TR><TD class="bg1"><B>BUILD ARTIFACTS</B></TD></TR>
<%
try {
mbuilds.each() { m -> %>
<TR><TD class="bg2"><B>${m.key.displayName}</B></TD></TR>
<% m.value.each() { mvnbld ->
def artifactz = mvnbld.artifacts
if(artifactz != null && artifactz.size() > 0) { %>
<TR>
<TD>
<% artifactz.each() { f -> %>
<li>
<a href="${rooturl}${mvnbld.url}artifact/${f}">${f}</a>
</li>
<% } %>
</TD>
</TR>
<% }
}
}
} catch(e) {
// we don't do anything
} %>
</TABLE>
<BR/>
<% } }catch(e) {
// we don't do anything
}
%> <!-- JUnit TEMPLATE --> <% def junitResultList = it.JUnitTestResult
try {
def cucumberTestResultAction = it.getAction("org.jenkinsci.plugins.cucumber.jsontestsupport.CucumberTestResultAction")
junitResultList.add(cucumberTestResultAction.getResult())
} catch(e) {
//cucumberTestResultAction not exist in this build
}
if (junitResultList.size() > 0) { %>
<TABLE width="100%">
<TR><TD class="bg1" colspan="2"><B>${junitResultList.first().displayName}</B></TD></TR>
<% junitResultList.each{
junitResult -> %>
<% junitResult.getChildren().each { packageResult -> %>
<TR><TD class="bg2" colspan="2"> Name: ${packageResult.getName()} Failed: ${packageResult.getFailCount()} test(s), Passed: ${packageResult.getPassCount()} test(s), Skipped: ${packageResult.getSkipCount()} test(s), Total: ${packageResult.getPassCount()+packageResult.getFailCount()+packageResult.getSkipCount()} test(s)</TD></TR>
<% packageResult.getFailedTests().each{ failed_test -> %>
<TR bgcolor="white"><TD class="test_failed" colspan="2"><B><li>Failed: ${failed_test.getFullName()} </li></B></TD></TR>
<% }
}
} %>
</TABLE>
<BR/>
<%
} %> <!-- CONSOLE OUTPUT -->
<% if(build.result==hudson.model.Result.FAILURE) { %>
<TABLE width="100%" cellpadding="0" cellspacing="0">
<TR><TD class="bg1"><B>CONSOLE OUTPUT</B></TD></TR>
<% build.getLog(100).each() { line -> %>
<TR><TD class="console">${org.apache.commons.lang.StringEscapeUtils.escapeHtml(line)}</TD></TR>
<% } %>
</TABLE>
<BR/>
<% } %> </BODY>
进入到项目任务的配置界面,配置一下自定义邮件格式,如下图所属,配置Content部分,最后的Attach build log 也加上

下图就是经过自定义后的邮件格式

哈哈,收到邮件,格式还行,还带构建日志。就这样吧。
8. 小结
终于完了,发现这种截图式博客真的特别麻烦,应该是录视频好些。哈哈!!这一篇博客就讲到这里的。还有更多的功能,暂时没有讲到。Jenkins可以做的事情还是很多的。通过写脚本,做任意想要做的事情。不过这个就是根据实际项目来实现了。以后有机会用到我再讲。
参考资料:
https://blog.csdn.net/u013066244/article/details/78665075
https://blog.csdn.net/galen2016/article/details/77975965
https://www.cnblogs.com/gcgc/p/5631385.html
https://www.cnblogs.com/bigben0123/p/7886092.html
https://www.cnblogs.com/xiewenming/p/7490828.html
本文地址: https://www.cnblogs.com/wunaozai/p/9997566.html
物联网架构成长之路(29)-Jenkins环境搭建的更多相关文章
- 物联网架构成长之路(15)-Jenkins部署SpringBoot
1.前言 现在慢慢也在负责一些工作了.这段时间有空,就多了解了解软件多人开发的一些知识.以前项目都是我一个人做的,从数据库设计到后端再到前端,全部放在一个war包丢到tomcat里面然后运行,利用to ...
- 物联网架构成长之路(25)-Docker构建项目用到的镜像1
0. 前言 现在项目处于初级阶段,按照规划,先构建几个以后可能会用到的Image,并上传到阿里云的Docker仓库.以后博客中用到的Image,大部分都会用到这几个基础的Image,构建一个简单的物联 ...
- 物联网架构成长之路(31)-EMQ基于HTTP权限验证
看过之前的文章就知道,我之前是通过搞插件,或者通过里面的MongoDB来进行EMQ的鉴权登录和权限验证.但是前段时间发现,还是通过HTTP WebHook 方式来调用鉴权接口比较适合实际使用.还是实现 ...
- 物联网架构成长之路(39)-Bladex开发框架环境搭建
0.前言 上一篇博客已经介绍了,阶段性小结.目前第一版的物联网平台已经趋于完成.框架基本不变了,剩下就是调整一些UI,还有配合硬件和市场那边,看看怎么推广这个平台.能不能挣点外快.第一版系统虽然简陋, ...
- 物联网架构成长之路(16)-SpringCloud从入门到吹水
1.前言 Spring Cloud 现在比较流行,版本更新也是蛮快的,网上资料也是很多.很多参考网上资料就可以学到了.这里给个 http://blog.csdn.net/forezp/article/ ...
- 物联网架构成长之路(43)-k8s从入门到放弃
0. 前言 这段时间要入门一下CI/CD了,以前简单的了解过Jenkins,现在要把以下的这个图的架构搭建起来.国外可能一两个命令就安装完成的事情,我折腾了2天多,真的差点放弃了. 1. 安装Virt ...
- 物联网架构成长之路(3)-EMQ消息服务器了解
1. 了解 物联网最基础的就是通信了.通信协议,物联网协议好像有那么几个,以前各个协议都有优劣,最近一段时间,好像各大厂商都采用MQTT协议,所以我也不例外,不搞特殊,采用MQTT协议,选定了协议,接 ...
- 物联网架构成长之路(8)-EMQ-Hook了解、连接Kafka发送消息
1. 前言 按照我自己设计的物联网框架,对于MQTT集群中的所有消息,是要持久化到磁盘的,这里采用一个消息队列中间件Kafka作为数据缓冲,缓冲结果存到数据仓库中,以供后续作为数据分析.由于MQTT集 ...
- 物联网架构成长之路(22)-Docker练习之Etcd服务搭建
0. 前言 时隔多日,前段时间忙完一个可有可无的项目后,又进入摸鱼时间,没有办法,非互联网公司,就是闲得蛋疼.又开始了自学之路.以前入门过Docker,然后又很久没有看了,最近重新看了一下,推荐一下这 ...
随机推荐
- Linux学习笔记 3 权限篇
chmod 查看命令 ls -l - rwx r_x r_x 4 user grop ...
- scrapy 命令行
关于命令详细使用 命令的使用范围 这里的命令分为全局的命令和项目的命令,全局的命令表示可以在任何地方使用,而项目的命令只能在项目目录下使用 全局的命令有:startprojectgenspiderse ...
- SpringBoot整合mongoDB
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 这一片文章介绍一个springboot整合mongodb,如果你了解整合mysql之类的 ...
- 使用open live writer客户端写博客zz
下载地址 http://openlivewriter.org/ 具体配置步骤 选择日志服务类型为"其它日志类型" 添加日志账户: 安装后的优化配置 获取博客园主题 安装完OLW(o ...
- 在UnrealEngine中用Custom节点实现高斯模糊
3x3高斯模糊 //input sW 分辨率宽 //input sH 分辨率高 //input NotUse 为了开启SceneTextureLookup函数而连接的节点,但是不参与逻辑 //inpu ...
- 写一个简单的JQ插件(例子)
虽然现在 vue angular react 当道啊但是那 JQ还是有一席之地很多很多的小单位啊.其实还会用到 我也放一个例子吧虽然我也不是很肯定有没有人写的比我更好啊但是我相信 我这个还是蛮实用的 ...
- C#文件及数据流技术
空间名称:Sysytem.IO 一.文件.文件夹操作1.创建.删除.移动.复制文件 2.创建.删除.移动.复制文件夹 二.流操作 1.FileSream - 提供读取和写入文件的方式 文本文件的写入与 ...
- redis(三)
string string是redis最基本的类型 最大能存储512MB数据 string类型是二进制安全的,即可以为任何数据,比如数字.图片.序列化对象等 命令 设置 设置键值 set key va ...
- Myeclispe下struts-config.xml文件无法图形界面打开
1.今天更改web.xml文件不小心误删了下面的配置文件,导致出现如图的错误 <servlet-mapping> <servlet-name>action</servle ...
- PHP04
PHP04 1.HTTP(hypertext transfer protocol) 1)HTTP是端与端之间的通讯协议 chrome://net-internals/ 可查看DNS缓存 浏览器-检查- ...