生成公钥和私钥并填入仓库

#输入ssh-keygen -t rsa -C "user@email.com",然后回车几次,会生成 id_rsa.pub 文件和 id_rsa 文件,分别存放公钥和私钥:

1
2
3
4
5
6
7
8
9
10
ssh-keygen -t rsa -C "zjarlin@outlook.com"
#三次回车====================

cd ~/.ssh
pbcopy<id_rsa.pub #将内容复制到剪切板,复制到gitee公钥和仓库公钥

#进图github要做的事==================

pbcopy<id_rsa #填入GITEE_RSA_PRIVATE_KEY

假如有以下四个仓库:

  1. git@github.com:somenzz/push_blog:写博客的项目仓库,里面有用于生成博客的 md 文件,和生成静态博客的脚手架,比如 VuePress,hexo 等,该仓库可以私有。
  2. git@github.com:somenzz/somenzz.github.io:存放博客的静态资源文件,用于 GitHub Pages 展示博客,必须开源。
  3. git@gitee.com/somenzz/somenzz:存放博客的静态资源文件,用于 Gitee Pages 展示博客,必须开源。
  4. ip 地址:xxx.xxx.xxx.xxx,或者域名 somenzz.cn,路径 /xxxx/public/,是自己购买的服务器,用于存放静态博客资源文件。

现在的目标就是,写好一篇文章,向仓库 1 推送之后,仓库 2、3、4 自动更新静态资源文件。当然了,你也可以根据自己情况,选择性的更新 2、3、4 中的一个或多个,只需要将对应的步骤从 GitHub Actions 配置中注释或删除即可。

1. 先定一个小目标

假如有以下四个仓库:

  1. git@github.com:somenzz/push_blog:写博客的项目仓库,里面有用于生成博客的 md 文件,和生成静态博客的脚手架,比如 VuePress,hexo 等,该仓库可以私有。
  2. git@github.com:somenzz/somenzz.github.io:存放博客的静态资源文件,用于 GitHub Pages 展示博客,必须开源。
  3. git@gitee.com/somenzz/somenzz:存放博客的静态资源文件,用于 Gitee Pages 展示博客,必须开源。
  4. ip 地址:xxx.xxx.xxx.xxx,或者域名 somenzz.cn,路径 /xxxx/public/,是自己购买的服务器,用于存放静态博客资源文件。

现在的目标就是,写好一篇文章,向仓库 1 推送之后,仓库 2、3、4 自动更新静态资源文件。当然了,你也可以根据自己情况,选择性的更新 2、3、4 中的一个或多个,只需要将对应的步骤从 GitHub Actions 配置中注释或删除即可。

2. 理解 GitHub Actions

这里说下我对 GitHub Actions 的理解,你提交到仓库 1 后,GitHub 会监控到,然后分配一台虚拟机先将你的项目 checkout 过去,然后按照你指定的 step 顺序执行定义好的 action,这些 action 就包括 npm run build 生成静态文件,push 到你指定的仓库等动作。

这就不可避免的涉及一些访问权限的控制,你要向 GitHub 证明你对这些仓库有控制权限,有些操作,还需要你提供 RSA 的私钥,登录的口令,当然了,这些口令都是加密存放的,不会泄漏,可放心使用。

为了实现上面的小目标,我们要让 GitHub 替我们做的事情如下:

  1. 编译项目,生成静态文件。也就是对仓库 1: git@github.com:somenzz/push_blog,执行 npm run build 生成博客的静态资源。
  2. 将静态资源 push 到 GitHub,也就是 push 到仓库 2: git@github.com:somenzz/somenzz.github.io,这一步完成后 GitHub Pages 就部署完成了。
  3. 将仓库 2 同步给仓库 3,也就是 git@github.com:somenzz/somenzz.github.io 同步给 git@gitee.com/somenzz/somenzz,这样两个项目的静态资源就一致了。
  4. 部署 Gitee Pages,因为 Gitee 的限制,需要手动点一下更新,现在把这一步变成一个 GitHub action。
  5. 使用 rsync 增量同步工具,将静态资源同步的自购服务器的对应目录上。

3. 一步一步跟我操作

现在,我们一步一步来。

首先在仓库 1 的根目录下,创建 .github/workflows/main.yml 文件,这就是 GitHub Actions 功能的配置文件,用于告诉 GitHub 要做哪些事情,写入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
name: Deploy GitHub Pages

# 触发条件:在 push 到 master 分支后
on:
push:
branches:
- master

# 任务
jobs:
build-and-deploy:
# 服务器环境:最新版 Ubuntu
runs-on: ubuntu-latest
steps:
# 拉取代码
- name: Checkout
uses: actions/checkout@v2
with:
persist-credentials: false

# 1、生成静态文件
- name: Build
run: npm install && npm run build

