refactor and use --mirror for clone/push

This commit is contained in:
Iliyan Ivanov 2021-01-14 19:04:42 +02:00
parent d41725d9ae
commit c8f5639f1d
Signed by: iliyan
GPG Key ID: A20B95830B5794F3
7 changed files with 268 additions and 25 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/runme.sh
/init.sh

52
README.md Normal file
View File

@ -0,0 +1,52 @@
Migrate to gitea
Usage:
With key over ssh
```
./migrate.sh \
--admin gitea_user \
--url http://gitea.example.com \
--token TOKEN_VALUE \
--pushurl ssh://git@gitea.example.com:3022 \
"ARG 1" ... "ARG N"
```
With password over http
```
./migrate.sh \
--admin gitea_user \
--url http://gitea.example.com \
--token TOKEN_VALUE \
--password PASSWORD_VALUE \
"ARG 1" ... "ARG N"
```
ARG format: ``"/path/to/repo:ORG_NAME:REPO_NAME"``
examples:
```
# only path to repo - owner will be $GITEA_ADMIN_USERNAME
# name will be result of $(basename "/path/to/repo" ".git")
/path/to/repo
# org only
/path/to/repo:ORG_NAME
# org and name
/path/to/repo:ORG_NAME:REPO_NAME
# name only - owner will be $GITEA_ADMIN_USERNAME
/path/to/repo::REPO_NAME
```
configuration can be done with file ``./init.sh``
```
GITEA_ADMIN_USERNAME="$USER"
GITEA_SERVER_PUSH_URL="ssh://git@gitea.example.com:3022"
GITEA_ADMIN_TOKEN="TOKEN_VALUE"
GITEA_SERVER_URL="http://gitea.example.com"
```
Required commands:
```
git
curl
```

1
bitbucket/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/init.sh

99
bitbucket/migrate_to_gitea.sh Executable file
View File

@ -0,0 +1,99 @@
#!/usr/bin/env bash
set -euf -o pipefail
curp="$(cd "$(dirname "$0")" && pwd)"
bb_projects() {
# get all projects
curl --silent \
-u ${BB_ADMIN_USERNAME}:${SRC_TOKEN} \
"${BB_SERVER_URL}/rest/api/1.0/projects/" |
jq -r '.values[] | .key' |
tr '[:upper:]' '[:lower:]'
}
bb_repos() {
[ -z "$1" ] && return
# by project
curl --silent \
-u ${BB_ADMIN_USERNAME}:${SRC_TOKEN} \
"${BB_SERVER_URL}/rest/api/1.0/projects/$1/repos/" |
jq -r '.values[].name' |
tr '[:upper:]' '[:lower:]'
}
# unset all GITEA_* variables
unset "${!GITEA_@}"
[ -f "$curp/init.sh" ] && source "$curp/init.sh"
[ -z "${SRC_TOKEN}" ] && {
echo "SRC_TOKEN is empty" 1>&2
exit 1
}
: ${BB_ADMIN_USERNAME:=$USER}
: ${BB_ADMIN_PASSWORD:=}
ARGS=()
pos_arg_flag=0
while [[ $# -gt 0 ]]; do
if [ "${pos_arg_flag}" -eq "1" ]; then
ARGS+=("$1")
shift 1
continue
fi
case "$1" in
--url | -u)
BB_SERVER_URL="$2"
shift 2
;;
--token | -t)
SRC_TOKEN="$2"
shift 2
;;
--admin | -a)
BB_ADMIN_USERNAME="$2"
shift 2
;;
--password | -p)
BB_ADMIN_PASSWORD="$2"
shift 2
;;
--pushurl | -s)
BB_SERVER_PUSH_URL="$2"
shift 2
;;
--)
pos_arg_flag=1
shift 1
;;
--*=*)
set -- "$(cat - <<<"$1" | cut -d '=' -f1)" "$(cat - <<<"$1" | cut -d '=' -f2-)" "${@:3}"
;;
*)
ARGS+=("$1")
shift 1
;;
esac
done
[ -z "${BB_SERVER_PUSH_URL}" ] &&
BB_SERVER_PUSH_URL="$(echo "${BB_SERVER_URL}" | perl -pe "s#(https?://)#\${1}${BB_ADMIN_USERNAME}:${BB_ADMIN_PASSWORD}@#")/scm/"
# mirror all remote repos and get changes
for prj in $(bb projects); do
for repo in $(bb repo "$prj"); do
if [ -d "$curp/$prj/$repo" ]; then
(
cd "$curp/$prj/$repo"
git remote update
)
else
git clone --mirror "${BB_SERVER_PUSH_URL}/$prj/$repo" "$prj/$repo"
fi
done
done
# migrate all repos to gitea
"$curp/../migrate.sh" "$@"

21
include/bitbucket.sh Normal file
View File

@ -0,0 +1,21 @@
bitbucket_projects() {
url="$1"
username="$2"
token="$3"
# get all projects
curl --silent \
-u ${username}:${token} \
"${url}/rest/api/1.0/projects/" |
jq -r '.values[] | .key' |
tr '[:upper:]' '[:lower:]'
}
bitbucket_repos() {
url="$1"
username="$2"
token="$3"
curl --silent \
-u ${username}:${token} \
"${url}/rest/api/1.0/projects/$1/repos/" |
jq -r '.values[].name' |
tr '[:upper:]' '[:lower:]'
}

85
include/gitea.sh Normal file
View File

