mirror of
https://github.com/RGBCube/GitHub2Forgejo
synced 2025-07-26 04:37:43 +00:00
Fix private repo cloning
This commit is contained in:
parent
81a362f773
commit
f157b3c077
2 changed files with 65 additions and 60 deletions
|
@ -31,11 +31,7 @@ This works on any Gitea or Forgejo instance.
|
||||||
|
|
||||||
### Can I migrate specific repositories?
|
### Can I migrate specific repositories?
|
||||||
|
|
||||||
Sure, just pass the URLs to them as arguments:
|
Nope. Just use the Gitea/Forgejo web UI for that.
|
||||||
|
|
||||||
```nu
|
|
||||||
./migrate.nu https://github.com/RGBCube/Foo https://github.com/RGBCube/Bar
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
119
migrate.nu
119
migrate.nu
|
@ -19,89 +19,98 @@ def or-default [default: closure] {
|
||||||
# GITEA_USER: The user to migrate the repositories to.
|
# GITEA_USER: The user to migrate the repositories to.
|
||||||
# GITEA_TOKEN: An access token for the user to actually insert repositories to.
|
# GITEA_TOKEN: An access token for the user to actually insert repositories to.
|
||||||
# STRATEGY: The strategy. Valid options are "mirrored" or "cloned" (case insensitive).
|
# STRATEGY: The strategy. Valid options are "mirrored" or "cloned" (case insensitive).
|
||||||
def main [
|
# 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".
|
||||||
...repo_urls: string # The GitHub repo URLs to migrate to Gitea or Forgejo. If not given, all will be fetched.
|
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 gitea_url = $env | get -i GITEA_URL | or-default { input $"(ansi green)Gitea 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 gitea_user = $env | get -i GITEA_USER | or-default { input $"(ansi green)Gitea 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 gitea_token = $env | get -i GITEA_TOKEN | or-default { input $"(ansi green)Gitea 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 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 gitea_uid = (
|
def get-repos [page_nr: number] {
|
||||||
http get $"($gitea_url)/api/v1/users/($gitea_user)"
|
|
||||||
-H [ Authorization $"token ($gitea_token)" ]
|
|
||||||
) | get -i id
|
|
||||||
|
|
||||||
if $gitea_uid == null {
|
|
||||||
echo "Invalid Gitea username or password"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
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 repo_urls = if ($repo_urls | length) != 0 {
|
|
||||||
$repo_urls
|
|
||||||
} else {
|
|
||||||
if $github_token != "" {
|
if $github_token != "" {
|
||||||
(
|
(http get $"https://api.github.com/user/repos?per_page=100&page=($page_nr)"
|
||||||
http get $"https://api.github.com/users/($github_user)/repos?per_page=100"
|
-H [ Authorization $"token ($github_token)" ])
|
||||||
-H [ Authorization $"token ($github_token)" ]
|
} else {
|
||||||
|
http get $"https://api.github.com/users/($github_user)/repos?per_page=100?page=($page_nr)"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mut github_repos = []
|
||||||
|
mut github_repo_page_nr = 1
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let next_repos = get-repos $github_repo_page_nr
|
||||||
|
$github_repos = ($github_repos | append $next_repos)
|
||||||
|
|
||||||
|
if ($next_repos | length) >= 100 {
|
||||||
|
$github_repo_page_nr += 1
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$github_repos = ($github_repos | filter { get owner.login | $in == $github_user })
|
||||||
|
|
||||||
|
# Delete mirrored repos that do not exist on GitHub.
|
||||||
|
if $force_sync {
|
||||||
|
let github_repo_names = ($github_repos | get name)
|
||||||
|
|
||||||
|
let gitea_mirrored_repos = (
|
||||||
|
http get $"($gitea_url)/api/v1/user/repos"
|
||||||
|
-H [ Authorization $"token ($gitea_token)" ]
|
||||||
|
| filter { get mirror }
|
||||||
)
|
)
|
||||||
| get html_url
|
|
||||||
|
let gitea_not_on_github = ($gitea_mirrored_repos | filter { not ($in.name in $github_repo_names) })
|
||||||
|
|
||||||
|
$gitea_not_on_github | each {|repo|
|
||||||
|
print --no-newline $"(ansi red)Deleting ($gitea_url)/($repo.full_name) because the mirror source doesn't exist on GitHub anymore...(ansi reset)"
|
||||||
|
|
||||||
|
(http delete $"($gitea_url)/api/v1/repos/($repo.full_name)"
|
||||||
|
-H [ Authorization $"token ($gitea_token)" ])
|
||||||
|
|
||||||
|
print $" (ansi green)Success!(ansi reset)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mirror repos that do exist on GitHub to Gitea.
|
||||||
|
$github_repos | each {|repo|
|
||||||
|
let url = if not $repo.private {
|
||||||
|
$repo.html_url
|
||||||
} else {
|
} else {
|
||||||
http get $"https://api.github.com/users/($github_user)/repos?per_page=100"
|
$"https://($github_token)@github.com/($github_user)/($repo.name)"
|
||||||
| get html_url
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$repo_urls | each {|url|
|
print --no-newline $"(ansi blue)($strategy | str capitalize | str replace "ed" "ing") ([ public private ] | get ($repo.private | into int)) repository ($url) to ($gitea_url)/($gitea_user)/($repo.name)...(ansi reset)"
|
||||||
let repo_name = $url | split row "/" | last
|
|
||||||
|
|
||||||
let repo_is_private = if ($github_token | is-empty) {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
http get ("https://api.github.com/repos/" + $github_user + "/" + $repo_name)
|
|
||||||
-H [ Authorization $"token ($github_token)" ]
|
|
||||||
).private
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = if not $repo_is_private {
|
|
||||||
$url
|
|
||||||
} else {
|
|
||||||
$"https://($github_token)@github.com/($github_user)/($repo_name)"
|
|
||||||
}
|
|
||||||
|
|
||||||
print --no-newline $"(ansi blue)($strategy | str replace "ed" "ing") ([ public private ] | get ($repo_is_private | into int)) repository ($url) to ($gitea_url)/($gitea_user)/($repo_name)..."
|
|
||||||
|
|
||||||
let response = (
|
let response = (
|
||||||
http post $"($gitea_url)/api/v1/repos/migrate"
|
http post $"($gitea_url)/api/v1/repos/migrate"
|
||||||
--allow-errors
|
--allow-errors
|
||||||
-t application/json
|
-t application/json
|
||||||
-H [
|
-H [ Authorization $"token ($gitea_token)" ]
|
||||||
Authorization $"token ($gitea_token)"
|
|
||||||
]
|
|
||||||
{
|
{
|
||||||
clone_addr: $url
|
clone_addr: $url
|
||||||
mirror: ($strategy != "cloned")
|
mirror: ($strategy != "cloned")
|
||||||
private: $repo_is_private
|
private: $repo.private
|
||||||
uid: $gitea_uid
|
|
||||||
|
|
||||||
repo_owner: $gitea_user
|
repo_owner: $gitea_user
|
||||||
repo_name: $repo_name
|
repo_name: $repo.name
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
let error_message = ($response | get -i message)
|
let error_message = ($response | get -i message)
|
||||||
if ($error_message != null and $error_message =~ "already exists") {
|
if ($error_message != null and $error_message =~ "already exists") {
|
||||||
print $" (ansi yellow)Already mirrored!"
|
print $" (ansi yellow)Already mirrored!(ansi reset)"
|
||||||
} else if ($error_message != null) {
|
} else if ($error_message != null) {
|
||||||
print $" (ansi red)Unknown error: ($error_message)"
|
print $" (ansi red)Unknown error: ($error_message)(ansi reset)"
|
||||||
} else {
|
} else {
|
||||||
print $" (ansi green)Success!"
|
print $" (ansi green)Success!(ansi reset)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
null
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue