travis_migrate_to_apps 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/bin/travis_migrate_to_apps +1 -1
- data/lib/travis_migrate_to_apps.rb +1 -139
- data/lib/travis_migrate_to_apps/cli.rb +150 -0
- data/lib/travis_migrate_to_apps/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54e04ebcc1b1588d8416207484abb238c5c71360
|
4
|
+
data.tar.gz: 7e17790cea3516724cfa8c74eb9b7ed05f60f857
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cec556801f69ef27dfa8191801e015b8d8eb13ddcf9cecc7d7ba658607ec2993a120bf476be74661eda88f2526089d90588d2a3b53a77e5c78ad2ad117ddaa24
|
7
|
+
data.tar.gz: c02be5038224c58862e83415f0b519ff375166ae92e912e8521cecd5c0b2e7b819343463c7fbcbbbe50f810ef87ae119a96d7200745926239ad18f82026e7b4e
|
data/Gemfile.lock
CHANGED
data/bin/travis_migrate_to_apps
CHANGED
@@ -1,139 +1 @@
|
|
1
|
-
require '
|
2
|
-
require 'json'
|
3
|
-
require 'colors'
|
4
|
-
|
5
|
-
class TravisMigrateToApps < Struct.new(:owner_name, :travis_access_token, :github_access_token)
|
6
|
-
include Colors
|
7
|
-
|
8
|
-
USAGE = 'Usage: travis_migrate_to_apps [owner_name] [travis_access_token] [github_access_token]'
|
9
|
-
|
10
|
-
MSGS = {
|
11
|
-
start: 'Starting to migrate %s to use the Travis CI GitHub App integration',
|
12
|
-
migrate_repos: 'Starting to migrate %i repositories',
|
13
|
-
migrated_repo: 'Migrated repository %s',
|
14
|
-
done: 'Done.',
|
15
|
-
missing_installation: 'Sorry but we could not find an active installation for %s',
|
16
|
-
missing_repos: 'Sorry but we could not find any repositories to migrate',
|
17
|
-
request_failed: "Sorry but a request %s failed, please check your auth token. (%i: %s)",
|
18
|
-
}
|
19
|
-
|
20
|
-
URIS = {
|
21
|
-
travis: {
|
22
|
-
installation: 'https://api.travis-ci.com/owner/%s?include=owner.installation',
|
23
|
-
repositories: 'https://api.travis-ci.com/owner/%s/repos?repository.active=true&repository.managed_by_installation=false&limit=%i&offset=%i'
|
24
|
-
},
|
25
|
-
github: {
|
26
|
-
installation_repos: 'https://api.github.com/user/installations/%i/repositories/%i'
|
27
|
-
}
|
28
|
-
}
|
29
|
-
|
30
|
-
HEADERS = {
|
31
|
-
travis: {
|
32
|
-
'Travis-API-Version' => '3',
|
33
|
-
'User-Agent' => 'Travis GitHub App Migration Tool',
|
34
|
-
'Authorization' => 'token %{token}'
|
35
|
-
},
|
36
|
-
github: {
|
37
|
-
'Accept' => 'application/vnd.github.machine-man-preview+json',
|
38
|
-
'Authorization' => 'token %{token}'
|
39
|
-
}
|
40
|
-
}
|
41
|
-
|
42
|
-
PER_PAGE = 20
|
43
|
-
|
44
|
-
attr_reader :installation
|
45
|
-
|
46
|
-
def initialize(*)
|
47
|
-
super
|
48
|
-
to_h.keys.each do |key|
|
49
|
-
missing_arg(key) unless send(key)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def run
|
54
|
-
msg :start, owner_name, color: :yellow
|
55
|
-
validate
|
56
|
-
migrate_repos
|
57
|
-
msg :done, color: :green
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def installation
|
63
|
-
@installation ||= fetch_installation
|
64
|
-
end
|
65
|
-
|
66
|
-
def repos
|
67
|
-
@repos ||= fetch_repos
|
68
|
-
end
|
69
|
-
|
70
|
-
def validate
|
71
|
-
error :missing_installation, owner_name unless installation
|
72
|
-
error :missing_repos unless repos.any?
|
73
|
-
end
|
74
|
-
|
75
|
-
def migrate_repos
|
76
|
-
msg :migrate_repos, repos.count
|
77
|
-
repos.each { |repo| migrate_repo(repo) }
|
78
|
-
end
|
79
|
-
|
80
|
-
def migrate_repo(repo)
|
81
|
-
uri = uri(:github, :installation_repos, installation['github_id'], repo['github_id'])
|
82
|
-
request(:put, uri, headers(:github))
|
83
|
-
msg :migrated_repo, repo['name']
|
84
|
-
end
|
85
|
-
|
86
|
-
def fetch_installation
|
87
|
-
uri = uri(:travis, :installation, owner_name)
|
88
|
-
data = request(:get, uri, headers(:travis))
|
89
|
-
data['installation']
|
90
|
-
end
|
91
|
-
|
92
|
-
def fetch_repos(repos = [], page = 1)
|
93
|
-
offset = (page - 1) * PER_PAGE
|
94
|
-
uri = uri(:travis, :repositories, owner_name, PER_PAGE, offset)
|
95
|
-
data = request(:get, uri, headers(:travis))
|
96
|
-
repos += data['repositories'].map { |repo| only(repo, 'name', 'github_id') }
|
97
|
-
fetch_repos(repos, page + 1) unless data['@pagination']['is_last']
|
98
|
-
repos
|
99
|
-
end
|
100
|
-
|
101
|
-
def uri(target, resource, *args)
|
102
|
-
URI(URIS[target][resource] % args)
|
103
|
-
end
|
104
|
-
|
105
|
-
def headers(target)
|
106
|
-
args = { token: send(:"#{target}_access_token") }
|
107
|
-
HEADERS[target].map { |key, value| [key, value % args] }.to_h
|
108
|
-
end
|
109
|
-
|
110
|
-
def request(method, uri, headers)
|
111
|
-
req = Net::HTTP.const_get(method.to_s.capitalize).new(uri)
|
112
|
-
headers.each { |key, value| req[key] = value }
|
113
|
-
http = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true)
|
114
|
-
res = http.request(req)
|
115
|
-
error :request_failed, uri, res.code, res.body unless res.is_a?(Net::HTTPSuccess)
|
116
|
-
JSON.parse(res.body) if method == :get
|
117
|
-
end
|
118
|
-
|
119
|
-
def error(key, *args)
|
120
|
-
abort colored(:red, MSGS[key] % args)
|
121
|
-
end
|
122
|
-
|
123
|
-
def msg(key, *args)
|
124
|
-
opts = args.last.is_a?(Hash) ? args.pop : {}
|
125
|
-
msg = MSGS[key] % args
|
126
|
-
msg = colored(opts[:color], msg) if opts[:color]
|
127
|
-
puts msg
|
128
|
-
end
|
129
|
-
|
130
|
-
def missing_arg(key)
|
131
|
-
puts colored(:red, "No #{key} given")
|
132
|
-
puts USAGE
|
133
|
-
abort
|
134
|
-
end
|
135
|
-
|
136
|
-
def only(hash, *keys)
|
137
|
-
hash.select { |key, _| keys.include?(key) }
|
138
|
-
end
|
139
|
-
end
|
1
|
+
require 'travis_migrate_to_apps/cli'
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'json'
|
3
|
+
require 'colors'
|
4
|
+
|
5
|
+
module TravisMigrateToApps
|
6
|
+
class Cli < Struct.new(:owner_name, :travis_access_token, :github_access_token)
|
7
|
+
include Colors
|
8
|
+
|
9
|
+
USAGE = 'Usage: travis_migrate_to_apps [owner_name] [travis_access_token] [github_access_token]'
|
10
|
+
|
11
|
+
MSGS = {
|
12
|
+
start: 'Starting to migrate the account %s to use the Travis CI GitHub App integration.',
|
13
|
+
fetch_installation: "Looking up %s's GitHub App installation.",
|
14
|
+
fetch_repos: "Looking up %s's active repositories.",
|
15
|
+
migrate_repos: 'Starting to migrate %i repositories.',
|
16
|
+
migrating_repo: 'Migrating repository %s ... ',
|
17
|
+
migrated_repo: 'done.',
|
18
|
+
done: 'Done.',
|
19
|
+
missing_installation: 'Sorry, we could not find an active installation for %s.',
|
20
|
+
missing_repos: 'Sorry, we could not find any repositories to migrate.',
|
21
|
+
request_failed: "Sorry, a %s request to %s failed, please check your auth token. (%i: %s)",
|
22
|
+
}
|
23
|
+
|
24
|
+
URIS = {
|
25
|
+
travis: {
|
26
|
+
installation: 'https://api.travis-ci.com/owner/%s?include=owner.installation',
|
27
|
+
repositories: 'https://api.travis-ci.com/owner/%s/repos?repository.active=true&repository.managed_by_installation=false&limit=%i&offset=%i'
|
28
|
+
},
|
29
|
+
github: {
|
30
|
+
installation_repos: 'https://api.github.com/user/installations/%i/repositories/%i'
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
HEADERS = {
|
35
|
+
travis: {
|
36
|
+
'Travis-API-Version' => '3',
|
37
|
+
'User-Agent' => 'Travis GitHub App Migration Tool',
|
38
|
+
'Authorization' => 'token %{token}'
|
39
|
+
},
|
40
|
+
github: {
|
41
|
+
'Accept' => 'application/vnd.github.machine-man-preview+json',
|
42
|
+
'Authorization' => 'token %{token}'
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
PER_PAGE = 20
|
47
|
+
|
48
|
+
attr_reader :installation
|
49
|
+
|
50
|
+
def initialize(*)
|
51
|
+
super
|
52
|
+
to_h.keys.each do |key|
|
53
|
+
missing_arg(key) unless send(key)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def run
|
58
|
+
msg :start, owner_name, color: :yellow
|
59
|
+
validate
|
60
|
+
migrate_repos
|
61
|
+
msg :done, color: :green
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def installation
|
67
|
+
@installation ||= fetch_installation
|
68
|
+
end
|
69
|
+
|
70
|
+
def repos
|
71
|
+
@repos ||= begin
|
72
|
+
msg :fetch_repos, owner_name
|
73
|
+
fetch_repos
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def validate
|
78
|
+
error :missing_installation, owner_name unless installation
|
79
|
+
error :missing_repos unless repos.any?
|
80
|
+
end
|
81
|
+
|
82
|
+
def migrate_repos
|
83
|
+
msg :migrate_repos, repos.count
|
84
|
+
repos.each { |repo| migrate_repo(repo) }
|
85
|
+
end
|
86
|
+
|
87
|
+
def migrate_repo(repo)
|
88
|
+
msg :migrating_repo, repo['name'], nl: false
|
89
|
+
uri = uri(:github, :installation_repos, installation['github_id'], repo['github_id'])
|
90
|
+
request(:put, uri, headers(:github))
|
91
|
+
msg :migrated_repo, repo['name']
|
92
|
+
end
|
93
|
+
|
94
|
+
def fetch_installation
|
95
|
+
msg :fetch_installation, owner_name
|
96
|
+
uri = uri(:travis, :installation, owner_name)
|
97
|
+
data = request(:get, uri, headers(:travis))
|
98
|
+
data['installation']
|
99
|
+
end
|
100
|
+
|
101
|
+
def fetch_repos(repos = [], page = 1)
|
102
|
+
offset = (page - 1) * PER_PAGE
|
103
|
+
uri = uri(:travis, :repositories, owner_name, PER_PAGE, offset)
|
104
|
+
data = request(:get, uri, headers(:travis))
|
105
|
+
repos += data['repositories'].map { |repo| only(repo, 'name', 'github_id') }
|
106
|
+
repos = fetch_repos(repos, page + 1) unless data['@pagination']['is_last']
|
107
|
+
repos
|
108
|
+
end
|
109
|
+
|
110
|
+
def uri(target, resource, *args)
|
111
|
+
URI(URIS[target][resource] % args)
|
112
|
+
end
|
113
|
+
|
114
|
+
def headers(target)
|
115
|
+
args = { token: send(:"#{target}_access_token") }
|
116
|
+
HEADERS[target].map { |key, value| [key, value % args] }.to_h
|
117
|
+
end
|
118
|
+
|
119
|
+
def request(method, uri, headers)
|
120
|
+
req = Net::HTTP.const_get(method.to_s.capitalize).new(uri)
|
121
|
+
headers.each { |key, value| req[key] = value }
|
122
|
+
http = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true)
|
123
|
+
res = http.request(req)
|
124
|
+
error :request_failed, method, uri, res.code, res.body unless res.is_a?(Net::HTTPSuccess)
|
125
|
+
JSON.parse(res.body) if method == :get
|
126
|
+
end
|
127
|
+
|
128
|
+
def error(key, *args)
|
129
|
+
abort colored(:red, MSGS[key] % args)
|
130
|
+
end
|
131
|
+
|
132
|
+
def msg(key, *args)
|
133
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
134
|
+
msg = MSGS[key] % args
|
135
|
+
msg = colored(opts[:color], msg) if opts[:color]
|
136
|
+
method = opts[:nl].is_a?(FalseClass) ? :print : :puts
|
137
|
+
send(method, msg)
|
138
|
+
end
|
139
|
+
|
140
|
+
def missing_arg(key)
|
141
|
+
puts colored(:red, "No #{key} given")
|
142
|
+
puts USAGE
|
143
|
+
abort
|
144
|
+
end
|
145
|
+
|
146
|
+
def only(hash, *keys)
|
147
|
+
hash.select { |key, _| keys.include?(key) }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: travis_migrate_to_apps
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Travis CI
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04-
|
11
|
+
date: 2018-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Migrate your GitHub organizations to use the Travis CI GitHub App integration.
|
14
14
|
email:
|
@@ -24,6 +24,7 @@ files:
|
|
24
24
|
- bin/travis_migrate_to_apps
|
25
25
|
- lib/colors.rb
|
26
26
|
- lib/travis_migrate_to_apps.rb
|
27
|
+
- lib/travis_migrate_to_apps/cli.rb
|
27
28
|
- lib/travis_migrate_to_apps/version.rb
|
28
29
|
homepage: https://github.com/travis-ci/travis_migrate_to_apps
|
29
30
|
licenses:
|