源:github
, gitlab
, gitee
源仓库:源仓库地址(不含网址),如 org/repo
目标仓库:目标仓库地址(不含网址),如 org/repo
状态:是否同步,true
表示同步,其它则表示不同步
sync.sh
#!/usr/bin/env bash
set -e
main() {
USER_TOKEN="${USER_TOKEN:-}"
USER_NAME="${GITLAB_USER_LOGIN:-}"
TARGET_HUB="${CI_SERVER_HOST:-}"
PROJECT_PATH="${CI_PROJECT_PATH:-}"
if [ -z "$USER_TOKEN" ] || [ -z "$USER_NAME" ] || [ -z "$TARGET_HUB" ]; then
echo "[ERROR] USER_TOKEN, USER_NAME, TARGET_HUB must be set"
exit 1
fi
PROJECT_PATH_URL="$(echo "$PROJECT_PATH" | sed 's/\//%2F/g')"
echo "FETCH API: https://$TARGET_HUB/api/v4/projects/$PROJECT_PATH_URL/wikis/home"
DATA=$(curl -fsSL -H "PRIVATE-TOKEN:$USER_TOKEN" "https://$TARGET_HUB/api/v4/projects/$PROJECT_PATH_URL/wikis/home" | jq '.content')
echo -e "$DATA" | sed 's# ##g' | 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=${STATUS%%|*}
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 "custom code hub: $CODE_HUB"
CODE_URL="https://$CODE_HUB/$CODE_REPO.git"
# 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
}
main "$@" || exit 1
.gitlab-ci.yaml
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:-}"
PROJECT_PATH="${CI_PROJECT_PATH:-}"
if [ -z "$USER_TOKEN" ] || [ -z "$USER_NAME" ] || [ -z "$TARGET_HUB" ]; then
echo "[ERROR] USER_TOKEN, USER_NAME, TARGET_HUB must be set"
exit 1
fi
PROJECT_PATH_URL="$(echo "$PROJECT_PATH" | sed 's/\//%2F/g')"
echo "FETCH API: https://$TARGET_HUB/api/v4/projects/$PROJECT_PATH_URL/wikis/home"
DATA=$(curl -fsSL -H "PRIVATE-TOKEN:$USER_TOKEN" "https://$TARGET_HUB/api/v4/projects/$PROJECT_PATH_URL/wikis/home" | jq '.content')
echo -e "$DATA" | sed 's# ##g' | 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=${STATUS%%|*}
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 "custom code hub: $CODE_HUB"
CODE_URL="https://$CODE_HUB/$CODE_REPO.git"
# 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