基于jenkins的持续集成10bet

来源:http://www.chinese-glasses.com 作者:Web前端 人气:99 发布时间:2020-03-24
摘要:时间: 2019-11-08阅读: 99标签: 部署 首先本文是基于Java项目来做的持续集成,那么第一个问题就是为什么要做持续集成? 期望: 做Java开发的同学应该深有感触,编译打包,scp把包传输到

时间: 2019-11-08阅读: 99标签: 部署

首先本文是基于Java项目来做的持续集成,那么第一个问题就是为什么要做持续集成?

期望:

做Java开发的同学应该深有感触,编译打包,scp把包传输到服务器,解压,启动tomcat ,或者启动jar,这个过程技术含量不大,但是就是这样重复一遍一遍,中间如果稍微不小心,那可能就要重新来过了,发布一下测试环境小则10分钟,多则半个小时一个钟头~

希望通过npm命令实现远程服务端部署部署分测试环境、生产环境打包部署前必须保证本地代码为最新代码,与git服务器同步需要保留vue cli的版本管理,上传代码前备份index.html,方便版本退回

我们应该有一个基本的原则,就像写代码的时候遵循DRY原则一样,重复的代码要想办法消除,重复执行的工作,理当用一个种办法来消除,这个时候jenkins出现了,程序员释放你们的双手吧,编译,打包,传包,发布,启动的过程,交给jenkins就好了。

思路

先说我的环境,我是基于centos系统搭建的持续集成环境,环境都大同小异,win,linux 环境下查不了多少。

定义测试环境与生产环境的配置对象,包括host、port、username、password、path(部署路径)、outputDir(打包文件夹)拉取所在分支最新代码,保证本地代码与git服务器一致(gitfetch--allgitreset--hardorigin/branchName gitpull,操作给出提示,确保本地有用代码已经提交)通过env环境打对应的包通过ssh2,远程执行linux stat命令,获取index.html文件的最后修改时间,工具这个时间生成版本号通过ssh2,执行linux的cp命令,拷贝服务器上index.html,重命名为index.201911081804.html(201911081804为index.html的最后修改时间)用scp2插件上传打包好的文件到服务器目标目录

首先要去jenkins官网下载最新的war包,然后这个war包部署到tomcat下,这个对于Java开发的同学没什么好说的把,so easy~

实现 (代码比较潦草,需要整理)

配置tomcat的server.xml文件,指向jenkins的解压目录

deploy.js

10bet 1

