1
Fork 0
mirror of https://github.com/RGBCube/GitHub2Forgejo synced 2025-07-27 05:07:45 +00:00

No more Gitea, only Forgejo

This commit is contained in:
RGBCube 2024-05-28 22:22:00 +03:00
parent fd315bdff5
commit 9523361143
Signed by: RGBCube
SSH key fingerprint: SHA256:CzqbPcfwt+GxFYNnFVCqoN5Itn4YFrshg1TrnACpA5M
2 changed files with 44 additions and 34 deletions

View file

@ -1,4 +1,4 @@
# GitHub to Gitea/Forgejo Migration Script # GitHub to Forgejo Migration Script
Plain simple, just install [Nushell](https://nushell.sh) and run the script: Plain simple, just install [Nushell](https://nushell.sh) and run the script:
@ -15,7 +15,7 @@ for a uninteractive run, or run the script like so:
And get a nice interactive experience. And get a nice interactive experience.
This works on any Gitea or Forgejo instance. This works on any Forgejo instance.
## FAQ ## FAQ
@ -31,7 +31,7 @@ This works on any Gitea or Forgejo instance.
### Can I migrate specific repositories? ### Can I migrate specific repositories?
Nope. Just use the Gitea/Forgejo web UI for that. Nope. Just use the Forgejo web UI for that.
## License ## License

View file

@ -1,33 +1,43 @@
#!/usr/bin/env nu #!/usr/bin/env nu
def or-default [default: closure] { def or-default [default: closure] {
if ($in | is-empty) { if ($in == null) {
do $default do $default
} else { } else {
$in $in
} }
} }
# Migrates a GitHub users repositories to a Gitea or Forgejo instance. # Migrates a GitHub users repositories to a Forgejo instance.
# #
# Here is the accepted environment variables, if one isn't set, it will # Accepted environment variables:
# be prompted for:
# #
# GITHUB_USER: The user to migrate from. # GITHUB_USER: The user to fetch the repositories from.
# GITHUB_TOKEN: An access token for fetching private repositories. Optional. # GITHUB_TOKEN: An access token for fetching private repositories. Optional.
# GITEA_URL: The URL to the Gitea or Forgejo instance #
# GITEA_USER: The user to migrate the repositories to. # FORGEJO_URL: The URL to the Forgejo instance. Must include the protocol (https://).
# GITEA_TOKEN: An access token for the user to actually insert repositories to. # FORGEJO_USER: The user to migrate the repositories to.
# STRATEGY: The strategy. Valid options are "mirrored" or "cloned" (case insensitive). # FORGEJO_TOKEN: An access token for the specified user.
# FORCE_SYNC: Whether to delete a mirrored repo from Gitea or Forgejo if the source on GitHub doesn't exist anymore. Must be either "true" or "false". #
# STRATEGY:
# The strategy. Valid options are "mirrored" or "cloned" (case insensitive).
# "mirrored" will mirror the repository and tell the Forgejo instance to
# periodically update it, "cloned" will only clone once. "cloned" is
# useful if you are never going to use GitHub again.
#
# FORCE_SYNC:
# Whether to delete a mirrored repo from the Forgejo instance if the
# source on GitHub doesn't exist anymore. Must be either "true" or "false".
#
# To leave an environment variable unspecified, set it to an empty string.
def main [] { def main [] {
let github_user = $env | get -i GITHUB_USER | or-default { input $"(ansi red)GitHub username: (ansi reset)" } let github_user = $env | get -i GITHUB_USER | or-default { input $"(ansi red)GitHub username: (ansi reset)" }
let github_token = $env | get -i GITHUB_TOKEN | or-default { input $"(ansi red)GitHub access token (ansi yellow)\((ansi blue)optional, only used for private repositories(ansi yellow))(ansi red): (ansi reset)" } let github_token = $env | get -i GITHUB_TOKEN | or-default { input $"(ansi red)GitHub access token (ansi yellow)\((ansi blue)optional, only used for private repositories(ansi yellow))(ansi red): (ansi reset)" }
let gitea_url = $env | get -i GITEA_URL | or-default { input $"(ansi green)Gitea instance URL \(with https://): (ansi reset)" } | str trim --right --char "/" let forgejo_url = $env | get -i FORGEJO_URL | or-default { input $"(ansi green)Forgejo instance URL \(with https://): (ansi reset)" } | str trim --right --char "/"
let gitea_user = $env | get -i GITEA_USER | or-default { input $"(ansi green)Gitea username or organization to migrate to: (ansi reset)" } let forgejo_user = $env | get -i FORGEJO_USER | or-default { input $"(ansi green)Forgejo username or organization to migrate to: (ansi reset)" }
let gitea_token = $env | get -i GITEA_TOKEN | or-default { input $"(ansi green)Gitea access token: (ansi reset)" } let forgejo_token = $env | get -i FORGEJO_TOKEN | or-default { input $"(ansi green)Forgejo access token: (ansi reset)" }
let strategy = $env | get -i STRATEGY | or-default { [ Mirrored Cloned ] | input list $"(ansi cyan)Should the repos be mirrored, or just cloned once?(ansi reset)" } | str downcase let strategy = $env | get -i STRATEGY | or-default { [ Mirrored Cloned ] | input list $"(ansi cyan)Should the repos be mirrored, or just cloned once?(ansi reset)" } | str downcase
let force_sync = $env | get -i FORCE_SYNC | or-default { [ "Yup, delete them" Nope ] | input list $"(ansi yellow)Should mirrored repos that don't have a GitHub source anymore be deleted?(ansi reset)" } | $in != "Nope" let force_sync = $env | get -i FORCE_SYNC | or-default { [ "Yup, delete them" Nope ] | input list $"(ansi yellow)Should mirrored repos that don't have a GitHub source anymore be deleted?(ansi reset)" } | $in != "Nope"
let github_repos = do { let github_repos = do {
def get-repos-at [page_nr: number] { def get-repos-at [page_nr: number] {
@ -60,32 +70,32 @@ def main [] {
if $force_sync { if $force_sync {
let github_repo_names = ($github_repos | get name) let github_repo_names = ($github_repos | get name)
let gitea_mirrored_repos = ( let forgejo_mirrored_repos = (
http get $"($gitea_url)/api/v1/user/repos" http get $"($forgejo_url)/api/v1/user/repos"
-H [ Authorization $"token ($gitea_token)" ] -H [ Authorization $"token ($forgejo_token)" ]
| filter { get mirror } | filter { get mirror }
| filter { ($github_token != "") and not $in.private } | filter { ($github_token != "") and not $in.private }
) )
let gitea_not_on_github = ($gitea_mirrored_repos | filter { not ($in.name in $github_repo_names) }) let forgejo_not_on_github = ($forgejo_mirrored_repos | filter { not ($in.name in $github_repo_names) })
$gitea_not_on_github | each {|gitea_repo| $forgejo_not_on_github | each {|forgejo_repo|
print --no-newline $"(ansi red)Deleting ($gitea_url)/($gitea_repo.full_name) because the mirror source doesn't exist on GitHub anymore...(ansi reset)" print --no-newline $"(ansi red)Deleting ($forgejo_url)/($forgejo_repo.full_name) because the mirror source doesn't exist on GitHub anymore...(ansi reset)"
(http delete $"($gitea_url)/api/v1/repos/($gitea_repo.full_name)" (http delete $"($forgejo_url)/api/v1/repos/($forgejo_repo.full_name)"
-H [ Authorization $"token ($gitea_token)" ]) -H [ Authorization $"token ($forgejo_token)" ])
print $" (ansi green_bold)Success!(ansi reset)" print $" (ansi green_bold)Success!(ansi reset)"
} }
} }
# Mirror repos that do exist on GitHub to Gitea. # Mirror repos that do exist on GitHub to Forgejo.
$github_repos | each {|github_repo| $github_repos | each {|github_repo|
print --no-newline $"(ansi blue)( print --no-newline $"(ansi blue)(
$strategy | str capitalize | str replace "ed" "ing" $strategy | str capitalize | str replace "ed" "ing"
) ( ) (
[ $"(ansi green)public(ansi blue)(char space)" $"(ansi red)private(ansi blue)" ] | get ($github_repo.private | into int) [ $"(ansi green)public(ansi blue)(char space)" $"(ansi red)private(ansi blue)" ] | get ($github_repo.private | into int)
) repository (ansi purple)($github_repo.html_url)(ansi blue) to (ansi white_bold)($gitea_url)/($gitea_user)/($github_repo.name)(ansi blue)...(ansi reset)" ) repository (ansi purple)($github_repo.html_url)(ansi blue) to (ansi white_bold)($forgejo_url)/($forgejo_user)/($github_repo.name)(ansi blue)...(ansi reset)"
let github_repo_url = if not $github_repo.private { let github_repo_url = if not $github_repo.private {
$github_repo.html_url $github_repo.html_url
@ -94,16 +104,16 @@ def main [] {
} }
let response = ( let response = (
http post $"($gitea_url)/api/v1/repos/migrate" http post $"($forgejo_url)/api/v1/repos/migrate"
--allow-errors --allow-errors
-t application/json -t application/json
-H [ Authorization $"token ($gitea_token)" ] -H [ Authorization $"token ($forgejo_token)" ]
{ {
clone_addr: $github_repo_url clone_addr: $github_repo_url
mirror: ($strategy != "cloned") mirror: ($strategy != "cloned")
private: $github_repo.private private: $github_repo.private
repo_owner: $gitea_user repo_owner: $forgejo_user
repo_name: $github_repo.name repo_name: $github_repo.name
} }
) )