持续集成持续发布CICD

git

cvs和svn都是集中式版本控制系统,而git是分布式版本控制系统。

1、集中式版本控制系统必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,呵呵。分布式版本控制系统可以不连网工作, 因为版本库就在你自己的电脑上。

2、集中式版本控制系统如果中央服务器挂了,就完蛋了。分布式版本控制系统可以没有中央服务器,每个人的电脑上都是一个完整的版本库,可靠性高。分布式版本控制系统也可以有一台充当"中央服务器"的电脑,但这个服务器的作用仅仅是用来方便"交换"大家的修改,没有它大家也一样干活,只是交换修改不方便而已。

git的安装

官网: https://git-scm.com/

bash 复制代码
[root@vm1 ~]# yum install git -y
[root@vm1 ~]# git --version
git version 1.8.3.1
[root@vm1 ~]# git --help    查看参数帮助
git的操作可以说只需要git一条命令加参数即可

git应用

git身份设置

因为git是分布式版本控制系统,不同的人提交代码需要区分,所以每个人都要设置一个身份标识。如果不设置的话谁会知道你这个开发者是张三,李四,还是王五呢?

bash 复制代码
[root@vm1 ~]# git config --global user.name "daniel"
[root@vm1 ~]# git config --global user.email "daniel@itcast.cn"
[root@vm1 ~]# git config --global color.ui true

[root@vm1 ~]# git config --list
user.name=daniel
user.email=daniel@itcast.cn
color.ui=true
创建本地仓库

工作目录(working directory): 也可叫工作区,是存放项目代码文件的一个目录。

仓库(repository) : 也可叫版本库,在git init命令初始化工作目录后会产生一个隐藏的子目录.git, 可以将其理解为git的仓库或版本库。

仓库分为本地仓库与远程仓库。

创建本地仓库的步骤:

bash 复制代码
1. 创建工作目录
    [root@vm1 ~]# mkdir GitTest
2. 在对应的工作目录中创建本地仓库
    [root@vm1 ~]# cd GitTest/
    [root@vm1 GitTest]# git init
    Initialized empty Git repository in /root/GitTest/.git/
    会产生一个.git子目录,所有除代码数据外的相关数据都在此目录,不要修改它(它就是仓库或叫版本库)
    [root@vm1 GitTest]# ls .git/
    branches  config  description  HEAD  hooks  info  objects  refs

mkdir创建一个工作目录, 然后cd进去, 使用git init就创建好了本地仓库。开发者就可以在工作目录里开发项目代码文件了。

暂存区

暂存区(stage或index): 也有叫缓存区,暂存区就看作是一个缓区区域,临时保存你的改动。

如果在工作目录创建了一个新文件,需要将新文件添加到暂存区。

添加文件到暂存区:

bash 复制代码
1, 准备一个文件
    [root@vm1 GitTest]# cat 1.py 
    print("hello world")
2, 使用git add命令提交到暂存区(git rm --cached 1.py从暂存区移除但保留在工作目录中)
    [root@vm1 GitTest]# git add 1.py
3, 提交第一个文件后,版本库.git子目录里就多了一个index
    [root@vm1 GitTest]# ls .git/
    branches  config  description  HEAD  hooks  index  info  objects  refs
4, 使用strings命令查看可以看到git add的文件列表
    [root@vm2 GitTest]# strings .git/index 
    DIRC
    1.py				这里可以看到1.py文件添加到了index文件里了
git版本控制

提交文件(第1个版本)

代码文件需要commit提交后才能纳入版本控制。

bash 复制代码
1, 可以使用git status查看工作目录里有哪些文件需要提交
    [root@vm1 GitTest]# git status
    # On branch master
    #
    # Initial commit
    #
    # Changes to be committed:
    #   (use "git rm --cached <file>..." to unstage)
    #
    #	new file:   1.py
    #
2, 使用git commit提交; -m 后接提交的说明信息
    [root@vm1 GitTest]# git commit -m "提交1.py"
    [master (root-commit) 4e67190] 提交1.py
     1 file changed, 1 insertion(+)
     create mode 100644 1.py
3, 再次git status查看状态,没有需要提交的文件了
    [root@vm1 GitTest]# git status
    # On branch master
    nothing to commit, working directory clean


修改再提交(第2个版本)

bash 复制代码
1, 修改1.py文件,我这里加了一句print("hello python")
    [root@vm1 GitTest]# cat 1.py
    print("hello world")
    print("hello python")
2, 使用git status查看,信息告诉我们1.py被修改了
    [root@vm1 GitTest]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #	modified:   1.py
    #
    no changes added to commit (use "git add" and/or "git commit -a")
3, 使用git diff查看修改了什么
    [root@vm1 GitTest]# git diff 1.py
    diff --git a/1.py b/1.py
    index 8cde782..5da7641 100644
    --- a/1.py
    +++ b/1.py
    @@ -1 +1,2 @@
     print("hello world")
    +print("hello python")
4, 提交修改(add+commit)
    [root@vm1 GitTest]# git add 1.py
    [root@vm1 GitTest]# git commit -m "添加了一行代码打印hello python"
    [master 0e9371b] 添加了一行代码打印hello python
     1 file changed, 1 insertion(+)


再修改再提交(第3个版本)

bash 复制代码
再增加一句代码print("hello linux")
[root@vm1 GitTest]# cat 1.py
print("hello world")
print("hello python")
print("hello linux")

[root@vm1 GitTest]# git add 1.py

[root@vm1 GitTest]# git commit -m "添加了一行代码打印hello linux"
[master b679b01] 添加了一行代码打印hello linux
 1 file changed, 1 insertion(+)
  • 工作目录中写好的代码文件需要先git add 文件名添加到暂存区,再git commit 文件名提交。以后每次修改都要重复前两步。
  • git status查看工作目录中的状态
  • git diff 文件名查看文件修改了什么
查看提交历史
bash 复制代码
1, 使用git log查看提交的历史版本信息

    [root@vm1 GitTest]# git log
    commit b679b01f2ee42c1c4a7e14ed5d37e02da131a98e
    Author: daniel <daniel@itcast.cn>
    Date:   Wed Jan 16 14:00:44 2019 +0800
    
        添加了一行代码打印hello linux
    
    commit 0e9371bfdbc27049c31017773248ae8333b5bf3f
    Author: daniel <daniel@itcast.cn>
    Date:   Tue Jan 15 23:43:58 2019 +0800
    
        添加了一行代码打印hello python
    
    commit 4e67190ec3c57f1708702c9eca5aebe88017bdd2
    Author: daniel <daniel@itcast.cn>
    Date:   Tue Jan 15 23:23:26 2019 +0800
    
        提交1.py

2, 使用git log --pretty=oneline查看提交的历史版本信息, 查看的显示信息更简洁。

    前面字符串你可以看作就是一个版本号(commit id)。

    [root@vm1 GitTest]# git log --pretty=oneline
    b679b01f2ee42c1c4a7e14ed5d37e02da131a98e 添加了一行代码打印hello linux
    0e9371bfdbc27049c31017773248ae8333b5bf3f 添加了一行代码打印hello python
    4e67190ec3c57f1708702c9eca5aebe88017bdd2 提交1.py
