Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

巧用Github Action同步代码到Gitee #79

Open
Yikun opened this issue Jan 17, 2020 · 17 comments
Open

巧用Github Action同步代码到Gitee #79

Yikun opened this issue Jan 17, 2020 · 17 comments

Comments

@Yikun
Copy link
Owner

Yikun commented Jan 17, 2020

1. 背景

在开源贡献的代码托管的过程中,我们有时候有需要将Github的代码同步到其他远端仓库的需求。具体的,对于我们目前参与的项目来说核心诉求是:以Github社区作为主仓,并且定期自动同步到Gitee作为镜像仓库

2. 调研

  • 结论1: 由于会被Github屏蔽,Gitee的自动同步功能暂时无法支持。
    这个问题在Gitee的官方反馈中,建议github导入的项目能设置定时同步提及过,官方的明确答复是不支持。最近又再次和官方渠道求证,由于会被Github屏蔽的关系,这个功能不会被支持。本着有轮子用轮子,没轮子造轮子的原则,我们只能选择自己实现

  • 结论2: 靠手动同步存在时效问题,可能会造成部分commit的丢失。
    Gitee本身是提供了手动同步功能的,也算比较好用,但是想想看,如果一个组织下面,发展到有几百上千个项目后,这种机制显然无法解决问题了。因此,我们需要某种计算资源去自动的完成同步

  • 结论3: 目前我们开源的好几个项目(例如Mindspore, OpenGauss, Kunpeng)都有类似的需求。
    作为一个合格的程序员,为了守住DRY(don't repeat yourself,不造重复的轮子)的原则,所以,我们需要实现一个工具,同步简单的配置就可以完成多个项目的同步。

最终结论:我们需要自己实现一个工具,通过某种计算资源自动的去完成周期同步功能。

3. 选型

其实调研结论有了后,我们面对的选型就那么几种:

  • 使用crontab调用脚本周期性同步。这个计算资源得我们自己维护,太重了。排除!
  • 使用Travis、OpenLab等CI资源。这些也可以支持,但是和Github的集成性比较差。
  • Github Action。无缝的和Github集成,处于对新生技术的新鲜感,还是想试一把的,就选他了!关于Github Action的详细内容可以直接在官网看到:https://github.com/features/actions

PS:严格来讲,Github Action其实是第二种选择的子集,其实就是单纯的想体验一把,并且把我们的业务需求实现了。

4. 实现

4.1 Github Action的实现

Github Action提供了2种方式去实现Action:

  • Docker container. 这种方式相当于在Github提供的计算资源起个container,在container里面把功能实现。具体的原理大致如下:
    image

  • JavaScript. 这种方式相当于在Github提供的计算资源上,直接用JS脚本去实现功能。

作为以后端开发为主的我们,没太多纠结就选择了第一种类型。关于怎么构建一个Github的Action可以参考Github的官方文档Building actions。官方文档真的写的非常详细了,并且也通了了hello-world级别的入门教程。

4.1 同步的核心代码实现

而最终的关键实现就是,我们需要定义这个容器运行的脚本,原理很简单:
image
大致就是以上4步:

  1. 通过Github API读取Repo列表。
  2. 下载或者更新Github repo的代码
  3. 设置远端分支
  4. 将最新同步的commit、branch、tag推送到Gitee。

关心细节的同学,具体可以参考代码:https://github.com/Yikun/gitee-mirror-action/blob/master/entrypoint.sh

5. 怎么用呢?

举了个简单的例子,我们想将Github/kunpengcompute同步到Gitee/kunpengcompute上面,需要做的非常简单,只需要2步:

  1. 将Gitee的私钥和Token,上传到项目的setting的Secrets中。
    image

可以参考官方指引

  1. 新建一个Github workflow,在这个workflow里面使用Gitee Mirror Action。
name: Gitee repos mirror periodic job
on:
# 如果需要PR触发把push前的#去掉
# push:
  schedule:
    # 每天北京时间9点跑
    - cron:  '0 1 * * *'
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: Mirror the Github organization repos to Gitee.
      uses: Yikun/[email protected]
      with:
        # 必选,需要同步的Github用户(源)
        src: github/Yikun
        # 必选,需要同步到的Gitee的用户(目的)
        dst: gitee/yikunkero
        # 必选,Gitee公钥对应的私钥,https://gitee.com/profile/sshkeys
        dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
        # 必选,Gitee对应的用于创建仓库的token,https://gitee.com/profile/personal_access_tokens
        dst_token:  ${{ secrets.GITEE_TOKEN }}
        # 如果是组织,指定组织即可,默认为用户user
        # account_type: org
        # 还有黑、白名单,静态名单机制,可以用于更新某些指定库
        # static_list: repo_name
        # black_list: 'repo_name,repo_name2'
        # white_list: 'repo_name,repo_name2'

可以参考鲲鹏库的实现

image

上图,大概是每个阶段的原理和最终的效果。现在,这个使用Gitee Mirror Action的workflow已经运行起来了,可以在链接看到。

6. 最后

好啦,这篇硬核软文就写到这里,有同步需求的同学,放心使用。更多用法,可以参考Hub-mirror-action的主页Readme。

Github Action 官方链接https://github.com/marketplace/actions/hub-mirror-action
代码仓库https://github.com/Yikun/hub-mirror-action

有任何问题或者疑问,希望可以和大家一起改进这个Action,有问题可以直接提Issue或者PR,不用客气。

@Yikun
Copy link
Owner Author

Yikun commented Feb 5, 2020

2.0已发布,现在支持github与gitee的双向同步。

@Yikun Yikun added the Git label Feb 5, 2020
@Yikun Yikun added the Publish label Mar 30, 2020
@leopardciaw
Copy link

请问下,如何优雅的在fork 其他人的GitHub项目代码后,能单向同步更新他人代码呢。不想因自己不小心,就pull给他人而造成困扰。谢谢~

@Yikun
Copy link
Owner Author

Yikun commented Aug 17, 2020

@leopardciaw
加个upstream,然后,每次用rebase更新

git remote add upstream http://github.com/xxx/test.git

git remote update upstream

git rebase upstream/master

git push origin dev:dev

@leopardciaw
Copy link

@leopardciaw
加个upstream,然后,每次用rebase更新

git remote add upstream http://github.com/xxx/test.git

git remote update upstream

git rebase upstream/master

git push origin dev:dev

谢谢答复,我试下,不懂再来请教。

@jalenzz
Copy link

jalenzz commented Aug 19, 2020

你好,可否支持 issue 的同步

@Yikun
Copy link
Owner Author

Yikun commented Aug 20, 2020

@jalenchuh 暂时没有支持计划哈

@codingriver
Copy link

@Yikun
2.0已发布,现在支持github与gitee的双向同步。

我用github做镜像仓库,用gitee做主仓库,怎么用action定时触发同步从gitee拉取到github,用你的action我没有配置好,出现错误了

2020-09-01T08:26:45.7736441Z �[31m(2/3)�[0m Importing...
2020-09-01T08:26:45.7822264Z load pubkey "/root/.ssh/id_rsa": invalid format
2020-09-01T08:26:45.8026664Z Warning: Permanently added 'github.com,140.82.114.3' (RSA) to the list of known hosts.
2020-09-01T08:26:46.2317529Z To github.com:codingriver/hugo-project.git
2020-09-01T08:26:46.2318579Z ! [rejected] origin/master -> master (fetch first)
2020-09-01T08:26:46.2319607Z error: failed to push some refs to '[email protected]:codingriver/hugo-project.git'

配置:
2020-09-01T08:26:36.0366725Z ##[group]Run Yikun/hub-mirror-action@master
2020-09-01T08:26:36.0367327Z with:
2020-09-01T08:26:36.0367713Z src: gitee/codingriver
2020-09-01T08:26:36.0368027Z dst: github/codingriver
2020-09-01T08:26:36.0370476Z dst_key: ***

2020-09-01T08:26:36.0370864Z dst_token: ***
2020-09-01T08:26:36.0371173Z white_list: hugo-project
2020-09-01T08:26:36.0371486Z account_type: user
2020-09-01T08:26:36.0371994Z clone_style: https
2020-09-01T08:26:36.0372336Z cache_path: /github/workspace/hub-mirror-cache
2020-09-01T08:26:36.0372670Z force_update: false
2020-09-01T08:26:36.0372976Z debug: false
如果支持,麻烦楼主给指点下,[email protected]

@Yikun
Copy link
Owner Author

Yikun commented Sep 1, 2020

@codingriver Yikun/hub-mirror-action#37 在项目里提issue哈。

看了下,主要是因为源和目的端的base不一样导致的。

对于这种,建议把force_update设置为true,进行强制刷新。(目的端请备份)。
另外,单个项目同步建议使用static_list:

  • white_list会先动态拿列表,然后再判断是否在list里
  • static_list直接从配置取值

@codingriver
Copy link

@codingriver Yikun/hub-mirror-action#37 在项目里提issue哈。

看了下,主要是因为源和目的端的base不一样导致的。

对于这种,建议把force_update设置为true,进行强制刷新。(目的端请备份)。
另外,单个项目同步建议使用static_list:

  • white_list会先动态拿列表,然后再判断是否在list里
  • static_list直接从配置取值

谢谢,自己看错了,以为rsa配置错了,留言后发现是仓库冲突,已经修复,再次感谢作者提供工具

@Yikun Yikun added Publish and removed Publish labels Oct 9, 2020
@classmatezhu
Copy link

我最近尝试了一下,发现不行了。然后去看了一眼您的鲲鹏里的运行情况,发现也是不能运行。

@Yikun
Copy link
Owner Author

Yikun commented Oct 8, 2021

@classmatezhu

Please make sure you have the correct access rights
and the repository exists.
Retry 2/3 exited 128, retrying in 2 seconds...
Load key "/root/.ssh/id_rsa": invalid format
Retry 3/3 exited 128, no more retries left.
[email protected]: Permission denied (publickey).
 Push failed 
fatal: Could not read from remote repository.
Total: 1, skip: 0, successed: 0, failed: 1.

看了下,你这个问题是因为key设置的问题,请确认secrets.GITEE_PRIVATE_KEY已经配置到了gitee侧的账户。鲲鹏目前无问题哦,显示失败是因为部分库为空导致的同步失败。

@numajinfei
Copy link

使用master版本,ssh方式,gh-->gitee正常,gitee-->gh(调换src, dst)失败:

(1/3) Downloading...
Updating repo...
(2/3) Creating...
binocular_vision repo exist, skip creating...
(3/3) Force pushing...
Remote exsits, re-create: set github to [email protected]:numajinfei/binocular_vision.git
(3/3) Force pushing...
Remote exsits, re-create: set github to [email protected]:numajinfei/binocular_vision.git
(3/3) Force pushing...
Cmd('git') failed due to: exit code(128)
  cmdline: git push -f github refs/remotes/origin/*:refs/heads/* --tags --prune
  stderr: 'Warning: Permanently added the ECDSA host key for IP address '192.30.255.112' to the list of known hosts.
[email protected]: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.'

@numajinfei
Copy link

也有报错如下:

(1/3) Downloading...
Updating repo...
(2/3) Creating...
binocular_vision repo exist, skip creating...
(3/3) Force pushing...
Remote exsits, re-create: set github to [email protected]:numajinfei/binocular_vision.git
(3/3) Force pushing...
Remote exsits, re-create: set github to [email protected]:numajinfei/binocular_vision.git
(3/3) Force pushing...
Cmd('git') failed due to: exit code(128)
  cmdline: git push -f github refs/remotes/origin/*:refs/heads/* --tags --prune
  stderr: '[email protected]: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.'
Total: 1, skip: 0, successed: 0, failed: 1.
Failed: ['binocular_vision']
+ exit 1

@Yikun
Copy link
Owner Author

Yikun commented Dec 30, 2021

@numajinfei 调换顺序以后,token和key也要刷新为新的目的仓的配置。

@numajinfei
Copy link

@Yikun
@numajinfei 调换顺序以后,token和key也要刷新为新的目的仓的配置。

gh--repo---secrets下新增了gh token, 而key具体怎么配置? 之前生成的是无密码的,现在需要gitee-->gh 同步的话,gh secrets端是存放pub key? 如gh配置private key,则workflow文件只需变化 token就行,gitee端只有pub key可配置项;只修改token的话,依然出现上述错误

@Yikun
Copy link
Owner Author

Yikun commented Dec 31, 2021

@numajinfei

  • dst_key 用于在目的端上传代码的私钥(默认可以从~/.ssh/id_rsa获取),可参考生成/添加SSH公钥generating SSH keys生成,并确认对应公钥已经被正确配置在目的端。对应公钥,Github可以在这里配置,Gitee可以这里配置。
  • dst_token 创建仓库的API tokens, 用于自动创建不存在的仓库,Github可以在这里找到,Gitee可以在这里找到。

@classmatezhu
Copy link

@Yikun
@classmatezhu

Please make sure you have the correct access rights
and the repository exists.
Retry 2/3 exited 128, retrying in 2 seconds...
Load key "/root/.ssh/id_rsa": invalid format
Retry 3/3 exited 128, no more retries left.
[email protected]: Permission denied (publickey).
 Push failed 
fatal: Could not read from remote repository.
Total: 1, skip: 0, successed: 0, failed: 1.

看了下,你这个问题是因为key设置的问题,请确认secrets.GITEE_PRIVATE_KEY已经配置到了gitee侧的账户。鲲鹏目前无问题哦,显示失败是因为部分库为空导致的同步失败。

万分感谢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants