-
Notifications
You must be signed in to change notification settings - Fork 8
/
migrate.rb
101 lines (81 loc) · 3.19 KB
/
migrate.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
require 'gitlab'
require 'octokit'
require 'octopoller'
require 'uri'
# Enter your details/credentials here
GL_SERVER = ""
GL_PRIVATE_TOKEN = ""
GH_PRIVATE_TOKEN = ""
GH_ORG_NAME = ""
GL_ENDPOINT = "http://#{GL_SERVER}/api/v4"
PROGRESS_FILE_NAME = "./progress.txt"
# Read or create progress file
if File.exist?(PROGRESS_FILE_NAME)
completed_repositories = File.open(PROGRESS_FILE_NAME).readlines.map(&:strip)
else
File.write(PROGRESS_FILE_NAME, "")
completed_repositories = []
end
# Instantiate/configure GL and GH clients
Gitlab.configure do |config|
config.endpoint = GL_ENDPOINT
config.private_token = GL_PRIVATE_TOKEN
end
# Create an authorised URL to the repo on GL using the GL private token
def gl_authed_uri(gl_project)
gl_repo_uri = URI.parse(gl_project.http_url_to_repo)
"http://oauth2:#{GL_PRIVATE_TOKEN}@#{GL_SERVER}#{gl_repo_uri.path}"
end
gh_client = Octokit::Client.new(:access_token => GH_PRIVATE_TOKEN)
# Fetch a list of all Gitlab projects
gl_projects = Gitlab.projects.auto_paginate
puts "Found #{gl_projects.length} projects."
# Loop through each GL project
gl_projects.each do |gl_project|
if completed_repositories.include?(gl_project.http_url_to_repo)
puts "Skipping #{gl_project.name} (id: #{gl_project.id}) as it already exists in the progress file."
next
else
puts "Importing #{gl_project.name} (id: #{gl_project.id}) from #{gl_project.http_url_to_repo}..."
end
# The repo to import to on GH
destination_repo = "#{GH_ORG_NAME}/#{gl_project.name.gsub(' ', '-')}"
# Ensure the GL user is a member of the project we want to export
begin Gitlab.add_team_member(gl_project.id, 4, 40)
puts "You've been successfully added as a maintainer of this project on GitLab."
rescue Gitlab::Error::Conflict => e
puts "You are already a member of this project on GitLab."
end
# Create the repository on GH or show an error
begin gh_client.create_repository(gl_project.name, organization: GH_ORG_NAME, private: true)
puts "New repo created on GitHub."
rescue Octokit::UnprocessableEntity => e
# If error everything else could fail, unless the error was that the repo already existed
puts "Error creating repository on GitHub: #{e.message}"
end
# Cancel any GH import for this repo - mainly used for testing
gh_client.cancel_source_import(destination_repo, accept: Octokit::Preview::PREVIEW_TYPES[:source_imports])
puts "Starting import to GitHub (this may take some time)..."
# Start the import to GH!
gh_client.start_source_import(
destination_repo,
gl_authed_uri(gl_project),
vcs: "git",
accept: Octokit::Preview::PREVIEW_TYPES[:source_imports]
)
# Check the progress of the import, re-poll until status is "Done"
Octopoller.poll(timeout: 15000) do
result = gh_client.source_import_progress(destination_repo, accept: Octokit::Preview::PREVIEW_TYPES[:source_imports])
print "\r#{result.status_text}"
if result.status_text == "Done"
nil
else
:re_poll
end
end
# Log this project as imported
File.write(PROGRESS_FILE_NAME, gl_project.http_url_to_repo + "\n", mode: 'a')
# All done!
puts "Finished import of #{gl_project.name}!"
puts "--------------------------------------\n"
end