Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GitHub import script] README.md + improvements #253

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions import/github/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import_all.rb is a ruby script that can import repositories from GitHub to GitLab.

## Simple usage:
```bash
ruby import_all.rb -u <github login> -p <github password> \
-s <github space to import projects from> -t <gitlab secret key> \
--gitlab-api http://<my.gitlab.host>/api/v3
```
This command will import all public projects from specified space. Take in mind, that you should specify valid GitHub user login and password (2-factor authentication is not supported). Also, script uses directory /tmp/clones, it should be **created** and **empty**.

## CLI options
* **-u, --user USER** - user to connect to *GitHub* with. Valid *GitHub* user login.
* **-p, --pw PASSWORD** - password for user to connect to *GitHub* with. Valid *GitHub* user password.
* **--api API** - API endpoint for *GitHub*. Default is "https://api.github.com". Change it to import from the *GitHub* Enterprise.
* **--web** - Web endpoint for *GitHub*. Default is "https://github.com/". Change it to import from the *GitHub* Enterprise.
* **--gitlab-api API** - API endpoint for *GitLab*. Set it to API endpoint of the destination *GitLab* instance.
* **-t, --gitlab-token TOKEN** - Private token for *GitLab*. Set it to the token from your *GitLab* account (http://my.gitlab.host/profile/account).
* **--ssh** - Use ssh for *GitHub*. By default, script uses **https** protocol to access *GitHub*. Use this option to change the protocol to the **ssh**.
* **-s, --space SPACE** - The space to import repositories from (User or Organization). If **--group** is not set, **SPACE** will also be used to determine destination projects **group** in *GitLab*. If **SPACE** is not set, the default space of the authenticated user will be used.
* **-g, --group GROUP** - The *GitLab* group to import projects to. Determines destination projects **group** in *GitLab*.
* **--private** - Import only private *GitHub* repositories (enables ssh). By default, script will try to import only public projects from specified space. Use this option to import only private projects of authenticated user (automatically enables **ssh** protocol, ignores **SPACE**).
* **--all** - Import both private and public *GitHub* repositories (enables ssh). By default, script will try to import only public projects from specified space. Use this option to import both public and private projects of authenticated user (automatically enables **ssh** protocol, ignores **SPACE**).
* **--repository REPOSITORY** -- Import only specified repository. By default, script will try to import all available repositories from selected **SPACE**. This option allows to import only one specified repository.
* **--[no-]issues** - [do not] import issues. Use this switch to enable or disable import of issues. Enabled by default.
* **--[no-]milestones** - [do not] import milestones. Use this switch to enable or disable import of milestones. Enabled by default.
* **-h, --help** - Display help.

## Examples
1. This example will import all private repositories of user1 from user1 **SPACE** from *GitHub* (https://github.com/user1/*) to user1 project group in *GitLab* (http://gitlab.example.com/user1/*).
```bash
rm -rf /tmp/clones/ && # remove /tmp/clones/ directory
mkdir /tmp/clones/ && # and recreate it
ruby import_all.rb -u user1 -p password_of_user1 -s user1 --private \
--gitlab-api http://gitlab.example.com/api/v3 -t some_private_token_from_gitalb
```

2. This example will import all public repositories from gitlabhq **SPACE** from *GitHub* (https://github.com/gitlabhq/*) to group1 project group in *GitLab* (http://gitlab.example.com/group1/*) without issues.
```bash
rm -rf /tmp/clones/ &&
mkdir /tmp/clones/ &&
ruby import_all.rb -u user1 -p password_of_user1 --group group1 \
-s gitlabhq --gitlab-api http://gitlab.example.com/api/v3 --no-issues \
-t some_private_token_from_gitalb
```

3. This example will import repository gitlabhq/gitlab-ci from *GitHub* (https://github.com/gitlabhq/gitlab-ci) to group2 project group in *GitLab* (http://gitlab.example.com/group2/gitlab-ci) with issues.
```bash
rm -rf /tmp/clones/ &&
mkdir /tmp/clones/ &&
ruby import_all.rb -u user1 -p password_of_user1 \
--gitlab-api http://gitlab.example.com/api/v3 --group group2 \
-t some_private_token_from_gitalb --repository gitlabhq/gitlab-ci
```
57 changes: 50 additions & 7 deletions import/github/import_all.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
:group => nil,
:ssh => false,
:private => false,
:repository => nil,
:import_issues => true,
:import_milestones => true,
:gitlab_api => 'http://gitlab.example.com/api/v3',
:gitlab_token => 'secret'
}
Expand Down Expand Up @@ -48,12 +51,25 @@
options[:private] = p
options[:ssh] = true
end
opts.on('--all', 'Import all GitHub repositories (enables ssh)') do |a|
options[:all] = a
options[:ssh] = true
end
opts.on('-s', '--space SPACE', 'The space to import repositories from (User or Organization)') do |s|
options[:space] = s
end
opts.on('-g', '--group GROUP', 'The GitLab group to import projects to') do |g|
options[:group] = g
end
opts.on('--repository REPOSITORY', String, 'Import only specified repository') do |r|
options[:repository] = r
end
opts.on('--[no-]issues', '[do not] import issues') do |b|
options[:import_issues] = b
end
opts.on('--[no-]milestones', '[do not] import milestones') do |b|
options[:import_milestones] = b
end
opts.on('-h', '--help', 'Display this screen') do
puts opts
exit
Expand All @@ -67,6 +83,14 @@
exit
end

if options[:private]
options[:space] = nil
end

if not options[:import_issues]
options[:import_milestones] = false
end

if options[:group].nil?
if options[:space].nil?
raise 'Both group and space can\'t be empty!'
Expand All @@ -89,8 +113,12 @@
#setup the clients
gh_client = Octokit::Client.new(:login => options[:usr], :password => options[:pw])
gl_client = Gitlab.client()
#get all of the repos that are in the specified space (user or org)
gh_repos = gh_client.repositories(options[:space], {:type => options[:private] ? 'private' : 'all'})
if options[:repository].nil?
#get all of the repos that are in the specified space (user or org)
gh_repos = gh_client.repositories(options[:space], {:type => options[:private] ? 'private' : (options[:all] ? 'all' : 'public')})
else
gh_repos = [gh_client.repository(options[:repository])]
end
gh_repos.each do |gh_r|
#
## clone the repo from the github server
Expand Down Expand Up @@ -129,7 +157,7 @@
name = "gh-#{gh_r.name}"
end

puts gh_r.name
puts "Importing repository '#{gh_r.name}'"
#create and push the project to GitLab
new_project = gl_client.create_project(name)
git_repo.add_remote("gitlab", new_project.ssh_url_to_repo)
Expand All @@ -140,12 +168,23 @@
labels.each do |l|
gl_client.create_label(new_project.id, l.name, '#'+l.color)
end


# Copy milestones for this project
milestone_hash = {}
if options[:import_milestones]
milestones = gh_client.milestones(gh_r.full_name)
milestones.each do |m|
gl_milestone = gl_client.create_milestone(new_project.id, m.title, {:description => m.description, :due_date => m.due_on })
milestone_hash[gl_milestone.title] = gl_milestone.id
puts "Imported milestone #{gl_milestone.title}"
end
end

#
## Look for issues in GitHub for this project and push them to GitLab
## I wish the GitLab API let me create comments for issues. Oh well, smashing it all into the body of the issue.
#
if gh_r.has_issues
if gh_r.has_issues and options[:import_issues]
issues = []

# Get opened issues
Expand Down Expand Up @@ -180,13 +219,17 @@

labels = i.labels.map {|l| l.name }.join(sep=',')

gl_issue = gl_client.create_issue(new_project.id, i.title, :description => body, :labels => labels)
unless i.milestone.nil? or i.milestone.title.nil? or milestone_hash[i.milestone.title].nil?
milestone_id = milestone_hash[i.milestone.title]
end

gl_issue = gl_client.create_issue(new_project.id, i.title, :description => body, :labels => labels, :milestone_id => milestone_id)

if i.state == 'closed'
gl_client.close_issue(new_project.id, gl_issue.id)
end

pp i.number.to_s + ' ' + i.title + ' ' + i.state + ' ' + labels
puts "Imported issue \##{i.number} '#{i.title}' \{#{i.state}\} [#{labels}]"
end
end

Expand Down