版本回退与还原
bash 复制代码
1, 使用git reset --hard HEAD^回退到上一个版本(也就是第2个版本)

    [root@vm1 GitTest]# git reset --hard HEAD^
    HEAD is now at 0e9371b 添加了一行代码打印hello python
    
    [root@vm1 GitTest]# cat 1.py 
    print("hello world")
    print("hello python")

2, 使用git reset --hard 第3个版本号还原到第3个版本。

    但如果我忘了第3个版本号是什么了,使用git reflog查看所有的操作历史。

    [root@vm1 GitTest]# git reflog
    0e9371b HEAD@{0}: reset: moving to HEAD^
    b679b01 HEAD@{1}: commit: 添加了一行代码打印hello linux
    0e9371b HEAD@{2}: commit: 添加了一行代码打印hello python
    4e67190 HEAD@{3}: commit (initial): 提交1.py

3, 还原到第3个版本

    [root@vm1 GitTest]# git reset --hard b679b01
    HEAD is now at b679b01 添加了一行代码打印hello linux
    
    [root@vm1 GitTest]# cat 1.py 
    print("hello world")
    print("hello python")
    print("hello linux")

4, 回退到上上一个版本, 也就是回退两个版本,使用git reset --hard HEAD^^

回退三个版本,使用git reset --hard HEAD^^^, 以此类推。

如果回退100个版本,那用100个^符号不方便,可以换成git reset  --hard HEAD~100

    [root@vm1 GitTest]# git reset --hard HEAD^^
    HEAD is now at 4e67190 提交1.py
    
    [root@vm1 GitTest]# cat 1.py 
    print("hello world")
  • 提交后的代码文件,使用git log查看当前版本及以前的历史版本。
  • 使用git reset --hard HEAD^或者git reset --hard HEAD~100实现版本回退。
  • 使用git reflog查看提交的所有操作及版本号。
  • 使用git reset --hard 版本号,你可以自由的在不同版本之间来回切换。
    git工作流再次理解与应用拓展:
  • 工作目录里任何修改或增加的文件,都要git add到暂存区,让暂存区和工作目录的状态一致,这样才能提交一个版本。
  • git commit提交的是在暂存区里的所有文件状态。也就是说是整个工作目录里的状态保存为一个版本,而不是某一个文件。
  • git版本控制不仅仅是用于项目开发,你也可以用于一个软件包仓库的版本控制。
撤销修改
bash 复制代码
准备一行或一段写错的代码
[root@vm1 GitTest]# cat 1.py 
print("hello world")
print("hello python")
print("hello linux")
print("hey,xxx is a gay")		这是写错的代码,需要反悔

想要撤销修改有以下方法:

  • 直接把写错的代码删除就好, 但如果改变的代码很多,开发者自己都忘了具体改了哪些代码,这种做法就不方便了
  • 使用git checkout -- 文件名就可以直接撤销修改了
  • 如果写乱了代码,添加暂存区但还没有commit提交。使用git reset HEAD 文件名取消暂存区添加,再git checkout -- 文件名来撤销修改
  • 如果写乱了代码,添加暂存区并提交了。则使用版本回退。
误删恢复
bash 复制代码
1, 只要文件git add到了暂存区, 无论有没有git commit提交。误删除后都可以使用 git checkout -- 文件名来恢复。

    [root@vm1 GitTest]# touch 2.py
    [root@vm1 GitTest]# git add 2.py
    [root@vm1 GitTest]# rm  -rf 2.py
    [root@vm1 GitTest]# ls
    1.py
    [root@vm1 GitTest]# git checkout -- 2.py
    [root@vm1 GitTest]# ls
    1.py  2.py

2, 如果文件没有git add到暂存区, 误删除了就没了。

    [root@vm1 GitTest]# touch 3.py
    [root@vm1 GitTest]# rm -rf 3.py
    
    下面命令恢复报错
    [root@vm1 GitTest]# git checkout -- 3.py
    error: pathspec '2.py' did not match any file(s) known to git.
文件删除
bash 复制代码
1, 没有git add到暂存区的文件直接rm删除就ok

2, git add添加到暂存区,但没有git commit提交的文件。需要rm删除本地,还要git rm 文件名删除

    [root@vm1 GitTest]# touch 3.py
    [root@vm1 GitTest]# git add 3.py
    [root@vm1 GitTest]# rm -rf 3.py
    [root@vm1 GitTest]# git rm 3.py
    rm '3.py'

3,  git add添加到暂存区,并且已经git commit提交的文件。需要rm删除本地,再git rm 文件名删除,最后再提交删除

    [root@vm1 GitTest]# touch 3.py
    [root@vm1 GitTest]# git add 3.py
    [root@vm1 GitTest]# git commit -m "提交了3.py"
    [master 0236aef] 提交了3.py
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 3.py
    
    [root@vm1 GitTest]# rm -rf 3.py
    [root@vm1 GitTest]# git rm 3.py
    rm '3.py'
    [root@vm1 GitTest]# git commit -m "删除了3.py"
    [master dc4ee5e] 删除了3.py
     1 file changed, 0 insertions(+), 0 deletions(-)
     delete mode 100644 3.py

git分支管理

先来考虑一个问题: 开发者A开发软件的某一个功能模块, 还没有开发完成,但害怕进度丢失就提交。假设另一位开发者B并不知道A没有完成, 而直接使用了A开发的文件,这造成了问题。

解决方法: 开发者A创建一个属于自己的分支,这个分支只属于A,不会影响其他人。开发完成后,合并到项目主分支即可。
查看分支

bash 复制代码
默认只有一个master分支, 前面有*号的代表为当前分支。

    [root@vm1 GitTest]# git branch
    * master

创建分支

bash 复制代码
使用git branch 分支名来创建分支

    [root@vm1 GitTest]# git branch dev
    
    [root@vm1 GitTest]# git branch 
      dev
    * master

切换分支

bash 复制代码
使用git checkout 分支名来切换分支

    [root@vm1 GitTest]# git checkout dev
    Switched to branch 'dev'
    [root@vm1 GitTest]# git branch 
    * dev
      master

合并分支

bash 复制代码
1, 在dev分支上新开发了一个代码文件,添加并提交

    [root@vm1 GitTest]# git branch 
    * dev						确认为dev分支
      master
    
    [root@vm1 GitTest]# echo "new feature" > 5.py
    [root@vm1 GitTest]# git add 5.py
    [root@vm1 GitTest]# git commit -m "增加了新特性"
    [dev 4a0c78e] 增加了新特性
     1 file changed, 1 insertion(+)
     create mode 100644 5.py

2, 切换到master上分支后,却发现根本没有这个文件

    [root@vm1 GitTest]# git checkout master
    Switched to branch 'master'
    [root@vm1 GitTest]# cat 5.py 
    cat: 5.py: No such file or directory

