本地推送Github Actions再推送到服务器

1.前提准备

  • 服务器*1
  • Github账号*1
  • 电脑*1
  • 勤劳的小手*1/双

本教程是通过 GitHub Actions 实现持续集成和持续部署(CI/CD),自动化生成静态文件并推送到目标仓库,目标仓库触发 Webhooks 通知服务器自动拉取最新代码部署。

建议是一个私人仓库 hexo-blog ,一个公开仓库 JLinmr.Github.io

2.部署到Github

本文不叙述这个了,直接看这个文章

3.使用Github Actions

GitHub Actions 是一个持续集成和持续部署(CI/CD)平台,可以在 GitHub 仓库中配置工作流。当有新的推送到达 GitHub 仓库时,GitHub Actions 会自动触发预定义的工作流。

1.创建工作流

方法一:在你的 GitHub 仓库中创建一个 .github/workflows 目录。然后,在这个目录中创建一个新的 YAML 文件,例如 main.yml,填入工作流配置⬇️

方法二:在你的Github仓库界面依次点击Actions➡️set up a workflow yourself,填入工作流配置⬇️

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
name: 部署 Hexo 到另一个仓库

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 检查源仓库分支
uses: actions/checkout@v3
with:
ref: main

- name: 配置 Node.js 版本
uses: actions/setup-node@v3
with:
node-version: "20.x"

- name: 安装 Hexo
run: |
npm install hexo-cli -g

- name: 缓存 node 模块
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}

- name: 安装依赖
if: steps.cache.outputs.cache-hit != 'true'
run: |
npm install --save

- name: 生成静态文件
run: |
hexo generate

- name: 检出目标仓库
uses: actions/checkout@v3
with:
repository: JLinMr/JLinmr.github.io # 目标仓库
path: target-repo # 目标仓库的本地路径
token: ${{ secrets.PAT }} # 使用你生成的个人访问令牌

- name: 删除并复制到目标仓库
run: |
rm -rf target-repo/*
cp -r public/* target-repo/

- name: 配置 Git 用户信息并推送到目标仓库
run: |
cd target-repo
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "通过 Github Actions 部署 Hexo 构建"
git push
env:
GITHUB_TOKEN: ${{ secrets.PAT }} # 使用你生成的个人访问令牌

不管是方法一还是方法二,最终的内容都是这个⬆️,根据自己的仓库信息,修改 目标仓库

1
2
3
4
5
6
- name: 检出目标仓库
uses: actions/checkout@v3
with:
repository: JLinMr/JLinmr.github.io # 目标仓库
path: target-repo # 目标仓库的本地路径
token: ${{ secrets.PAT }} # 使用你生成的个人访问令牌

2.配置访问令牌

最开始我以为同账号下是有权限的,但是试了一下没有权限推送到 JLinMr/JLinmr.github.io 仓库。即使使用 GITHUB_TOKEN,也只能访问当前仓库,而不能访问其他仓库。所以在这种情况下,选择了配置个人访问令牌来获得足够的权限

1.生成访问令牌

  1. 进入 Settings
  2. 点击 Developer settings
  3. 选择 Personal access tokens
  4. 点击 Tokens(classic)
  5. 点击 Generate new token
  6. 输入令牌的描述,选择需要的权限( repo 权限),然后点击 Generate token
  7. 复制生成的令牌

2.添加到 Secrets

  1. 进入你的 GitHub 仓库。
  2. 点击 Settings
  3. 选择 Secrets and variables➡️Actions
  4. 点击 New repository secret
  5. 输入 PAT,粘贴你的个人访问令牌到 Secret * 字段,然后点击 Add secret

3.触发工作流

修改仓库内容触发工作流,首次可能比较慢,因为工作流配置了缓存 Node.js 依赖

4.配置Webhook

本教程使用宝塔面板进行配置Webhook ,其他请自行测试

1.下载WebHook和添加

  1. 点击宝塔左侧软件商城,搜索并下载安装宝塔WebHook

  2. 点击设置➡️添加Hook,填入名称和下面配置

  3. 注意你需要,修改脚本内容为你自己的

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
#!/bin/bash
echo ""
# 输出当前时间
date --date='0 days ago' "+%Y-%m-%d %H:%M:%S"
echo "开始"

# 定义变量
branch="main"
gitPath="/www/wwwroot/blog.bsgun.cn/"
gitHttp="https://github.com/JLinMr/JLinmr.GitHub.io.git"

echo "Web站点路径:$gitPath"

# 函数:初始化 Git 仓库
init_git_repo() {
if [ ! -d ".git" ]; then
echo "在该目录下克隆 git"
sudo git clone $gitHttp gittemp
sudo mv gittemp/.git .
sudo rm -rf gittemp
fi
}

# 函数:拉取最新代码并设置权限
pull_latest_code() {
echo "拉取最新的项目文件"
git remote add origin $gitHttp
git branch --set-upstream-to=origin/$branch $branch
sudo git fetch --all
sudo git reset --hard origin/$branch
sudo git pull --rebase 2>&1
echo "设置目录权限"
sudo chown -R www:www $gitPath
}

# 判断项目路径是否存在
if [ -d "$gitPath" ]; then
cd $gitPath
init_git_repo
pull_latest_code
else
echo "该项目路径不存在"
echo "新建项目目录"
mkdir -p $gitPath
cd $gitPath
init_git_repo
pull_latest_code
fi

echo "结束"
exit 0

2.配置密钥

  1. 点击查看密钥

  2. 复制密钥的内容和蓝色选中的内容

  3. 打开你的Github内公开的仓库,依次点击settings➡️WebHooks➡️Add WebHook

  4. 按照步骤4的图片进行填写内容,然后点击Add WebHookPayload URL填写蓝色选中内容)(Content type改成Json

  5. 成功的话会显示为步骤5,第一次是Ping(如果开启了SSL,且打开验证你有大概率会失败)

可以直接看图片按照图片顺序配置,其他的都是默认

步骤1

步骤2

步骤3

步骤4

步骤5

5.触发钩子

在你的私人仓库内进行增,删,改,任意操作即可触发GitHub Actions,然后公开仓库触发钩子,服务器进行拉取仓库的最新代码

6.写在最后

因为写这个的时候已经完成了,我也没进行测试这一套流程(但是我就是这样成的),如果有什么问题可以在评论区评论留言