travis_migrate_to_apps 0.0.1 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f62ca1e281bce57365c17ea8826871ba7cbf80fa
4
- data.tar.gz: bf406955dd183c6e2ea7e3b5758a31af43964040
2
+ SHA256:
3
+ metadata.gz: 11aa9acdabfe9c4b3266ef1c1561efab04abd4ac06f89cb02931ebe29580cbb3
4
+ data.tar.gz: 21d585480351fbd6bc1e3745025e6aba13208d23a64e4f4bc32ca08f0499dfd2
5
5
  SHA512:
6
- metadata.gz: e1bda52e5041df03d4a7885cdd1ab1e0e25afe9c439293f356a15e03bd4c1c12030e3e0cc4ecf6fdcf3c7511676307037fb885c8d7ff7ebbc22ad40f261a53bd
7
- data.tar.gz: '09364eab42385c7bb39e772fa6a2ce468c787aee39eaeffd1cfbe5282bc0fbf6e37edf3f33c102569deb79da0f55d520f1baa02fc1db09b11e1ad5ed203b8720'
6
+ metadata.gz: 5ddb124d2978f0845f223287e6e7bf4a688179793371971a05aa134b918889ae8dddd41ee805b050236431705fdb71c283b24851646c3f05839692f7a1d2271b
7
+ data.tar.gz: 550a753c4c3f6c654923ca8fc5b0c994707b3dd4e884cfdfb141427fd387f4aa29aaf63047a9bc160e079ff82c7291cf52a4c211924df259ea06fab99da4a524
data/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # Migrate your GitHub organizations to use the Travis CI GitHub App integration
2
+
3
+ This gem will help you migrate the repositories you have on [https://travis-ci.com](travis-ci.com) from legacy [GitHub Services](https://developer.github.com/v3/guides/replacing-github-services/) integration to the new [GitHub Apps](https://developer.github.com/apps/) integration.
4
+
5
+ The main difference is that you will now give Travis CI access to your repositories on a repository basis instead of giving it access to all of them.
6
+
7
+ Hence, we have developped this gem to help you migrate your repositories that are currently active on Travis CI in one sweep rather than having to add them manually one by one in the GitHub UI.
8
+
9
+ Here are the steps:
10
+
11
+ ## 1. Install the gem
12
+ ```
13
+ gem install travis_migrate_to_apps
14
+ ```
15
+
16
+ ## 2. Generate a GitHub personal access token with repo scope
17
+
18
+ You can generate a new GitHub token [here](https://github.com/settings/tokens/new).
19
+
20
+ Choose the name of your liking and ensure to select the whole `repo` scope as shown below:
21
+
22
+ ![GitHub new token page](https://github.com/travis-ci/travis_migrate_to_apps/blob/assets/github-token-new.png)
23
+
24
+ Then click the "Generate token" button at the bottom to generate the token.
25
+
26
+ You'll then be back on the GitHub token page:
27
+
28
+ ![GitHub token page](https://github.com/travis-ci/travis_migrate_to_apps/blob/assets/github-token-added.png)
29
+
30
+ Take care of copying the newly generated token and save it for later usage.
31
+
32
+ **Note: if you are migrating an organization, the token must be generated by [an owner of the GitHub organization](https://help.github.com/articles/permission-levels-for-an-organization/).**
33
+
34
+ ## 3. Activate the Travis CI GitHub Apps integration with 1 repo
35
+
36
+ Go to your profile page on Travis CI: https://travis-ci.com/profile
37
+
38
+ Click the "Activate GitHub Apps Integration" button highlighted below:
39
+
40
+ ![Activate GitHub Apps Integration button](https://github.com/travis-ci/travis_migrate_to_apps/blob/assets/github-apps-button-on-profile-page.png)
41
+
42
+ You'll directed to the GitHub Apps page for the Travis CI app:
43
+
44
+ ![GitHub Apps page](https://github.com/travis-ci/travis_migrate_to_apps/blob/assets/travis-ci-github-app.png)
45
+
46
+ Choose at least one repository and click the "Approve & Install" button.
47
+
48
+ You'll then be redirected to your profile page on Travis CI and the newly added repository should appear under "GitHub Apps Integration":
49
+
50
+ ![Travis CI profile page](https://github.com/travis-ci/travis_migrate_to_apps/blob/assets/travis-ci-profile-with-github-apps-integration.png)
51
+
52
+ ## 4. Get your Travis CI API token
53
+
54
+ Here are the two ways you can get this token:
55
+
56
+ 1. On your profile page: https://travis-ci.com/profile
57
+
58
+ ![Travis CI token on profile page](https://github.com/travis-ci/travis_migrate_to_apps/blob/assets/travis-ci-token-profile-page.png)
59
+
60
+ 2. Via the [Travis CI client](https://github.com/travis-ci/travis.rb) by running: `travis token --pro`
61
+
62
+ ## 5. Run the gem
63
+
64
+ ```
65
+ travis_migrate_to_apps [owner_name] [travis_access_token] [github_access_token]
66
+ ```
67
+
68
+ where
69
+
70
+ - `[owner_name]` is the GitHub account (user or organization) where the repositories you want to migrate are located
71
+ - `[travis_access_token]` is the Travis CI token obtained in step #4 above
72
+ - `[github_access_token]` is the GitHub token obtained in step #2 above
73
+
74
+ Happy migration!
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'travis_migrate_to_apps'
4
4
 
5
- TravisMigrateToApps.new(*ARGV)
5
+ TravisMigrateToApps::Cli.new(*ARGV).run
data/lib/colors.rb ADDED
@@ -0,0 +1,15 @@
1
+ module Colors
2
+ COLORS = {
3
+ red: "\e[31m",
4
+ green: "\e[32m",
5
+ yellow: "\e[33m",
6
+ blue: "\e[34m",
7
+ gray: "\e[37m",
8
+ reset: "\e[0m"
9
+ }
10
+
11
+ def colored(color, str)
12
+ return str if color == :none
13
+ [COLORS[color], str, COLORS[:reset]].join
14
+ end
15
+ end
@@ -0,0 +1,158 @@
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, :api_endpoint, :github_api_endpoint)
7
+ include Colors
8
+
9
+ USAGE = 'Usage: travis_migrate_to_apps [owner_name] [travis_access_token] [github_access_token] [travis api endpoint | https://api.travis-ci.com] [github api endpoint | https://api.github.com]'
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: '%s/owner/%s?include=owner.installation',
27
+ repositories: '%s/owner/%s/repos?repository.active=true&repository.managed_by_installation=false&limit=%i&offset=%i'
28
+ },
29
+ github: {
30
+ installation_repos: '%s/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
+ attr_reader :api_endpoint
50
+ attr_reader :github_api_endpoint
51
+
52
+ def initialize(*)
53
+ super
54
+ to_h.keys.each do |key|
55
+ if key == :api_endpoint
56
+ @api_endpoint = to_h[key] ? to_h[key] : 'https://api.travis-ci.com'
57
+ elsif key == :github_api_endpoint
58
+ @github_api_endpoint = to_h[key] ? to_h[key] : 'https://api.github.com'
59
+ else
60
+ missing_arg(key) unless send(key)
61
+ end
62
+ end
63
+ end
64
+
65
+ def run
66
+ msg :start, owner_name, color: :yellow
67
+ validate
68
+ migrate_repos
69
+ msg :done, color: :green
70
+ end
71
+
72
+ private
73
+
74
+ def installation
75
+ @installation ||= fetch_installation
76
+ end
77
+
78
+ def repos
79
+ @repos ||= begin
80
+ msg :fetch_repos, owner_name
81
+ fetch_repos
82
+ end
83
+ end
84
+
85
+ def validate
86
+ error :missing_installation, owner_name unless installation
87
+ error :missing_repos unless repos.any?
88
+ end
89
+
90
+ def migrate_repos
91
+ msg :migrate_repos, repos.count
92
+ repos.each { |repo| migrate_repo(repo) }
93
+ end
94
+
95
+ def migrate_repo(repo)
96
+ msg :migrating_repo, repo['name'], nl: false
97
+ uri = uri(:github, :installation_repos, github_api_endpoint, installation['github_id'], repo['github_id'])
98
+ request(:put, uri, headers(:github))
99
+ msg :migrated_repo, repo['name']
100
+ end
101
+
102
+ def fetch_installation
103
+ msg :fetch_installation, owner_name
104
+ uri = uri(:travis, :installation, api_endpoint, owner_name)
105
+ data = request(:get, uri, headers(:travis))
106
+ data['installation']
107
+ end
108
+
109
+ def fetch_repos(repos = [], page = 1)
110
+ offset = (page - 1) * PER_PAGE
111
+ uri = uri(:travis, :repositories, api_endpoint, owner_name, PER_PAGE, offset)
112
+ data = request(:get, uri, headers(:travis))
113
+ repos += data['repositories'].map { |repo| only(repo, 'name', 'github_id') }
114
+ repos = fetch_repos(repos, page + 1) unless data['@pagination']['is_last']
115
+ repos
116
+ end
117
+
118
+ def uri(target, resource, *args)
119
+ URI(URIS[target][resource] % args)
120
+ end
121
+
122
+ def headers(target)
123
+ args = { token: send(:"#{target}_access_token") }
124
+ HEADERS[target].map { |key, value| [key, value % args] }.to_h
125
+ end
126
+
127
+ def request(method, uri, headers)
128
+ req = Net::HTTP.const_get(method.to_s.capitalize).new(uri)
129
+ headers.each { |key, value| req[key] = value }
130
+ http = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true)
131
+ res = http.request(req)
132
+ error :request_failed, method, uri, res.code, res.body unless res.is_a?(Net::HTTPSuccess)
133
+ JSON.parse(res.body) if method == :get
134
+ end
135
+
136
+ def error(key, *args)
137
+ abort colored(:red, MSGS[key] % args)
138
+ end
139
+
140
+ def msg(key, *args)
141
+ opts = args.last.is_a?(Hash) ? args.pop : {}
142
+ msg = MSGS[key] % args
143
+ msg = colored(opts[:color], msg) if opts[:color]
144
+ method = opts[:nl].is_a?(FalseClass) ? :print : :puts
145
+ send(method, msg)
146
+ end
147
+
148
+ def missing_arg(key)
149
+ puts colored(:red, "No #{key} given")
150
+ puts USAGE
151
+ abort
152
+ end
153
+
154
+ def only(hash, *keys)
155
+ hash.select { |key, _| keys.include?(key) }
156
+ end
157
+ end
158
+ end
@@ -1,3 +1,3 @@
1
1
  module TravisMigrateToApps
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.5'
3
3
  end
@@ -1,127 +1 @@
1
- require 'net/https'
2
- require 'json'
3
-
4
- class TravisMigrateToApps < Struct.new(:owner_name, :travis_access_token, :github_access_token)
5
- USAGE = 'Usage: travis_migrate_to_apps [owner_name] [travis_access_token] [github_access_token]'
6
-
7
- MSGS = {
8
- start: 'Starting to migrate %s to use the Travis CI GitHub App integration',
9
- migrate_repos: 'Starting to migrate %i repositories',
10
- migrated_repo: 'Migrated repository %s',
11
- done: 'Done.',
12
- missing_installation: 'Sorry but we could not find an active installation for %s',
13
- missing_repos: 'Sorry but we could not find any repositories to migrate',
14
- request_failed: "Sorry but a request %s failed, please check your auth token. (%i: %s)",
15
- }
16
-
17
- URIS = {
18
- travis: {
19
- installation: 'https://api.travis-ci.com/owner/%s?include=owner.installation',
20
- repositories: 'https://api.travis-ci.com/owner/%s/repos?repository.active=true&repository.managed_by_installation=false&limit=%i&offset=%i'
21
- },
22
- github: {
23
- installation_repos: 'https://api.github.com/user/installations/%i/repositories/%i'
24
- }
25
- }
26
-
27
- HEADERS = {
28
- travis: {
29
- 'Travis-API-Version' => '3',
30
- 'User-Agent' => 'Travis GitHub App Migration Tool',
31
- 'Authorization' => 'token %{token}'
32
- },
33
- github: {
34
- 'Accept' => 'application/vnd.github.machine-man-preview+json',
35
- 'Authorization' => 'token %{token}'
36
- }
37
- }
38
-
39
- PER_PAGE = 20
40
-
41
- attr_reader :installation
42
-
43
- def initialize(*)
44
- super
45
- to_h.keys.each do |key|
46
- abort "#{USAGE}\nNo #{key} given" unless send(key)
47
- end
48
- end
49
-
50
- def run
51
- msg :start, owner_name
52
- validate
53
- migrate_repos
54
- msg :done
55
- end
56
-
57
- private
58
-
59
- def installation
60
- @installation ||= fetch_installation
61
- end
62
-
63
- def repos
64
- @repos ||= fetch_repos
65
- end
66
-
67
- def validate
68
- error :missing_installation, owner_name unless installation
69
- error :missing_repos unless repos.any?
70
- end
71
-
72
- def migrate_repos
73
- msg :migrate_repos, repos.count
74
- repos.each { |repo| migrate_repo(repo) }
75
- end
76
-
77
- def migrate_repo(repo)
78
- uri = uri(:github, :installation_repos, repo['github_id'], installation['github_id'])
79
- request(:put, uri, headers(:github))
80
- msg :migrated_repo, repo['name']
81
- end
82
-
83
- def fetch_installation
84
- uri = uri(:travis, :installation, owner_name)
85
- data = request(:get, uri, headers(:travis))
86
- data['installation']
87
- end
88
-
89
- def fetch_repos(repos = [], page = 1)
90
- offset = (page - 1) * PER_PAGE
91
- uri = uri(:travis, :repositories, owner_name, PER_PAGE, offset)
92
- data = request(:get, uri, headers(:travis))
93
- repos += data['repositories'].map { |repo| only(repo, 'name', 'github_id') }
94
- fetch_repos(repos, page + 1) unless data['@pagination']['is_last']
95
- repos
96
- end
97
-
98
- def uri(target, resource, *args)
99
- URI(URIS[target][resource] % args)
100
- end
101
-
102
- def headers(target)
103
- args = { token: send(:"#{target}_access_token") }
104
- HEADERS[target].map { |key, value| [key, value % args] }.to_h
105
- end
106
-
107
- def request(method, uri, headers)
108
- req = Net::HTTP.const_get(method.to_s.capitalize).new(uri)
109
- res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
110
- http.request(req)
111
- end
112
- error :request_failed, uri, res.code, res.body unless res.is_a?(Net::HTTPSuccess)
113
- JSON.parse(res.body) if method == :get
114
- end
115
-
116
- def error(key, *args)
117
- abort MSGS[key] % args
118
- end
119
-
120
- def msg(key, *args)
121
- puts MSGS[key] % args
122
- end
123
-
124
- def only(hash, *keys)
125
- hash.select { |key, _| keys.include?(key) }
126
- end
127
- end
1
+ require 'travis_migrate_to_apps/cli'
metadata CHANGED
@@ -1,27 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: travis_migrate_to_apps
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.5
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-28 00:00:00.000000000 Z
11
+ date: 2022-01-20 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:
15
15
  - support@travis-ci.com
16
- executables: []
16
+ executables:
17
+ - travis_migrate_to_apps
17
18
  extensions: []
18
19
  extra_rdoc_files: []
19
20
  files:
20
21
  - Gemfile
21
- - Gemfile.lock
22
22
  - LICENSE.md
23
+ - README.md
23
24
  - bin/travis_migrate_to_apps
25
+ - lib/colors.rb
24
26
  - lib/travis_migrate_to_apps.rb
27
+ - lib/travis_migrate_to_apps/cli.rb
25
28
  - lib/travis_migrate_to_apps/version.rb
26
29
  homepage: https://github.com/travis-ci/travis_migrate_to_apps
27
30
  licenses:
@@ -42,8 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
42
45
  - !ruby/object:Gem::Version
43
46
  version: '0'
44
47
  requirements: []
45
- rubyforge_project:
46
- rubygems_version: 2.6.13
48
+ rubygems_version: 3.1.2
47
49
  signing_key:
48
50
  specification_version: 4
49
51
  summary: Migrate your GitHub organizations to use the Travis CI GitHub App integration
data/Gemfile.lock DELETED
@@ -1,44 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- travis_migrate_to_apps (0.0.1)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- addressable (2.5.2)
10
- public_suffix (>= 2.0.2, < 4.0)
11
- crack (0.4.3)
12
- safe_yaml (~> 1.0.0)
13
- diff-lcs (1.3)
14
- hashdiff (0.3.7)
15
- public_suffix (3.0.2)
16
- rspec (3.7.0)
17
- rspec-core (~> 3.7.0)
18
- rspec-expectations (~> 3.7.0)
19
- rspec-mocks (~> 3.7.0)
20
- rspec-core (3.7.1)
21
- rspec-support (~> 3.7.0)
22
- rspec-expectations (3.7.0)
23
- diff-lcs (>= 1.2.0, < 2.0)
24
- rspec-support (~> 3.7.0)
25
- rspec-mocks (3.7.0)
26
- diff-lcs (>= 1.2.0, < 2.0)
27
- rspec-support (~> 3.7.0)
28
- rspec-support (3.7.1)
29
- safe_yaml (1.0.4)
30
- webmock (3.3.0)
31
- addressable (>= 2.3.6)
32
- crack (>= 0.3.2)
33
- hashdiff
34
-
35
- PLATFORMS
36
- ruby
37
-
38
- DEPENDENCIES
39
- rspec
40
- travis_migrate_to_apps!
41
- webmock
42
-
43
- BUNDLED WITH
44
- 1.16.1