3, 合并分支,再查看能在master分支上查看到了

    [root@vm1 GitTest]# git merge dev
    Updating dc4ee5e..4a0c78e
    Fast-forward
     5.py | 1 +
     1 file changed, 1 insertion(+)
     create mode 100644 5.py
     
    [root@vm1 GitTest]# cat 5.py 
    new feature

分支冲突

有些复杂的情况会造成冲突,这个时候git就不能帮我们自动的合并分支。我们就要手动处理冲突。

bash 复制代码
1, 在dev分支修改文件

    [root@vm1 GitTest]# git checkout dev
    Switched to branch 'dev'
    [root@vm1 GitTest]# echo "冲突测试" >> 5.py 
    [root@vm1 GitTest]# cat 5.py 
    new feature
    冲突测试

2, 提交dev分支上的修改

    [root@vm1 GitTest]# git add 5.py
    [root@vm1 GitTest]# git commit -m "冲突测试"
    [dev de5075c] 冲突测试
     1 file changed, 1 insertion(+)

3, 切回master分支,也修改相同的文件

    [root@vm1 GitTest]# git checkout master
    Switched to branch 'master'
    [root@vm1 GitTest]# echo "哈哈" >> 5.py 
    [root@vm1 GitTest]# cat 5.py 
    new feature
    哈哈

4, 提交master分支上的修改

    [root@vm1 GitTest]# git add 5.py
    [root@vm1 GitTest]# git commit -m "冲突测试"
    [master c17f325] 冲突测试
     1 file changed, 1 insertion(+)

5, 合并dev分支到master,就会出现冲突了

    [root@vm1 GitTest]# git merge dev
    Auto-merging 5.py
    CONFLICT (content): Merge conflict in 5.py
    Automatic merge failed; fix conflicts and then commit the result.

6, 手工解决冲突

git使用<<<<<<<<<,=========,>>>>>>>>符号分割冲突的内容,手动删除这些符号,并修改成你想要的内容

    解决冲突前:
    [root@vm1 GitTest]# cat 5.py 
    new feature
    <<<<<<< HEAD
    哈哈
    =======
    冲突测试
    >>>>>>> dev
    
    解决冲突后:
    [root@vm1 GitTest]# cat 5.py 
    new feature
    冲突解决

7, 解决冲突后添加并提交,最后再合并

    [root@vm1 GitTest]# git add 5.py
    [root@vm1 GitTest]# git commit -m "冲突解决"
    [master fb05c2f] 冲突解决
    [root@vm1 GitTest]# git merge dev
    Already up-to-date.

删除分支

使用git branch -d 分支名来删除分支。注意: 不能删除当前使用的分支

bash 复制代码
[root@vm1 GitTest]# git branch
  dev
* master

[root@vm1 GitTest]# git branch -d dev
Deleted branch dev (was de5075c).

[root@vm1 GitTest]# git branch
* master

windows版git(拓展)

windows上安装git











windows上使用git

github和gitlab

GitHub是目前最火的开源项目代码托管平台。它是基于web的Git仓库,提供公有仓库和私有仓库,但私有仓库是需要付费的。GitLab可以创建免费的私有仓库。GitLab是利用 Ruby开发的一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。它拥有与Github类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序(Wall)进行交流。它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。

github

注册github账号

github官网地址: https://www.github.com





登录注册账号时填写的邮箱,找到github发的邮件,打开并点击里面的Verify email address


创建项目

这样就创建好了第一个项目。

使用github远程仓库

第1步: 在gibhub上获取克隆地址

第2步: 克隆项目到本地linux,默认克隆到当前目录

bash 复制代码
[root@vm1 ~]# git clone https://github.com/linux-daniel/daniel_project.git
Cloning into 'daniel_project'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.

[root@vm1 ~]# ls daniel_project/
README.md

[root@vm1 ~]# cat daniel_project/README.md 
# daniel_project
教学测试项目

第3步: 提交代码文件

bash 复制代码
在克隆下来的仓库里准备一个代码文件
[root@vm1 ~]# cd daniel_project/
[root@vm1 daniel_project]# vim hello.py 
print("hello world")

[root@vm1 daniel_project]# git add hello.py
[root@vm1 daniel_project]# git commit -m "提交hello.py"
[master b59e1d6] 提交hello.py
 1 file changed, 1 insertion(+)
 create mode 100644 hello.py

第4步: 使用git push推送到github

bash 复制代码
[root@vm1 daniel_project]# git push -u origin master
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Username for 'https://github.com': linux-daniel					这里输入你的github账号名
Password for 'https://linux-daniel@github.com': 				再输入你的github密码
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 302 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/linux-daniel/daniel_project.git
   2ff4805..b59e1d6  master -> master

第5步: 回到github验证

使用下面的命令可以实现https的密码缓存(下次不用再输密码了)

bash 复制代码
 # git config --global credential.helper store

免密push

免密push其实就是利用了ssh免密登录的原理:

1.在本地产生空密码密钥对

2.本地保留私钥,把公钥给对方

3.实现本地到远程的免密

第1步: 开发者电脑产生ssh空密码密钥对

bash 复制代码
[root@vm1 daniel_project]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -C "root@daniel.cluster.com"  -N ""

第2步: 把公钥文件的内容复制到剪贴板

bash 复制代码
[root@vm1 daniel_project]# cat /root/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCz2rKSMbJwvdRN5VnsaRA0ydDDtm0ruTQY0ZVsynuj15RcFuKjrlYAEF3rU2AowL7n68xWabf3lC9l6WZjLa6cibfjW1wNnroPE2kzZADSoxcAAYxKVg/wkG2j5lPC4jJRPiSLg/yCyDA7go567ShvUCH8goMXMyMzKx1eIaU2nZoLnh7ulBv4URs5jPSE9kwhQ9MnUIzihQRvz9tqURYKIzmthSkm0CyXAlT6qufTdaNp/KmoH2Idj+rXufEsLF5qHD0lKaSM4bKZvqWNhd4a6XrF9DpoeSpeI63P3ZZkVTbmTSFgbBM8+KgxvGyUxfvjimo8Ed8TY5TGA6qC+g7F root@daniel.cluster.com

第3步: github上添加开发者的公钥



第4步: 获取ssh克隆方式地址

第5步: 开发者再git clone项目到本地

bash 复制代码
[root@vm1 ~]# rm daniel_project/ -rf
[root@vm1 ~]# git clone git@github.com:linux-daniel/daniel_project.git
Cloning into 'daniel_project'...
The authenticity of host 'github.com (13.229.188.59)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
RSA key fingerprint is MD5:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,13.229.188.59' (RSA) to the list of known hosts.
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 0), reused 3 (delta 0), pack-reused 0
Receiving objects: 100% (6/6), done.

第6步: 再准备一个新的代码文件, 添加并提交

bash 复制代码
[root@vm1 ~]# cd daniel_project/

