背景:
最近看流水线有点意思,就说自己也搞一套。
预期效果:
idea提交代码后,GitHub接收,jenkins自动部署。【后续加个自动部署时的代码检查、单元测试、安全测试、sonarqube】
思路分析:
idea上的spring代码push到github,github接到信号push事件,用钩子webhook转发到jenkins,jenkins利用设置好的钩子接收到代码,做后续的操作【比如代码审查、功能测试、安全测试、压力测试、自动部署服务器等等】。
步骤:
1.开发spring程序。自处比较简单。
这里能调通测试接口就行。
值得注意的是,需要配置钩子接口【这里简单介绍下,钩子就是一个触发事件的工具,就像你用钩子把鱼勾过来,把衣服勾过来一样,把想要的东西用钩子拿过来,使你和事务联系起来】。接口是一个"webhook"的接口,后面配置github时会用到。
2.配置webhook接口:
代码如下:
package com.consumer.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@Slf4j
@RestController
@RequestMapping("/webhook")
public class WebHookController {
private static final String SECRET = "12345"; // 在GitHub设置Webhook时填写的密钥
private static final String HEADER_X_HUB_SIGNATURE_256 = "X-Hub-Signature-256";
@PostMapping
public ResponseEntity<String> receiveWebhook(
@RequestHeader HttpHeaders headers,
@RequestBody String payload) {
log.info("come.");
log.info("payload:{},headers:{}", payload, headers);
// 验证签名
boolean success = verifySignature(headers, payload);
log.info("success:" + success);
// if (!success) {
// return new ResponseEntity<>("Invalid signature", HttpStatus.UNAUTHORIZED);
// }
log.info("payload" + payload);
// 处理 Webhook 事件
// 这里可以根据需要解析 payload 并执行相应的逻辑
//....
return new ResponseEntity<>("Webhook received", HttpStatus.OK);
}
private boolean verifySignature(HttpHeaders headers, String payload) {
String headerValue = headers.getFirst(HEADER_X_HUB_SIGNATURE_256);
log.info("headerValue:{}", headerValue);
if (headerValue == null || !headerValue.startsWith("sha256=")) {
return false;
}
String[] parts = headerValue.split("=", 2);
if (parts.length != 2) {
return false;
}
String signature = parts[1];
log.info("signature:{}", signature);
try {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(SECRET.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
mac.init(keySpec);
byte[] hmacBytes = mac.doFinal(payload.getBytes(StandardCharsets.UTF_8));
String calculatedSignature = "sha256=" + Base64.getEncoder().encodeToString(hmacBytes);
log.info("calculatedSignature:{},headerValue:{}", calculatedSignature, headerValue);
return calculatedSignature.equals(headerValue);
} catch (Exception e) {
log.error("Error verifying signature", e);
return false;
}
}
}
上面屏蔽了验证,有个github配置钩子时信息的接收。
3.idea配置github:
我这里简单配置了一个git远程仓库地址。
不懂的大家可以去搜索下"idea 配置github",这个难度不高,就略过了。查完回来记得接着看。会的可以略过。
4.github配置钩子
蓝色箭头就是配置webhook的地方,在仓库代码的设置里。注意,这里不是github的设置,是仓库的设置。
详情:
URL:填写你的服务器地址,阿里云、腾讯云、华为云、自己的服务器等都可以,
【注意1:】必须是公网可以打开的,本地的localhost是不行的。我这里用的免费的ngrok,这里就不展开细讲了,大家可以百度下ngrok,是一个内网穿透的工具,也就是可以把localhost变https的地址。
类型:选application/json
这里配置完了github.
下面是一些注意事项【踩过坑的】:
【注意2:】
1).GitHub配置的地址里github-wook后面要加"/".不然会报400
2).github配置的地址里必须是8080端口。不然jenkins调不通
3).使用ngrok的话自己可以联调自己刚才写的githook接口是否是通的。方法是:配置好github的webhook后,自己在idea项目里commit->push,此时idea控制台会接收消息,接收到后idea会返回200给github,测试github会通的。
如果idea设置别的返回代码如401等,对号不会显示。
5.配置jenkins
Jenkins是一个自动部署的软件,可以部署程序等等。
在Jenkins里配置流水线:
1).下载jenkins
进jenkins官网下载到本地,然后启动,默认8080端口。这里就是上面说的为啥github配置的地址必须是端口8080【学会了以后自己可以修改对应的,新人不建议】。
2). 启动jenkins后配置流水线
启动流水线后输入密码,这里jenkins会提示你密码文件的位置,一般在c盘,复制粘贴就可以。
登录后需要下载jenkins的插件,按系统提示的默认插件安装就行,包含常用的github、maven等插件。安装完之后就可以部署流水线了。
3). 建立流水线
登陆的用户名默认是admin,密码就是刚才说的c盘密码文件。我这里自定义了文件位置,
登录后的jenkins页面
点击"新建Item",然后进入详情页
我选的是这两个,确定后进入下一页
这里的25**@是我的github的密钥验证,也是账号密码或者密钥,大家可以在jenkins的设置里配置,也可以这里点击新建自动跳转设置。
这里的分支根据自己选,默认master,我github是dev,就加了一个。
jenkinsfile是本地的文件,
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello, World!'
}
}
}
}
这个文件是放在本地的,本地的位置需要配置在jenkins的"设置"->"工作空间"里.
[有报错可以看jenkins的报错日志]
这里的报错日志有2个地方可以看,一个是console_output
还有一个是hook_log
配置完之后就可以测试了。
6.测试:
idea里push代码分支,jenkins里会有日志
下拉
Done.