github_workflow 0.3.7 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8271e322b33f74a9d09a2ddb73493a177954b367dfb2b4ead132dbe72874ffad
4
- data.tar.gz: ba726efdd702aa7021637ef2d03f9975fbb7e9cbe21ccfe3b825c34fad7fd888
3
+ metadata.gz: 8e9f6a6dfe205f986f1d69b2a778ca8aaf008833423cbde6e664818d90c7c0e0
4
+ data.tar.gz: 1f3dce21f39ca0e0ca4cba5ddcafa0c1817b2e0fd4d8e5ef2de82b6abd4a6f21
5
5
  SHA512:
6
- metadata.gz: e38c3753cab0d496d407c1fa2f9afcd32f8f78c823013ded75d9ca0dfb8418d02ac837dbabc7910c4d73be9a97aecdf60b8cfa5691c5624e863f5dbbe05a61f1
7
- data.tar.gz: 3477e960a0b6b08ed0350ca2e7e498ea0262dc95c314ddc0834b87d18dec4c09b366249da6d887746dfba4e6253d7551489503f3ac93991d3f26a08077c4db74
6
+ metadata.gz: a4b8055a935171f2c1a9e694ada8ca0b78704e4c49f5880745f4c1920023841fcd94d1819a39bdd26bee89b35a1a6c508de49f16538b45bd261dad39b0798d97
7
+ data.tar.gz: 824bc8e9cfadf38d68a9e6b34d22a715eeaa08c3dc260ce7637aef8e10f7cc89bfa2313992dd8a0619f88c4908207c68268c04551d3867e48c6de354ea0892e4
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.2
1
+ 2.7.4
data/README.md CHANGED
@@ -1,3 +1,13 @@
1
+ # Setup
2
+
3
+ Install the [GitHub cli](https://cli.github.com/manual/)
4
+
5
+ `brew install gh`
6
+
7
+ login to the cli
8
+
9
+ `gh login`
10
+
1
11
  # Github Workflow
2
12
 
3
13
  ```
@@ -12,4 +22,5 @@ Commands:
12
22
  github_workflow push_and_pr # Push branch to origin and convert Issue to Pull Request
13
23
  github_workflow start -i, --issue-id=ISSUE_ID # Create branch named with issue number and issue title
14
24
  github_workflow status # Check PR CI status
25
+ github_workflow reviews # Print out reviewers list and their PRs count
15
26
  ```
@@ -18,9 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.require_paths = ["lib"]
19
19
 
20
20
  spec.add_dependency "thor", "~> 1.0.1"
21
- spec.add_dependency "faraday", "~> 0.11", "< 2.0"
22
21
  spec.add_dependency "terminal-table", "~> 1.5"
23
- spec.add_dependency "ruby-trello", "~> 2.1"
24
22
 
25
23
  spec.add_development_dependency "bundler"
26
24
  spec.add_development_dependency "pry"
@@ -1,61 +1,22 @@
1
1
  require "rubygems"
2
2
  require "pry"
3
- require "faraday"
4
3
  require "thor"
5
4
  require "open3"
6
5
  require "json"
7
6
  require "terminal-table"
8
- require "trello"
7
+ require_relative "gh_cli_client.rb"
9
8
 
10
9
  module GithubWorkflow
11
10
  class Cli < Thor
12
11
  PROCEED_TEXT = "Proceed? [y,yes]: ".freeze
13
12
 
14
- GITHUB_CONFIG = <<~TEXT
15
- {
16
- "oauth_token": "TOKEN",
17
- "user_and_repo": "ORG/REPO",
18
- "trello_key": "KEY",
19
- "trello_token": "TOKEN",
20
- "trello_board_id": "BOARD_ID",
21
- "trello_platform_board_id": "BOARD_ID"
22
- }
23
- TEXT
24
-
25
13
  include Thor::Actions
26
14
 
27
- default_task :trello
28
-
29
- desc "trello", "Create issue from card"
30
- method_option :card_number, aliases: "-i", type: :string, required: true
31
- def trello
32
- ensure_github_config_present
33
- init_trello
34
- set_trello_card(type: nil)
35
- create_issue_from_trello_card
36
- stash
37
- rebase_main
38
- create_branch
39
- stash_pop
40
- end
41
-
42
- desc "platform", "Create issue from card"
43
- method_option :card_number, aliases: "-i", type: :string, required: true
44
- def platform
45
- ensure_github_config_present
46
- init_trello
47
- set_trello_card(type: :platform)
48
- create_issue_from_trello_card
49
- stash
50
- rebase_main
51
- create_branch
52
- stash_pop
53
- end
15
+ default_task :start
54
16
 
55
17
  desc "start", "Create branch named with issue number and issue title"
56
18
  method_option :issue_id, aliases: "-i", type: :string, required: true
57
19
  def start
58
- ensure_github_config_present
59
20
  stash
60
21
  rebase_main
61
22
  create_branch
@@ -65,7 +26,6 @@ module GithubWorkflow
65
26
  desc "create_pr", "Convert Issue to Pull Request"
66
27
  method_option :base_branch, aliases: "-b", type: :string
67
28
  def create_pr
68
- ensure_github_config_present
69
29
  ensure_origin_exists
70
30
  convert_issue_to_pr
71
31
  end
@@ -73,16 +33,14 @@ module GithubWorkflow
73
33
  desc "push_and_pr", "Push branch to origin and convert Issue to Pull Request"
74
34
  method_option :base_branch, aliases: "-b", type: :string
75
35
  def push_and_pr
76
- ensure_github_config_present
77
36
  push_and_set_upstream
78
37
  convert_issue_to_pr
79
38
  end
80
39
 
81
40
  desc "status", "Check PR CI status"
82
41
  def status
83
- ensure_github_config_present
84
42
  ensure_origin_exists
85
- response = JSON.parse(github_client.get("repos/#{user_and_repo}/statuses/#{current_branch}").body)
43
+ response = github_client.get_statuses
86
44
 
87
45
  if response.empty?
88
46
  alert "No statuses yet. Have you pushed your branch?"
@@ -104,21 +62,20 @@ module GithubWorkflow
104
62
 
105
63
  desc "info", "Print out issue description"
106
64
  def info
107
- ensure_github_config_present
108
- puts get_issue(issue_number_from_branch)["body"]
65
+ issue = github_client.get_issue(issue_number_from_branch)
66
+ puts "#{issue["html_url"]}\n\n"
67
+ puts "[##{issue["number"]}] #{issue["title"]}\n"
68
+ puts issue["body"]
109
69
  end
110
70
 
111
71
  desc "open", "Open issue or PR in browser"
112
72
  def open
113
- ensure_github_config_present
114
- response = JSON.parse(github_client.get("repos/#{user_and_repo}/issues/#{issue_number_from_branch}").body)
115
- `/usr/bin/open -a "/Applications/Google Chrome.app" '#{response["html_url"]}'`
73
+ open_url(github_client.get_issue(issue_number_from_branch)["html_url"])
116
74
  end
117
75
 
118
76
  desc "create_and_start", "Create and start issue"
119
77
  method_option :name, aliases: "-m", type: :string, required: true
120
78
  def create_and_start
121
- ensure_github_config_present
122
79
  create_issue
123
80
  end
124
81
 
@@ -147,8 +104,7 @@ module GithubWorkflow
147
104
 
148
105
  desc "reviews", "Displays count of requested reviews for each user"
149
106
  def reviews
150
- ensure_github_config_present
151
- reviewers = get_prs_list.map { |pr| pr["requested_reviewers"].map { |r| r["login"] } }.flatten
107
+ reviewers = github_client.get_prs_list.map { |pr| pr["requested_reviewers"].map { |r| r["login"] } }.flatten
152
108
  reviewer_counts = reviewers.group_by { |i| i }.map { |k, v| [k, v.count] }
153
109
 
154
110
  if reviewer_counts.any?
@@ -170,16 +126,8 @@ module GithubWorkflow
170
126
  end
171
127
 
172
128
  no_tasks do
173
- def get_issue(id)
174
- JSON.parse(github_client.get("repos/#{user_and_repo}/issues/#{id}").body)
175
- end
176
-
177
- def get_pr(id)
178
- JSON.parse(github_client.get("repos/#{user_and_repo}/pulls/#{id}").body)
179
- end
180
-
181
- def get_prs_list
182
- JSON.parse(github_client.get("repos/#{user_and_repo}/pulls&per_page=100").body)
129
+ def open_url(url)
130
+ `/usr/bin/open -a "/Applications/Google Chrome.app" '#{url}'`
183
131
  end
184
132
 
185
133
  def create_branch
@@ -194,118 +142,21 @@ module GithubWorkflow
194
142
  end
195
143
  end
196
144
 
197
- def create_issue_from_trello_card
198
- say_info("Creating issue")
199
-
200
- issue_params = {
201
- title: trello_card.name,
202
- body: issue_body_from_trello_card,
203
- assignees: [current_github_username],
204
- labels: trello_card.labels.map(&:name)
205
- }
206
-
207
- response = JSON.parse(github_client.post("repos/#{user_and_repo}/issues", issue_params.to_json).body)
208
-
209
- @issue_id = response["number"]
210
-
211
- github_client.post("/repos/#{user_and_repo}/issues/#{@issue_id}/comments", { body: trello_card.short_url }.to_json)
212
- trello_card.add_attachment response["html_url"]
213
- end
214
-
215
- def issue_body_from_trello_card
216
- [trello_card.desc, trello_deploy_note, trello_product_review_type, trello_pm].compact.join("\n\n")
217
- end
218
-
219
- def trello_pm
220
- custom_field = trello_card.custom_field_items.detect { |cfi| cfi.custom_field.name == "PM" }
221
-
222
- if custom_field.present?
223
- "**Responsible:** #{custom_field.option_value['text']}"
224
- end
225
- end
226
-
227
- def trello_deploy_note
228
- custom_field = trello_card.custom_field_items.detect { |cfi| cfi.custom_field.name == "Deploy Note" }
229
-
230
- if custom_field.present?
231
- "**Deploy Note:** #{custom_field.value['text']}"
232
- end
233
- end
234
-
235
- def trello_product_review_type
236
- custom_field = trello_card.custom_field_items.detect { |cfi| cfi.custom_field.name == "Product Review" }
237
-
238
- if custom_field.present?
239
- "**Product Review:** #{custom_field.option_value['text']}"
240
- end
241
- end
242
-
243
- def current_github_username
244
- JSON.parse(github_client.get("user").body)["login"]
245
- end
246
-
247
- def set_trello_card(type:)
248
- say_info("Fetching trello card")
249
-
250
- trello_board =
251
- if type
252
- Trello::Board.find(project_config["trello_#{type}_board_id"])
253
- else
254
- Trello::Board.find(project_config["trello_board_id"])
255
- end
256
-
257
- @trello_card = trello_board.find_card(options["card_number"].to_i)
258
- end
259
-
260
- def trello_card
261
- @trello_card
262
- end
263
-
264
- def ensure_github_config_present
265
- if project_config.nil? || (JSON.parse(GITHUB_CONFIG).keys - project_config.keys).any?
266
- failure("Please add `.github_workflow` file containing:\n#{GITHUB_CONFIG}")
267
- end
268
- end
269
-
270
- def init_trello
271
- Trello.configure do |config|
272
- config.developer_public_key = project_config["trello_key"]
273
- config.member_token = project_config["trello_token"]
274
- end
275
- end
276
-
277
- def project_config
278
- @project_config ||= JSON.parse(File.read(".github_workflow")) rescue nil
279
- end
280
-
281
- def oauth_token
282
- project_config["oauth_token"]
283
- end
284
-
285
- def user_and_repo
286
- project_config["user_and_repo"]
287
- end
288
-
289
145
  def push_and_set_upstream
290
146
  `git rev-parse --abbrev-ref HEAD | xargs git push origin -u`
291
147
  end
292
148
 
293
149
  def create_issue
294
- github_client.post(
295
- "repos/#{user_and_repo}/issues",
296
- JSON.generate(
297
- {
298
- title: options[:name]
299
- }
300
- )
150
+ github_client.create_issue(
151
+ title: options[:name]
301
152
  ).tap do |response|
302
- if response.success?
153
+ if response["number"]
303
154
  pass("Issue created")
304
- @issue_id = JSON.parse(response.body)["number"]
155
+ @issue_id = response["number"]
305
156
  start
306
157
  else
307
158
  alert("An error occurred when creating issue:")
308
- alert("#{response.status}: #{JSON.parse(response.body)['message']}")
159
+ alert("#{response['message']}")
309
160
  end
310
161
  end
311
162
  end
@@ -315,22 +166,17 @@ module GithubWorkflow
315
166
  end
316
167
 
317
168
  def convert_issue_to_pr
318
- github_client.post(
319
- "repos/#{user_and_repo}/pulls",
320
- JSON.generate(
321
- {
322
- head: current_branch,
323
- base: options[:base_branch] || "main",
324
- issue: issue_number_from_branch.to_i
325
- }
326
- )
169
+ github_client.convert_issue_to_pr(
170
+ issue_number_from_branch.to_i,
171
+ head: current_branch,
172
+ base: options[:base_branch] || "main",
327
173
  ).tap do |response|
328
- if response.success?
174
+ if response["url"]
329
175
  pass("Issue converted to Pull Request")
330
- say_info(JSON.parse(response.body)["url"])
176
+ say_info(response["html_url"])
331
177
  else
332
178
  alert("An error occurred when creating PR:")
333
- alert("#{response.status}: #{JSON.parse(response.body)['message']}")
179
+ alert("#{response['message']}")
334
180
  end
335
181
  end
336
182
  end
@@ -348,16 +194,12 @@ module GithubWorkflow
348
194
  end
349
195
 
350
196
  def branch_name_for_issue_number
351
- issue = JSON.parse(github_client.get("repos/#{user_and_repo}/issues/#{issue_id}").body)
197
+ issue = github_client.get_issue(issue_id)
352
198
  "#{issue['number']}_#{issue['title'].strip.downcase.gsub(/[^a-zA-Z0-9]/, '_').squeeze("_")}"
353
199
  end
354
200
 
355
201
  def github_client
356
- Faraday.new(url: "https://api.github.com") do |faraday|
357
- faraday.request :url_encoded
358
- faraday.adapter Faraday.default_adapter
359
- faraday.authorization :Bearer, oauth_token
360
- end
202
+ @gh_client ||= GhCliClient.new
361
203
  end
362
204
 
363
205
  def rebase_main
@@ -392,7 +234,7 @@ module GithubWorkflow
392
234
  @merged_pr_branches ||=
393
235
  pr_branches.map do |branch|
394
236
  id = branch.split("_")[0].to_i
395
- merged = !!get_pr(id)["merged"]
237
+ merged = !!github_client.get_pr(id)["merged"]
396
238
  print merged ? "✅ " : "❌ "
397
239
  puts " #{branch}"
398
240
  merged ? branch : nil
@@ -404,7 +246,7 @@ module GithubWorkflow
404
246
  end
405
247
 
406
248
  def commits_for_range
407
- JSON.parse(github_client.get("repos/#{user_and_repo}/compare/#{options[:commit_range]}").body)
249
+ github_client.commits_for_range(options[:commit_range])
408
250
  end
409
251
 
410
252
  def pull_request_in_commit_range
@@ -414,13 +256,11 @@ module GithubWorkflow
414
256
 
415
257
  prs = pr_ids.map do |id|
416
258
  say_info("Fetching Pull Request ##{id}")
417
- pr = github_client.get("repos/#{user_and_repo}/pulls/#{id}")
259
+ pr = github_client.get_pr(id)
418
260
 
419
- if pr.status == 404
420
- JSON.parse(github_client.get("repos/#{user_and_repo}/issues/#{id}").body)
421
- else
422
- JSON.parse(pr.body)
423
- end
261
+ next pr if pr["number"]
262
+
263
+ github_client.get_issue(id)
424
264
  end
425
265
  end
426
266
 
@@ -0,0 +1,41 @@
1
+
2
+ class GhCliClient
3
+
4
+ def get_issue(id)
5
+ request("'repos/{owner}/{repo}/issues/#{id}'")
6
+ end
7
+
8
+ def get_pr(id)
9
+ request("'repos/{owner}/{repo}/pulls/#{id}'")
10
+ end
11
+
12
+ def get_prs_list
13
+ request("'repos/{owner}/{repo}/pulls?per_page=100'")
14
+ end
15
+
16
+ def create_issue(title:, body: '')
17
+ request("'repos/{owner}/{repo}/issues'", args: {title: title, body: body})
18
+ end
19
+
20
+ def convert_issue_to_pr(id, head:, base:)
21
+ request("'repos/{owner}/{repo}/pulls'", args: {issue: id.to_i, head: head, base: base})
22
+ end
23
+
24
+ def commits_for_range(commit_range)
25
+ # https://docs.github.com/en/rest/commits/commits#compare-two-commits
26
+ request("'repos/{owner}/{repo}/compare/#{commit_range}'")
27
+ end
28
+
29
+ def get_statuses(branch: '{branch}')
30
+ request("'repos/{owner}/{repo}/statuses/#{branch}'")
31
+ end
32
+
33
+ protected
34
+
35
+ def request(url, args: {})
36
+ arg_params = args.map{ |k,v| "-F '#{k}'='#{v}'" }.join(' ')
37
+ response = `gh api #{url} #{arg_params}`
38
+ parsed = JSON.parse(response)
39
+ parsed
40
+ end
41
+ end
@@ -1,3 +1,3 @@
1
1
  module GithubWorkflow
2
- VERSION = "0.3.7"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: github_workflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Liscio
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-15 00:00:00.000000000 Z
11
+ date: 2022-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -24,26 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.0.1
27
- - !ruby/object:Gem::Dependency
28
- name: faraday
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '0.11'
34
- - - "<"
35
- - !ruby/object:Gem::Version
36
- version: '2.0'
37
- type: :runtime
38
- prerelease: false
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - "~>"
42
- - !ruby/object:Gem::Version
43
- version: '0.11'
44
- - - "<"
45
- - !ruby/object:Gem::Version
46
- version: '2.0'
47
27
  - !ruby/object:Gem::Dependency
48
28
  name: terminal-table
49
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,20 +38,6 @@ dependencies:
58
38
  - - "~>"
59
39
  - !ruby/object:Gem::Version
60
40
  version: '1.5'
61
- - !ruby/object:Gem::Dependency
62
- name: ruby-trello
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '2.1'
68
- type: :runtime
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '2.1'
75
41
  - !ruby/object:Gem::Dependency
76
42
  name: bundler
77
43
  requirement: !ruby/object:Gem::Requirement
@@ -114,7 +80,7 @@ dependencies:
114
80
  - - "~>"
115
81
  - !ruby/object:Gem::Version
116
82
  version: '10.0'
117
- description:
83
+ description:
118
84
  email:
119
85
  - bliscio@daisybill.com
120
86
  executables:
@@ -130,12 +96,13 @@ files:
130
96
  - bin/github_workflow
131
97
  - github_workflow.gemspec
132
98
  - lib/github_workflow/cli.rb
99
+ - lib/github_workflow/gh_cli_client.rb
133
100
  - lib/github_workflow/version.rb
134
101
  homepage: https://github.com/daisybill/github_workflow
135
102
  licenses:
136
103
  - MIT
137
104
  metadata: {}
138
- post_install_message:
105
+ post_install_message:
139
106
  rdoc_options: []
140
107
  require_paths:
141
108
  - lib
@@ -150,8 +117,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
117
  - !ruby/object:Gem::Version
151
118
  version: '0'
152
119
  requirements: []
153
- rubygems_version: 3.1.4
154
- signing_key:
120
+ rubygems_version: 3.1.6
121
+ signing_key:
155
122
  specification_version: 4
156
123
  summary: DaisyBill's internal github workflows
157
124
  test_files: []