利用Github Action实现Github到Gitee的持续同步
1、什么是Github Action
github action
是github
推出的自动化CI/CD
的功能,随着2019
年11
月后github
对该功能的全面开放,现在所有的github
用户可以直接使用该功能
github action
的语法类似于gitlab ci
,与之相比,还有更多优势,例如:
action
对github
各个事件的支持更为全面,如release
、pull-request
、issue
事件等等action
支持直接使用别人编写好的action
action
的执行器类似于gitlab runner
,可以使用github
托管的执行器,也可以托管自己的执行器。甚至在action
运行的时候,还可以通过某些特殊技巧进入到执行器里面,相当于一台临时的服务器供我们使用
2、github和gitee同步
github
的服务器在国外,因为某些原因,在大多数的网络环境下都是无法顺畅访问的
gitee
的服务器在国内,由国内公司运营
纵使如此,大多数开发者还是习惯使用github
(远在海外,也要想尽各种办法)
那么为什么需要把github
和gitee
的仓库进行同步呢?原因不言而喻
目前可用的进行同步的方法可能有:
- 利用
gitee
官方的同步(导入github
项目),这种方法只能一次性导入 - 本地同时关联
gitee
和github
,提交时都push
一份,这种方法纯属手动 - 利用
github action
下面介绍利用github action
如何实现github
到gitee
的持续同步
3、选用或编写action
实现github
和gitee
同步的思路主要是基于我们的账户调用github
和gitee
各自的api
接口和密钥通信,在执行器内拉取并推送代码库到gitee
action
的编写语法和gitlab ci
很相似,同时github
还推出了官方的action
市场,地址为 https://github.com/marketplace
这里我们使用的action
是Yikun/hub-mirror-action
4、语法示例
上述action
,支持较为全面。参照说明,相关不同场景下的语法如下:
- 组织同步
同步Github
的组织到Gitee
- name: Organization mirror
uses: Yikun/hub-mirror-action@master
with:
src: github/kunpengcompute
dst: gitee/kunpengcompute
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
dst_token: ${{ secrets.GITEE_TOKEN }}
account_type: org
- 黑/白名单
动态获取源端github
的repos
,但仅同步名为hub-mirror-action
,不同步hashes
这个repo
到Gittee
- name: Single repo mirror
uses: Yikun/hub-mirror-action@master
with:
src: github/Yikun
dst: gitee/yikunkero
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
dst_token: ${{ secrets.GITEE_TOKEN }}
white_list: "hub-mirror-action"
black_list: "hashes"
- 静态名单(可用于单一仓库同步)
不会动态获取源端github
的repos
,仅同步hub-mirror-action
这个repo
- name: Black list
uses: Yikun/hub-mirror-action@master
with:
src: github/Yikun
dst: gitee/yikunkero
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
dst_token: ${{ secrets.GITEE_TOKEN }}
static_list: "hub-mirror-action"
- 使用ssh方式进行clone
- name: ssh clone style
uses: Yikun/hub-mirror-action@master
with:
src: github/Yikun
dst: gitee/yikunkero
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
dst_token: ${{ secrets.GITEE_TOKEN }}
clone_style: "ssh"
- 强制更新,并打开debug日志开关
- name: Mirror with force push (git push -f)
uses: Yikun/hub-mirror-action@master
with:
src: github/Yikun
dst: gitee/yikunkero
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
dst_token: ${{ secrets.GITEE_TOKEN }}
force_update: true
debug: true
- 设置命令行超时时间为1小时
- name: Mirror with force push (git push -f)
uses: Yikun/hub-mirror-action@master
with:
src: github/Yikun
dst: gitee/yikunkero
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
dst_token: ${{ secrets.GITEE_TOKEN }}
force_update: true
timeout: '1h'
5、准备工作
5.1 设置dst_key
在github
上打开一个自己的仓库(可以是一个已有的仓库,也可以是用来专门存放action
的仓库),这里以我的个人公开仓库为例
首先在本地生成一个ssh
密钥对
# ssh-keygen -t rsa -f ~/Documents/ssh-key/id_rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/ssgeek/Documents/Document/ssh-key/id_rsa.
Your public key has been saved in /Users/ssgeek/Documents/Document/ssh-key/id_rsa.pub.
The key fingerprint is:
SHA256:eUf8KzgFFoTikDoo1at9/fVpftcUWkWgTgPNbWTVOdM ssgeek@honganrongdeMac-mini.local
The key's randomart image is:
+---[RSA 3072]----+
| . . o+o o++*|
| . + . . +ooo+E|
| o . + . o *. +|
|o o . . o = o o |
|. + .S . + + .|
| . . . .. +.. ..|
| . .o....o.|
| .. .+ +|
| o...|
+----[SHA256]-----+
在github
打开settings
—>secrets
,新建一个secret
,名为GITEE_PRIVATE_KEY
,值为上面生成的密钥对的私钥
然后登录到gitee
,在个人设置—>安全设置—>SSH
公钥中添加上面生成的密钥对的公钥,命名随意
5.2 设置dst_token
在gitee
打开个人设置—>安全设置—>私人令牌,新建一个私人令牌,命名随意,复制生成的令牌值
在github
打开settings
—>secrets
,新建一个secret
,名为GITEE_TOKEN
,值为上面复制的令牌值
6、github同步到gitee
在刚才的GitHub
仓库中,新建 .github/workflows/SyncToGitee.yml
文件,其中.github/workflows/
是固定的目录名
内容如下
name: Sync Github Repos To Gitee
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Sync Github Repos To Gitee # 名字随便起
uses: Yikun/hub-mirror-action@v1.1 # 使用Yikun/hub-mirror-action
with:
src: github/Hargeek # 源端账户名(github)
dst: gitee/ssgeek # 目的端账户名(gitee)
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} # SSH密钥对中的私钥
dst_token: ${{ secrets.GITEE_TOKEN }} # Gitee账户的私人令牌
account_type: user # 账户类型
clone_style: "https" # 使用https方式进行clone,也可以使用ssh
debug: true # 启用后会显示所有执行命令
force_update: true # 启用后,强制同步,即强制覆盖目的端仓库
static_list: "python-nianbao-struct" # 静态同步列表,在此填写需要同步的仓库名称,可填写多个
timeout: '600s' # git超时设置,超时后会自动重试git操作
相关语法说明:
- on
指定action
的触发条件,一般有:使用web事件触发工作流,并且可以具体指定branches
,tags
以及文件路径;使用cron
语法指定时间触发工作流
- job
指定相应的任务,每一个step
是一个步骤,step
是job
的最小单元,所有step
配置在steps
中
其中uses
用于使用其他用户所发布的action
其他的内容这里不再赘述,更多内容可以参考官方语法说明 github action doc
提交该action
,观察github
上的执行视图
此时打开gitee
,就会发现自动创建了同名称的仓库且自动提交了同样的代码
分析action
的执行日志,主要如下
...
Successfully installed GitPython-3.1.13 PyYAML-5.4.1 certifi-2021.5.30 chardet-4.0.0 gitdb-4.0.7 idna-2.10 requests-2.25.1 six-1.16.0 smmap-4.0.0 tenacity-6.3.1 urllib3-1.26.6
+ python3 /hub-mirror/hubmirror.py --src github/Hargeek --dst gitee/ssxr --dst-token *** --account-type user --clone-style https --cache-path /github/workspace/hub-mirror-cache --black-list '' --white-list '' --static-list python-nianbao-struct --force-update true --debug true --timeout 600s
Backup python-nianbao-struct
(1/3) Downloading...
Starting git clone https://github.com/Hargeek/python-nianbao-struct.git
Clone completed: /github/workspace/github/workspace/hub-mirror-cache/python-nianbao-struct
(2/3) Creating...
python-nianbao-struct doesn't exist, create it...
Destination repo creating accepted.
(3/3) Force pushing...
Total: 1, skip: 0, successed: 1, failed: 0.
Failed: []
+ exit 0
Cleaning up orphan processes
大致流程:执行器运行起来后,自动检出了该仓库,然后判断目标仓库是否存在,不存在则先创建,存在则直接执行强制推送
后面每一次提交代码或对仓库做变更都可以按照触发条件触发action
的执行了
7、小结
到这里,利用github action
将github
仓库的代码实时同步到gitee
就完成了,个人认为github action
比gitlabci
更为强大且有更多高阶玩法,但企业内部一般还都是私有仓库,因此对个人来说还是很实用的
See you ~