github_workflow 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c9d551fbda6a545a0fb85ffbcefeb43a8bfb1f9c
4
+ data.tar.gz: 9c6895664cdd69ce38ee216cef9422b3e4cf3493
5
+ SHA512:
6
+ metadata.gz: 3aa3959df85a40b3334a23353779bd79dde7f108eaf2d0f5313668096410e4d5012ec371aa80a88cad9ebb4195ee1cdf31c80b10b06539e294f80f5685ab94fa
7
+ data.tar.gz: 68f184bb3c52de1769f8d83a5e4e564e2f57dbbdc6607439c177e78ec1d4ec4a3bb5cdea2faf1045b0578cce611a51530ffb47daa6bf2d980d04ee0916bafaf5
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.1
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # Github Workflow
2
+
3
+ ```
4
+ $ bin/github_workflow -h
5
+
6
+ Commands:
7
+ github_workflow create_and_start -m, --name=NAME # Create and start issue
8
+ github_workflow create_pr # Convert Issue to Pull Request
9
+ github_workflow help [COMMAND] # Describe available commands or one specific command
10
+ github_workflow info # Print out issue description
11
+ github_workflow open # Open issue or PR in browser
12
+ github_workflow push_and_pr # Push branch to origin and convert Issue to Pull Request
13
+ github_workflow start -i, --issue-id=ISSUE_ID # Create branch named with issue number and issue title
14
+ github_workflow status # Check PR CI status
15
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "github_workflow/cli"
4
+
5
+ GithubWorkflow::Cli.start
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "github_workflow/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "github_workflow"
8
+ spec.version = GithubWorkflow::VERSION
9
+ spec.authors = ["Ben Liscio"]
10
+ spec.email = ["bliscio@daisybill.com"]
11
+
12
+ spec.summary = %q{DaisyBill's internal github workflows}
13
+ spec.homepage = "https://github.com/daisybill/github_workflow"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "thor", "~> 0.19"
21
+ spec.add_dependency "faraday", "~> 0.11"
22
+ spec.add_dependency "terminal-table", "~> 1.5"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.14"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ end
@@ -0,0 +1,240 @@
1
+ require "rubygems"
2
+ require "faraday"
3
+ require "thor"
4
+ require "open3"
5
+ require "json"
6
+ require "terminal-table"
7
+
8
+ module GithubWorkflow
9
+ class Cli < Thor
10
+ include Thor::Actions
11
+
12
+ default_task :start
13
+
14
+ desc "start", "Create branch named with issue number and issue title"
15
+ method_option :issue_id, aliases: "-i", type: :string, required: true
16
+
17
+ def start
18
+ ensure_github_config_present
19
+ checkout_master
20
+ rebase_master
21
+ create_branch
22
+ end
23
+
24
+ desc "create_pr", "Convert Issue to Pull Request"
25
+
26
+ def create_pr
27
+ ensure_github_config_present
28
+ ensure_origin_exists
29
+ convert_issue_to_pr
30
+ end
31
+
32
+ desc "push_and_pr", "Push branch to origin and convert Issue to Pull Request"
33
+
34
+ def push_and_pr
35
+ ensure_github_config_present
36
+ push_and_set_upstream
37
+ convert_issue_to_pr
38
+ end
39
+
40
+ desc "status", "Check PR CI status"
41
+
42
+ def status
43
+ ensure_github_config_present
44
+ ensure_origin_exists
45
+ response = JSON.parse(github_client.get("repos/#{user_and_repo}/statuses/#{current_branch}?access_token=#{oauth_token}").body)
46
+
47
+ if response.empty?
48
+ alert "No statuses yet. Have you pushed your branch?"
49
+ else
50
+ table = Terminal::Table.new(style: { width: 80 }) do |table_rows|
51
+ table_rows << %w(CI Status Description)
52
+ table_rows << :separator
53
+
54
+ response.map { |status| status["context"] }.uniq.map do |status|
55
+ response.select { |st| st["context"] == status }.sort_by { |st| st["updated_at"] }.last
56
+ end.each do |status|
57
+ table_rows << %w(context state description).map { |key| status[key] }
58
+ end
59
+ end
60
+
61
+ puts table
62
+ end
63
+ end
64
+
65
+ desc "info", "Print out issue description"
66
+
67
+ def info
68
+ ensure_github_config_present
69
+ response = JSON.parse(github_client.get("repos/#{user_and_repo}/issues/#{issue_number_from_branch}?access_token=#{oauth_token}").body)
70
+ puts response["body"]
71
+ end
72
+
73
+ desc "open", "Open issue or PR in browser"
74
+
75
+ def open
76
+ ensure_github_config_present
77
+ response = JSON.parse(github_client.get("repos/#{user_and_repo}/issues/#{issue_number_from_branch}?access_token=#{oauth_token}").body)
78
+ `/usr/bin/open -a "/Applications/Google Chrome.app" '#{response["html_url"]}'`
79
+ end
80
+
81
+ desc "create_and_start", "Create and start issue"
82
+
83
+ method_option :name, aliases: "-m", type: :string, required: true
84
+
85
+ def create_and_start
86
+ ensure_github_config_present
87
+ create_issue
88
+ end
89
+
90
+ no_tasks do
91
+ def create_branch
92
+ `git checkout -b #{branch_name_for_issue_number}`
93
+ end
94
+
95
+ def ensure_origin_exists
96
+ Open3.capture2("git rev-parse --abbrev-ref --symbolic-full-name @{u}").tap do |_, status|
97
+ unless status.success?
98
+ failure("Upstream branch does not exist. Please set before creating pull request. E.g., `git push -u origin branch_name`")
99
+ end
100
+ end
101
+ end
102
+
103
+ def ensure_github_config_present
104
+ unless project_config && project_config["oauth_token"] && project_config["user_and_repo"]
105
+ failure('Please add `.github` file containing `{ "oauth": "TOKEN", "repo": "user/repo" }`')
106
+ end
107
+ end
108
+
109
+ def project_config
110
+ @project_config ||= JSON.parse(File.read(".github")) rescue nil
111
+ end
112
+
113
+ def oauth_token
114
+ project_config["oauth_token"]
115
+ end
116
+
117
+ def user_and_repo
118
+ project_config["user_and_repo"]
119
+ end
120
+
121
+ def push_and_set_upstream
122
+ `git rev-parse --abbrev-ref HEAD | XARGS git push origin -u`
123
+ end
124
+
125
+ def create_issue
126
+ github_client.post(
127
+ "repos/#{user_and_repo}/issues?access_token=#{oauth_token}",
128
+ JSON.generate(
129
+ {
130
+ title: options[:name]
131
+ }
132
+ )
133
+ ).tap do |response|
134
+ if response.success?
135
+ pass("Issue created")
136
+ @issue_id = JSON.parse(response.body)["number"]
137
+ start
138
+ else
139
+ alert("An error occurred when creating issue:")
140
+ alert("#{response.status}: #{JSON.parse(response.body)['message']}")
141
+ end
142
+ end
143
+ end
144
+
145
+ def issue_id
146
+ @issue_id ||= options[:issue_id]
147
+ end
148
+
149
+ def convert_issue_to_pr
150
+ github_client.post(
151
+ "repos/#{user_and_repo}/pulls?access_token=#{oauth_token}",
152
+ JSON.generate(
153
+ {
154
+ head: current_branch,
155
+ base: "master",
156
+ issue: issue_number_from_branch
157
+ }
158
+ )
159
+ ).tap do |response|
160
+ if response.success?
161
+ pass("Issue converted to Pull Request")
162
+ say_info(JSON.parse(response.body)["url"])
163
+ else
164
+ alert("An error occurred when creating PR:")
165
+ alert("#{response.status}: #{JSON.parse(response.body)['message']}")
166
+ end
167
+ end
168
+ end
169
+
170
+ def issue_number_from_branch
171
+ current_branch.split("_").first.tap do |issue_number|
172
+ if !issue_number
173
+ failure("Unable to parse issue number from branch. Are you sure you have a branch checked out?")
174
+ end
175
+ end
176
+ end
177
+
178
+ def current_branch
179
+ `git rev-parse --abbrev-ref HEAD`.chomp
180
+ end
181
+
182
+ def branch_name_for_issue_number
183
+ issue = JSON.parse(github_client.get("repos/#{user_and_repo}/issues/#{issue_id}?access_token=#{oauth_token}").body)
184
+ "#{issue['number']}_#{issue['title'].strip.downcase.gsub(/[^a-zA-Z0-9]/, '_').squeeze("_")}"
185
+ end
186
+
187
+ def github_client
188
+ Faraday.new(url: "https://api.github.com") do |faraday|
189
+ faraday.request :url_encoded
190
+ faraday.adapter Faraday.default_adapter
191
+ end
192
+ end
193
+
194
+ def rebase_master
195
+ say_info("Fetching changes and rebaseing master")
196
+
197
+ if success?("git pull --rebase")
198
+ pass("Fetched and rebased")
199
+ else
200
+ failure("Failed to fetch or rebase")
201
+ end
202
+ end
203
+
204
+ def checkout_master
205
+ say_info("Checking out master")
206
+
207
+ if success?("git checkout master")
208
+ pass("Checked out master")
209
+ else
210
+ failure("Failed to checkout master")
211
+ end
212
+ end
213
+
214
+ def success?(command)
215
+ IO.popen(command) do |output|
216
+ output.each { |line| puts line }
217
+ end
218
+
219
+ $?.success?
220
+ end
221
+
222
+ def alert(message)
223
+ say_status("ALERT", message, :red)
224
+ end
225
+
226
+ def say_info(message)
227
+ say_status("INFO", message, :black)
228
+ end
229
+
230
+ def pass(message)
231
+ say_status("OK", message, :green)
232
+ end
233
+
234
+ def failure(message)
235
+ say_status("FAIL", message, :red)
236
+ exit
237
+ end
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,3 @@
1
+ module GithubWorkflow
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: github_workflow
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben Liscio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.19'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.19'
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
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.11'
41
+ - !ruby/object:Gem::Dependency
42
+ name: terminal-table
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.14'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.14'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ description:
84
+ email:
85
+ - bliscio@daisybill.com
86
+ executables:
87
+ - github_workflow
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".ruby-version"
93
+ - Gemfile
94
+ - README.md
95
+ - Rakefile
96
+ - bin/github_workflow
97
+ - github_workflow.gemspec
98
+ - lib/github_workflow/cli.rb
99
+ - lib/github_workflow/version.rb
100
+ homepage: https://github.com/daisybill/github_workflow
101
+ licenses:
102
+ - MIT
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 2.5.1
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: DaisyBill's internal github workflows
124
+ test_files: []