Migrating from GitHub to Codeberg

By chimo on (updated on )

Some scripts I quickly wrote to copy my GitHub repositories over to Codeberg.

Copy

There are probably a ton of better scripts out there, but I wanted to write my own for various reasons.

It:

  1. Iterates through a user’s repositories.
  2. Ignores repositories part of an organization.
  3. Migrates the code and issues from GitHub to a public repo on Codeberg.

Requirements:

  • github-cli - Because I couldn’t be bothered handling API pagination.
  • GH_TOKEN - Environment variable holding your GitHub Personal Access Token
  • CB_TOKEN - Environment variable holding your Codeberg Personal Access Token
#!/bin/sh -eu

get_repos() (
    gh api -H "Accept: application/vnd.github+json" \
        -H "X-GitHub-Api-Version: 2022-11-28" /user/repos \
        --jq '.[] | select(.owner.type == "User").clone_url' \
        -X GET \
        --paginate
)


migrate_repo() (
    repo_url="${1}"

    path_leaf="${repo_url##*/}"
    repo_name="${path_leaf%.*}"

    body=$(cat << EOF
{
"auth_token": "${GH_TOKEN}",
"clone_addr": "${repo}",
"repo_name": "${repo_name}",
"issues": true,
"private": false,
"service": "github"
}
EOF
)

    curl -X POST 'https://codeberg.org/api/v1/repos/migrate' \
        -H 'accept: application/json' \
        -H 'content-type: application/json' \
        -H "Authorization: token ${CB_TOKEN}" \
        -d "${body}"
)


main() (
    repos=$(get_repos)


    while IFS= read -r repo
    do
        echo "Migrating ${repo}..."
        migrate_repo "${repo}"
        sleep 10
    done <<EOF
$repos
EOF
)


main

Redirect

A couple of days after copying the repositories over, after ensuring everything was where it should be on Codeberg, I wrote another script to replace my GitHub repositories with a single README in each repo mentioning the move.

It:

  1. Iterates through a user’s repositories.
  2. Deletes the repository (to get rid of history, issues, etc).
  3. Creates and clones a repository of the same name.
  4. Adds a README.md pointing to the new location.
  5. Pushes the file over to GitHub over SSH.

Requirements:

  • github-cli - Because I had it installed for the previous script
  • GH_TOKEN - Environment variable holding your GitHub Personal Access Token
  • Replace <cb-username> with your Codeberg username
  • Replace <gh-username> with your GitHub username
#!/bin/sh -eu

get_repos() (
    gh api -H "Accept: application/vnd.github+json" \
        -H "X-GitHub-Api-Version: 2022-11-28" /user/repos \
        --jq '.[] | select(.owner.type == "User").clone_url' \
        -X GET \
        --paginate
)


main() (
    repos=$(get_repos)

    while IFS= read -r repo_url
    do
        path_leaf="${repo_url##*/}"
        repo="${path_leaf%.*}"

        # Delete
        echo "Deleting ${repo}..."
        gh repo delete "${repo}" --yes
        sleep 10

        # Create, clone
        echo "Creating ${repo}..."
        gh repo create "${repo}" \
            --homepage "https://codeberg.org/<cb-username>/${repo}" \
            --clone \
            --public

        cd "${repo}"

        # Create README
        sed 's/<repo>/'"${repo}"'/' ../template.md > README.md

        # Push
        git add .
        git commit -m 'Moved'
        git push git@github.com:<gh-username>/"${repo}".git master

        cd ..
    done <<EOF
$repos
EOF
)


main

My template.md file looks like:

# Moved

This repository has been moved to https://codeberg.org/<cb-username>/<repo>