# 2、部署到 GitHub Pages
- name: Deploy
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
REPOSITORY_NAME: somenzz/somenzz.github.io
BRANCH: master
FOLDER: public
#注意这里的 public 是仓库根目录下的 public,也就是 npm run build 生成静态资源的路径,比如有的人是 `docs/.vuepress/dist`

# 3、同步到 gitee 的仓库
- name: Sync to Gitee
uses: wearerequired/git-mirror-action@master
env:
# 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY
SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}
with:
# 注意替换为你的 GitHub 源仓库地址
source-repo: git@github.com:somenzz/somenzz.github.io.git
# 注意替换为你的 Gitee 目标仓库地址
destination-repo: git@gitee.com:somenzz/somenzz.git

# 4、部署到 Gitee Pages
- name: Build Gitee Pages
uses: yanglbme/gitee-pages-action@main
with:
# 注意替换为你的 Gitee 用户名
gitee-username: somenzz
# 注意在 Settings->Secrets 配置 GITEE_PASSWORD
gitee-password: ${{ secrets.GITEE_PASSWORD }}
# 注意替换为你的 Gitee 仓库,仓库名严格区分大小写,请准确填写,否则会出错
gitee-repo: somenzz/somenzz
# 要部署的分支,默认是 master,若是其他分支,则需要指定(指定的分支必须存在)
branch: master

# 5、部署到 somenzz.cn 服务器
- name: rsync deployments
uses: burnett01/rsync-deployments@4.1
with:
# 这里是 rsync 的参数 switches: -avzh --delete --exclude="" --include="" --filter=""
switches: -avzh
path: public/
remote_path: /home/ubuntu/public/
remote_host: somenzz.cn
remote_port: 22
remote_user: ubuntu
remote_key: ${{ secrets.MY_UBUNTU_RSA_PRIVATE_KEY }}

稍微有点长,为了便于你理解,每一步我都有注释,这就是实现这个小目标,GitHub Actions 工作流需要的全部内容,遵循 YAML 格式,这里我做一个大致的说明:

  • on 表示触发条件
  • jobs 表示要做的工作
  • jobs 下的 step 表示要做的步骤,前一步失败,后面不会继续执行。
  • jobs 下的 step 下有 name、uses、with 等,表示一个 action。
  • name 表示 action 的名称,uses 表示使用哪个插件,with 表示传给插件的参数。
  • secrets.XXX 这个 XXX 表示本仓库的环境变量,配置在仓库设置里面的 secrets 菜单栏,都是加密的。

uses 中用的就是别人写好的插件,持续集成由很多操作组成,比如抓取代码、运行测试、登录远程服务器,发布到第三方服务等等,这些操作都用共性,GitHub 就允许其他人把写好的插件共享到插件市场供其他人使用,因此如果你需要某个 action,不必自己写复杂的脚本,直接引用他人写好的 action 即可,你说方便不方便,插件市场见本文的学习资源小节。。

上述文件 .github/workflows/main.yml 写好之后,先别着急 push,一旦 push,这些 actions 就会执行,在参数正确的配置之前,报错那是肯定的。

接下来我说一下一些参数的意义以及如何确定这些参数的值。

1、secrets.ACCESS_TOKEN

对应的配置代码:

1
2
3
4
5
6
7
8
# 部署到 GitHub Pages
- name: Deploy
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
REPOSITORY_NAME: somenzz/somenzz.github.io
BRANCH: master
FOLDER: public

这个 ACCESS_TOKEN 是访问 GitHub API 的令牌,可以在 GitHub 主页,点击个人头像,Settings -> Developer settings -> Personal access tokens 进行生成或更新,第一次生成后你可以看到这个令牌,然后再也不会显示,因此你需要记下来,假如这个字符串是 aaa,然后打开仓库 1 的设置页面,设置 secrets,加入环境变量, name 是 ACCESS_TOKEN,value 是 aaa。如下图所示:

img

image

img

image

img

image

这一段配置文件的作用就是,将 public 目录内的文件 push 到 somenzz/somenzz.github.io 的 master 分支,其中 public 就是 npm run build 生成的静态资源所在的位置。

2、secrets.GITEE_RSA_PRIVATE_KEY

没错,这里就是 RSA 的私钥,这里如果你不熟悉 RSA,可能会产生困惑,不是说公钥在网上传输,私钥不公开吗? 没错,确实是这样,Gitee 上保存你账户对应的公钥,GitHub 仓库的 secrets.GITEE_RSA_PRIVATE_KEY 保存着私钥,因为 GitHub 的服务器不会让你亲自登录设置密钥对,因此需要配置 secrets.GITEE_RSA_PRIVATE_KEY 来告知 GitHub,解密操作需要的私钥并不是在网上传输,只有自己知道。

GitHub Actions 的服务器会使用你的账户登录 Gitee,Gitee 使用你的公钥加密后传输给这台服务器,这台服务器使用你设置的私钥才能解密成功,通讯完成。如果想搞懂 RSA 算法可以看我之前写的文章一文搞懂 RSA 算法,是全网讲的最明白的文章。