// /deploy.jsconst scpClient = require("scp2");const exec = require("child_process").exec;const execSync = require("child_process").execSync;const readline = require("readline");/* *定义多个服务器账号 */const SERVER_LIST = { // 测试环境 test: { name: "测试环境", host: "", // ip port: 22, // 端口 username: "root", // 登录服务器的账号 password: "@", // 登录服务器的账号 path: "/home/static/cnhpec", // 发布至静态服务器的项目路径 outputDir: "dist/" // 打包的目录 对应vue.config的outputDir配置 }, // 开发环境 prod: { name: "生产环境", host: "", port: 22, username: "root", password: "@", path: "/home/static/cnhpec", outputDir: "dist/" }};const argv = process.argv.slice(2);const env = argv[0] ? (argv[0] === "prod" ? "prod" : "test") : "test";const indexFile = SERVER_LIST[env].path + "/index.html";const Client = require("ssh2").Client;const conn = new Client();conn .on("ready", function() { init(); }) .on("error", function(err) { if (err) throw err; }) .connect({ host: SERVER_LIST[env].host, port: SERVER_LIST[env].port, username: SERVER_LIST[env].username, password: SERVER_LIST[env].password });async function init() { await pull(); // 拉git最新代码 await build(); // 打包 await rename(); // 备份服务器代码,生成版本 await upload(); // 上传代码}function pull() { return new Promise(function(resolve, reject) { const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); select(); function select() { rl.question( "此操作git项目强制与远端同步!!!本地代码没提交不要轻易进行操作!!!nn此操作git项目强制与远端同步!!!本地代码没提交不要轻易进行操作!!!nn此操作git项目强制与远端同步!!!本地代码没提交不要轻易进行操作!!!(y/n)", function(answer) { answer = answer.trim().toLowerCase(); if (answer === "y") { const branch = execSync("git symbolic-ref --short HEAD"); exec(`git fetch --all  git reset --hard origin/${branch.toString()}  git pull`, function(err, stdout, stderr) { if (err) { console.error("项目强制与远端同步失败!!!"); reject(); throw err; } console.info(stdout.toString()); console.error(stderr); console.log("项目强制与远端同步成功"); resolve(); }); rl.close(); } else if (answer === "n") { reject(); rl.close(); process.exit(0); } else { select(); } } ); } });}function build() { return new Promise(function(resolve, reject) { console.log(`开始打包${env === "prod" ? "生产" : "测试"}环境。。。。。。`); exec("npm run " + env, function(err, stdout, stderr) { if (err) { console.error("打包失败!!!"); reject(); process.exit(1); throw err; } console.info(stdout.toString()); console.error(stderr); console.log("打包成功"); resolve(); }); });}function rename() { return new Promise(function(resolve, reject) { console.log("开始备份服务器版本。。。。。。"); conn.exec("stat " + indexFile, function(err, stream) { if (err) { console.error("服务器版本备份失败。。。。。。"); conn.end(); reject(); process.exit(1); throw err; } let mtime; stream .on("close", function(code) { if (code == 0) { copy(mtime, resolve, reject); } else { resolve(); } }) .on("data", function(data) { console.info(data.toString()); mtime = data.toString().split("n")[7]; mtime = mtime.replace(/[u4e00-u9fa5]/g, "").replace(":", ""); mtime = formatDate(mtime); }) .stderr.on("data", function(data) { console.warn(data.toString()); }); }); });}function copy(mtime, resolve, reject) { conn.exec("/bin/cp " + indexFile + " " + SERVER_LIST[env].path + "/index." + mtime + ".html", function(err, stream) { if (err) { console.error("服务器版本备份失败。。。。。。"); conn.end(); reject(); process.exit(1); throw err; } stream .on("close", function(code) { if (code == 0) { console.log("服务器版本备份成功"); resolve(); } else { console.error("服务器版本备份失败。。。。。。"); conn.end(); reject(); process.exit(1); } }) .on("data", function(data) { console.info(data.toString()); }) .stderr.on("data", function(data) { console.error(data.toString()); }); });}function upload() { return new Promise(function(resolve, reject) { scpClient.scp( SERVER_LIST[env].outputDir, { host: SERVER_LIST[env].host, port: SERVER_LIST[env].port, username: SERVER_LIST[env].username, password: SERVER_LIST[env].password, path: SERVER_LIST[env].path }, function(err) { conn.end(); if (err) { reject(); process.exit(1); throw err; } else { console.log("Success! 成功发布到" + (env === "prod" ? "生产" : "测试") + "服务器!"); resolve(); process.exit(0); } } ); });}function formatDate(date) { const isZero = m = (m  10 ? "0" + m : m), time = new Date(date), y = time.getFullYear(), m = time.getMonth() + 1, d = time.getDate(), h = time.getHours(), mm = time.getMinutes(), s = time.getSeconds(); return y + "" + isZero(m) + "" + isZero(d) + "" + isZero(h) + "" + isZero(mm) + "" + isZero(s);}

进入tomcat bin目录,./startup.sh

package.json添加部署命令

10bet 2

{ "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build --mode build", "test": "vue-cli-service build --mode test", "lint": "vue-cli-service lint", "i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'", "deploy:test": "node ./deploy test", "deploy:prod": "node ./deploy prod" }, "devDependencies": { "scp2": "^0.5.0" }}

可以去tomcat 目录下的logs目录去查看catalina.out的日志输出文件,如果看到jenkins is fully up and running ,jenkins已经启动成功了~

总结

登录jenkins,第一次登录会有一个初始密码,会让你修改掉

确保了代码最新来打包保证版本可以退回未考虑基于vue cli多页开发,html文件的版本备份没有做成vue cli的插件还是本地部署的,没有实现服务端部署,像jenkins一样(做出vue cli插件,在部署服务器上启动vue ui,访问在里面点击deploy,可实现类型jenkins部署效果)

10bet 3

第一步:初始进来是没有这些个工程的,首先我们需要找到系统管理的菜单,进去找到Global Tool Configuration

10bet 4

10bet 5

Global Tool Configuration里面,需要你手动配置,你的jdk版本,你的git版本,还有maven版本及目录,编译打包的时候基于你配置的maven,git的配置是因为要从分支获取对应的代码进行编译。

第二步:系统管理里面还有一个比较重要的配置,是在系统管理-系统设置内,找到Publish over SSH对应的设置,如下

10bet 6

为啥要重点说下Publish over SSH,是因为后面要通过这个ssh把jar包或者war包通过ssh的方式,把包传输到对应的目标服务器的指定目录,当然还可以通过另一种方式来部署,后续再谈。配置完别忘记点下面的testing测试下配置是否可以正常连接对应的服务器哦。

第三步:创建对应需要持续集成的项目

10bet 7

先输入项目的名称,选择构建一个maven项目。

10bet 8

本文由10bet发布于Web前端,转载请注明出处:基于jenkins的持续集成10bet

关键词:

最火资讯