背景
由于公司或者某些地方对 GitHub 的网络非常的不友好,所以我希望这时候把代码直接推送到我的服务器上,由服务器同步到 GitHub 上去。
而家里的网络我会直接推送到 GitHub,所以这个时候也需要 GitHub 能把代码同步到服务器上,便于其他客户端从服务器获取到最新的代码。
步骤
1. 在服务器上创建空仓库
在服务器上创建一个新的空仓库作为中转站,该仓库将不储存代码,只保存提交记录(即git log)。例如,你可以使用以下命令在中转服务器上创建一个新的仓库:
mkdir myrepo.git
cd myrepo.git
git init --bare
2. 在中转服务器上添加 Git hook
在中转服务器上,创建一个名为 post-receive
的 Git hook,并添加以下脚本:
#!/bin/bash
while read oldrev newrev refname
do
# 只在主分支上的提交才触发
if [[ $refname = "refs/heads/main" ]]; then
# 将代码推送到 GitHub
git push origin main
fi
done
post-receive
hook 将会在有新的代码提交时被触发,并自动将代码推送到 GitHub 的特定仓库中。
3. 为 post-receive
文件添加可执行权限
保存并退出 post-receive
文件。然后,为 post-receive
文件添加可执行权限。
chmod +x post-receive
4. 在本地计算机上添加远程仓库
在本地计算机上,在你的代码仓库中添加一个名为 origin
的远程仓库,该仓库指向你在中转服务器上创建的空仓库。可以使用以下命令将此远程仓库添加到你的代码仓库中:
git remote add origin username@transit-server:/path/to/myrepo.git
其中,username
是中转服务器的用户名,transit-server
是中转服务器的主机名或 IP 地址,/path/to/myrepo.git
是在中转服务器上创建的空仓库的路径。
5. 将代码推送到中转服务器
在本地,可以将你的代码推送到中转服务器。
git push origin main
现在,当你从本地推送代码到中转服务器时,post-receive
hook 将自动将代码推送到 GitHub 上的相应仓库。
6. 将 GitHub 上的代码同步到中转服务器
当你直接将代码推送到 GitHub 时,你需要确保中转服务器上的代码也是最新的。为此,可以创建一个 GitHub Actions workflow 来实现这个功能。下面是一个简单的工作流程,可以在 GitHub 接收到 push 事件时将代码推送到中转服务器仓库的对应分支:
name: Sync to Transfer Server
on:
push:
branches:
- main
jobs:
push-to-transfer-server:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Configure SSH
uses: webfactory/ssh-agent@v0.5.0
with:
ssh-private-key: ${{ secrets.SERVER_PRIVATE_KEY }}
- name: Push to Server
uses: appleboy/ssh-action@master
with:
host: ${{ vars.SERVER_HOST }}
username: ${{ vars.SERVER_USERNAME }}
key: ${{ secrets.SERVER_PRIVATE_KEY }}
script: |
cd ${{ vars.SERVER_PATH }}
git fetch
latest_commit=$(git rev-parse FETCH_HEAD)
git update-ref refs/heads/main $latest_commit
这个workflow会在接收到main分支上的push事件时触发。它会先将代码检出到工作目录中,使用 SSH 连接到远程服务器,并将代码推送到服务器上。
要想让你的GitHub连接你的服务器,你需要在服务器上生成一个SSH密钥对,
你可以使用ssh-keygen
命令来生成密钥对。
将公钥添加到服务器上的authorized_keys
文件中,该文件通常位于服务器上的~/.ssh/目录中。你可以使用文本编辑器或ssh-copy-id命令将公钥添加进去。
将私钥复制到GitHub仓库的secrets中。你可以进入GitHub仓库,选择“Settings” > “Secrets” > “New repository secret”,然后将私钥复制粘贴到值字段中。
这就是${{ secrets.SERVER_PRIVATE_KEY }}
这个变量了。
而${{ vars.SERVER_USERNAME }}
这类变量则是在刚刚的Variables 里面创建的。