之前关注的有些 GitHub 仓库,总是有突然消失的情况,所以就写了个代码同步的CI。
因为,有些平台(比如 framagit)不提供 镜像拉取的功能。或者那些平台(比如 gitcode)的「同步」功能很鸡肋,时不时会同步不成功。
镜像拉取
sync
设置
CI/CD
变量
USER_TOKEN
访问令牌
作业
流水线计划
同步到本账号名下的仓库、本账号或读写的仓库
REPOS.md
示例:
| 源 | 源仓库 | 目标仓库 | 状态 | | -------- | --------------------------------------------------- | ---------------- | ---- | | `github` | `linuxdeepin/linglong` | `myorg/linuxdeepin/linglong` | true |
| 源 | 源仓库 | 目标仓库 | 状态 |
源:github, gitlab, gitee 源仓库:源仓库地址(不含网址),如 org/repo 目标仓库:目标仓库地址(不含网址),如 org/repo 状态:是否同步,true 表示同步,其它则表示不同步
github
gitlab
gitee
org/repo
true
.gitlab-ci.yml
default: image: alpine:latest stages: - build build-sync-job: stage: build before_script: | apk update apk add curl git jq script: | USER_TOKEN="${USER_TOKEN}" USER_NAME="${GITLAB_USER_LOGIN}" TARGET_HUB="${CI_SERVER_HOST}" awk -F'|' '{print $2, $3, $4, $5}' "REPOS.md" | while IFS=" " read -r ORIGIN_HUB ORIGIN_REPO TARGET_REPO STATUS; do CODE_HUB=$(echo "$ORIGIN_HUB" | cut -d '`' -f 2) CODE_REPO=$(echo "$ORIGIN_REPO" | cut -d '`' -f 2) TARGET_REPO=$(echo "$TARGET_REPO" | cut -d '`' -f 2) STATUS=$(echo "$STATUS" | cut -d '`' -f 2) CODE_HUB="${CODE_HUB-github}" CODE_REPO="${CODE_REPO-}" TARGET_REPO="${TARGET_REPO-}" STATUS="${STATUS-}" if [ -z "$CODE_HUB" ] || [ -z "$CODE_REPO" ] || [ -z "$TARGET_REPO" ]; then continue fi if [ "$STATUS" != "true" ]; then continue fi case $CODE_HUB in github | gitlab | gitee) CODE_URL="https://$CODE_HUB.com/$CODE_REPO.git" ;; *) echo "unknown code hub: $CODE_HUB" continue ;; esac HTTPS_REPO_URL="https://$USER_NAME:$USER_TOKEN@$TARGET_HUB/$TARGET_REPO.git" echo "CODE_URL: $CODE_URL" echo "HTTPS_REPO_URL: $HTTPS_REPO_URL" [ -d procode ] && rm -rf procode git clone "$CODE_URL" procode cd procode || { echo "not found procode" exit 1 } git remote add target "$HTTPS_REPO_URL" git fetch git push target --all --force git push target --tags --force cd .. done
当前只写了 github, gitlab, gitee,可自行修改以支持同步其它平台。或者将代码提取出来,以支持非 GitLab 平台。
github, gitlab, gitee
更新本组织的仓库镜像。适合创建一个专门同步的组织
原理是,从 GitLab 提供的 API 获取当前组织下的所有仓库,并提取描述信息,再进行同步。
先创建一个仓库,可为空仓库。或者直接从源站导入。然后修改仓库描述:
# 格式:::PALTFORM@ORG/REPO 空格后面可以添加描述。 # 若不添加平台,则默认为 github。即 ::aaa/bbb 实际为 ::github@aaa/bbb # 注意,最后是有个空格的。 ::gedoor/legado # 或者 ::gitee@gedoor/legado
default: image: alpine:latest stages: - build build-sync-job: stage: build before_script: | apk update apk add bash curl git jq script: | ORG_NAME="$CI_PROJECT_NAMESPACE" curl -o projects.json -H "PRIVATE-TOKEN:$USER_TOKEN" "https://$CI_SERVER_HOST/api/v4/groups/$ORG_NAME/projects" JSON_DATA=$(cat projects.json) for entry in $(echo "$JSON_DATA" | jq -r '.[] | @base64'); do decoded_entry=$(echo "$entry" | base64 -d) path=$(echo "$decoded_entry" | jq -r '.path') description=$(echo "$decoded_entry" | jq -r '.description') http_url_to_repo=$(echo "$decoded_entry" | jq -r '.http_url_to_repo') path_with_namespace=$(echo "$decoded_entry" | jq -r '.path_with_namespace') case $description in "::"*) echo "-> [$path] sync ..." # origin repo -> ::gitlab@org/repo THIS IS SYNC PROJECT SYNC_VARS="$(echo "$description" | head -n 1 | awk -F ' ' '{print $1}' | sed 's#::##')" ORIGIN_HUB=$(echo "$SYNC_VARS" | awk -F@ '{print $1}') ORIGIN_REPO=$(echo "$SYNC_VARS" | awk -F@ '{print $2}') # default github if [[ -z "$ORIGIN_REPO" ]]; then ORIGIN_REPO="$ORIGIN_HUB" ORIGIN_HUB="github" fi case $ORIGIN_HUB in github | gitlab | gitee) CODE_URL="https://$ORIGIN_HUB.com/$ORIGIN_REPO.git" ;; *) echo "unknown code hub: $ORIGIN_HUB" return ;; esac HTTPS_REPO_URL="https://$GITLAB_USER_LOGIN:$USER_TOKEN@$CI_SERVER_HOST/$path_with_namespace.git" echo "HTTPS_REPO_URL: $HTTPS_REPO_URL" [[ -d procode ]] && rm -rf procode git clone "$CODE_URL" procode cd procode git remote add target "$HTTPS_REPO_URL" git fetch git push target --all --force git push target --tags --force cd .. ;; # *) echo "path: $path skip sync." ;; esac done
可将代码部分提取出来,自行实现支持更多平台的同步(同步到本平台、同步到其它平台、同步到多个平台。拉取更多的平台)。
两种方式各有侧重点: 第一种,每次有新的仓库需要同步时,都需要重新修改 REPOS.md文件,但是支持个人账号名下的账号,以及其它个别组织的的个别仓库。 第二种,只支持当前组织下的仓库。但是,当有新的项目需要同步时,可以直接修改新仓库,并修改描述即可。适合创建一个专门做镜像用的组织。
如果是要做代码推送时同步的功能。不需要这么麻烦,只需要在在“设置”->“仓库”->“镜像仓库”中设置推送的目标仓库即可。
Popular Ranking
Popular Events
之前关注的有些 GitHub 仓库,总是有突然消失的情况,所以就写了个代码同步的CI。
配置
sync
。sync
仓库设置
->CI/CD
->变量
,设置 CI 环境变量USER_TOKEN
,值为当前用户的访问令牌
。作业
->流水线计划
中创建定时任务。方式一:从文件中读取同步信息
同步到本账号名下的仓库、本账号或读写的仓库
REPOS.md
示例:
.gitlab-ci.yml
当前只写了
github, gitlab, gitee
,可自行修改以支持同步其它平台。或者将代码提取出来,以支持非 GitLab 平台。方式二:从描述中读取同步信息
更新本组织的仓库镜像。适合创建一个专门同步的组织
先创建一个仓库,可为空仓库。或者直接从源站导入。然后修改仓库描述:
.gitlab-ci.yml
可将代码部分提取出来,自行实现支持更多平台的同步(同步到本平台、同步到其它平台、同步到多个平台。拉取更多的平台)。
两种方式各有侧重点:
第一种,每次有新的仓库需要同步时,都需要重新修改
REPOS.md
文件,但是支持个人账号名下的账号,以及其它个别组织的的个别仓库。第二种,只支持当前组织下的仓库。但是,当有新的项目需要同步时,可以直接修改新仓库,并修改描述即可。适合创建一个专门做镜像用的组织。