我这里准备一个haha.py文件
[root@vm1 daniel_project]# cat haha.py 
print("haha")

[root@vm1 daniel_project]# git add haha.py
[root@vm1 daniel_project]# git commit -m "提交haha.py"
[master 2186bae] 提交haha.py
 1 file changed, 1 insertion(+)
 create mode 100644 haha.py

第7步: 这次再使用git push就会发现不需要输入账号密码了

bash 复制代码
[root@vm1 daniel_project]# git push

第8步: github上验证

小结: github有两种连接方式:

1.Clone with HTTPS

2.Clone with SSH(通过ssh免密密钥对实现免密push)
github分支(拓展)

第1步: 在github上创建一个新的dev分支

第2步: 开发者电脑的dev分支上开发,并上传到github的dev分支 (这里可以再次git clone,也可以直接在本地对应的创建dev分支,还可以git pull进行同步更新)

bash 复制代码
[root@vm1 daniel_project]# git pull
[root@vm1 daniel_project]# git branch dev
[root@vm1 daniel_project]# git checkout dev
Switched to branch 'dev'
[root@vm1 daniel_project]# echo "新功能" > new.py
[root@vm1 daniel_project]# git add new.py
[root@vm1 daniel_project]# git commit -m "增加了发红包功能"
[dev 2d38f8e] 增加了发红包功能
 1 file changed, 1 insertion(+)
 create mode 100644 new.py
[root@vm1 daniel_project]# git push -u origin dev
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 295 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To git@github.com:linux-daniel/daniel_project.git
   2186bae..2d38f8e  dev -> dev
Branch dev set up to track remote branch dev from origin.

第3步: 在github上创建pull request将dev分支的新代码merge到master分支



第4步: 验证最终效果

多人协作(拓展)

如果有多个开发者开发项目的话,如何代码合并呢?

clone与fork的区别:

clone: 任何人都可以下载作者的整个项目,但非作者不能push到作者的项目里(因为没有作者的账号密码)

fork:

张三fork了作者的项目,相当于可以下载作者的一个项目副本。

张三开发完后再上传到张三自己的账号里

张三请求合并到作者的账号项目里

作者可以同意或拒绝这个请求

第1步: 再申请一个github账号模拟第二位开发者(我这里新申请的账号为linux-daniel2),登录后查找linux-daniel第一位开发者的项目

第2步: 第二位开发者fork第一位开发者的项目,就会在自己的账号里得到项目代码的副本

第3步: 第二位开发者使用自己的电脑(这里我使用vm5来模拟)进行开发,然后上传

bash 复制代码
[root@vm5 ~]# git clone https://github.com/linux-daniel2/daniel_project.git
Cloning into 'daniel_project'...
remote: Enumerating objects: 13, done.
remote: Counting objects: 100% (13/13), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 13 (delta 1), reused 9 (delta 1), pack-reused 0
Unpacking objects: 100% (13/13), done.

[root@vm5 ~]# cd daniel_project/

[root@vm5 daniel_project]# git branch dev
[root@vm5 daniel_project]# git checkout dev
Switched to branch 'dev'

[root@vm5 daniel_project]# echo "分享功能" > new2.py
[root@vm5 daniel_project]# git add new2.py
[root@vm5 daniel_project]# git commit -m "增加了分享功能"

[root@vm5 daniel_project]# git push -u origin dev
Username for 'https://github.com': linux-daniel2
Password for 'https://linux-daniel2@github.com':
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 313 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/linux-daniel2/daniel_project.git
   2d38f8e..1c95bf2  dev -> dev
Branch dev set up to track remote branch dev from origin.

第4步: 第二位开发者确认开发的代码上传到自己的github仓库成功

第5步: 第二位开发者创建pull request将代码请求合并到第一位开发者的原项目里去

第6步: 回到第一位开发者的账号,对第二位开发者的请求进行合并确认


第7步: 因为是合并到原项目的dev分支,如果没问题的话,还需要合并到master分支。

最终结果图如下:

步骤小结:

开发者1为项目拥有者, 开发者2帮开发者1开发新功能

1.开发者2 fork 开发者1的项目(相当于copy一个副本)

2.开发者2使用git clone这个项目副本到自己的开发电脑

3.开发者2开发新功能,并push到项目副本

4.开发者2使用pull request将开发好的新功能请求合并到开发者1的项目仓库

5.开发者1确认

gitlab

gitlab下载


gitlab安装与配置

准备一台新虚拟机来安装(内存可适当调大点,比如1.5G)

bash 复制代码
安装

    [root@vm2 ~]# yum install -y policycoreutils-python
    [root@vm2 ~]# rpm -ivh gitlab-ce-11.8.2-ce.0.el7.x86_64.rpm

配置

    [root@vm2 ~]# vim /etc/gitlab/gitlab.rb
    13 external_url 'http://10.1.1.12'		修改成gitlab服务器的IP地址,对外服务

初始化

    [root@vm2 ~]# gitlab-ctl reconfigure			
    时间较久,需要3分钟左右时间,会自动帮助配置各个组件,并启动

查看状态

    [root@vm2 ~]# gitlab-ctl status	
    run: alertmanager: (pid 10563) 36s; run: log: (pid 10234) 64s
    run: gitaly: (pid 10343) 39s; run: log: (pid 9380) 163s
    run: gitlab-monitor: (pid 10417) 38s; run: log: (pid 10082) 80s
    run: gitlab-workhorse: (pid 10364) 39s; run: log: (pid 9835) 104s
    run: logrotate: (pid 9916) 93s; run: log: (pid 9952) 90s
    run: nginx: (pid 9876) 99s; run: log: (pid 9908) 96s
    run: node-exporter: (pid 10399) 38s; run: log: (pid 10003) 84s
    run: postgres-exporter: (pid 10585) 35s; run: log: (pid 10267) 60s
    run: postgresql: (pid 9499) 158s; run: log: (pid 9562) 157s
    run: prometheus: (pid 10452) 37s; run: log: (pid 10161) 70s
    run: redis: (pid 9275) 170s; run: log: (pid 9296) 169s
    run: redis-exporter: (pid 10426) 38s; run: log: (pid 10127) 74s
    run: sidekiq: (pid 9787) 111s; run: log: (pid 9808) 110s
    run: unicorn: (pid 9731) 117s; run: log: (pid 9781) 114s

gitlab登录

http://10.1.1.12 设置密码(密码需要最少8位)



gitlab设置

配置邮箱服务的用途:

账号注册时,邮件验证

有合并请求时,邮件通知

修改密码时,通过邮件修改





开发者设置ssh密钥

第1步: 在开发者电脑上产生空密码密钥

(注意:可以直接使用上面实验的github开发者的密钥,也可以模拟新的开发者重新产生,再做一遍。这里我们再做一次)