这里说下如何生成 RSA 的公钥和私钥。

打开终端,输入以下命令:

1
ssh-keygen -t ed25519 -C "your_email@example.com"

这里的邮箱是你 Gitee 的注册邮箱。如果服务器不支持 ed25519 算法,可以这样:

1
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

我这里使用的就是第二种,然后一路回车即可。执行完成后,在 ~/.ssh 目录下可以看到 id_rsa、id_rsa.pub 等文件,其中私钥就是 id_rsa,公钥就是 id_rsa.pub,这就是密钥对,一个可用于加密,另一个可用于解密。

打开 gitee.com 并登录,点击自己头像右下角,选择设置-> ssh 公钥,将 id_rsa.pub 的内容复制到公钥的输入框里,公钥的标题可以自己填写,如下图所示:

img

image

接下来设置 secrets.GITEE_RSA_PRIVATE_KEY ,在 GitHub 上打开仓库 1 的设置页面,点击 secrets,增加环境变量,name 就填写 secrets.GITEE_RSA_PRIVATE_KEY,value 就填写 id_rsa 文件的内容,如下图所示:

img

image

注意 id_rsa 文件的内容通常如下所示:

1
2
3
4
5
6
7
8
$ cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAgEA4v2D0sH/puF4GWZdCfeontuoInVna7jxmtrnHxiOHkoIt5Mp/lMO
6kHWxpSxumQ+CAuqdVYGcsE+8FL0wCBBolpAK7jmX+S7l9wTkPJxYduOPxRBbKFKZp07R/
......
C2FVan1VGNpJ/wAAAA9zb21lbnp6QDE2My5jb20BAg==
-----END OPENSSH PRIVATE KEY-----

注意第一行和最后一行也是要添加进去的,不然 GitHub actions 会提示 id_rsa 格式不正确。

3、secrets.GITEE_PASSWORD

对应的配置文件代码段:

1
2
3
4
5
6
7
8
9
10
11
12
# 4、部署到 Gitee Pages
- name: Build Gitee Pages
uses: yanglbme/gitee-pages-action@main
with:
# 注意替换为你的 Gitee 用户名
gitee-username: somenzz
# 注意在 Settings->Secrets 配置 GITEE_PASSWORD
gitee-password: ${{ secrets.GITEE_PASSWORD }}
# 注意替换为你的 Gitee 仓库,仓库名严格区分大小写,请准确填写,否则会出错
gitee-repo: somenzz/somenzz
# 要部署的分支,默认是 master,若是其他分支,则需要指定(指定的分支必须存在)
branch: master

这里就很简单了,用户名可以明文,密码一定要放在 secrets 环境变量中,即使仓库开源,也不至于泄漏自己的登录密码信息,这一步依然是在仓库 1 的设置页面添加 secrets 环境变量,和前述的操作一样,不在赘述。

4、secrets.MY_UBUNTU_RSA_PRIVATE_KEY

对应的配置文件代码段

1
2
3
4
5
6
7
8
9
10
11
12
# 5、部署到 somenzz.cn 服务器
- name: rsync deployments
uses: burnett01/rsync-deployments@4.1
with:
# 这里是 rsync 的参数 switches: -avzh --delete --exclude="" --include="" --filter=""
switches: -avzh
path: public/
remote_path: /home/ubuntu/public/
remote_host: somenzz.cn
remote_port: 22
remote_user: ubuntu
remote_key: ${{ secrets.MY_UBUNTU_RSA_PRIVATE_KEY }}

这个是自购服务器的私钥,一般情况下云服务器都会提供一个私钥文件,推荐你使用私钥登录服务器,和第二个参数的原理是一致的,如果服务器没有给你这个私钥,请自行生成一个可用于登录的私钥。

这里用到了 rsync,是一个增量同步工具,可以只传输有变化的文件,大大减轻网络带宽,具体的使用方法可参考阮一峰老师的教程:https://www.ruanyifeng.com/blog/2020/08/rsync.html

执行、验证、结果通知

以上 4 个参数配置完成之后,就可以对仓库 1 push,然后点开 GitHub 上的 actions 看下执行过程。

1
2
3
4
$ cd xxx/push_blog/
$ git add -u
$ git commit -m "add article"
$ git push

打开 GitHub 上的 push_blog 仓库,点击 Actions,可以看到部署的结果,结果的标题就是 commit 信息,如下图所示:

img

image

点击标题,可以看到详细情况:

img

image

再点击,可以看到每一个 action 的详情:

img

image

接下来就是访问下网站是否正常:

强制刷新下,看看新增的文章是否已经到位。

你会问了,如果报错了怎么收到通知? 点击 Notifications 添加接受通知的邮件即可,如下图所示:

img

链接:https://www.jianshu.com/p/5911a37118cd
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。