1、什么是Github Action

github actiongithub推出的自动化CI/CD的功能,随着201911月后github对该功能的全面开放,现在所有的github用户可以直接使用该功能

github action的语法类似于gitlab ci,与之相比,还有更多优势,例如:

  • actiongithub各个事件的支持更为全面,如releasepull-requestissue事件等等
  • action支持直接使用别人编写好的action
  • action的执行器类似于gitlab runner,可以使用github托管的执行器,也可以托管自己的执行器。甚至在action运行的时候,还可以通过某些特殊技巧进入到执行器里面,相当于一台临时的服务器供我们使用

2、github和gitee同步

github的服务器在国外,因为某些原因,在大多数的网络环境下都是无法顺畅访问的

gitee的服务器在国内,由国内公司运营

纵使如此,大多数开发者还是习惯使用github(远在海外,也要想尽各种办法)

那么为什么需要把githubgitee的仓库进行同步呢?原因不言而喻

目前可用的进行同步的方法可能有:

  • 利用gitee官方的同步(导入github项目),这种方法只能一次性导入
  • 本地同时关联giteegithub,提交时都push一份,这种方法纯属手动
  • 利用github action

下面介绍利用github action如何实现githubgitee的持续同步

3、选用或编写action

实现githubgitee同步的思路主要是基于我们的账户调用githubgitee各自的api接口和密钥通信,在执行器内拉取并推送代码库到gitee

action的编写语法和gitlab ci很相似,同时github还推出了官方的action市场,地址为 https://github.com/marketplace

这里我们使用的actionYikun/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

  • 黑/白名单

动态获取源端githubrepos,但仅同步名为hub-mirror-action,不同步hashes这个repoGittee

- 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"
  • 静态名单(可用于单一仓库同步)

不会动态获取源端githubrepos,仅同步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事件触发工作流,并且可以具体指定branchestags以及文件路径;使用cron语法指定时间触发工作流

  • job

指定相应的任务,每一个step是一个步骤,stepjob的最小单元,所有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 actiongithub仓库的代码实时同步到gitee就完成了,个人认为github actiongitlabci更为强大且有更多高阶玩法,但企业内部一般还都是私有仓库,因此对个人来说还是很实用的

See you ~