bash 复制代码
[root@vm1 ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -C "dev1@itcast.cn" -N ""

第2步: 查看并复制公钥

bash 复制代码
[root@vm1 ~]# cat /root/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAJW+LIFdcC0DI6oM6eOf6+EPks2ODyPaR/cAWKeFcfnSvuU84ZFYtziQyJYf1RdXwxo6vH+XyBNwOGrTLB1m33RvAgUznVhBH3KA9l1OimYSqEdQJ+4g+LVDkrgj/vIRc1dv7wDglyYGOOFfRftRK/QEHK911MOyJCK1nH0rr7eE7sP33aD6I6DoIfaSC0UUDPfwHDg/bQUDsF/ez4tEPOTSeJ2jVyytArHOAjtflL1+ZvP25F4osdSXju6IG8i7HHiZ0sz1WuQEYH8KzrY/zf8DBFrnOB4vl2UTNwP/NjT06TY78gKMJqcpf1maZR3YIeYlA03ccSOWSZuqq50eP dev1@itcast.cn

第3步: 在gitlab界面添加公钥


gitlab创建仓库

第1步: 在gitlab上创建项目(其实也就是存放代码的仓库)

第2步: 自定义项目名称,描述等

第3步: 验证创建好的项目

克隆远程仓库到本地

第1步: 查看gitlab上的帮助

第2步: 在开发者电脑上设置身份标识

bash 复制代码
[root@vm1 ~]# git config --global user.name "daniel"
[root@vm1 ~]# git config --global user.email "daniel@itcast.cn"
[root@vm1 ~]# git clone git@10.1.1.12:root/mywebsite.git

第3步: 在开发者电脑上使用git命令clone,并上传项目

bash 复制代码
[root@vm1 ~]# cd mywebsite/

[root@vm1 mywebsite]# echo "test web" > README.md
[root@vm1 mywebsite]# git add .
[root@vm1 mywebsite]# git commit -m "add README.md"

[root@vm1 mywebsite]# git push -u origin master

第4步: 验证

git 分布式版本控制工具

github和gitlab都属于远程仓库

git clone: 把远程仓库的项目代码下载到本地

git push: 把本地的项目代码上传到远程仓库

git pull: 把远程仓库的项目代码下载更新到本地

远程仓库两种访问方法:

http

ssh 使用空密码密钥做免密

持续集成(CI)

Continuous integration,简称CI,是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。

持续集成的目的不是减少build失败的次数,而是尽早发现问题,在最短的时间内解决问题,减少风险和浪费。从而让产品开发流程更加敏捷,缩短产品开发周期,在产品上线后,让用户用得更加顺畅。

在没有应用持续集成之前,传统的开发模式是项目一开始就划分模块,每个开发人员分别负责一个模块,等所有的代码都开发完成之后再集成到一起提交给测试人员,随着软件技术团队的发展,软件已经不能简单地通过划分模块的方式来开发,需要项目内部相互协作,划分模块这种传统的模式的弊端也越来越明显。由于很多bug在项目早期的设计、编码阶段就引入,到最后集成测试时才发现问题,开发人员需要花费大量的时间来定位bug,加上软件的复杂性,bug的定位就更难了,甚至出现不得不调整底层架构的情况。这种情况的发生不仅仅对测试进度造成影响,而且会拖长整个项目周期。

而持续集成可以有效解决软件开发过程中的许多问题,在集成测试阶段之前就帮助开发人员发现问题,从而可以有效的确保软件质量,减小项目的风险,使软件开发团队从容的面对各种变化。持续集成报告中可以体现目前项目进度,哪部分需要已经实现,哪些代码已经通过自动化测试,代码质量如何,让开发团队和项目组了解项目的真实状况。

持续交付(CD)

Continuous Delivery,简称CD,持续交付是指软件开发过程,从原始需求到最终产品开发过程中,较短周期内以需求的小颗粒度(小批量)频繁提交的过程。主要指集成后的代码在类生产环境(测试环境,预发布环境等)中测试并及时反馈的过程。

1.开发过程的快速迭代,小步快跑,及时纠正偏离主线

2.小颗粒度实现,避免颗粒度大,出现问题解决麻烦

3.迅速反馈软件功能,避免方向性错误

4.团队角色(含客户)协作密切,减少时间浪费

jenkins

Jenkins是一个可扩展的持续集成引擎,是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。Jenkins非常易于安装和配置,简单易用。

官网:https://jenkins.io/
jenkins下载


jenkins安装

准备一台服务器安装jenkins(我这里IP为10.1.1.13)

bash 复制代码
- 静态IP(要求能上外网)
- 主机名
- 关闭防火墙,selinux
- 时间同步
- 确认openjdk1.8版本已经安装,yum install java-1.8.0-openjdk-devel -y

    [root@jenkins_server ~]# java -version
    openjdk version "1.8.0_161"
    OpenJDK Runtime Environment (build 1.8.0_161-b14)
    OpenJDK 64-Bit Server VM (build 25.161-b14, mixed mode)
bash 复制代码
第1步: 将下载好的软件包拷贝到jenkins服务器上直接rpm命令安装

    [root@jenkins_server ~]# rpm -ivh jenkins-2.150.3-1.1.noarch.rpm

第2步: 启动服务并验证端口

    [root@jenkins_server ~]# systemctl start jenkins
    [root@jenkins_server ~]# chkconfig jenkins on
    
    [root@jenkins_server ~]# lsof -i:8080
    COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    java    4334 jenkins  163u  IPv6  45095      0t0  TCP *:webcache (LISTEN)

第3步: 查看密码文件里的密码(此为初始管理员用户admin的密码)。通过浏览器访问填上密码(地址为服务器ip的8080端口)

    [root@jenkins_server ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
    d750b101634b453b87deccfd06365fc9

注意,上述jenkins-2.150.3-1.1.noarch.rpm安装浏览器访问F12控制台报错503,就参考官网安装最新版jenkins

bash 复制代码
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
yum clean all && yum makecache
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.rpm
rpm -ivh jdk-21_linux-x64_bin.rpm
yum install jenkins -y
systemctl start jenkins
systemctl enable jenkins

卸载
rpm -qa |grep jenkins
rpm -e jenkins-2.150.3-1.1.noarch
yum remove jenkins-2.504.3-1.1.noarch -y
bash 复制代码
查看密码文件里的密码(此为初始管理员用户admin的密码)。通过浏览器访问填上密码(地址为服务器ip的8080端口)
    [root@jenkins_server ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
    d750b101634b453b87deccfd06365fc9




重启后页面变中文了

旧版本操作流程,jenkins-2.150.3-1.1.noarch.rpm,安装旧版本jenkins后浏览器访问F12控制台报错503,就卸载java环境重新安装java,rpm -qa | grep -i jdk,rpm -e java-1.8.0-openjdk-1.8.0.412.b08-1.el7_9.x86_64 java-1.8.0-openjdk-headless-1.8.0.412.b08-1.el7_9.x86_64,yum install java-1.8.0-openjdk-devel -y

第4步: 选择安装推荐的插件(如果是offline状态,或者报错找不到XXX插件,请参考下面的插件安装小节)

第5步: 创建新管理员用户(创建了新的管理员用户后,原来的admin用户就不能用了),也可直接使用初始管理员admin登录

第6步:确认访问地址

第7步: 进入jenkins主页面

退出登录的密码问题

1, log out登出后,再次登录使用admin用户, 密码为cat /var/lib/jenkins/secrets/initialAdminPassword得到字符串

2, 如果要修改密码,按下面图示操作:

3, 如果忘记密码, 按下面方法可以免出验证进行登录

bash 复制代码
[root@jenkins_server ~]# cp  /var/lib/jenkins/config.xml /备份目录/config.xml.bak
先备份一下

[root@jenkins_server ~]# vim /var/lib/jenkins/config.xml
打开此文件,然后把下面的一段注释(使用<!--  -->来注释)或删除

  8   <useSecurity>true</useSecurity>
  9   <authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy">
 10     <denyAnonymousReadAccess>true</denyAnonymousReadAccess>
 11   </authorizationStrategy>
 12   <securityRealm class="hudson.security.HudsonPrivateSecurityRealm">
 13     <disableSignup>true</disableSignup>
 14     <enableCaptcha>false</enableCaptcha>
 15   </securityRealm>

[root@jenkins_server ~]# systemctl restart jenkins
重启服务后,web访问就不需要密码验证了

插件安装(拓展)

1, 因为下载插件的官方在国外,网络可能会不稳定。如果在安装插件那一步出现offline或者找不到XXX插件的报错,可以换个网络试试。或者休息一下,换个时间再试。还不行可以试试下面的方法

bash 复制代码
[root@jenkins_server ~]# vim /var/lib/jenkins/hudson.model.UpdateCenter.xml

<?xml version='1.1' encoding='UTF-8'?>
<sites>
  <site>
    <id>default</id>
    <url>https://updates.jenkins.io/update-center.json</url>
  </site>
</sites>

把上面的https改为http的访问
保存后重启jenkins服务再尝试

2, 如果实在是无法下载插件,可以将别人下载好的插件打包给你,解压到/var/lib/jenkins/plugins/目录。需要重启jenkins服务,才能在web界面读取到解压的插件。

bash 复制代码
ls  /var/lib/jenkins/plugins/  (先清空删除此目录之前下载一半失败的插件)
tar -xf jenkins_plugins.tar -C /var/lib/jenkins/plugins/
systemctl restart jenkins

3, 可以在下面地址下载插件(插件为.hpi结尾的文件), 然后上传到jenkins(这种方法适合单个插件安装)

插件地址:http://updates.jenkins-ci.org/download/plugins

git+github+jenkins


开发者电脑准备

第1步: 在开发者电脑上安装git工具

bash 复制代码
[root@vm1 ~]# yum install git -y

第2步: 在开发者电脑上创建空密码密钥对

bash 复制代码
[root@vm1 ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -C "dev1@itcast.cn" -N ""

第3步: 在开发者电脑上查看并复制公钥

bash 复制代码
[root@vm1 ~]# cat /root/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+8f9vVJ8kskBojsxqaA95DQzLemCuA3o9nWE1sCjHHy/xxT4Ev57WbVCCPnCy3/pR49o5i7RE+5/dA4Ct+QXpj02pE2mPiehMIGFmjolhYFqIq7lnTSQ+zVtetIxnn2zmOx0qz+Zdr/wSCh/Czl7+Y2RClSq2sgD80/eF/uBpdlku2ejXAnIKFn3NekbqM4gYao/XTDLMW7D7pyQ0CFaI0xwEdXroy7ozAyFo76kvxs4IztAslcUeEj/CGha3WsLATRTeDNK5YGlI8jcw0WEcZocEhbS2RhkikQjACGgrae3WpJY/szH9BQeH8rIF2vR5s0DlPy9PJtBAxuUe8hJ/ dev1@itcast.cn

第4步: 将开发者公钥添加到github




github上新建项目仓库



开发者提交文件测试

第1步: 在github上获取ssh免密地址

第2步: 开发者电脑上设置开发者身份

bash 复制代码
[root@vm1 ~]# git config --global user.name "dev"
[root@vm1 ~]# git config --global user.email "dev@itcast.cn"
[root@vm1 ~]# git config --global color.ui true

第3步: clone项目到开发者本地电脑

bash 复制代码
[root@vm1~]# git clone git@github.com:linux-daniel/jenkins.git
Cloning into 'jenkins'...
The authenticity of host 'github.com (52.74.223.119)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
RSA key fingerprint is MD5:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,52.74.223.119' (RSA) to the list of known hosts.
warning: You appear to have cloned an empty repository.

第4步: 提交测试代码文件

bash 复制代码
[root@vm1 ~]# cd jenkins/
[root@vm1 jenkins]# echo "test" >> README.md

[root@vm1 jenkins]# git add README.md
[root@vm1 jenkins]# git commit -m "add README.md"

[root@vm1 jenkins]# git push -u origin master

第5步: github上验证

nginx服务器准备

在nginx服务器上安装nginx,并启动服务

bash 复制代码
[root@nginx ~]# yum install epel-release -y 
[root@nginx ~]# yum install nginx -y
[root@nginx ~]# systemctl start nginx
[root@nginx ~]# systemctl enable nginx

jenkins安装插件

jenkins图形确认安装git plugin和publish over ssh插件





配置jenkins通过publish over ssh免密连接nginx

第1步: 在jenkins服务器上生成空密码密钥对

bash 复制代码
[root@jenkins_server ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -C "jenkins-server@itcast.cn" -N ""

第2步: 查看并复制私钥

bash 复制代码
[root@jenkins_server ~]# cat /root/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAvWekHSkS23a/8kN6SkDTjFdcdw5zuupaVY9KJd2Ejnfg7/ZU
6fqOO1b8bAzYMkf8aKTcStKEwBWV6TYA/ljGG/6oAz1UGwBke/Sw6wASp7wN4MUQ
HQDeHKv+odPHuSloK47e3LrjzCssXYPrvNmzsLKXIzbmiGJNAZYznYMBtnDNxpiy
1L+4zQeSTOfT0MCbF/KTgbyffRCNHC/m8Ow89NF1XW37he3XV8wimM6NrGtndw1N
YVZMyx85xEsK9m2Wxee+P7KgIdL5nmbGJOBbTUi4dlt9j4T+mOxr4AF9oaZKS0o2
oJlJyyl9TKtHQM6d2Qw8BGXOGMDVSB8WT1Q5UwIDAQABAoIBAHsCS4iQu2mDBwhN
IKgG0B2OQ0QjQ7A6Ma7tn6dV5ZgtbQ4Lenx3OFZ7mPaHpQWK0PgZUeTaMlMZ8cGD
TEPj3c4ipnVsKCpdJ+WFNj15T6RWMuEuutdLT/VpEreA9m5f4QKhCEZsrjNUOr0F
R13gOZ5hblz1c+VRilekeCMtCTi1jKkDdVNFRcdQe8m8kttFVC2hSPB7tJxEoxmp
kAPkPBwU0E/6pA591JYCUk7lNQ9eBDgoBbb9cglEa4tn3Hh7AoyXcJTvYoC1vH1M
zN/1MLHyME76a/intrQM9frYwgM1gUdZU5i5kt4/SFQfd/qM8Axvy7s0qcFf5jxo
Ey4Ob4kCgYEA9HkCeBMexLZnVbZrDNiaapANdPafY9PILduZ9nVQmWh4rRcu47r0
D1V6yDtBS8+p/sPJu/4KYEn/8yDWHjxd3O194XaAKl9xgqUPP23txohp99pHy2mL
21eqthC0QKk2bH23jAQxjd0MAz5mK4uO1r/BFhSnJpK4i5/jVIHqm3cCgYEAxlXq
lqSruCYzwzMX/7Gv1lqexmUGmXiqQ4LWtOlQIaL+BoPOajp2mJjJMsIF1qkQwZnp
L+WdP02j7esBD1hI9G+lISCyqjTG+OCdNFiQ3SFJDZoLrcBN1uByjgANPleMiP9y
zq+xa+zBQ2YEtAEA8gp37QzfA2P6zihCNQqmUAUCgYEAgcrFHs635SQaFI12pClT
QgQcwN42nR9RBdezFAAQvIGUoADQ6iLVdFajiy66ae9kh1eXAPHMvHZNJt1mEENo
aeTEkjEBtn1ZnEzZnYlVVbQS3n3K5BmzIM6YWXTg3ft4Y30TN4j6biDPQeGdCL1d
JnJDpt9sJrR6udY3MSSQU90CgYEAnqnkvRaG+Q42opWhQUAYdtaP5g6ztNq++rsU
oC11mTMXHIcc/gY/EdxIOH7WxN8DNJ232kVKAnZOCerSMkBiPImEBHhv9ZG7CyZF
HLctTHlwQ51Ucm9A1gFAIzEPZywKlR4l7grHWJtSEGTwpj+XTgnp3o1JayD0Zy/1
pxEZ8zECgYEAnS/PHs+164GYPkWlYxGw04UE4SlQGa0QqT1WfctFPctU5PVqpwHi
imEFS+V89p1N+bQpgEI+WqlRGgODcjIE0ho8DqhsKaqu0AeVPN91Dgi20giJE8xo
TnYioS3qpxXtPiwrVR8PUZ/WZ/YtM0jwvYXowsSHeqVfCUBNGHqvwEA=
-----END RSA PRIVATE KEY-----

第3步: 在jenkins中添加ssh私钥

第4步: 在jenkins服务器上配置对nginx服务器的免密登录

bash 复制代码
[root@jenkins_server ~]# ssh-copy-id -i 10.1.1.14
10.1.1.14为nginx服务器的IP

第5步: 然后填写连接nginx信息,测试连接成功后保存

添加Jenkins服务器公钥到github

添加过程见上面

为jenkins服务器添加凭据

凭据是jenkins给自己的构建项目授权用的。

我们本项目案例里jenkins是通过ssh免密去找github的项目仓库clone或pull项目代码。

在前面的配置里已经把jenkins服务器的公钥添加到了github仓库上, 在jenkins服务器上root用户使用git clone 项目地址都可以成功。

但是jenkins服务本身并不允许使用自己的私钥去访问github的公钥, 给个凭据, 让它能做就解决问题了

总结: 凭据是一种和第三方程序(如github,gitlab等)通讯的权限授权。本案例的凭据就是允许使用ssh免密。你可以把这个凭据在jenkins里授予给任何需要ssh免密通讯的构建项目。

第1步: 在jenkins界面添加凭据



第2步: 添加凭据信息

bash 复制代码
[root@jenkins_server ~]# cat /root/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAvWekHSkS23a/8kN6SkDTjFdcdw5zuupaVY9KJd2Ejnfg7/ZU
6fqOO1b8bAzYMkf8aKTcStKEwBWV6TYA/ljGG/6oAz1UGwBke/Sw6wASp7wN4MUQ
HQDeHKv+odPHuSloK47e3LrjzCssXYPrvNmzsLKXIzbmiGJNAZYznYMBtnDNxpiy
1L+4zQeSTOfT0MCbF/KTgbyffRCNHC/m8Ow89NF1XW37he3XV8wimM6NrGtndw1N
YVZMyx85xEsK9m2Wxee+P7KgIdL5nmbGJOBbTUi4dlt9j4T+mOxr4AF9oaZKS0o2
oJlJyyl9TKtHQM6d2Qw8BGXOGMDVSB8WT1Q5UwIDAQABAoIBAHsCS4iQu2mDBwhN
IKgG0B2OQ0QjQ7A6Ma7tn6dV5ZgtbQ4Lenx3OFZ7mPaHpQWK0PgZUeTaMlMZ8cGD
TEPj3c4ipnVsKCpdJ+WFNj15T6RWMuEuutdLT/VpEreA9m5f4QKhCEZsrjNUOr0F
R13gOZ5hblz1c+VRilekeCMtCTi1jKkDdVNFRcdQe8m8kttFVC2hSPB7tJxEoxmp
kAPkPBwU0E/6pA591JYCUk7lNQ9eBDgoBbb9cglEa4tn3Hh7AoyXcJTvYoC1vH1M
zN/1MLHyME76a/intrQM9frYwgM1gUdZU5i5kt4/SFQfd/qM8Axvy7s0qcFf5jxo
Ey4Ob4kCgYEA9HkCeBMexLZnVbZrDNiaapANdPafY9PILduZ9nVQmWh4rRcu47r0
D1V6yDtBS8+p/sPJu/4KYEn/8yDWHjxd3O194XaAKl9xgqUPP23txohp99pHy2mL
21eqthC0QKk2bH23jAQxjd0MAz5mK4uO1r/BFhSnJpK4i5/jVIHqm3cCgYEAxlXq
lqSruCYzwzMX/7Gv1lqexmUGmXiqQ4LWtOlQIaL+BoPOajp2mJjJMsIF1qkQwZnp
L+WdP02j7esBD1hI9G+lISCyqjTG+OCdNFiQ3SFJDZoLrcBN1uByjgANPleMiP9y
zq+xa+zBQ2YEtAEA8gp37QzfA2P6zihCNQqmUAUCgYEAgcrFHs635SQaFI12pClT
QgQcwN42nR9RBdezFAAQvIGUoADQ6iLVdFajiy66ae9kh1eXAPHMvHZNJt1mEENo
aeTEkjEBtn1ZnEzZnYlVVbQS3n3K5BmzIM6YWXTg3ft4Y30TN4j6biDPQeGdCL1d
JnJDpt9sJrR6udY3MSSQU90CgYEAnqnkvRaG+Q42opWhQUAYdtaP5g6ztNq++rsU
oC11mTMXHIcc/gY/EdxIOH7WxN8DNJ232kVKAnZOCerSMkBiPImEBHhv9ZG7CyZF
HLctTHlwQ51Ucm9A1gFAIzEPZywKlR4l7grHWJtSEGTwpj+XTgnp3o1JayD0Zy/1
pxEZ8zECgYEAnS/PHs+164GYPkWlYxGw04UE4SlQGa0QqT1WfctFPctU5PVqpwHi
imEFS+V89p1N+bQpgEI+WqlRGgODcjIE0ho8DqhsKaqu0AeVPN91Dgi20giJE8xo
TnYioS3qpxXtPiwrVR8PUZ/WZ/YtM0jwvYXowsSHeqVfCUBNGHqvwEA=
-----END RSA PRIVATE KEY-----


jenkins任务创建

第1步: 创建新任务

第2步: 自定义任务名称与风格

第3步: 自定义任务描述

第4步: 定义源码管理

第5步:定义构建方法

第6步: 定义构建的源码,目标主机和目标目录

第7步: 设置完毕,保存,并验证


手动构建

第1步: 立即构建

第2步: 在workspace工作区间查看

第3步: 查看控制台输出信息

第4步: nginx服务器上验证文件是否被传到nginx家目录

bash 复制代码
[root@nginx ~]# ls /usr/share/nginx/html/
404.html  index.html      poweredby.png
50x.html  nginx-logo.png  README.md
可以看到README.md被传过来了

自动发布系统


Gitlab上创建自动构建仓库

第1步: gitlab上创建新仓库

第2步: 自定义项目名称等

第3步: 确认创建成功

在开发者电脑clone创建好的项目,进行开发(开发者要产生ssh空密码密钥对,把公钥添加到gitlab)

bash 复制代码
# git clone git@10.1.1.12:root/auto_build_web.git
# cd auto_build_web

jenkins安装对应插件

jenkins安装gitlab与gitlab hook插件


添加Jenkins服务器公钥到gitlab

第1步: jenkins产生root用户的ssh空密码密钥对

bash 复制代码
[root@jenkins_server ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -C "jenkins_server@itcast.cn" -N ""
[root@jenkins_server ~]# cat /root/.ssh/id_rsa.pub

添加公钥到gitlab

第2步: 复制gitlab上自动发布项目地址

第3步: 在jenkins服务器上克隆仓库,确认连接OK

bash 复制代码
[root@jenkins-server ~]# git clone git@10.1.1.12:root/auto_build_web.git
Cloning into 'auto_build_web'...
The authenticity of host '10.1.1.12 (10.1.1.12)' can't be established.
ECDSA key fingerprint is SHA256:Sp1FZaHscluT1mTIKFUiFQPoqcsSL2urGiujjlUN4lE.
ECDSA key fingerprint is MD5:8b:95:f9:83:8c:ea:e8:43:e4:58:36:9b:8f:c5:ba:96.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.1.1.12' (ECDSA) to the list of known hosts.
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

jenkins创建自动构建任务

凭据使用的是上面实验的凭据(如果ssh密钥对重新产生了,就需要重配置凭据)






注意: 执行此脚本不再是使用publish over ssh插件,而是使用jenkins服务器上的jenkins用户来执行的

bash 复制代码
#!/bin/bash

#源目录为jenkins存放任务文件的目录 
SOURCE_DIR=/var/lib/jenkins/workspace/$JOB_NAME/
#目标目录为nginx服务器的家目录
DEST_DIR=/usr/share/nginx/html
#使用rsync同步源到nginx服务器家目录(需要免密登录),IP为nginx服务器IP
/usr/bin/rsync -av --delete $SOURCE_DIR root@10.1.1.14:$DEST_DIR

问题: 既然是使用jenkins服务器上的jenkins用户来执行,为什么rsync不传给10.1.1.14的jenkins用户,而是传给它的root用户?

答: 因为10.1.1.14上没有jenkins用户,就算有jenkins用户,对/usr/share/nginx/html也没有写权限。
配置jenkins服务器上的jenkins用户

bash 复制代码
[root@jenkins-server ~]# grep jenkins /etc/passwd
jenkins:x:988:982:Jenkins Automation Server:/var/lib/jenkins:/bin/false

[root@jenkins-server ~]# usermod -s /bin/bash jenkins

[root@jenkins-server ~]# grep jenkins /etc/passwd
jenkins:x:988:982:Jenkins Automation Server:/var/lib/jenkins:/bin/bash
bash 复制代码
[root@jenkins-server ~]# su - jenkins
-bash-4.2$ ssh-keygen -t rsa -C "jenkins user" -N ""

-bash-4.2$ ssh-copy-id -i root@10.1.1.14

jenkins全局安全配置


配置gitlab允许本地网络使用webhook

gitlab默认在本地网络不能使用webhook,所以需要我们配置允许(注意要使用管理员配置,普通用户看不到下图的扳手图标)




为gitlab自动构建项目添加webhook




代码自动发布测试

开发者电脑上使用git提交测试文件(确认前面clone过项目仓库)

bash 复制代码
[root@vm1 ~]# cd auto_build_web/
[root@vm1 auto_build_web]# echo "auto_build_web" > index.html
[root@vm1 auto_build_web]# git add index.html
[root@vm1 auto_build_web]# git commit -m "add index.html"
[root@vm1 auto_build_web]# git push -u origin master

在nginx服务器上验证

bash 复制代码
[root@nginx ~]# cat /usr/share/nginx/html/index.html 
auto_build_web


pycharm与自动发布系统结合(拓展)

开发者开发代码一般会使用IDE集成开发工具(比如pycharm这种),那么使用pycharm开发的代码能否直接利用自动发布系统发布到业务服务器上呢? 答案是肯定的。

这次使用windows模拟开发者电脑









nginx服务器上测试验证

bash 复制代码
[root@nginx ~]# cat /usr/share/nginx/html/index.html 
auto_build_web
pycharm测试
相关推荐
LCG元6 小时前
基于MCP的CI/CD流水线:自动化部署到云平台的实践
运维·ci/cd·自动化
鼠鼠我捏,要死了捏6 小时前
生产环境CI/CD流水线构建与优化实践指南
ci/cd·devops·流水线
老马啸西风2 天前
maven 发布到中央仓库之 Ignore Licence-04
java·ci/cd·maven
hwj运维之路4 天前
GitOps实践指南:GitLab CI/CD + ArgoCD 实现 Kubernetes 自动化部署
ci/cd·gitlab·argocd
qinyia4 天前
利用Wisdom SSH高效搭建CI/CD工作流
运维·ci/cd·ssh
尤达c5 天前
Jenkins on Mesos 高可用高并发部署
运维·ci/cd·devops
裁二尺秋风5 天前
CI/CD — DevOps概念之实现k8s持续交付持续集成(一)
ci/cd·kubernetes·devops
少女续续念7 天前
2025年 CI/CD 流水线对比:国产化 DevSecOps 谁主沉浮?
ci/cd
裁二尺秋风9 天前
CI/CD — Pipeline的使用以及Blue Ocean多分支流水线的使用方法
ci/cd·gitlab·jenkins