diff --git a/README.md b/README.md index bb874af..d455549 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,13 @@ ## Usage +To use this script you need to install `jq` package on your system. + +On Ubuntu 22 it can be done using this command: +``` +sudo apt install jq +``` + Currently, there are two scripts in this repository. One is able to create mirrors for various GitHub entities and the other is capable of deleting an entire Gitea organization with all of its repositories. diff --git a/gitea2gitea-mirror b/gitea2gitea-mirror deleted file mode 100755 index 3bc3769..0000000 --- a/gitea2gitea-mirror +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/bash - -# -# Script to mirror Gitea repos to another Gitea instance. -# -# Modes: -# - Mirror a public/private repo -# - Mirror all public/private repos of a user -# - Mirror all public/private repos of an organization -# -# Heavily inspired by: -# https://github.com/juergenhoetzel/github2gitea-mirror -# - -# ENVs: -# ACCESS_TOKEN_SRC = Gitea token of the source instance -# GITERA_URL_SRC = Gitea URL of the source instance -# ACCESS_TOKEN_TRG = Gitea token of the target instance -# GITEA_URL_TRG = Gitea URL of the target instance - -# Displays the given input including "=> " on the console. -log () { - echo "=> $1" -} - -CURL="curl -f -S -s" - -# Check for correctly set ENVs -# TODO: GITEA_URL_SRC is also necessary -# ACCESS_TOKEN_TRG and GITEA_URL_TRG are always necessary -if [[ -z "${ACCESS_TOKEN_TRG}" || -z "${GITEA_URL_TRG}" ]]; then - echo -e "Please set the Gitea access token and URL in environment:\nexport ACCESS_TOKEN_TRG=abc\nexport GITEA_URL_TRG=http://gitea:3000\n" >&2 - echo -e "Don't use a trailing slash in URL!" - exit 1 -fi - -# Parse input arguments -if [[ -z "$1" ]]; then - log "No parameter(s) given. Exit." - exit 1 -fi -while [[ "$#" -gt 0 ]]; do - case $1 in - -m|--mode) mode="$2"; shift ;; - -o|--org) gitea_organization="$2"; shift ;; - -u|--user) gitea_user="$2"; shift ;; - -v|--visibility) visibility="$2"; shift ;; - -r|--repo) repo="$2"; shift ;; - *) log "Unknown parameter passed: $1"; exit 1 ;; - esac - shift -done - -# Prints a message on how to use the script with exit 1 -fail_print_usage () { - echo -e "Usage: $0" - echo -e " -m, --mode {org,repo,user} Mode to use; either mirror an organization or an user." - echo -e " -o, --org \$organization Gitea organization to mirror and/or the target organization in Gitea." - echo -e " -u, --user \$gitea_user Gitea user to gather the repositories from." - echo -e " -v, --visibility {public,private} Visibility for the created Gitea organization." - echo -e " -r, --repo \$repo_url Gitea URL of a single repo to create a mirror for." - echo "" >&2 - exit 1; -} - -# Check if mode is set -if [[ -z "${mode}" ]]; then - fail_print_usage -fi - -# Check required parameters per mode -if [ "${mode}" == "org" ]; then - if [[ -z "${gitea_organization}" ]]; then - echo -e "Organization not set." - fail_print_usage - fi - - if [[ -z "${visibility}" ]]; then - echo -e "Visibility not set." - fail_print_usage - fi -elif [ "${mode}" == "repo" ]; then - if [[ -z "${repo}" || -z "${gitea_user}" ]]; then - echo -e "Repo URL or Gitea user not set." - fail_print_usage - fi -elif [ "${mode}" == "user" ]; then - if [[ -z "${gitea_user}" ]]; then - echo -e "Gitea user not set." - fail_print_usage - fi -else - echo -e "Mode not found." - fail_print_usage -fi - -# TODO: -#set -euo pipefail -set -eu pipefail - -header_options_trg=(-H "Authorization: Bearer ${ACCESS_TOKEN_TRG}" -H "accept: application/json" -H "Content-Type: application/json") -header_options_src=(-H "Authorization: Bearer ${ACCESS_TOKEN_SRC}" -H "accept: application/json" -H "Content-Type: application/json") -jsonoutput=$(mktemp -d -t gitea-repos-XXXXXXXX) - -#trap "rm -rf ${jsonoutput}" EXIT -# TODO - -# Sets the uid to the specified Gitea organization -set_uid() { - uid=$($CURL "${header_options_trg[@]}" $GITEA_URL_TRG/api/v1/orgs/${gitea_organization} | jq .id) -} - -# Sets the uid to the specified Gitea user -set_uid_user() { - uid=$($CURL "${header_options_trg[@]}" $GITEA_URL_TRG/api/v1/users/${gitea_user} | jq .id) -} - -# Fetches all public/private repos of the given Gitea organization to JSON files -fetch_orga_repos() { - # TODO - log "Fetch organization repos." - i=1 - # GitHub API just returns empty arrays instead of 404 - while $CURL "https://api.github.com/orgs/${gitea_organization}/repos?page=${i}&per_page=100" -u "username:${GITHUB_TOKEN}" >${jsonoutput}/${i}.json \ - && (( $(jq <${jsonoutput}/${i}.json '. | length') > 0 )) ; do - (( i++ )) - done -} - -# Fetches all public/private repos of the given Gitea user to JSON files -fetch_user_repos() { - # TODO - log "Fetch user repos." - # i=1 - # GitHub API just returns empty arrays instead of 404 - # while $CURL "https://api.github.com/user/repos?affiliation=owner&page=${i}&per_page=100" -u "${github_user}:${GITHUB_TOKEN}" >${jsonoutput}/${i}.json \ - # && (( $(jq <${jsonoutput}/${i}.json '. | length') > 0 )) ; do - # (( i++ )) - # done - -# $CURL -w "%{http_code}\n" "${header_options_src[@]}" -d @- -X GET $GITEA_URL_SRC/api/v1/user/repos - mkdir -p $jsonoutput - # touch $jsonoutput/1.json - $CURL "${header_options_src[@]}" -X GET $GITEA_URL_SRC/api/v1/user/repos >$jsonoutput/1.json - - # TODO - # exit 1 -} - -# Fetches one public/private Gitea repo to a JSON file -fetch_one_repo() { - # TODO - log "Fetch one repo." - # Remove URL prefix - repo=$(echo $repo | sed "s/https:\/\/github.com\///g" | sed "s/.git//g") - $CURL "https://api.github.com/repos/$repo" -u "username:${GITHUB_TOKEN}" >${jsonoutput}/1.json -} - -# Creates a specific migration repo on Gitea -create_migration_repo() { - log "Create migration repo." - if ! $CURL -w "%{http_code}\n" "${header_options_trg[@]}" -d @- -X POST $GITEA_URL_TRG/api/v1/repos/migrate > ${jsonoutput}/result.txt 2>${jsonoutput}/stderr.txt; then - local code=$(<${jsonoutput}/result.txt) - if (( code != 409 ));then # 409 == repo already exits - cat ${jsonoutput}/stderr.txt >&2 - fi - fi -} - -# Creates a specific public/private organization on Gitea -create_migration_orga() { - visibility="${1:-}" - log "Create migration orga with name: ${gitea_organization}" - if ! $CURL -X POST $GITEA_URL_TRG/api/v1/orgs "${header_options_trg[@]}" --data '{"username": "'"${gitea_organization}"'", "visibility": "'"${visibility}"'"}' > ${jsonoutput}/result.txt 2>${jsonoutput}/stderr.txt; then - local code=$(<${jsonoutput}/result.txt) - if (( code != 422 ));then # 422 == orga already exits - cat ${jsonoutput}/stderr.txt >&2 - fi - fi -} - -# Creates a migration repo on Gitea for each Gitea repo in the JSON files -repos_to_migration() { - # TODO - log "Repos to migration started." - # for f in ${jsonoutput}/*.json; do - # n=$(jq '. | length'<$f) - # if [[ "${n}" -gt "0" ]]; then - # (( n-- )) # last element - # else - # continue; - # fi - # for i in $(seq 0 $n); do - # mig_data=$(jq ".[$i] | .uid=${uid} | \ - # if(.visibility==\"private\") then .private=true else .private=false end |\ - # if(.visibility==\"private\") then .auth_username=\"${github_user}\" else . end | \ - # if(.visibility==\"private\") then .auth_password=\"${GITHUB_TOKEN}\" else . end | \ - # .mirror=true | \ - # .clone_addr=.clone_url | \ - # .description=.description[0:255] | \ - # .repo_name=.name | \ - # {uid,repo_name,clone_addr,description,mirror,private,auth_username,auth_password}" <$f) - # echo "Migrating repo" $(jq ".[$i] | .uid=${uid} | .name" <$f) - # echo $mig_data | create_migration_repo - # done - # done - - -} - -# Creates one migration repo on Gitea for the one Gitea repo in '1.json' -one_repo_to_migration() { - # TODO - log "One repo to migration started." - # There should only be one JSON file - for f in ${jsonoutput}/*.json; do - mig_data=$(jq ".repo_owner=\"${gitea_user}\" | \ - if(.visibility==\"private\") then .private=true else .private=false end |\ - if(.visibility==\"private\") then .auth_username=\"${gitea_user}\" else . end | \ - if(.visibility==\"private\") then .auth_password=\"${GITEA_TOKEN_SRC}\" else . end | \ - .mirror=true | \ - .clone_addr=.clone_url | \ - .description=.description[0:255] | \ - .repo_name=.name | \ - {repo_owner,repo_name,clone_addr,description,mirror,private,auth_username,auth_password}" <$f) - echo "Migrating repo" $(jq ".name" <$f) - echo $mig_data | create_migration_repo - done -} - -# Actual run the script -if [ "${mode}" == "org" ]; then - log "Mode = organization" - fetch_orga_repos - create_migration_orga ${visibility} - set_uid - repos_to_migration -elif [ "${mode}" == "repo" ]; then - log "Mode = single repo" - fetch_one_repo - one_repo_to_migration -elif [ "${mode}" == "user" ]; then - log "Mode = user" -# set_uid_user - fetch_user_repos - exit 1 - # TODO - repos_to_migration -fi - -log "Finished."