@ -0,0 +1,85 @@
gitea_endpoint() {
UTYPE="$1"
if [ "${UTYPE}" == "org" ]; then
API_ENDPOINT="orgs"
elif [ "${UTYPE}" == "user" ]; then
API_ENDPOINT="admin/users"
else
echo "unknown type '${UTYPE}'" 1>&2
exit 1
fi
echo -n "${API_ENDPOINT}"
}
gitea_users() {
GITEA_SERVER_API_URL="${GITEA_SERVER_URL}/api/v1"
curl --silent \
-H "Authorization: token ${GITEA_ADMIN_TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
"${GITEA_SERVER_API_URL}/$(gitea_endpoint "${UTYPE:-user}")" \
"$@"
}
gitea_repos() {
GITEA_SERVER_API_URL="${GITEA_SERVER_URL}/api/v1"
owner="$1"
curl --silent \
-H "Authorization: token ${GITEA_ADMIN_TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
"${GITEA_SERVER_API_URL}/$(gitea_endpoint "${UTYPE:-user}")/${owner}/repos" \
"${@:2}"
}
gitea_create_org() {
name="$1"
id=$(UTYPE=org gitea_users -X POST -d "{ \"username\": \"$name\", \"visibility\": \"limited\"}" | jq -r '.id')
[[ "$id" != "null" ]] && sleep 1 || true
}
gitea_create_user() {
name="$1"
id=$(gitea_users -X POST -d "{ \"username\": \"$name\", \"visibility\": \"limited\"}" | jq -r '.id')
[[ "$id" != "null" ]] && sleep 1 || true
}
gitea_create_repo() {
owner="$1"
repo="$2"
repoid=$(
UTYPE=$3 gitea_repos \
"$owner" \
-X POST \
-d "{\"auto_init\": false, \"private\": true, \"name\": \"$repo\"}" |
jq -r '.id'
)
[[ "$repoid" != "null" ]] && sleep 5 || true
}
gitea_create_repo_user() {
gitea_create_repo "$1" "$2" "user"
}
gitea_create_repo_org() {
gitea_create_repo "$1" "$2" "opg"
}
gitea_add_key_ssh() {
GITEA_SERVER_API_URL="${GITEA_SERVER_URL}/api/v1"
owner="$1"
pubkey_val="$(cat "${2}" | cut -d ' ' -f1,2 | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))')"
pubkey_name="$(cat "${2}" | cut -d ' ' -f3)"
curl --silent -X POST "${GITEA_SERVER_API_URL}/admin/users/${owner}/keys" \
-H "Authorization: token ${GITEA_ADMIN_TOKEN}" \
-H "accept: application/json" -H "Content-Type: application/json" \
-d "{ \"key\": ${pubkey_val}, \"read_only\": false ,\"title\":\"${pubkey_name}\"}"
}
gitea_add_key_gpg() {
GITEA_SERVER_API_URL="${GITEA_SERVER_URL}/api/v1"
gpg_key="$(gpg --export --armor "$1" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))')"
curl --silent -X POST "${GITEA_SERVER_API_URL}/user/gpg_keys" \
-H "Authorization: token ${GITEA_ADMIN_TOKEN}" \
-H "accept: application/json" -H "Content-Type: application/json" \
-d "{ \"armored_public_key\": ${gpg_key}"
}

View File

@ -4,23 +4,11 @@ set -euf -o pipefail
curp="$(cd "$(dirname "$0")" && pwd)"
create_org() {
orgid=$(curl --silent -X POST "${GITEA_SERVER_API_URL}/orgs" \
-H "Authorization: token ${GITEA_ADMIN_TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-d "{ \"username\": \"$1\", \"visibility\": \"limited\"}" | jq -r '.id')
[[ "$orgid" != "null" ]] && sleep 1 || true
}
# unset all GITEA_* variables
unset "${!GITEA_@}"
create_repo() {
repoid=$(curl --silent -X POST "${GITEA_SERVER_API_URL}$2" \
-H "Authorization: token ${GITEA_ADMIN_TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-d "{\"auto_init\": false, \"private\": true, \"name\": \"$1\"}" | jq -r '.id')
[[ "$repoid" != "null" ]] && sleep 5 || true
}
[ -f "$curp/init.sh" ] && source "$curp/init.sh"
source "${curp}/include/gitea.sh"
# defaults
: ${GITEA_ADMIN_USERNAME:=$USER}
@ -76,12 +64,6 @@ done
GITEA_SERVER_API_URL="${GITEA_SERVER_URL}/api/v1"
# repo examples
# /path/to/repo:orgname ( orgname only )
# /path/to/repo::reponame ( repo name only )
# /path/to/repo:orgname:reponame ( all options passed )
# /path/to/repo ( use name from path, no org )
# init repos
for repo in "${ARGS[@]}"; do
repoPath="$(echo "$repo" | cut -d ':' -f1 | tr -d '[:space:]')"
@ -91,14 +73,16 @@ for repo in "${ARGS[@]}"; do
if [ -z "$repoOrg" ]; then
repoAPIEP="/user/repos"
repoOwner="${GITEA_ADMIN_USERNAME}"
UTYPE=user
else
create_org "$repoOrg"
gitea_create_org "$repoOrg"
repoAPIEP="/org/$repoOrg/repos"
repoOwner="$repoOrg"
UTYPE=org
fi
create_repo "${repoName}" "${repoAPIEP}" 1>&2
gitea_create_repo "${repoOwner}" "${repoName}" "${UTYPE}" 1>&2
(
cd "$repoPath"
git push "${GITEA_SERVER_PUSH_URL}/${repoOwner}/${repoName}.git" master
git push "${GITEA_SERVER_PUSH_URL}/${repoOwner}/${repoName}.git" --mirror
)
done