devops持续集成
Devops
Devops介绍
开发 development
运维 operations
Devops作用
提高产品质量
自动化测试
持续集成
代码质量管理工具
程序员鼓励师
Devops实现
设计架构规划-代码的存储-构建-测试、预生产、部署、监控
服务器准备
纯干净的系统
IP | 主机名 | 配置 |
---|---|---|
10.0.0.200 | git | 1核2G 20G硬盘 |
10.0.0.201 | jenkins | 1核1G 20G硬盘 |
10.0.0.202 | nexus | 1核2G 20G硬盘 |
10.0.0.203 | sonar | 1核2G 20G硬盘 |
10.0.0.7 | web | 1核1G 20G硬盘 |
版本控制系统
版本控制系统简介
vcs version control system
版本控制系统是一种记录一个或若干个文件内容变化,以便将来查阅特定版本内容情况的系统
- 记录文件的所有历史变化
- 随时可恢复到任何一个历史状态
- 多人协作开发
为什么需要版本控制系统
常见版本管理工具
- SVN
集中式的版本控制系统,只有一个中央数据仓库,如果中央数据仓库挂了或者不可访问,所有的使用者无法使用SVN,无法进行提交或备份文件。
- Git
分布式的版本控制系统,在每个使用者电脑上就有一个完整的数据仓库,没有网络依然可以使用Git,当然为了习惯及团队协作,会将本地数据同步到Git服务器或者Github等代码仓库。
Git安装
系统环境准备
# 查看系统版本
[root@git ~]# cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)
# 查看内核版本3.10.0-229.el7.x86_64
[root@git ~]# uname -r
3.10.0-1127.19.1.el7.x86_64
# 确认Selinux关闭状态
[root@git ~]# getenforce
Disabled
# 关闭防火墙
[root@git ~]# systemctl stop firewalld
Git安装部署
# 安装Git
[root@git ~]# yum install git
[root@git ~]# git config
--global 使用全局配置文件
--system 使用系统级配置文件
--local 使用版本库级配置文件
# 配置git使用用户
[root@git ~]# git config --global user.name "wuqi"
# 配置git使用邮箱
[root@git ~]# git config --global user.email "wuqi@qq.com"
# 配置语法高亮
[root@git ~]# git config --global color.ui true
# 查看配置列表
[root@git ~]# git config --list
user.name=wuqi
user.email=wuqi@qq.com
color.ui=true
# 查看配置文件
[root@git ~]# cat .gitconfig
[user]
name = lizhenya
email = lizhenya@qq.com
[color]
ui = true
Git初始化
初始化工作目录、对新建的目录或者已存在的目录都可进行初始化
# 创建工作目录
[root@git ~]# mkdir git_data && cd git_data
# 初始化
[root@git ~]# git init
# 查看工作区状态
[root@git ~]# git status
# 位于分支 master
#
# 初始提交
#
无文件要提交(创建/拷贝文件并使用 "git add" 建立跟踪)
隐藏目录.git
下文件介绍:
branches # 分支目录
config # 定义项目特有的配置选项
description # 仅供git web程序使用
HEAD # 指示当前的分支
hooks # 包含git钩子文件目录
info # 包含一个全局排除文件(exclude文件)目录
objects # 存放所有数据内容,有info和pack两个子目录
refs # 存放指向数据(分支)的提交对象的指针
index # 保存暂存区信息,在刚执行git init后,这个文件还没有
Git使用
创建数据-提交数据
git四种状态
sequenceDiagram
participant Untracked
participant Unmodified
participant Modified
participant Staged
Untracked->>Staged: Add the file
Unmodified->>Modified: Edit the file
Modified->>Staged: Stage the file
Unmodified->>Untracked: Remove the file
Staged->>Unmodified: Commit
git基础命令
- 初始状态
[root@git git_data]# git status
# 位于分支 master
#
# 初始提交
#
无文件要提交(创建/拷贝文件并使用 "git add" 建立跟踪)
- 创建文件
[root@git git_data]# touch a b c
[root@git git_data]# git status
# 位于分支 master
#
# 初始提交
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# a
# b
# c
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
- 提交到暂存区
[root@git git_data]# git add a
[root@git git_data]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: a
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# b
# c
[root@git git_data]# ll .git/
总用量 16
drwxr-xr-x 2 root root 6 10月 23 09:59 branches
-rw-r--r-- 1 root root 92 10月 23 09:59 config
-rw-r--r-- 1 root root 73 10月 23 09:59 description
-rw-r--r-- 1 root root 23 10月 23 09:59 HEAD
drwxr-xr-x 2 root root 242 10月 23 09:59 hooks
-rw-r--r-- 1 root root 96 10月 23 10:11 index # git add a 把文件提交到了暂存区
drwxr-xr-x 2 root root 21 10月 23 09:59 info
drwxr-xr-x 5 root root 40 10月 23 10:11 objects
drwxr-xr-x 4 root root 31 10月 23 09:59 refs
[root@git git_data]# git add . # 使用git add . 或者* 添加当前目录中所有改动过的文件
[root@git git_data]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: a
# 新文件: b
# 新文件: c
#
- 删除文件
1.先从暂存区撤回到工作区、然后直接删除文件
git rm --cached c
rm -f c
2.同时删除暂存区域和工作区域的文件
git rm -f b
[root@git git_data]# git rm --cached c
rm 'c'
[root@git git_data]# ll
总用量 0
-rw-r--r-- 1 root root 0 10月 23 10:10 a
-rw-r--r-- 1 root root 0 10月 23 10:10 b
-rw-r--r-- 1 root root 0 10月 23 10:10 c
[root@git git_data]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: a
# 新文件: b
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# c
- 提交到本地仓库
[root@git git_data]# git commit -m "commit newfile a"
[master(根提交) 034cb75] commit newfile a
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a
create mode 100644 b
[root@git git_data]# git status
# 位于分支 master
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# c
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
# 提交到暂存区过, 再修改, 使用 -a 参数可以直接提交到本地仓库
[root@git git_data]# echo bbb > a
[root@git git_data]# git commit -am "commit modified a"
[master 73240fc] commit modified a
1 file changed, 1 insertion(+), 1 deletion(-)
- 修改文件名称两种方法
[root@git git_data]# mv a a.txt
[root@git git_data]# git status
# 位于分支 master
# 尚未暂存以备提交的变更:
# (使用 "git add/rm <file>..." 更新要提交的内容)
# (使用 "git checkout -- <file>..." 丢弃工作区的改动)
#
# 删除: a
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# a.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
1.从暂存区删除a文件,再重新提交a.txt文件
[root@git git_data]# git rm --cached a
rm 'a'
[root@git git_data]# git status
# 位于分支 master
# 要提交的变更:
# (使用 "git reset HEAD <file>..." 撤出暂存区)
#
# 删除: a
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# a.txt
[root@git git_data]# git add a.txt
[root@git git_data]# git status
# 位于分支 master
# 要提交的变更:
# (使用 "git reset HEAD <file>..." 撤出暂存区)
#
# 重命名: a -> a.txt # 识别到a和a.txt相同为重命名
#
[root@git git_data]# git commit -m "commit mv a a.txt"
[master 62832d4] commit mv a a.txt
1 file changed, 0 insertions(+), 0 deletions(-)
rename a => a.txt (100%)
2.直接用git命令重命名
[root@git git_data]# git mv a.txt a # 同时修改工作区域和暂存区域的文件名称
[root@git git_data]# git status
# 位于分支 master
# 要提交的变更:
# (使用 "git reset HEAD <file>..." 撤出暂存区)
#
# 重命名: a.txt -> a
#
[root@git git_data]# git commit -m "commit mv a.txt a"
[master 47b2c38] commit mv a.txt a
1 file changed, 0 insertions(+), 0 deletions(-)
rename a.txt => a (100%)
- 查看
git status 只能查看区域状态的不同,不能查看文件内容的变化。
git diff 查看内容的不同
[root@git git_data]# echo aaa > a
# 默认比较本地工作目录和暂存区文件的不同
[root@git git_data]# git diff a
diff --git a/a b/a
index e69de29..72943a1 100644
--- a/a
+++ b/a
@@ -0,0 +1 @@
+aaa
# 提交a文件到暂存区域,再用git diff比较是相同的
[root@git git_data]# git add a
[root@git git_data]# git diff a
# 比较暂存区和本地仓库文件的不同
[root@git git_data]# git diff --cached a
diff --git a/a b/a
index e69de29..72943a1 100644
--- a/a
+++ b/a
@@ -0,0 +1 @@
+aaa
# 提交后在比对则暂存区和本地仓库内容相同
[root@git git_data]# git commit -m "modified a"
[master 6826ad1] modified a
1 file changed, 1 insertion(+)
[root@git git_data]# git diff --cached a
- 镜像和日志
[root@git git_data]# git commit # 相当于虚拟机的镜像,任何操作都被做了一次快照,可恢复到任意一个位置
# 位于分支 master
无文件要提交,干净的工作区
[root@git git_data]# git log # 查看当前版本前历史的git commit快照操作
commit 73240fc8e1202f480fc2461be360148399c7dfe1 # 哈希唯一标识的字符串
Author: wuqi <wuqi@qq.com> # 作者个人信息
Date: Fri Oct 23 10:35:49 2020 +0800 # 时间
commit modified a # -m 个人写的提交描述信息
commit 6826ad197467d19b8a76f2d96f5ead6b12c7e779
Author: wuqi <wuqi@qq.com>
Date: Fri Oct 23 10:28:57 2020 +0800
modified a
commit 47b2c381e2fcbdd4fa6893a368940ca7de7dc491
Author: wuqi <wuqi@qq.com>
Date: Fri Oct 23 10:26:12 2020 +0800
commit mv a.txt a
commit 62832d4a4602b7027054b3938e219981c6c05099
Author: wuqi <wuqi@qq.com>
Date: Fri Oct 23 10:25:02 2020 +0800
commit mv a a.txt
commit e187945735c774e0e041cced9c96647be8ad6cc0
Author: wuqi <wuqi@qq.com>
Date: Fri Oct 23 10:22:25 2020 +0800
commit deleted b
commit 034cb75378760cdd0f1c4a03561277f3d3b69622
Author: wuqi <wuqi@qq.com>
Date: Fri Oct 23 10:15:02 2020 +0800
commit newfile a
[root@git git_data]# git log --oneline # 一行简单的显示所有commit信息
73240fc commit modified a
6826ad1 modified a
47b2c38 commit mv a.txt a
62832d4 commit mv a a.txt
e187945 commit deleted b
034cb75 commit newfile a
[root@git git_data]# git log --oneline --decorate # 显示当前的指针位置
73240fc (HEAD, master) commit modified a
6826ad1 modified a
47b2c38 commit mv a.txt a
62832d4 commit mv a a.txt
e187945 commit deleted b
034cb75 commit newfile a
[root@git git_data]# git log -1 # 只显示最近一条提交日志的内容
commit 73240fc8e1202f480fc2461be360148399c7dfe1
Author: wuqi <wuqi@qq.com>
Date: Fri Oct 23 10:35:49 2020 +0800
commit modified a
[root@git git_data]# git log -p # 显示所有提交日志的详细改动信息
commit 73240fc8e1202f480fc2461be360148399c7dfe1
Author: wuqi <wuqi@qq.com>
Date: Fri Oct 23 10:35:49 2020 +0800
commit modified a
diff --git a/a b/a
index 72943a1..f761ec1 100644
--- a/a
+++ b/a
@@ -1 +1 @@
-aaa
+bbb
commit 6826ad197467d19b8a76f2d96f5ead6b12c7e779
:
- 恢复历史数据
1.只更改了本地目录
[root@git git_data]# echo "333" >> a # 添加新内容
[root@git git_data]# git status
# 位于分支 master
# 尚未暂存以备提交的变更:
# (使用 "git add <file>..." 更新要提交的内容)
# (使用 "git checkout -- <file>..." 丢弃工作区的改动) # 覆盖工作区的改动
#
# 修改: a
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
[root@git git_data]# git checkout -- a # 从暂存区覆盖本地工作目录
[root@git git_data]# git status
# 位于分支 master
无文件要提交,干净的工作区
[root@git git_data]# cat a
aaa
2.修改了本地目录且同时提交到了暂存区
[root@git git_data]# echo ccc >> a # 添加新内容
[root@git git_data]# git add . # 提交到暂存区
[root@git git_data]# git diff --cached # 比对暂存区和本地仓库的内容
diff --git a/a b/a
index 72943a1..959479a 100644
--- a/a
+++ b/a
@@ -1 +1,2 @@
aaa
+ccc
[root@git git_data]# git status
# 位于分支 master
# 要提交的变更:
# (使用 "git reset HEAD <file>..." 撤出暂存区)
#
# 修改: a
[root@git git_data]# git reset HEAD a # 本地仓库覆盖暂存区域
重置后撤出暂存区的变更:
M a
[root@git git_data]# git diff a
diff --git a/a b/a
index 72943a1..959479a 100644
--- a/a
+++ b/a
@@ -1 +1,2 @@
aaa
+ccc
[root@git git_data]# git diff --cached a
3.修改了工作目录且同时提交到了暂存区和本地仓库
[root@git git_data]# echo bbb >> a # 添加新内容
[root@git git_data]# git commit -m "add bbb"
[root@git git_data]# echo ccc >> a
[root@git git_data]# git commit -am "add ccc"
# 这时候发现改错代码了,想还原某一次提交的文件快照
[root@git git_data]# git log --oneline
59ba2a9 add ccc
dbead4c add bbb
4c57a60 modified a
5692532 rename a.txt a
7adfca0 commit a.txt
b4017a8 commit a
`Git服务程序中有一个叫做HEAD的版本指针,当用户申请还原数据时,其实就是将HEAD指针指向到某个特定的提交版本,但是因为Git是分布式版本控制系统,为了避免历史记录冲突,故使用了SHA-1计算出十六进制的哈希字串来区分每个提交版本,另外默认的HEAD版本指针会指向到最近一次提交的版本记录`
[root@git git_data]# git reset --hard 4c57a60
HEAD 现在位于 4c57a60 modified a
`刚刚的操作实际上就是改变了一下HEAD版本指针的位置,就是你将HEAD指针放在那里,那么你的当前工作版本就会定位在那里,要想把内容再还原到最新提交的版本,先看查看下提交版本号`
# 打开发现回退错了,应该回退到bbb版本
[root@git git_data]# cat a
aaa
# 这时候查看log没有commit bbb的历史了
[root@git git_data]# git log --oneline
4c57a60 modified a
5692532 rename a.txt a
7adfca0 commit a.txt
b4017a8 commit a
`怎么搞得?竟然没有了add bbb这个提交版本记录?`
`原因很简单,因为我们当前的工作版本是历史的一个提交点,这个历史提交点还没有发生过add bbb 更新记录,所以当然就看不到了,要是想"还原到未来"的历史更新点,可以用git reflog命令来查看所有的历史记录:`
# 使用git reflog 可查看总历史内容
[root@git git_data]# git reflog
4c57a60 HEAD@{0}: reset: moving to 4c57a60
59ba2a9 HEAD@{1}: commit: add ccc
dbead4c HEAD@{2}: commit: add bbb
4c57a60 HEAD@{3}: commit: modified a
5692532 HEAD@{4}: commit: rename a.txt a
7adfca0 HEAD@{5}: commit: commit a.txt
b4017a8 HEAD@{6}: commit (initial): commit a
# 然后使用reset回到bbb的版本内容下
[root@git git_data]# git reset --hard dbead4c
HEAD 现在位于 dbead4c add bbb
[root@git git_data]# cat a
aaa
bbb
git分支
分支即是平行空间,假设你在为某个手机系统研发拍照功能,代码已经完成了80%,但如果将这不完整的代码直接提交到git仓库中,又有可能影响到其他人的工作,此时我们便可以在该软件的项目之上创建一个名叫"拍照功能"的分支,这种分支只会属于你自己,而其他人看不到,等代码编写完成后再与原来的项目主分支合并下即可,这样即能保证代码不丢失,又不影响其他人的工作。
一般在实际的项目开发中,我们要尽量保证master分支是非常稳定的,仅用于发布新版本,平时不要随便直接修改里面的数据文件,而工作的时候则可以新建不同的工作分支,等到工作完成后在合并到master分支上面,所以团队的合作分支看起来会像上面图那样。
# 显示当前的指针位置
[root@git git_data]# git log --oneline --decorate
dbead4c (HEAD, master) add bbb # 默认分支指向你最后一次的提交 HEAD头、指针
4c57a60 modified a
5692532 rename a.txt a
7adfca0 commit a.txt
b4017a8 commit a
`HEAD 指针指向哪个分支、说明你当前在哪个分支下工作`
# 新建testing分支
[root@git git_data]# git branch testing
# 查看当前所有分支(* 当前分支)
[root@git git_data]# git branch
* master # *号在哪里就说明当前在哪个分支上入下图所示
testing
# 显示当前的指针位置
[root@git git_data]# git log --oneline --decorate
dbead4c (HEAD, testing, master) add bbb
4c57a60 modified a
5692532 rename a.txt a
7adfca0 commit a.txt
b4017a8 commit a
# 切换到testing分支、对应的HEAD指针也指向了testing
[root@git git_data]# git checkout testing
切换到分支 'testing'
# 查看当前所有分支(* 当前分支)
[root@git git_data]# git branch
master
* testing
[root@git git_data]# touch test
[root@git git_data]# git add .
[root@git git_data]# git commit -m "commit test"
# 切换到master分支后指针指向到了master
[root@git git_data]# git checkout master
切换到分支 'master'
[root@git git_data]# git branch
* master
testing
# 此时master是没有test文件的、保证master分支是线上环境的
[root@git git_data]# ll
总用量 4
-rw-r--r-- 1 root root 8 8月 23 08:42 a
[root@git git_data]# touch master
[root@git git_data]# git add .
[root@git git_data]# git commit -m "commit master"
# 合并分支 提示输入描述信息 相当于git的-m参数
[root@git git_data]# git merge testing
[root@git git_data]# git log --oneline --decorate
3258705 (HEAD, master) Merge branch 'testing'
f5ae1d8 commit master
ad4f25a (testing) commit test
dbead4c add bbb
4c57a60 modified a
5692532 rename a.txt a
7adfca0 commit a.txt
b4017a8 commit a
git合并冲突
相同文件相同行被不同分支修改,并提交到各自的本地仓库后,再合并分支时会发生合并冲突。
自动合并失败,不冲突的文件已经合并,冲突的文件自动标识到文件里,需要手动更改要保留的代码,然后再进行提交,这样就是最新的分支,可以直接删除其他的分支。
[root@git git_data]# echo "master" >> a
[root@git git_data]# git commit -am "modified a master"
[root@git git_data]# git checkout testing
切换到分支 'testing'
[root@git git_data]# git branch
master
* testing
[root@git git_data]# cat a
aaa
bbb
[root@git git_data]# echo "testing" >> a
[root@git git_data]# git commit -am "modified a on testing branch"
[root@git git_data]# git checkout master
[root@git git_data]# git merge testing
自动合并 a
冲突(内容):合并冲突于 a
自动合并失败,修正冲突然后提交修正的结果。
# 冲突的文件自动标识到文件里,手动更改要保留的代码
[root@git git_data]# cat a
bbb
<<<<<<< HEAD
master
=======
testing
>>>>>>> testing
# 然后再进行提交
[root@git git_data]# git commit -am "merge testing to master"
[root@git git_data]# git log --oneline --decorate
bba413d (HEAD, master) merge testing to master
34d7a55 (testing) modified a on testing branch
ec1a424 modified a master
3258705 Merge branch 'testing'
f5ae1d8 commit master
ad4f25a commit test
# 删除分支-d参数
[root@git git_data]# git branch -d testing
已删除分支 testing(曾为 34d7a55)。
[root@git git_data]# git branch
* master
# 创建并切换到分支testing
[root@git git_data]# git checkout -b testing
git标签
标签也是指向了一次commit提交,是一个里程碑式的标签,回滚打标签直接加标签号,不需要加唯一字符串,不好记。
# 默认给当前指定标签 -a 指定标签名字 -m 指定说明文字
[root@git git_data]# git tag -a v1.0 -m "aaa bbb master tesing version v1.0"
# 查看所有标签
[root@git git_data]# git tag
v1.0
# 为某一次的提交指定标签
[root@git git_data]# git tag -a v2.0 dbead4c -m "add bbb version v2.0"
# 查看所有标签
[root@git git_data]# git tag
v1.0
v2.0
# 查看v1.0提交日志的详细改动信息
[root@git git_data]# git show v1.0
tag v1.0
Tagger: wuqi <wuqi@qq.com>
Date: Mon Oct 26 09:53:35 2020 +0800
... ...
# 直接还原数据到v2.0
[root@git git_data]# git reset --hard v2.0
HEAD 现在位于 dbead4c add bbb
[root@git git_data]# ll
总用量 4
-rw-r--r-- 1 root root 8 8月 23 11:26 a
-rw-r--r-- 1 root root 0 8月 23 11:25 b
# 删除标签 -d参数
[root@git git_data]# git tag -d v2.0
# 默认情况下,git push不会把标签推送到远程服务器
# 把标签推送至指定远程分支
git push -u origin v1.0
# 把所有分支推送至指定远程分支
git push -u origin --tags
# 删除远程分支指定标签
git push -u origin :refs/tags/v1.0
git命令总结
git init # 初始化仓库
git status # 查看仓库的状态信息
git add file # 将新的文件提交到暂存区
git rm --cached file # 删除暂存的内容
git commit -m "newfile a" # 提交暂存区的内容到本地仓库
git commit -am "modifiled b.txt ->>cccc" # 如果仓库中已经存在当前文件 修改文件后 不需要提交到暂存区直接可以提交到本地仓库
git checkout --b # 将暂存区的文件覆盖工作目录
git rm -f b # 同时删除工作区域和暂存区域的内容
git mv b b.txt # 修改名称
git diff # 默认比较的是工作目录和暂存区
git diff --cached # 比对的是暂存区和本地仓库
git add . # 提交工作目录所有的文件到暂存区
git log # 查看当前版本下历史的所有commit提交
git log --oneline # 一行显示所有的commit提交
git log --oneline --decorate # 查看当前的指针位置
git log -1 # 显示最近的1条commit
git log -p # 显示所有改动过的内容详细信息
git log –stat -2 # stat简要显示数据增该行数,这样能够看到提交中修改过的内容,对文件添加或移动的行数,并在最后列出所有增减行的概要信息
git log –pretty=oneline # pretty根据不同的格式展示提交的历史信息(根据版本号与后面注释查找我们需要的文件)
git log –pretty=fuller # 以更详细的模式输出提交的历史记录(谁提交、提交时间、注释内容)
git log –pretty=fomat:“%h %cn” # 查看当前所有提交记录的简短SHA-1哈希字串与提交着的姓名 ,其他格式见备注(类似AWK切割内容,指定想要看的内容,显得方便,参数有固定语法)
git reflog # 查看所有的历史提交
git reset --hard 哈希值 # 回滚到指定版本
git reset --hard HEAD^ # 还原历史提交版本上一次
git reset --hard HEAD~5 # 用~的方式去数的话比较麻烦,还可指定前几个的数量
git branch # 查看当前的所有分支
git checkout dev # 切换到dev分支
git merge dev # 把dev的新的文件合并到master分支 第一次merge可能出现vim对话框 -m 填写描述信息 保存退出即可
git checkout -b dev # 创建并切换到dev分支
git tag # 查看当前所有的tag版本
git tag -a -m # 为当前的版本创建tag
git tag -a 哈希值 -m # 针对某个版本创建tag
git show v1.0 # 查看v1.0的详细信息
git tag -d v1.0 # 删除tag
Github使用
Github顾名思义是一个Git版本库的托管服务,是目前全球最大的软件仓库,拥有上百万的开发者用户,也是软件开发和寻找资源的最佳途径,Github不仅可以托管各种Git版本仓库,还拥有了更美观的Web界面,您的代码文件可以被任何人克隆,使得开发者为开源项贡献代码变得更加容易,当然也可以付费购买私有库,这样高性价比的私有库真的是帮助到了很多团队和企业。
首先
注册用户
创建仓库
快速设置
如果您之前已经做过这种事情
在桌面上设置
HTTP协议
https://github.com/用户名/local.git
SSH协议
git@github.com:用户名/local.git
需要主机
- 生成密钥对
- 推送公钥到Github
通过创建新文件或上载现有文件来开始使用。我们建议每个存储库都包括 README, LICENSE和.gitignore。
HTTP协议
命令行创建新的存储库
echo "# local" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
# 添加远程仓库名称origin 地址https://github.com/xian578/local.git
git remote add origin https://github.com/xian578/local.git
git push -u origin main
命令行推送现有存储库
git remote add origin https://github.com/xian578/local.git
git branch -M main
git push -u origin main
另一个存储库导入代码
您可以使用Subversion,Mercurial或TFS项目中的代码初始化此存储库。
SSH协议
# 创建密钥对
ssh-keygen
cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWkc1VP54A8eOvuaC93Jgee752t48WRnUZZsvFNLau7fDmr2uvOveVQkc0e4aQ... ... root@git
将公钥添加到你的github账户中
命令行创建新的存储库
echo "# local" >> README.md
git init
git add README.md
git commit -m "first commit"
# 添加远程仓库名称origin 地址git@github.com:xian578/local.git
git remote add origin git@github.com:xian578/local.git
git push -u origin master
# 推送本地仓库master分支到远程仓库origin
[root@git git_data]# git push -u origin master
Warning: Permanently added the RSA host key for IP address '192.30.255.113' to the list of known hosts.
Counting objects: 17, done.
Compressing objects: 100% (13/13), done.
Writing objects: 100% (17/17), 1.36 KiB | 0 bytes/s, done.
Total 17 (delta 0), reused 0 (delta 0)
To git@github.com:xian578/local.git
* [new branch] master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。
克隆HTTPS到本地
cd /tmp/
git clone https://github.com/xian578/local.git
注意:
低版本的系统存在版本问题提示
fatal: unable to access 'https://github.com/oldboylzy/oldboy.git/': Peer reports
incompatible or unsupported protocol version
升级版本即可
yum update -y nss curl libcurl
[root@git tmp]# cd local/
# 创建文件
[root@git local]# touch d
# 提交到暂存区
[root@git local]# git add .
# 提交到本地仓库
[root@git local]# git commit -m "add d"
# 修改配置文件为SSH协议
[root@git local]# sed -i '/url/c url = git@github.com:xian578/local.git' .git/config
# 提交到远程仓库
[root@git local]# git push -u origin master
[root@git local]# cd /root/git_data/
# 拉取远程仓库最新代码
[root@git git_data]# git pull
# 查看当前设置的远程仓库名
[root@git local]# git remote
origin
# 移除远程仓库origin
[root@git git_data]# git remote remove origin
Gitlab安装
GitLab简介
GitLab 是一个用于仓库管理系统的开源项目。使用Git作为代码管理工具,并在此基础上搭建起来的web服务。可通过Web界面进行访问公开的或者私人项目。它拥有与Github类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序(Wall)进行交流。它还提供一个代码片段收集功能可以轻松实现代码复用。
安装环境:
1、 CentOS 6或者7
2、 2G内存(实验)生产(至少4G)
3、 安装包:gitlab-ce-10.2.2-ce
4、 禁用防火墙,关闭selinux
安装依赖
yum install -y curl policycoreutils-python openssh-server
防火墙配置
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
systemctl reload firewalld
下载软件包
官方源:gitlab-ce-10.2.2-ce.0.el7.x86_64.rpm
国内镜像:gitlab-ce-10.2.2-ce.0.el7.x86_64.rpm
wget -O /opt/gitlab-ce-10.2.2-ce.0.el7.x86_64.rpm https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.2.2-ce.0.el7.x86_64.rpm
# 或者提前下好
cd /opt && rz -bye gitlab-ce-10.2.2-ce.0.el7.x86_64.rpm
安装软件包
rpm -ivh /opt/gitlab-ce-10.2.2-ce.0.el7.x86_64.rpm
或者
# 解决本地rpm包的依赖问题
yum localinstall -y /opt/gitlab-ce-10.2.2-ce.0.el7.x86_64.rpm
安装后自带开机自启动
配置
更改url地址为本机IP地址
sed -i "/^external_url.*/c external_url 'http://10.0.0.200'" /etc/gitlab/gitlab.rb
# 重新配置 请等待一段时间
gitlab-ctl reconfigure
浏览器访问登录
首次访问时,您将被重定向到密码重置屏幕。更改您的管理员帐户的密码,您将被重定向回登录屏幕。使用默认帐户的用户名root
登录。
目录
/opt/gitlab/ # 程序安装目录
/opt/gitlab/bin/ # 二进制文件目录
/var/opt/gitlab # 数据目录
/var/opt/gitlab/git-dfata # 存放仓库数据
/var/log/gitlab/ # 存放服务日志
命令
gitlab-ctl status # 查看目前gitlab所有服务运维状态
gitlab-ctl stop # 停止gitlab服务
gitlab-ctl stop nginx # 单独停止某个服务
gitlab-ctl start # 启动gitlab服务
gitlab-ctl tail # 查看所有服务的日志
Gitlab服务构成
nginx:静态web服务器
gitlab-workhorse: 轻量级的反向代理服务器
logrotate:日志文件管理工具
postgresql:数据库
redis:缓存数据库
sidekiq:用于在后台执行队列任务(异步执行)。(Ruby)
unicorn:An HTTP server for Rack applications,GitLab Rails应用是托管在这个服务器上面的。(Ruby Web Server,主要使用Ruby编写)
汉化
1、下载汉化补丁
[root@git ~]# git clone https://gitlab.com/xhang/gitlab.git
2、查看全部分支版本
[root@git ~]# cd gitlab && git branch -a
3、对比版本、生成补丁包
[root@git gitlab]# git diff remotes/origin/10-2-stable remotes/origin/10-2-stable-zh > ../10.2.2-zh.diff
4、停止服务器
[root@git gitlab]# gitlab-ctl stop
5、打补丁
[root@git gitlab]# patch -d /opt/gitlab/embedded/service/gitlab-rails -p1 < ../10.2.2-zh.diff
6、启动服务器和重新配置
[root@git gitlab]# gitlab-ctl start
[root@git gitlab]# gitlab-ctl reconfigure
Gitlab使用
OSS权限控制
给组分配项目管理权限
用户属于组, 拥有组的项目管理权限
登录成功后主页
配置外观
管理区域-外观
关闭注册
管理区域-设置-去掉注册使能的勾
创建组(四个路径)
管理区域-项目-创建组
设置组名称、描述、可见度等创建群组
创建项目(仓库)
管理区域-创建项目
配置SSH免密登录
# 创建密钥对
ssh-keygen
cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWkc1VP54A8eOvuaC93Jgee752t48WRnUZZsvFNLau7fDmr2uvOveVQkc0e4aQ... ... root@git
将公钥添加到你的gitlab账户中
命令行指令
Git全局设置
git config --global user.name "Administrator"
git config --global user.email "admin@example.com"
创建一个新的仓库
git clone git@10.0.0.200:oldboy/Local.git
cd Local
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master
现有资料夹
cd existing_folder
git init
git remote add origin git@10.0.0.200:oldboy/Local.git
git add .
git commit -m "Initial commit"
git push -u origin master
注意: 如果SSH不使用默认22端口时
cat > ~/.ssh/config <<EOF
## gitlab
Port 12345
EOF
现有的Git存储库
cd existing_repo
git remote rename origin old-origin
git remote add origin git@10.0.0.200:oldboy/Local.git
git push -u origin --all
git push -u origin --tags
创建用户
新用户第一次登录需要修改密码
dev用户登陆登录成功后只能看到空的仓库
添加用户入组
管理区域-选择创建的oldboy组-添加用户dev-权限给开发人员-增加用户到群组
注意: 新用户新主机需要配置SSH免密登录和命令行指令全局配置走一遍, 最后克隆仓库到本地, 进入仓库目录
推送代码到dev分支
git checkout -b dev
touch dev
git add .
git commit -m "add dev"
git push -u origin dev
提交合并请求
合并dev分支到master主分支
第一次, 进入仓库或者在仓库里刷新仓库页面, 右上角有蓝色的创建合并分支请求链接
以后. 在左侧边栏的合并分支请求中
dev用户可以自己审核分支合并请求, 这是不允许的. 因此需要保护分支
保护分支
此时合并dev分支再推送到master显示拒绝
[root@jenkins Local]# git checkout master
[root@jenkins Local]# git merge dev
更新 d669c23..a75f76b
Fast-forward
dev | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dev
[root@jenkins Local]# git push -u origin master
Total 0 (delta 0), reused 0 (delta 0)
remote: GitLab: You are not allowed to push code to protected branches on this project.
To git@10.0.0.200:oldboy/Local.git
! [remote rejected] master -> master (pre-receive hook declined)
error: 无法推送一些引用到 'git@10.0.0.200:oldboy/Local.git'
dev用户也不能审核分支合并请求, 只有root用户能审核
注意:
分支保护是针对项目的, 新增项目需要新增分支保护
合并后在gitlab服务端master上没有dev、要先进行pull
[root@git git_data]# git pull
Gitlab备份
对gitlab进行备份将会创建一个包含所有库和附件的归档文件。
对备份的恢复只能恢复到与备份时的gitlab相同的版本。
将gitlab迁移到另一台服务器上的最佳方法就是通过备份和还原。
gitlab提供了一个简单的命令行来备份整个gitlab,并且能灵活的满足需求。
备份文件将保存在配置文件中定义的backup_path
中,文件名为TIMESTAMP_gitlab_backup.tar
,
TIMESTAMP
为备份时的时间戳。TIMESTAMP的格式为:EPOCH_YYYY_MM_DD_Gitlab-version
。
如果自定义备份目录需要赋予git权限
配置前提:
cat >> /etc/gitlab/gitlab.rb <<EOF
gitlab_rails['backup_path'] = '/data/backup/gitlab'
# 备份保留的时间(以秒为单位,这个是七天默认值)
gitlab_rails['backup_keep_time'] = 604800
EOF
mkdir -p /data/backup/gitlab
chown -R git.git /data/backup/gitlab
gitlab-ctl reconfigure
执行:gitlab-rake gitlab:backup:create
生成一次备份。
[root@git ~]# gitlab-rake gitlab:backup:create
Dumping database ...
Dumping PostgreSQL database gitlabhq_production ... [DONE]
done
Dumping repositories ...
* web-site/frontend ... [DONE]
* web-site/frontend.wiki ... [SKIPPED]
* web-site/backend ... [SKIPPED]
* web-site/backend.wiki ... [SKIPPED]
* devops/accout ... [DONE]
* devops/accout.wiki ... [SKIPPED]
* devops/user ... [DONE]
* devops/user.wiki ... [SKIPPED]
* web-site/accout ... [DONE]
* web-site/accout.wiki ... [SKIPPED]
done
Gitlab恢复
停止数据写入服务
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq
检查两个写入数据的服务是否down掉
gitlab-ctl status
恢复备份
gitlab-reke gitlab:backup:restore BACKUP=源码备份文件名
注意不加.tar后缀,在备份目录找源码文件,文件在备份目录找,提示默认yes。
重启gitlab服务
gitlab-ctl restart
检查是否启动成功
gitlab-ctl status
说明:过一会再访问gitlab页面,才可看到恢复的仓库。
Jenkins
官网: https://www.jenkins.io/zh/
官网说明: https://www.jenkins.io/zh/doc/pipeline/tour/deployment/
Jenkins中文文档: https://www.w3cschool.cn/jenkins/
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。
安装配置
安装准备
- 两台服务器
- 关闭selinux和防火墙
- 内存2G
- 硬盘50G+
- 官网下载地址:http://pkg.jenkins.io/redhat-stable/
- 清华园下载地址:https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/
主机名 | IP |
---|---|
jenkins | 10.0.0.201 |
nexus | 10.0.0.202 |
安装JDK运行环境和jenkins服务
上传JDK和jenkins安装包
rz jenkins-2.176.1-1.1.noarch.rpm jdk-8u181-linux-x64.rpm
安装rpm包
rpm -ivh jdk-8u181-linux-x64.rpm
rpm -ivh jenkins-2.176.1-1.1.noarch.rpm
也可以直接yum安装java
yum -y install java
安装完JDK测试
[root@jenkins ~]# java -version
openjdk version "1.8.0_262"
OpenJDK Runtime Environment (build 1.8.0_262-b10)
OpenJDK 64-Bit Server VM (build 25.262-b10, mixed mode)
配置jenkins
# 查看jenkins所有文件
[root@jenkins ~]# rpm -ql jenkins
/etc/init.d/jenkins # 自带开机启动
/etc/logrotate.d/jenkins # 日志分隔配置文件
/etc/sysconfig/jenkins # jenkins 主配置文件,"端口","JENKINS_HOME"等都可以在这里配置
/usr/lib/jenkins # jenkins安装目录
/usr/lib/jenkins/jenkins.war # 升级直接替换该war包
/usr/sbin/rcjenkins # 二进制命令
/var/cache/jenkins # var包解压目录,jenkins网页代码目录
/var/lib/jenkins # 默认的JENKINS_HOME
/var/log/jenkins # Jenkins日志文件目录
# 查看jenkins配置文件目录, 刚安装是空的, 启动后就有文件了
[root@jenkins ~]# ll /var/lib/jenkins
# 修改启动用户为root
[root@jenkins ~]# sed -i '/^JENKINS_USER.*/c JENKINS_USER="root"' /etc/sysconfig/jenkins
启动jenkins
[root@CentOS7 ~]# systemctl start jenkins
访问浏览器解锁
解锁密码
cat /var/lib/jenkins/secrets/initialAdminPassword
插件安装
- 自动安装可选插件
- 手动下载插件上传安装
- 插件放入插件目录
跳过安装插件,直接上传插件到目录
两种方式都不使用, 右上角X跳过
修改登录密码
用户名默认admin
上传插件
[root@jenkins ~]# ll /var/lib/jenkins/
总用量 32
-rw-r--r-- 1 root root 1644 10月 26 17:22 config.xml
-rw-r--r-- 1 root root 156 10月 26 17:12 hudson.model.UpdateCenter.xml
-rw------- 1 root root 1712 10月 26 17:12 identity.key.enc
-rw-r--r-- 1 root root 7 10月 26 17:22 jenkins.install.InstallUtil.lastExecVersion
-rw-r--r-- 1 root root 7 10月 26 17:22 jenkins.install.UpgradeWizard.state
-rw-r--r-- 1 root root 171 10月 26 17:12 jenkins.telemetry.Correlator.xml
drwxr-xr-x 2 root root 6 10月 26 17:12 jobs # 每次构建后构建的结果目录
drwxr-xr-x 3 root root 19 10月 26 17:12 logs
-rw-r--r-- 1 root root 907 10月 26 17:12 nodeMonitors.xml
drwxr-xr-x 2 root root 6 10月 26 17:12 nodes
drwxr-xr-x 2 root root 6 10月 26 17:12 plugins # 插件目录
-rw-r--r-- 1 root root 64 10月 26 17:12 secret.key
-rw-r--r-- 1 root root 0 10月 26 17:12 secret.key.not-so-secret
drwx------ 4 root root 265 10月 26 17:12 secrets
drwxr-xr-x 2 root root 67 10月 26 17:12 updates
drwxr-xr-x 2 root root 24 10月 26 17:12 userContent
drwxr-xr-x 3 root root 56 10月 26 17:12 users
上传插件包解压到plugins下
[root@jenkins ~]# cd /var/lib/jenkins/
[root@jenkins jenkins]# rm -rf plugins
[root@jenkins jenkins]# rz jenkins_plugins.tar.gz
[root@jenkins jenkins]# tar xf jenkins_plugins.tar.gz
重启
[root@jenkins jenkins]# systemctl restart jenkins
注意: 如果要使用在线安装, 请先替换为国内源
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
主页 --> Manage Jenkins --> Manage Plugins --> 高级 --> 升级站点
创建项目
主页-->新建Item-->构建一个自由风格的软件项目-->确定-->配置-->保存
- 创建一个自由风格的项目freestyle-job
- 丢失旧的构建
构建
- 构建 --> 增加构建步骤 --> Execute shell --> 命令 --> 保存
执行shell命令
查看运行的当前路径pwd
构建后的项目存储在/var/lib/jenkins/workspace/
- 项目页面 --> 立即构建(Build Now)
手动运行一次构建
- 查看结果(控制台输出)
导入项目
在码云查找一个开源HTML页面的监控平台
复制HTTPS链接: https://gitee.com/kangjie1209/monitor.git
gitlab创建导入项目
复制SSH链接: git@10.0.0.200:oldboy/monitor.git
gitlab设置保护分支
部署web
web服务器安装nginx
启动并开机启动nginx
yum -y install nginx
systemctl start nginx
systemctl enable nginx
拉取代码
jenkins项目配置从git(gitlab)获取代码,由于我们dev用户是配置在jenkins上,已经配置过SSH免密钥登录,所以无需认证即可下载代码
注意: 请先在命令行测试gitlab获取代码,失败检查链接,SSH和公钥
手动构建
- 编写脚本
把 jenkins项目从gitlab仓库里获取的代码上传到web服务器站点目录下
[root@jenkins ~]# mkdir -p /server/scripts
[root@jenkins ~]# vi /server/scripts/deploy_rollback.sh
#!/bin/sh
DATE=$(date +%Y-%m-%d-%H-%M-%S)
CODE_DIR="$WORKSPACE"
WEB_DIR="/usr/share/nginx/"
tar_code(){
cd $CODE_DIR && tar zcf /opt/web-$DATE.tar.gz ./*
}
scp_code_to_web(){
scp /opt/web-$DATE.tar.gz 10.0.0.7:$WEB_DIR
}
tarxf_code(){
ssh 10.0.0.7 "cd $WEB_DIR && mkdir web-$DATE && tar xf web-$DATE.tar.gz -C web-$DATE ; rm -f web-$DATE.tar.gz"
}
ln_html(){
ssh 10.0.0.7 "cd $WEB_DIR && rm -rf html && ln -s web-$DATE html"
}
main(){
tar_code;
scp_code_to_web;
tarxf_code;
ln_html;
}
main
- jenkins访问web配置SSH免密钥登录
# 推送公钥
[root@jenkins ~]# ssh-copy-id -p 12345 -i ~/.ssh/id_rsa.pub root@10.0.0.7
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '[10.0.0.7]:12345 ([10.0.0.7]:12345)' can't be established.
ECDSA key fingerprint is SHA256:/DJPCv0JT3hZfTYlILAZFWeDYg5LRIpq5yLsk+TtAjU.
ECDSA key fingerprint is MD5:b1:cb:62:8e:61:68:68:60:bf:b3:eb:6b:3f:be:e6:a9.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@10.0.0.7's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -p '12345' 'root@10.0.0.7'"
and check to make sure that only the key(s) you wanted were added.
# 连接测试
[root@jenkins ~]# ssh -p12345 root@10.0.0.7
Last login: Tue Oct 27 09:10:49 2020
[root@web ~]#
- jenkins构建调用部署脚本(此处写脚本全路径)--> 保存
- 项目页面 --> 立即构建(Build Now)
查看控制台输出
- 浏览器查看验证
自动构建
常用于测试环境发布
- 项目配置-->启动自动触发构建, 复制URL: http://10.0.0.201:8080/project/freestyle_job
- 高级选项-->生成令牌-->复制令牌: 084bbfebc9a4259ffbf8abe3d39cb2f4
- gitlab设置-->集成-->配置-->增加web钩子
链接(URL): http://10.0.0.201:8080/project/freestyle_job
安全令牌: 084bbfebc9a4259ffbf8abe3d39cb2f4
- 克隆monitor代码后修改代码进行推送
[root@git ~]# git clone git@10.0.0.200:oldboy/monitor.git
# 更改代码
[root@git ~]# vim monitor/index.html
... ...
<a class="logo pull-left" href="index.html" style="width: 233px">移动能效管理</a>
... ...
[root@git ~]# cd monitor/
# 创建并切换到dev分支
[root@git monitor]# git checkout -b dev
M index.html
切换到一个新分支 'dev'
# 提交到本地仓库
[root@git monitor]# git commit -am "modified index.html"
[dev f3793f9] modified index.html
1 file changed, 1 insertion(+), 1 deletion(-)
# 提交到远程仓库dev分支
[root@git monitor]# git push -u origin dev
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 295 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote:
remote: To create a merge request for dev, visit:
remote: http://10.0.0.200/oldboy/monitor/merge_requests/new?merge_request%5Bsource_branch%5D=dev
remote:
To git@10.0.0.200:oldboy/monitor.git
* [new branch] dev -> dev
分支 dev 设置为跟踪来自 origin 的远程分支 dev。
- dev用户提交合并分支请求
- root用户审核请求
- jenkins自动构建
- 浏览器查看验证
自动创建Git标签
jenkins每次构建项目成功后给Git仓库打一个tag,以便下次构建出现问题可以及时通过tag恢复到上一个版本
- 源码管理-->Git-->高级-->Name(远程仓库ID)-->保存
- 构建后操作-->Git Publisher-->勾选"Push Only If Build Succeeds"-->配置-->保存
- 修改代码提交合并验证
[root@git monitor]# vim index.html
[root@git monitor]# git commit -am "modified index.html"
[root@git monitor]# git push -u origin dev
jenkins返回构建状态到gitlab
- gitlab生成个人访问令牌
gitlab-->用户设置-->访问令牌Access Tokens
复制令牌(只显示一次): VH33jTAXCTgNz9nHEPR9
- Jenkins配置令牌认证
主页-->系统管理(Manage Jenkins)-->系统设置(Configure System)-->Gitlab
添加凭据
- Jenkins项目配置构建后操作
- 修改代码提交合并验证
[root@git monitor]# vim index.html
[root@git monitor]# git commit -am "modified index.html"
[root@git monitor]# git push -u origin dev
从Gitlab的monitor仓库主页, 可以看到通过标志(绿色对号), 表示Jenkins项目构建成功
可以一路跳转到Jenkins项目流水线日志, 注意要登录Jenkins
参数化构建
- 安装插件Git Parameter
在Manage Jenkins-->插件管理(Manage Plugins)-->可选插件中
搜索Git Parameter 直接安装即可,已安装则忽略此步骤
- 示例: 项目配置-->General-->参数化构建过程(This project is parameterized)-->添加参数-->Multi-line String Parameter (文本参数) 和 Choice Parameter (选项参数)
清空或注释构建, 然后保存
执行的界面自动变为参数化构建
查看控制台
参数化构建就是自定义变量构建
参数化发布和回滚
常用于产品正式发布
通过tag传递参数实现代码发布和代码回滚的操作(需要git添加tag)
- 项目配置-->General-->参数化构建过程(This project is parameterized)-->添加参数-->Git Parameter 和 Choice Parameter (选项参数)
- 把源码管理的git拉取代码的
*/master
更改为变量$git_version
- 构建改回使用脚本, 保存
- 修改脚本, 添加参数判断语句
[root@jenkins ~]# vi /server/scripts/deploy_rollback.sh
#!/bin/sh
DATE="verison-$git_version"
CODE_DIR="$WORKSPACE"
WEB_DIR="/usr/share/nginx/"
tar_code(){
cd $CODE_DIR && tar zcf /opt/web-$DATE.tar.gz ./*
}
scp_code_to_web(){
scp /opt/web-$DATE.tar.gz 10.0.0.7:$WEB_DIR
}
tarxf_code(){
ssh 10.0.0.7 "cd $WEB_DIR && mkdir web-$DATE && tar xf web-$DATE.tar.gz -C web-$DATE ; rm -f web-$DATE.tar.gz"
}
ln_html(){
ssh 10.0.0.7 "cd $WEB_DIR && rm -rf html && ln -s web-$DATE html"
}
main(){
tar_code;
scp_code_to_web;
tarxf_code;
ln_html;
}
if [ "$deploy_env" == "deploy" ];then
main
elif [ "$deploy_env" == "rollback" ];then
ln_html
fi
- 当重复执行构建后会生成多个相同版本的文件,利用jenkins变量值解决重复性构建问题
jenkins变量
GIT_COMMIT
当前版本提交产生的哈希唯一值GIT_PREVIOUS_SUCCESSFUL_COMMIT
已经提交过的版本的哈希唯一值
使用以上两个值做比较,如果已提交则退出,如果没有提交过则继续执行构建
if [ "$deploy_env" == "deploy" ];then
if [ "$GIT_COMMIT" == "$GIT_PREVIOUS_SUCCESSFUL_COMMIT" ];then
echo "当前 $git_version 版本号已部署, 不允许重复构建"
else
main
fi
elif [ "$deploy_env" == "rollback" ];then
ln_html
fi
- 提交tag
[root@git monitor]# git log --oneline --decorate
[root@git monitor]# git tag -a v1.0 f6070e1 -m "tag v1.0"
[root@git monitor]# git tag -a v2.0 f3793f9 -m "tag v2.0"
[root@git monitor]# git tag -a v3.0 6ce246b -m "tag v3.0"
[root@git monitor]# git tag -a v4.0 57aa967 -m "tag v4.0"
[root@git monitor]# git push -u origin --tags
- 修改代码提交tag
[root@git monitor]# vim index.html
[root@git monitor]# git commit -am "modified index.html"
[root@git monitor]# git tag -a v5.0 -m "tag v5.0"
[root@git monitor]# git push -u origin v5.0
- 手动发布或回滚
此时每个标签相当于一个分支, 和master分支与分支保护没有关系了, 主要用于回滚, 和自动构建分开搭建。
如果想要配合自动构建, 构建后创建Git标签使用。
注意统一两个项目配置的标签格式一致:
Git Publisher 配置
Tag to push
v$BUILD_NUMBER.0
参数化构建脚本
deploy_rollback.sh
自动构建脚本
deploy.sh
[root@jenkins ~]# vi /server/scripts/deploy.sh
#!/bin/sh
DATE="v$BUILD_NUMBER.0"
CODE_DIR="$WORKSPACE"
WEB_DIR="/usr/share/nginx/"
tar_code(){
cd $CODE_DIR && tar zcf /opt/web-$DATE.tar.gz ./*
}
scp_code_to_web(){
scp /opt/web-$DATE.tar.gz 10.0.0.7:$WEB_DIR
}
tarxf_code(){
ssh 10.0.0.7 "cd $WEB_DIR && mkdir web-$DATE && tar xf web-$DATE.tar.gz -C web-$DATE ; rm -f web-$DATE.tar.gz"
}
ln_html(){
ssh 10.0.0.7 "cd $WEB_DIR && rm -rf html && ln -s web-$DATE html"
}
main(){
tar_code;
scp_code_to_web;
tarxf_code;
ln_html;
}
main
部署代码权限
- 修改jenkins进程用户为root
vim /etc/sysconfig/jenkins
... ...
JENKINS_USER=”jenkins”
... ...
- 将代码目录用户改为jenkins
mkdir /data/www -p
chown -R jenkins.jenkins /data/www
- 使用sudo授权
visudo
Maven
Maven是一个项目管理和综合工具。Maven提供给开发人员构建一个完整的生命周期框架。
开发团队可以自动完成该项目的基础设施建设,Maven使用标准的目录结构和默认构建生命周期。
Apache的开源项目主要服务于JAVA平台的构建、依赖管理、项目管理。
Project Object Model,项目对象模型。通过xml格式保存的pom.xml文件。该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。该文件是由开发维护,我们运维人员可以不用去关心。
安装到jenkins服务器
- 下载Maven 3安装包
官网:http://maven.apache.org/download.cgi
清华镜像:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/
- 安装Maven
tar xf apache-maven-3.3.9-bin.tar.gz
mv apache-maven-3.3.9 /usr/local/maven
# 加入环境变量
echo "PATH=\$PATH:/usr/local/maven/bin" >> /etc/profile
. /etc/profile
# 查看版本号
mvn -v
- 上传一个简单的java项目包hello-world.tar.gz并进行解压
tar xf hello-world-war.tar.gz
# 进入目录
cd hello-world-war
# 打包, 默认会去maven的中央仓库去下载需要的依赖包和插件到.m2目录下
mvn package
# 跳过测试用例打包
mvn package -Dmaven.test.skip=true
打包流程命令
validate(验证): 验证项目正确,并且所有必要信息可用。compile(编译): 编译项目源码
test(测试): 使用合适的单元测试框架测试编译后的源码。
package(打包): 源码编译之后,使用合适的格式(例如JAR格式)对编译后的源码进行打包。integration-test(集成测试): 如果有需要,把包处理并部署到可以运行集成测试的环境中去。verify(验证): 进行各种测试来验证包是否有效并且符合质量标准。
install(安装): 把包安装到本地仓库,使该包可以作为其他本地项目的依赖。
deploy(部署): 在集成或发布环境中完成,将最终软件包复制到远程存储库,以与其他开发人员和项目共享。
clean (清除) : 清除上次编译的结果
- 创建Maven私服nexus
① 安装Java
方式一: 安装rpm包
rpm -ivh jdk-8u181-linux-x64.rpm
方式二: 直接yum安装java
yum -y install java
安装完JDK测试
[root@jenkins ~]# java -version
openjdk version "1.8.0_262"
OpenJDK Runtime Environment (build 1.8.0_262-b10)
OpenJDK 64-Bit Server VM (build 25.262-b10, mixed mode)
注意统一Java版本
③ 解压,移动,配置,启动,开机自启动
tar xf nexus-3.13.0-01-unix.tar.gz
mv nexus-3.13.0-01 /usr/local/nexus
echo "PATH=\$PATH:/usr/local/nexus/bin" >> /etc/profile
. /etc/profile
nexus start
echo /usr/local/nexus/bin/nexus start >> /etc/rc.local && chmod +x /etc/rc.d/rc.local
④ 浏览器登录
用户名: admin 密码: admin123
⑤ 配置阿里云仓库源
找到类型为代理的中央仓库
修改源为阿里云源-->页面最下放 保存(Save)
http://maven.aliyun.com/nexus/content/groups/public
- 配置Maven仓库使用nexus源
① 在项目下的pom.xml配置,只在当前的项目生效
② 在maven下的settings.xml配置,在全局所有项目生效
# 在指定标签下插入配置项
# <servers> 标签,添加 Nexus 默认认证信息
# <mirrors> 标签,添加镜像
# <profiles> 标签,添加仓库信息
# <settings></settings>标签中, 添加 <activeProfiles> 标签,激活仓库
vim /usr/local/maven/conf/settings.xml
... ...
<servers>
... ...
<server>
<id>my-nexus-releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>my-nexus-snapshot</id>
<username>admin</username>
<password>admin123</password>
</server>
... ...
</servers>
... ...
<mirrors>
... ...
<mirror>
<!--This sends everything else to /public -->
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/nexus/content/groups/public/</url>
</mirror>
... ...
</mirrors>
... ...
<profiles>
... ...
<profile>
<id>nexus</id>
<!--Enable snapshots for the built in central repo to direct -->
<!--all requests to nexus via the mirror -->
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
... ...
<profiles>
<activeProfiles>
<!--make the profile active all the time -->
<activeProfile>nexus</activeProfile>
</activeProfiles>
... ...
- gitlab创建一个maven仓库
- git服务器上传java项目到maven仓库
tar xf hello-world-war.tar.gz
# 进入目录
cd hello-world-war
git init
git remote add maven git@10.0.0.200:oldboy/maven.git
git add .
git commit -m "Initial commit"
git push -u maven master
- Jenkins配置Maven集成
主页-->系统管理(Manage Jenkins)-->全局工具配置(Global Tool Configuration)-->Maven-->新增 Maven -->去掉自动安装的勾-->填写Name和手动安装 Maven 客户端的路径-->保存
- Jenkins新建maven项目
从gitlab上获取源码
不构建触发器
构建执行命令: 先清除 再打包
Goais and options
clean package
Post Steps --> add post-build step --> Execute shell --> 命令 --> 保存
远程推送war包
命令根据tomcat安装方式不同路径有所区别(见下文)
方法一
方法二
- 部署tomcat到web服务器
方法一 提前准备的包
rz apache-tomcat-8.0.27.tar.gz
tar zvxf apache-tomcat-8.0.27.tar.gz
mv apache-tomcat-8.0.27 /usr/local/tomcat
# tomcat启动加速的方法
sed -i '117c securerandom.source=file:/dev/urandom' /usr/java/jdk1.8.0_181-amd64/jre/lib/security/java.security
/usr/local/tomcat/bin/startup.sh
远程推送war包
ssh root@10.0.0.7 'rm -rf /usr/local/tomcat/webapps/*'
scp -rp target/*.war 10.0.0.7:/usr/local/tomcat/webapps/ROOT.war
方法二 yum
yum -y install tomcat
# tomcat启动加速的方法
sed -i '117c securerandom.source=file:/dev/urandom' /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.262.b10-0.el7_8.x86_64/jre/lib/security/java.security
systemctl start tomcat
systemctl enable tomcat
远程推送war包
ssh root@10.0.0.7 'rm -rf /usr/share/tomcat/webapps/*'
scp -rp target/*.war 10.0.0.7:/usr/share/tomcat/webapps/ROOT.war
- 执行构建-->浏览器访问 http://10.0.0.7:8080/
- 配置maven项目参数化发布和回滚
① 配置maven项目使用的参数
② 配置根据版本号进行拉取代码
③ 配置执行脚本 --> 保存
sh /server/scripts/maven.sh
④ java项目脚本
[root@jenkins ~]# vi /server/scripts/maven.sh
#!/bin/sh
DATE="v$BUILD_NUMBER.0"
CODE_DIR="$WORKSPACE"
# tomcat方法一安装
#WEB_DIR="/usr/local/tomcat/webapps"
#ln_java(){
# ssh root@10.0.0.7 "cd $WEB_DIR && rm -rf ROOT ROOT.war && ln -s java-${git_version} ROOT.war && /usr/local/tomcat/bin/shutdown.sh && /usr/local/tomcat/bin/startup.sh"
#}
# tomcat方法二安装
WEB_DIR="/usr/share/tomcat/webapps"
ln_java(){
ssh root@10.0.0.7 "cd $WEB_DIR && rm -rf ROOT ROOT.war && ln -s java-${git_version} ROOT.war && systemctl restart tomcat"
}
scp_code(){
scp target/*.war 10.0.0.7:$WEB_DIR/java-${git_version}
}
main(){
scp_code
ln_java
}
if [ "$deploy_env" == "deploy" ];then
if [ "$GIT_COMMIT" == "$GIT_PREVIOUS_SUCCESSFUL_COMMIT" ];then
echo "该 $git_version 版本号已部署, 不用重复部署"
else
main
fi
elif [ "$deploy_env" == "rollback" ];then
ln_java
fi
⑤ 提交三个tag版本v1.0和v2.0和v3.0
[root@git ~]# cd hello-world-war/
[root@git hello-world-war]# git tag -a v1.0 -m "v1.0"
[root@git hello-world-war]# git push -u maven v1.0
[root@git hello-world-war]# vim src/main/webapp/index.jsp
[root@git hello-world-war]# git commit -am "modified index.jsp"
[root@git hello-world-war]# git push -u maven master
[root@git hello-world-war]# git push -u maven master v2.0
[root@git hello-world-war]# vim src/main/webapp/index.jsp
[root@git hello-world-war]# git commit -am "modified index.jsp"
[root@git hello-world-war]# git tag -a v3.0 -m "v3.0"
[root@git hello-world-war]# git push -u maven master v3.0
⑥ 执行参数化构建--> 浏览器访问 http://10.0.0.7:8080/ 验证
扩展重Java项目
# 为jeesns项目准备好数据库jeesns,设置数据库root用户密码为root
yum installl mariadb-server -y
mysql_secure_installation
mysqladmin -uroot password 'root'
mysql -uroot -proot -e 'create database jeesns;'
yum install sshpass -y
sshpass -p123456 scp /opt/jeesns/jeesns-web/database/jeesns.sql root@10.0.0.12:/tmp
sshpass -p123456 ssh root@10.0.0.12 'mysql -uroot -proot jeesns </tmp/jeesns.sql'
提交两个tag版本v1.0和v2.0
vim jeesns-web/src/main/webapp/WEB-INF/templates/front/index.ftl
# 修改推荐阅读 为推荐阅读v1.0
代码质量检测SonarQube
- SonarQube基于java开发,需安装open JDK8版本
- SonarQube需要依赖MySQL数据库,至少5.6版本以上
- SonarQube的小型实例至少4G内存,如果大型实例需要16G内存
安装依赖软件
yum -y install git java unzip wget
安装数据库
安装数据库yum源
rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
安装MySQL5.6
yum -y --enablerepo=mysql56-community --disablerepo=mysql80-community install mysql-community-server
启动mysql
systemctl start mysqld
systemctl enable mysqld
如果端口监听到tcp6
netstat -tulnp
方法一: 修改配置文件并重启mysql
sed -i "/\[mysqld\]/a bind-address=0.0.0.0" /etc/my.cnf
systemctl restart mysqld
方法二: 关闭系统的tcp6并加载
cat >> /etc/sysctl.conf <<EOF
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
EOF
sysctl -p
配置数据库密码
mysqladmin -uroot passwd 123
创建sonar库
mysql -uroot -p123 -e "CREATE DATABASE sonar DEFAULT CHARACTER SET utf8;"
mysql -u root -p123 -e "show databases;"
安装SonarQube
下载sonar 社区版本
wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-8.5.1.38104.zip
或上传
rz sonarqube-7.0.zip
解压,移动,创建sonar用户并授权
unzip sonarqube-7.0.zip -d /usr/local/
mv /usr/local/sonarqube-7.0 /usr/local/sonarqube
useradd sonar
chown -R sonar.sonar /usr/local/sonarqube/
配置sonar连接本地数据库(去掉三条注释)
vim /usr/local/sonarqube/conf/sonar.properties
sonar.jdbc.username=root
sonar.jdbc.password=123
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewrieBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
使用普通用户sonar启动sonarqube
su - sonar -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start"
加入开机自启动
echo su - sonar -c \"/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start\" >> /etc/rc.local && chmod +x /etc/rc.d/rc.local
浏览器访问http://10.0.0.203:9000/about
登录
用户名admin 密码admin
生成tokin(只显示一次) root: eadcae17c5dc28b26a1e7612e37593a8ff21a669
选择配置, 设置项目名称
客户端推送操作
sonar-scanner \
-Dsonar.projectKey=a \
-Dsonar.sources=. \
-Dsonar.host.url=http://10.0.0.203:9000 \
-Dsonar.login=eadcae17c5dc28b26a1e7612e37593a8ff21a669
安装插件
- 安装中文汉化插件
在页面标题的配置(Quality Gates) --> 应用市场 --> 搜索框输入chinese
检出 chinese pack 插件,然后点击右侧 安装(install),安装完点击 重启(restart) 生效
注意: 默认已安装C JAVA Python PHP JS 等代码质量分析工具。
如果一个项目使用了JAVA CSS JS HTML,默认情况下sonar只会检测JAVA JS等代码的漏洞和bug。
只有安装了CSS HTML等插件,才会检测该项目代码中JAVA JS HTML CSS代码的漏洞和bug。
- 手动安装插件
移除原有插件目录 -->上传并解压已有插件目录备份包到原有插件目录 --> 授权用户sonar--> 以sonar用户重载sonar
mv /usr/local/sonarqube/extensions/plugins /usr/local/sonarqube/extensions/plugins_back
rz -bye sonar_plugins.tar.gz
tar xf sonar_plugins.tar.gz -C /usr/local/sonarqube/extensions
chown sonar.sonar -R /usr/local/sonarqube/extensions/plugins
su - sonar -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh restart"
下载客户端
jenkins服务器推送html代码至SonarQube检测
客户端其他版本下载地址
SonarScanner 4.0 https://docs.sonarqube.org/7.9/analysis/scan/sonarscanner/
直接在左侧边栏搜索对应版本
创建一个html项目
右键复制链接在jenkins服务器
下载客户端,解压,移动,配置
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.2.0.1873-linux.zip
unzip sonar-scanner-cli-4.2.0.1873-linux.zip
mv sonar-scanner-4.2.0.1873-linux /usr/local/sonar-scanner
cat > /usr/local/sonar-scanner/conf/sonar-scanner.properties <<EOF
#Configure here general information about the environment, such as SonarQube server connection details for example
#No information about specific project should appear here
#----- Default SonarQube server
sonar.host.url=http://10.0.0.203:9000
sonar.login=eadcae17c5dc28b26a1e7612e37593a8ff21a669
#----- Default source code encoding
sonar.sourceEncoding=UTF-8
EOF
命令行代码推送
- sonar Web
配置--> 权限 -->打开认证--> 保存
- jenkins服务器
进入项目目录-->推送代码
cd /var/lib/jenkins/workspace/freestyle_job
/usr/local/sonar-scanner/bin/sonar-scanner \
-Dsonar.projectKey=html \
-Dsonar.sources=.
简化推送命令
echo "PATH=\$PATH:/usr/local/sonar-scanner/bin" >> /etc/profile
. /etc/profile
- 页面查看
执行成功后的结果
- 推送java代码进行分析
方法1 使用sonar-scanner推送
cd /var/lib/jenkins/workspace/maven-job
sonar-scanner \
-Dsonar.projectKey=java \
-Dsonar.sources=.
方法2 使用推送
cd /var/lib/jenkins/workspace/maven-job
mvn sonar:sonar \
-Dsonar.host.url=http://10.0.0.203:9000 \
-Dsonar.login=eadcae17c5dc28b26a1e7612e37593a8ff21a669
集成sonar
将sonar集成到jenkins中,在测试环境自动发布前先推送到sonar进行检测
1)jenkins安装插件
jenkins需要安装SonarQube Scanner插件,前面手动安装插件包中已下载
2)jenkins配置SonarQube服务端
主页-->系统管理(Manage Jenkins)-->系统设置(Configure System)-->SonarQube servers
添加 SonarQube --> Name 随意填写 --> URL 添加SonarQube servers的地址 --> 保存
再进入SonarQube servers --> token添加 --> Jenkins
填写 --> secret text --> 之前安装SonarQube的Token --> ID --> 描述 --> 添加
选择凭据 --> 保存
- jenkins配置执行sonar-scanner命令的家目录,让jenkins能找到该命令
主页-->系统管理(Manage Jenkins)-->全局工具配置(Global Tool Configuration)-->SonarQube Scanner-->去掉自动安装的勾-->填写Name和手动安装sonar客户端的路径-->保存
- jenkins使用自动构建脚本
[root@jenkins ~]# vi /server/scripts/deploy_rollback.sh
#!/bin/sh
DATE=$(date +%Y-%m-%d-%H-%M-%S)
CODE_DIR="$WORKSPACE"
WEB_DIR="/usr/share/nginx/"
tar_code(){
cd $CODE_DIR && tar zcf /opt/web-$DATE.tar.gz ./*
}
scp_code_to_web(){
scp /opt/web-$DATE.tar.gz 10.0.0.7:$WEB_DIR
}
tarxf_code(){
ssh 10.0.0.7 "cd $WEB_DIR && mkdir web-$DATE && tar xf web-$DATE.tar.gz -C web-$DATE ; rm -f web-$DATE.tar.gz"
}
ln_html(){
ssh 10.0.0.7 "cd $WEB_DIR && rm -rf html && ln -s web-$DATE html"
}
main(){
tar_code;
scp_code_to_web;
tarxf_code;
ln_html;
}
main
- jenkins项目配置中增加构建项sonar
按住鼠标左键上下拖动调换两个Execute的位置
Analysis properties --> 保存
# 项目在sonarqube上的显示名称
# 项目的唯一标识ID,不能重复
# 项目的源码的位置,.表示当前目录
sonar.projectName=${JOB_NAME}
sonar.projectKey=html
sonar.sources=.
执行构建--> 在SonarQube中查看结果
- jenkins配置java项目
方法1 使用sonar客户端推送
增加构建项sonar --> Analysis properties 设置 --> 保存
sonar.projectName=${JOB_NAME}
sonar.projectKey=java
sonar.sources=.
注意: 如果需要class路径, 请添加参数
sonar.java.binaries
sonar.java.binaries=jeesns-service/target/sonar
方法2 使用maven推送
clean
verify
sonar:sonar
-Dsonar.host.url=http://10.0.0.203:9000
-Dsonar.login=eadcae17c5dc28b26a1e7612e37593a8ff21a669
Jenkins集成钉钉
项目发布结果通过钉钉的方式发送给运维人员
钉钉目前系统已关闭自定义功能,所以目前暂时无法使用状态,使用微信方式
- 实现简单
- 时时提醒
- 便于查看
- 邮件配置复杂
- 邮件容易被当做垃圾邮件被拒收
- 创建群组
- 添加机器人电脑端选择群设置->群智能助手->添加更多->自定义通过webhook接入自定义服务
Jenkins集成微信
git有新代码提交时会触发钩子自动完成上线,运维和开发人员不用时刻盯着jenkins,通过微信的方式给运维和开发人员发送结果。
- 注册微信企业公众号
搜索微信公众平台=->立即注册=->选择企业微信-->完善信息-->手机验证码-->微信扫二维码-->注册成功进入后台
- 应用管理->创建应用
上传图片-->填写应用名称-->可见范围-->创建应用
保存好
AgentId 1000002
Secret vccwlcoLvyzjIKIGmOTtIuvdPP7C8BsyubFWrcU7fhA
账户 LiZhenYa
我的企业--> 企业ID wwdda5a3fe8e107a73
后面要写入py脚本
- jenkins服务器使用脚本
cd /server/scripts/
rz jenkins_notify.py
更改py脚本内对应的内容
vim jenkins_notify.py
... ...
"touser" : "LiZhenYa",
... ...
"agentid" : 1000002,
... ...
Corpid = "wwdda5a3fe8e107a73"
Secret = "vccwlcoLvyzjIKIGmOTtIuvdPP7C8BsyubFWrcU7fhA"
... ...
之前没记住, 可以看下图去找
- jenkins安装插件
由于jenkins没有官网的插件来完成此功能,所以我们只能用网络上一些开源的插件(前面手动安装插件包中已下载)
wget https://github.com/daniel-beck/changelog-environment-plugin
cd changelog-environment-plugin-master
mvn verify
执行完成 当前目录下生成文件 target/changelog-environment.hpi
,上传到jenkins即可使用
- jenkins配置
jenkins项目配置-->构建环境-->勾选 Add Changelog Information to Environment
Entry Format
ChangeLog内容,时间,提交人
%3$s(at %4$s via %1$s)
Date Format
时间格式
yyyy-MM-dd HH:mm:ss
构建后操作-->增加构建后操作步骤-->Post build task
Post build task 选项依赖Hudson Post build task 插件(前面手动安装插件包中已下载)
jenkins服务器安装python requests模块
yum -y install python-pip
pip2.7 install requests -i https://pypi.mirrors.ustc.edu.cn/simple/
Script
echo "==========Start Notify=============="
echo ${SCM_CHANGELOG} > /tmp/${JOB_NAME}_change.log
python /server/scripts/jenkins_notify.py ${BUILD_URL} /tmp/${JOB_NAME}_change.log ${JOB_NAME}
rm -fv /tmp/${JOB_NAME}_change.log
SCM_CHANGELOG 变量依赖 Changelog Environment Plugin插件(前面手动安装插件包中已下载)
- 执行构建--> 在企业微信查看结果
变更日志就是提交的注释(git commit -am "merge testing to master"
)
Jenkins Pipeline
CI 持续集成
持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
比如(你家装修厨房,其中一项是铺地砖,边角地砖要切割大小。如果一次全切割完再铺上去,发现尺寸有误的话,浪费和返工时间就大了,不如切一块铺一块。这就是持续集成。)
CD 持续部署
持续部署(Continuous Deployment)是通过自动化的构建、测试和部署循环来快速交付高质量的产品。某种程度上代表了一个开发团队工程化的程度,毕竟快速运转的互联网公司人力成本会高于机器,投资机器优化开发流程化相对也提高了人的效率。
比如(装修厨房有很多部分,每个部分都有检测手段,如地砖铺完了要测试漏水与否,线路铺完了要通电测试电路通顺,水管装好了也要测试冷水热水。如果全部装完了再测,出现问题可能会互相影响,比如电路不行可能要把地砖给挖开……。那么每完成一部分就测试,这是持续部署。)
持续交付
持续交付(Continuous Delivery)频繁地将软件的新版本,交付给质量团队或者用户,以供评审尽早发现生产环境中存在的问题;如果评审通过,代码就进入生产阶段。
比如(全部装修完了,你去验收,发现地砖颜色不合意,水池太小,灶台位置不对,返工吗?所以不如每完成一部分,你就去用一下试用验收,这就是持续交付。)
敏捷思想中提出的这三个观点,还强调一件事:通过技术手段自动化这三个工作。加快交付速度。
在Jenkins流程稳定,不再需要修改后,再将流程写入pipeline,显示阶段视图,变量解析显示,方便查找问题。
- 什么是pipeline
Jenkins 2.0的精髓是Pipeline as Code,是帮助Jenkins实现CI到CD转变的重要角色。
什么是Pipeline,简单来说,就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程。Pipeline的实现方式是一套Groovy DSL,任何发布流程都可以表述为一段Groovy脚本,并且Jenkins支持从代码库直接读取脚本,从而实现了Pipeline as Code的理念。
- Pipeline 概念
Pipeline 是一个用户定义的 CD 流水线模式。Pipeline 代码定义了通常包含构建、测试和发布步骤的完整的构建过程。
Node
node 是一个机器,它是 Jenkins 环境的一部分,并且能够执行 Pipeline。同时,node 代码块也是脚本式 Pipeline 语法的关键特性。
Stage
Stage 块定义了在整个 Pipeline 中执行的概念上不同的任务子集(例如"构建","测试"和"部署"阶段),许多插件使用它来可视化或呈现 Jenkins 管道状态/进度。
Step
一项任务。从根本上讲,一个步骤告诉 Jenkins 在特定时间点(或过程中的"步骤")要做什么。例如,使用 sh step:sh 'make'
可以执行 make 这个 shell 命令。
- jenkins file
声明式 脚本式
脚本式语法格式:
pipeline{
agent any
stages{
stage("get code"){
steps{
echo "get code from scm"
}
}
stage("package"){
steps{
echo "packge code"
}
}
stage("deploy"){
steps{
echo "deploy packge to node1"
}
}
}
}
创建一个pipeline项目
① 直接在jenkins项目配置页面编写脚本式pipeline
执行构建-->查看结果
② jenkins项目配置页面从Gitlub仓库读取Jenkinsfile文件
在Gitlub仓库中创建一个Jenkinsfile文件
执行构建-->查看结果
③ 更改Gitlub仓库Jenkinsfile文件 --> 提交修改
pipeline{
agent any
stages{
stage("get code"){
steps{
echo "get code"
}
}
stage("unit test"){
steps{
sh '/usr/local/sonar-scanner/bin/sonar-scanner -Dsonar.projectKey=html -Dsonar.projectName=${JOB_NAME} -Dsonar.sources=.'
}
}
stage("package"){
steps{
sh 'tar zcf /opt/web-${BUILD_ID}.tar.gz ./* --exclude=./git --exclude=jenkinsfile'
}
}
stage("deploy"){
steps{
sh 'ssh 10.0.0.7 "cd /usr/share/nginx && mkdir web-${BUILD_ID}"'
sh 'scp /opt/web-${BUILD_ID}.tar.gz 10.0.0.7:/usr/share/nginx/web-${BUILD_ID}'
sh 'ssh 10.0.0.7 "cd /usr/share/nginx/web-${BUILD_ID} && tar xf web-${BUILD_ID}.tar.gz && rm -rf web-${BUILD_ID}.tar.gz"'
sh 'ssh 10.0.0.7 "cd /usr/share/nginx && rm -rf html && ln -s web-${BUILD_ID} /usr/share/nginx/html"'
}
}
}
}
执行构建-->查看结果
- 流水线语法
分布式构建
如果项目需要定期集成,同时每次集成都需要较长时间。如果都运行在master服务器上,会消耗过多资源,导致其他项目搁置无法集成,这时就需要在建立多台设备,并配置作为slave机器来为master提供负载服务。
slave端配置(nexus服务器)
- 安装java jdk git 并创建脚本目录
[root@nexus ~]# yum -y install java git
[root@nexus ~]# mkdir -p /server/scripts
- 配置SSH免秘钥认证
① 生成密钥对
ssh-keygen
② 拷贝slave端的公钥推送给web
ssh-copy-id -i .ssh/id_rsa.pub 10.0.0.7
③ ssh链接gitlab服务器获取known_hosts
ssh 10.0.0.200
注意: 如果SSH不使用默认22端口
④ 拷贝slave端的公钥上传至gitlab
cat .ssh/id_rsa.pub
⑤ 手动拉取测试
git clone git@10.0.0.200:oldboy/monitor.git
jenkins服务器配置
- 配置SSH免秘钥认证
拷贝jenkins的公钥推送给slave端
ssh-copy-id -i .ssh/id_rsa.pub 10.0.0.202
- 将jenkins上已配置好的 soanr-scanner 和 maven 目录 及脚本文件推送到slave端
scp -r /usr/local/sonar-scanner 10.0.0.202:/usr/local/
scp -r /usr/local/maven 10.0.0.202:/usr/local/
scp /server/scripts/* 10.0.0.202:/server/scripts/
ssh 10.0.0.202 'echo "PATH=\$PATH:/usr/local/sonar-scanner/bin:/usr/local/maven/bin" >> /etc/profile && . /etc/profile'
注意: 做软链接的要推送带版本号的目录!
- jenkins配置节点
主页-->系统管理(Manage Jenkins)-->节点管理(Manage Nodes)-->新建节点
填写节点名称-->勾选 Permanent Agent --> 确定
配置-->Jenkins凭据
描述 node1-10.0.0.202
并发构建数 2
远程工作目录 /home/jenkins
标签 node1
用法 尽可能的使用这个节点
配置jenkins私钥 --> 添加 --> 选择刚添加的凭据
[root@jenkins ~]# cat .ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAwRHJiUaAHhaDDcZbH20+/czGv/Ig/QwwORHarn0M2eGc0skW
... ...
-----END RSA PRIVATE KEY-----
配置从节点的工具目录
git
/usr/libexec/git-core/git
maven
/usr/local/maven
sonar
/usr/local/sonar-scanner
配置最终结果 --> 保存
- 配置成功后状态
- 同时执行多个构建测试
项目总结
项目经验:
代码自动化发布
项目需求:
运维配合开发测试占用大量的时间
快速实现CICD从而尽早发现代码或部署过程中存在的问题
使用参数化构建进行线上发布降低出错率、实现秒级回滚
发布结果通知相关人员
项目实现:
搭建Gitlab服务器并控制项目权限
搭建并配置Jenkins服务器
按项目需求创建
TAG项目(为MASTER主干打标签)
测试项目(快速CI CD及早发现问题并且配置自动触发不要运维干预)
JAVA项目(jenkins集成mvn编译并发布测试环境)
发布项目(利用tag标签进行线上发布和秒级回滚)
搭建SonarQube代码质量检测平台(Jenkins集成Sonar进行自动化代码分析检测)
搭建Nexus私服(java代码下载依赖快速编译)
编写Jenkins-pipeline流水线(看板方式快速定位问题)
Jenkins增加三台从节点实现分布式构建(提高项目的构建速度和稳定性)
Jenkins集成第三方插件发送构建结果到运维开发组
devops持续集成的更多相关文章
- 构建gitlab+Jenkins+harbor+kubernetes的DevOps持续集成持续部署环境
构建gitlab+Jenkins+harbor+kubernetes的DevOps持续集成持续部署环境 整个环境的结构图. 一.准备工作 gitlab和harbor我是安装在kubernetes集群外 ...
- DevOps - 持续集成(Continuous Integration)
1 - 持续集成简介 持续集成(Continuous integration,简称CI)是软件的开发和发布标准流程中最重要的部分. 作为一种开发实践,在CI中可以通过自动化等手段高频率地去获取产品反馈 ...
- DevOps - 持续集成
最近在担任公司部门的DevOps Champion的角色,一直觉得这个只是一个协调者的角色(而不是一个SME的角色),我的工作大概就是将每个项目的devops工具收集一下,然后用图表的形式去体现大家用 ...
- devops持续集成,Centos7.6下gitlab+jenkins(pipeline)实现代码自动上线
持续集成 gitlab+jenkins(pipeline)实现代码自动上线 环境准备:Centos7.6版本ip:192.168.0.13 主机名:gitip:192.168.0.23 主机名:jen ...
- 【下一代核心技术DevOps】:(五)微服务CI与Rancher持续集成
1. 引言 DevOps的核心魅力是快速的持续集成交付,降低研发和实施运维之间的交互,使得传统的各种扯皮现象统统消失.最重要的是降低成本 保障产品交付可靠性. 使用Rancher作为持续集成的关键环节 ...
- 03 持续集成和部署/基础设施 - DevOps之路
02 持续集成和部署/基础设施 - DevOps之路 文章Github地址,欢迎start:https://github.com/li-keli/DevOps-WiKi 服务的持续集成和部署这里有两套 ...
- [dotnet core]落地微服务特色的DevOps管道,持续集成/部署到kubernetes。
目录 前言 目标 工具 - 最小的学习成本 方案 - 愿景 1. 持续集成 - CI 2. 持续部署 - CD 部署环境 1. 部署gitlab-runner 2. 注册gitlab-runner 搭 ...
- 在推送提交之后阻止Azure DevOps (TFS)持续集成
在Azure DevOps服务器上配置生成定义时,可以配置连续集成(CI)生成.每次签入或提交到源代码库时都会自动运行一个CI构建.这种机制允许开发人员启动一个自动化的过程,例如编译和部署构建.这是一 ...
- Android Studio 集成 TFS,实现安卓移动开发的持续集成和交付(DevOps)
目录 1 集成TFS系统.... 1.1 概述.... 1.2 安装TFS插件.... 1.2.1 在线安装方式.... 1.2.2 离线安装方案.... 1.3 常见操作.... 1.3.1 新建G ...
随机推荐
- Sql注入--数字型手工测试
Sql注入--数字型手工测试 漏洞原因:是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的"数据"拼接到SQL语句中后,被当作SQL语句的一部分执行. 从而 ...
- 第15.45节、PyQt输入部件:QKeySequenceEdit快捷键输入部件简介和使用案例
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.功能简介 Key Sequence Edit输 ...
- 使用PyQt(Python+Qt)+动态编译36行代码实现的计算器
PyQt是基于跨平台的图形界面C++开发工具Qt加Python包装的一个GPL软件(GPL是GNU General Public License的缩写,是GNU通用公共授权非正式的中文翻译),Qt基于 ...
- 云服务器AWD平台搭建
开学后实验室来了几个新同学,在线上CTF方面大家一直在持续学习,但AWD模式的CTF我们练习并不多,所以准备搭建一个AWD平台用于实验室成员的线下赛攻防练习. 最开始的是防灾科技大学的线下AWD靶场: ...
- centos7最小安装后——网络配置、常见命令安装,远程连接、yum源安装软件包
安装环境 #软件:vmware 14 #centos版本:CentOS-7-x86_64-DVD-1810 下载地址: #网络配置:NAT模式 配置 网络配置 #动态获取ip: centos7最小安装 ...
- 对 精致码农大佬 说的 Task.Run 会存在 内存泄漏 的思考
一:背景 1. 讲故事 这段时间项目延期,加班比较厉害,博客就稍微停了停,不过还是得持续的技术输出呀! 园子里最近挺热闹的,精致码农大佬分享了三篇文章: 为什么要小心使用 Task.Run [http ...
- 深入理解Java虚拟机(七)——类文件结构
Java的无关性 由于计算机领域中有很多操作系统和硬件平台同时在竞争,所以,很多编程语言的程序设计会与其运行的平台和操作系统产生耦合,这样就大大增加了程序员的工作,为了适应不同的平台,需要修改很多代码 ...
- 如何理解group by语句
参考文章: https://blog.csdn.net/hao1066821456/article/details/69556644 如何实现一对多关系,得到一行多列的显示方式: group by可以 ...
- Android全面解析之Window机制
前言 你好! 我是一只修仙的猿,欢迎阅读我的文章. Window,读者可能更多的认识是windows系统的窗口.在windows系统上,我们可以多个窗口同时运行,每个窗口代表着一个应用程序.但在安卓上 ...
- Reflect个人记录
Reflect是一个内置方法,并不能通过构造函数的来进行构建 Reflect.construct: 与new操作父有一些类似,相当于new target(...) 例: 我们先自己定义一个类 clas ...