github_workflow 0.3.9 → 0.4.3
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/.gitignore +2 -0
- data/.ruby-version +1 -1
- data/README.md +34 -24
- data/github_workflow.gemspec +0 -2
- data/lib/github_workflow/cli.rb +102 -214
- data/lib/github_workflow/daisybill.rb +34 -0
- data/lib/github_workflow/gh_cli_client.rb +60 -0
- data/lib/github_workflow/version.rb +1 -1
- metadata +5 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 221999fe5304093bf6533718d5866ad58dc006af43945177f65e65d058dc6c8c
|
4
|
+
data.tar.gz: f48cea6b9a3a7588cc47f70ff257e54c4316edda6394df12cb3c25dfedb2f6de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 238cf09eaabe2ed9d28cd57d187f88a470a1e4614e188eb6ee709b16521848be294944c12f1571961baef940f3929e9a13bdeea0ee46c4ebff0cdd36ce4b3646
|
7
|
+
data.tar.gz: ea20ea5e64ff0432454c18d206bcffa3b448dd32c56e708e979de4a090875099c6737059fd9a5b8e1ad9a87482dc88a53786f2b4c76b6f593a16a54d834bb31a
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.1.3
|
data/README.md
CHANGED
@@ -1,32 +1,42 @@
|
|
1
|
-
#
|
1
|
+
# Setup
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
## GitHub CLI
|
4
|
+
|
5
|
+
Install instructions:
|
6
|
+
|
7
|
+
### MacOS:
|
8
|
+
`brew install gh`
|
9
|
+
|
10
|
+
### Ubuntu
|
11
|
+
|
12
|
+
1. Add a reference to the package repository
|
13
|
+
* `sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key C99B11DEB97541F0`
|
14
|
+
* `sudo apt-add-repository https://cli.github.com/packages`
|
15
|
+
2. Install the Github CLI
|
16
|
+
* `sudo apt update`
|
17
|
+
* `sudo apt install gh`
|
18
|
+
|
19
|
+
## Heroku CLI
|
20
|
+
|
21
|
+
For some commands you may need the [heroku cli installed](https://devcenter.heroku.com/articles/heroku-cli#install-the-heroku-cli)
|
16
22
|
|
17
|
-
#
|
23
|
+
# Commands
|
18
24
|
|
19
25
|
```
|
20
26
|
$ bin/github_workflow -h
|
21
27
|
|
22
28
|
Commands:
|
23
|
-
github_workflow
|
24
|
-
github_workflow
|
25
|
-
github_workflow
|
26
|
-
github_workflow
|
27
|
-
github_workflow
|
28
|
-
github_workflow
|
29
|
-
github_workflow
|
30
|
-
github_workflow
|
31
|
-
github_workflow
|
29
|
+
github_workflow cleanup # Remove merged PR branches
|
30
|
+
github_workflow create_and_start -m, --name=NAME # Create and start issue
|
31
|
+
github_workflow create_pr # Convert Issue to Pull Request
|
32
|
+
github_workflow deploy_diff # view deployment diff between staging and production for apps
|
33
|
+
github_workflow deploy_notes -r, --commit-range=COMMIT_RANGE # Generate Deploy notes for a range of commits
|
34
|
+
github_workflow help [COMMAND] # Describe available commands or one specific command
|
35
|
+
github_workflow info # Print out issue description
|
36
|
+
github_workflow issues # Show issue information for the organization
|
37
|
+
github_workflow open # Open issue or PR in browser
|
38
|
+
github_workflow push_and_pr # Push branch to origin and convert Issue to Pull Request
|
39
|
+
github_workflow reviews # Displays count of requested reviews for each user
|
40
|
+
github_workflow start -i, --issue-id=ISSUE_ID # Create branch named with issue number and issue title
|
41
|
+
github_workflow status # Check PR CI status
|
32
42
|
```
|
data/github_workflow.gemspec
CHANGED
@@ -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"
|
data/lib/github_workflow/cli.rb
CHANGED
@@ -1,88 +1,52 @@
|
|
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
|
-
|
7
|
+
require_relative "gh_cli_client.rb"
|
8
|
+
require_relative "daisybill.rb"
|
9
9
|
|
10
10
|
module GithubWorkflow
|
11
11
|
class Cli < Thor
|
12
12
|
PROCEED_TEXT = "Proceed? [y,yes]: ".freeze
|
13
|
-
|
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
|
13
|
+
TRUNCATE_DEFAULT = 50
|
24
14
|
|
25
15
|
include Thor::Actions
|
26
16
|
|
27
|
-
default_task :
|
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
|
17
|
+
default_task :start
|
54
18
|
|
55
19
|
desc "start", "Create branch named with issue number and issue title"
|
56
20
|
method_option :issue_id, aliases: "-i", type: :string, required: true
|
21
|
+
method_option :truncate_branch_at, aliases: "-t", type: :numeric, default: TRUNCATE_DEFAULT
|
22
|
+
method_option :no_checkout, type: :boolean, required: false, default: false
|
57
23
|
def start
|
58
|
-
ensure_github_config_present
|
59
24
|
stash
|
60
25
|
rebase_main
|
61
|
-
create_branch
|
26
|
+
create_branch(options[:no_checkout])
|
62
27
|
stash_pop
|
63
28
|
end
|
64
29
|
|
65
30
|
desc "create_pr", "Convert Issue to Pull Request"
|
66
31
|
method_option :base_branch, aliases: "-b", type: :string
|
32
|
+
method_option :draft, aliases: "-d", type: :boolean, required: false, default: true
|
67
33
|
def create_pr
|
68
|
-
ensure_github_config_present
|
69
34
|
ensure_origin_exists
|
70
35
|
convert_issue_to_pr
|
71
36
|
end
|
72
37
|
|
73
38
|
desc "push_and_pr", "Push branch to origin and convert Issue to Pull Request"
|
74
39
|
method_option :base_branch, aliases: "-b", type: :string
|
40
|
+
method_option :draft, aliases: "-d", type: :boolean, required: false, default: true
|
75
41
|
def push_and_pr
|
76
|
-
ensure_github_config_present
|
77
42
|
push_and_set_upstream
|
78
43
|
convert_issue_to_pr
|
79
44
|
end
|
80
45
|
|
81
46
|
desc "status", "Check PR CI status"
|
82
47
|
def status
|
83
|
-
ensure_github_config_present
|
84
48
|
ensure_origin_exists
|
85
|
-
response =
|
49
|
+
response = github_client.get_statuses
|
86
50
|
|
87
51
|
if response.empty?
|
88
52
|
alert "No statuses yet. Have you pushed your branch?"
|
@@ -104,21 +68,22 @@ module GithubWorkflow
|
|
104
68
|
|
105
69
|
desc "info", "Print out issue description"
|
106
70
|
def info
|
107
|
-
|
108
|
-
puts
|
71
|
+
issue = github_client.get_issue(issue_number_from_branch)
|
72
|
+
puts "#{issue["html_url"]}\n\n"
|
73
|
+
puts "[##{issue["number"]}] #{issue["title"]}\n"
|
74
|
+
puts issue["body"]
|
109
75
|
end
|
110
76
|
|
111
77
|
desc "open", "Open issue or PR in browser"
|
112
78
|
def open
|
113
|
-
|
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"]}'`
|
79
|
+
open_url(github_client.get_issue(issue_number_from_branch)["html_url"])
|
116
80
|
end
|
117
81
|
|
118
82
|
desc "create_and_start", "Create and start issue"
|
119
83
|
method_option :name, aliases: "-m", type: :string, required: true
|
84
|
+
method_option :truncate_branch_at, aliases: "-t", type: :numeric, default: TRUNCATE_DEFAULT
|
85
|
+
method_option :no_checkout, type: :boolean, required: false, default: false
|
120
86
|
def create_and_start
|
121
|
-
ensure_github_config_present
|
122
87
|
create_issue
|
123
88
|
end
|
124
89
|
|
@@ -147,8 +112,7 @@ module GithubWorkflow
|
|
147
112
|
|
148
113
|
desc "reviews", "Displays count of requested reviews for each user"
|
149
114
|
def reviews
|
150
|
-
|
151
|
-
reviewers = get_prs_list.map { |pr| pr["requested_reviewers"].map { |r| r["login"] } }.flatten
|
115
|
+
reviewers = github_client.get_prs_list.map { |pr| pr["requested_reviewers"].map { |r| r["login"] } }.flatten
|
152
116
|
reviewer_counts = reviewers.group_by { |i| i }.map { |k, v| [k, v.count] }
|
153
117
|
|
154
118
|
if reviewer_counts.any?
|
@@ -162,136 +126,67 @@ module GithubWorkflow
|
|
162
126
|
end
|
163
127
|
end
|
164
128
|
|
165
|
-
desc "
|
166
|
-
method_option :
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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)
|
183
|
-
end
|
184
|
-
|
185
|
-
def create_branch
|
186
|
-
`git checkout -b #{branch_name_for_issue_number} main`
|
187
|
-
end
|
188
|
-
|
189
|
-
def ensure_origin_exists
|
190
|
-
Open3.capture2("git rev-parse --abbrev-ref --symbolic-full-name @{u}").tap do |_, status|
|
191
|
-
unless status.success?
|
192
|
-
failure("Upstream branch does not exist. Please set before creating pull request. E.g., `git push -u origin branch_name`")
|
193
|
-
end
|
129
|
+
desc "deploy_diff", "view deployment diff between staging and production for apps"
|
130
|
+
method_option :all, aliases: "-a", type: :boolean, default: false
|
131
|
+
def deploy_diff
|
132
|
+
apps = Daisybill::APPS
|
133
|
+
unless options[:all]
|
134
|
+
current_repo = github_client.get_repo_info
|
135
|
+
apps.reject! do |a|
|
136
|
+
a[:github_org] != current_repo[:owner] || a[:github_repo] != current_repo[:repo]
|
194
137
|
end
|
195
138
|
end
|
196
139
|
|
197
|
-
|
198
|
-
|
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
|
140
|
+
apps.each do |app|
|
141
|
+
owner = app[:github_org]
|
142
|
+
repo = app[:github_repo]
|
218
143
|
|
219
|
-
|
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
|
144
|
+
puts "\n**** #{owner}/#{repo} ****\n"
|
226
145
|
|
227
|
-
|
228
|
-
|
146
|
+
full_diff = `heroku pipelines:diff -a #{app[:heroku_staging_app]}`
|
147
|
+
puts full_diff
|
148
|
+
revisions = full_diff.split("compare/").last.strip.split("...")
|
229
149
|
|
230
|
-
|
231
|
-
"**Deploy Note:** #{custom_field.value['text']}"
|
232
|
-
end
|
233
|
-
end
|
150
|
+
latest_commit = github_client.latest_remote_commit(owner: owner, repo: repo)
|
234
151
|
|
235
|
-
|
236
|
-
custom_field = trello_card.custom_field_items.detect { |cfi| cfi.custom_field.name == "Product Review" }
|
152
|
+
next if revisions.size < 2
|
237
153
|
|
238
|
-
if
|
239
|
-
"
|
154
|
+
if latest_commit != revisions.last
|
155
|
+
puts "WARNING - heroku staging app deploy is behind at commit #{revisions.last}. The repository is at commit #{latest_commit}"
|
240
156
|
end
|
241
|
-
end
|
242
157
|
|
243
|
-
|
244
|
-
JSON.parse(github_client.get("user").body)["login"]
|
158
|
+
puts formatted_deploy_notes(revisions.join('...'), owner: owner, repo: repo)
|
245
159
|
end
|
160
|
+
end
|
246
161
|
|
247
|
-
|
248
|
-
|
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
|
162
|
+
desc "deploy_notes", "Generate Deploy notes for a range of commits"
|
163
|
+
method_option :commit_range, aliases: "-r", type: :string, required: true
|
259
164
|
|
260
|
-
|
261
|
-
|
262
|
-
|
165
|
+
def deploy_notes
|
166
|
+
puts formatted_deploy_notes(options[:commit_range], owner: github_client.get_repo_info[:owner], repo: github_client.get_repo_info[:repo])
|
167
|
+
puts formatted_deploy_notes
|
168
|
+
end
|
263
169
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
end
|
170
|
+
no_tasks do
|
171
|
+
def open_url(url)
|
172
|
+
`/usr/bin/open -a "/Applications/Google Chrome.app" '#{url}'`
|
268
173
|
end
|
269
174
|
|
270
|
-
def
|
271
|
-
|
272
|
-
|
273
|
-
|
175
|
+
def create_branch(no_checkout = false)
|
176
|
+
if no_checkout
|
177
|
+
`git branch #{branch_name_for_issue_number} main`
|
178
|
+
else
|
179
|
+
`git checkout -b #{branch_name_for_issue_number} main`
|
274
180
|
end
|
181
|
+
say_info("created branch #{branch_name_for_issue_number}")
|
275
182
|
end
|
276
183
|
|
277
|
-
def
|
278
|
-
@
|
279
|
-
|
280
|
-
|
281
|
-
result = File.exists?(global_config_path) ? JSON.parse(File.read(global_config_path)) : {}
|
282
|
-
local_config_data = JSON.parse(File.read(CONFIG_FILE_NAME))
|
283
|
-
result.merge(local_config_data)
|
284
|
-
rescue
|
285
|
-
{}
|
184
|
+
def ensure_origin_exists
|
185
|
+
Open3.capture2("git rev-parse --abbrev-ref --symbolic-full-name @{u}").tap do |_, status|
|
186
|
+
unless status.success?
|
187
|
+
failure("Upstream branch does not exist. Please set before creating pull request. E.g., `git push -u origin branch_name`")
|
286
188
|
end
|
287
|
-
|
288
|
-
|
289
|
-
def oauth_token
|
290
|
-
project_config["oauth_token"]
|
291
|
-
end
|
292
|
-
|
293
|
-
def user_and_repo
|
294
|
-
project_config["user_and_repo"]
|
189
|
+
end
|
295
190
|
end
|
296
191
|
|
297
192
|
def push_and_set_upstream
|
@@ -299,21 +194,16 @@ module GithubWorkflow
|
|
299
194
|
end
|
300
195
|
|
301
196
|
def create_issue
|
302
|
-
github_client.
|
303
|
-
|
304
|
-
JSON.generate(
|
305
|
-
{
|
306
|
-
title: options[:name]
|
307
|
-
}
|
308
|
-
)
|
197
|
+
github_client.create_issue(
|
198
|
+
title: options[:name]
|
309
199
|
).tap do |response|
|
310
|
-
if response
|
200
|
+
if response["number"]
|
311
201
|
pass("Issue created")
|
312
|
-
@issue_id =
|
202
|
+
@issue_id = response["number"]
|
313
203
|
start
|
314
204
|
else
|
315
205
|
alert("An error occurred when creating issue:")
|
316
|
-
alert("#{response
|
206
|
+
alert("#{response['message']}")
|
317
207
|
end
|
318
208
|
end
|
319
209
|
end
|
@@ -323,22 +213,18 @@ module GithubWorkflow
|
|
323
213
|
end
|
324
214
|
|
325
215
|
def convert_issue_to_pr
|
326
|
-
github_client.
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
base: options[:base_branch] || "main",
|
332
|
-
issue: issue_number_from_branch.to_i
|
333
|
-
}
|
334
|
-
)
|
216
|
+
github_client.convert_issue_to_pr(
|
217
|
+
issue_number_from_branch.to_i,
|
218
|
+
head: current_branch,
|
219
|
+
base: options[:base_branch] || "main",
|
220
|
+
draft: options[:draft],
|
335
221
|
).tap do |response|
|
336
|
-
if response
|
222
|
+
if response["url"]
|
337
223
|
pass("Issue converted to Pull Request")
|
338
|
-
say_info(
|
224
|
+
say_info(response["html_url"])
|
339
225
|
else
|
340
226
|
alert("An error occurred when creating PR:")
|
341
|
-
alert("#{response
|
227
|
+
alert("#{response['message']}")
|
342
228
|
end
|
343
229
|
end
|
344
230
|
end
|
@@ -356,16 +242,18 @@ module GithubWorkflow
|
|
356
242
|
end
|
357
243
|
|
358
244
|
def branch_name_for_issue_number
|
359
|
-
issue =
|
360
|
-
"#{issue['number']}_#{issue['title'].strip.downcase.gsub(/[^a-zA-Z0-9]/, '_').squeeze("_")}"
|
245
|
+
issue = github_client.get_issue(issue_id)
|
246
|
+
branch_name ="#{issue['number']}_#{issue['title'].strip.downcase.gsub(/[^a-zA-Z0-9]/, '_').squeeze("_")}"
|
247
|
+
|
248
|
+
if options[:truncate_branch_at]
|
249
|
+
branch_name[0...options[:truncate_branch_at]]
|
250
|
+
else
|
251
|
+
branch_name
|
252
|
+
end
|
361
253
|
end
|
362
254
|
|
363
255
|
def github_client
|
364
|
-
|
365
|
-
faraday.request :url_encoded
|
366
|
-
faraday.adapter Faraday.default_adapter
|
367
|
-
faraday.authorization :Bearer, oauth_token
|
368
|
-
end
|
256
|
+
@gh_client ||= GhCliClient.new
|
369
257
|
end
|
370
258
|
|
371
259
|
def rebase_main
|
@@ -400,7 +288,7 @@ module GithubWorkflow
|
|
400
288
|
@merged_pr_branches ||=
|
401
289
|
pr_branches.map do |branch|
|
402
290
|
id = branch.split("_")[0].to_i
|
403
|
-
merged = !!get_pr(id)["merged"]
|
291
|
+
merged = !!github_client.get_pr(id)["merged"]
|
404
292
|
print merged ? "✅ " : "❌ "
|
405
293
|
puts " #{branch}"
|
406
294
|
merged ? branch : nil
|
@@ -411,37 +299,37 @@ module GithubWorkflow
|
|
411
299
|
`git branch`.gsub(" ", "").split("\n").select { |br| br.match /^[0-9]/ }
|
412
300
|
end
|
413
301
|
|
414
|
-
def
|
415
|
-
|
416
|
-
end
|
417
|
-
|
418
|
-
def pull_request_in_commit_range
|
419
|
-
pr_ids = commits_for_range["commits"].map do |commit|
|
302
|
+
def pull_request_in_commit_range(commits, owner:, repo:)
|
303
|
+
pr_ids = commits.map do |commit|
|
420
304
|
commit.dig("commit", "message").to_s.match(/(?<=\[#)\d{4,5}(?=\])/).to_s.to_i
|
421
305
|
end.uniq.compact
|
422
306
|
|
423
307
|
prs = pr_ids.map do |id|
|
424
308
|
say_info("Fetching Pull Request ##{id}")
|
425
|
-
pr = github_client.
|
309
|
+
pr = github_client.get_pr(id, owner: owner, repo: repo)
|
426
310
|
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
JSON.parse(pr.body)
|
431
|
-
end
|
311
|
+
next pr if pr["number"]
|
312
|
+
|
313
|
+
github_client.get_issue(id, owner: owner, repo: repo)
|
432
314
|
end
|
433
315
|
end
|
434
316
|
|
435
|
-
def formatted_deploy_notes
|
436
|
-
|
437
|
-
|
317
|
+
def formatted_deploy_notes(commit_range, owner:, repo:)
|
318
|
+
notes = pull_request_in_commit_range(
|
319
|
+
github_client.commits_for_range(commit_range, owner: owner, repo: repo)["commits"],
|
320
|
+
owner: owner,
|
321
|
+
repo: repo
|
322
|
+
).map do |pr|
|
323
|
+
deploy_note = pr["body"].to_s.split("**Deploy Note:**")[1].to_s.split(/\n/)[0].to_s.strip
|
438
324
|
|
439
|
-
if deploy_note.length >
|
440
|
-
"- #{deploy_note}"
|
441
|
-
else
|
442
|
-
%Q{Missing deploy note: #{pr["title"]}}
|
325
|
+
if deploy_note.length > 3
|
326
|
+
"- [##{pr["number"]}] #{deploy_note}"
|
443
327
|
end
|
444
|
-
end.
|
328
|
+
end.compact
|
329
|
+
|
330
|
+
notes = ['- No notes'] if notes.empty?
|
331
|
+
|
332
|
+
notes.unshift("[#{repo}]")
|
445
333
|
end
|
446
334
|
|
447
335
|
def success?(command)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Daisybill
|
2
|
+
APPS = [
|
3
|
+
DAISYBILL = {
|
4
|
+
"github_org": "daisybill",
|
5
|
+
"github_repo": "daisyBill",
|
6
|
+
"heroku_staging_app": "daisybill-staging"
|
7
|
+
},
|
8
|
+
ELLIS = {
|
9
|
+
"github_org": "daisybill",
|
10
|
+
"github_repo": "ellis",
|
11
|
+
"heroku_staging_app": "ellis-staging"
|
12
|
+
},
|
13
|
+
AUTH_INBOX = {
|
14
|
+
"github_org": "daisybill",
|
15
|
+
"github_repo": "auth-inbox",
|
16
|
+
"heroku_staging_app": "auth-inbox-staging"
|
17
|
+
},
|
18
|
+
KNOWLEDGEABLE = {
|
19
|
+
"github_org": "daisybill",
|
20
|
+
"github_repo": "knowledgeable",
|
21
|
+
"heroku_staging_app": "knowledgeable-staging"
|
22
|
+
},
|
23
|
+
FEE_SCHEDULE = {
|
24
|
+
"github_org": "daisybill",
|
25
|
+
"github_repo": "fee_schedule",
|
26
|
+
"heroku_staging_app": "fee-schedule-staging"
|
27
|
+
},
|
28
|
+
WCB_XML_CLEARINGHOUSE = {
|
29
|
+
"github_org": "daisybill",
|
30
|
+
"github_repo": "wcb_xml_clearinghouse",
|
31
|
+
"heroku_staging_app": "wcb-xml-clearinghouse-staging"
|
32
|
+
}
|
33
|
+
]
|
34
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
class GhCliClient
|
3
|
+
|
4
|
+
def get_issue(id, owner: nil, repo: nil)
|
5
|
+
request("'#{path_base(owner, repo)}/issues/#{id}'")
|
6
|
+
end
|
7
|
+
|
8
|
+
def get_pr(id, owner: nil, repo: nil)
|
9
|
+
request("'#{path_base(owner, repo)}/pulls/#{id}'")
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_prs_list(owner: nil, repo: nil)
|
13
|
+
request("'#{path_base(owner, repo)}/pulls?per_page=100'")
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_issue(title:, body: '', owner: nil, repo: nil)
|
17
|
+
request("'#{path_base(owner, repo)}/issues'", args: {title: title, body: body})
|
18
|
+
end
|
19
|
+
|
20
|
+
def convert_issue_to_pr(id, head:, base:, owner: nil, repo: nil, draft: true)
|
21
|
+
request("'#{path_base(owner, repo)}/pulls'", args: {issue: id.to_i, head: head, base: base, draft: draft})
|
22
|
+
end
|
23
|
+
|
24
|
+
def commits_for_range(commit_range, owner: nil, repo: nil)
|
25
|
+
# https://docs.github.com/en/rest/commits/commits#compare-two-commits
|
26
|
+
request("'#{path_base(owner, repo)}/compare/#{commit_range}'")
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_statuses(branch: '{branch}', owner: nil, repo: nil)
|
30
|
+
request("'#{path_base(owner, repo)}/statuses/#{branch}'")
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_repo_info
|
34
|
+
@repo_info ||= begin
|
35
|
+
result = `gh repo view --json owner,name -q ".owner.login,.name"`.split("\n").compact
|
36
|
+
{
|
37
|
+
owner: result[0],
|
38
|
+
repo: result[1]
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def latest_remote_commit(owner:, repo:)
|
44
|
+
result = `gh browse -R '#{owner}/#{repo}' -n -c`
|
45
|
+
result.split("/").last.strip
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def path_base(owner, repo)
|
51
|
+
"repos/#{owner || "{owner}"}/#{repo || "{repo}"}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def request(url, args: {})
|
55
|
+
arg_params = args.map{ |k,v| "-F '#{k}'='#{v}'" }.join(' ')
|
56
|
+
response = `gh api #{url} #{arg_params}`
|
57
|
+
parsed = JSON.parse(response)
|
58
|
+
parsed
|
59
|
+
end
|
60
|
+
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
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Liscio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-10 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
|
@@ -130,6 +96,8 @@ files:
|
|
130
96
|
- bin/github_workflow
|
131
97
|
- github_workflow.gemspec
|
132
98
|
- lib/github_workflow/cli.rb
|
99
|
+
- lib/github_workflow/daisybill.rb
|
100
|
+
- lib/github_workflow/gh_cli_client.rb
|
133
101
|
- lib/github_workflow/version.rb
|
134
102
|
homepage: https://github.com/daisybill/github_workflow
|
135
103
|
licenses:
|
@@ -150,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
118
|
- !ruby/object:Gem::Version
|
151
119
|
version: '0'
|
152
120
|
requirements: []
|
153
|
-
rubygems_version: 3.
|
121
|
+
rubygems_version: 3.3.26
|
154
122
|
signing_key:
|
155
123
|
specification_version: 4
|
156
124
|
summary: DaisyBill's internal github workflows
|