gh-events 0.6.2 → 0.8.3

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
2
  SHA256:
3
- metadata.gz: 7f9a4fc61ec5714b1d49249d449496180f7a7e378b327a9c2e8d7e467c06b9a5
4
- data.tar.gz: 83d0c56649117b8a3f091215223467f327e326b28e81874e9dce4cb5e2ac61b7
3
+ metadata.gz: 23309b6819c759bd4ae39468e40dc374409484ae1ec4568c42713ba82dbf305e
4
+ data.tar.gz: f9decf307c3770b981bbca41bb149f008a59aa8279a2b01ef59e4adb8d55a44b
5
5
  SHA512:
6
- metadata.gz: 1e688bda0e36e9dee4b97b3a166bf2b1e2a574767a19099d666ec5ed1fa07c7d6e0193226b92b4d67d652f3228f990308dc700cfbb37f80bfce1abc7821e2189
7
- data.tar.gz: dd7072f3c14de36c0f63c33430f129f790db2c0908f7ce900c84ee0c049427b1f442bdbf77360058d5670cf909141bbaa100bcf3204712c2dc220af602854bc8
6
+ metadata.gz: e24a1288484269407ae8761f2db4b49e6f6f0413e7ab4bdbd43e2405f87c8ce71ac117feb42cb82bfe756a2acbf9122180b1169901380acc82db3698001adefa
7
+ data.tar.gz: 37c811378a88220d83d070ac5bb02ae8466e6e1be977a40307a32610b11f071a56d319832b50671c931d2d738a336fa5b9d9b21236cc32a7ef861da5295bd570
@@ -0,0 +1,60 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ build:
8
+ docker:
9
+ # specify the version you desire here
10
+ - image: circleci/ruby:2.6.5
11
+
12
+ # Specify service dependencies here if necessary
13
+ # CircleCI maintains a library of pre-built images
14
+ # documented at https://circleci.com/docs/2.0/circleci-images/
15
+ # - image: circleci/postgres:9.4
16
+
17
+ working_directory: ~/repo
18
+
19
+ steps:
20
+ - checkout
21
+
22
+ # Download and cache dependencies
23
+ - restore_cache:
24
+ keys:
25
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
26
+ # fallback to using the latest cache if no exact match is found
27
+ - v1-dependencies-
28
+
29
+ - run:
30
+ name: install dependencies
31
+ command: |
32
+ gem install bundler:2.0.2
33
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
34
+
35
+ - save_cache:
36
+ paths:
37
+ - ./vendor/bundle
38
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
39
+
40
+ # run tests!
41
+ - run:
42
+ name: run tests
43
+ command: |
44
+ mkdir /tmp/test-results
45
+ TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
46
+ circleci tests split --split-by=timings)"
47
+
48
+ bundle exec rspec \
49
+ --format progress \
50
+ --format RspecJunitFormatter \
51
+ --out /tmp/test-results/rspec.xml \
52
+ --format progress \
53
+ $TEST_FILES
54
+
55
+ # collect reports
56
+ - store_test_results:
57
+ path: /tmp/test-results
58
+ - store_artifacts:
59
+ path: /tmp/test-results
60
+ destination: test-results
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gh-events (0.6.2)
4
+ gh-events (0.8.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -21,6 +21,8 @@ GEM
21
21
  diff-lcs (>= 1.2.0, < 2.0)
22
22
  rspec-support (~> 3.9.0)
23
23
  rspec-support (3.9.0)
24
+ rspec_junit_formatter (0.4.1)
25
+ rspec-core (>= 2, < 4, != 2.12.0)
24
26
 
25
27
  PLATFORMS
26
28
  ruby
@@ -30,6 +32,7 @@ DEPENDENCIES
30
32
  gh-events!
31
33
  rake (~> 10.0)
32
34
  rspec (~> 3.0)
35
+ rspec_junit_formatter (~> 0.4)
33
36
 
34
37
  BUNDLED WITH
35
- 2.0.2
38
+ 2.1.4
@@ -0,0 +1,7 @@
1
+ Copyright 2020 Phil Hofmann
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,11 +1,31 @@
1
- # Github::Events
1
+ # Github Events
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/github/events`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Via Webhooks Github can send a plethora of events, which can be used
4
+ to facilitate all kinds of automation.
5
+
6
+ These events are _untyped_, meaning they clearly lack a property
7
+ `type` to identify the type of event received. The rationale here
8
+ might be that one would have different webhook endpoints for each type
9
+ of events. But maintaining lots of endpoints is cumbersome. When all
10
+ the events end up in one endpoint, this library helps by adding a
11
+ property `type` to the event.
12
+
13
+ Additionally this library provides means of translating the plain
14
+ event (a deeply nested data structure serialized to JSON) into a human
15
+ readable textutal representation. Some functionality is wrapped in a
16
+ command line utilites, for your convenience.
4
17
 
5
- TODO: Delete this and the text above, and describe your gem
6
18
 
7
19
  ## Installation
8
20
 
21
+ ### To use the command line utilities
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install gh-events
26
+
27
+ ### To use as a library in your own project
28
+
9
29
  Add this line to your application's Gemfile:
10
30
 
11
31
  ```ruby
@@ -16,13 +36,58 @@ And then execute:
16
36
 
17
37
  $ bundle
18
38
 
19
- Or install it yourself as:
20
-
21
- $ gem install gh-events
22
39
 
23
40
  ## Usage
24
41
 
25
- TODO: Write usage instructions here
42
+ ### CLI Util
43
+
44
+ #### Typing
45
+
46
+ You can use the command `gh-events` to list the types of events
47
+ stored in JSON files.
48
+
49
+ ```
50
+ % gh-events spec/fixtures/*.json
51
+ events/001.json: commit_comment
52
+ events/002.json: create
53
+ events/003.json: delete
54
+ events/004.json: deployment
55
+ events/005.json: deployment_status
56
+ events/006.json: fork
57
+ ...
58
+ ```
59
+
60
+ #### Translating
61
+
62
+ The `gh-event2text` util will receive one event via stdin. Let's say
63
+ you have a github _commit_comment_ event stored in a file named
64
+ `event.json`. With you can to this:
65
+
66
+ ```
67
+ % cat event.json | gh-event2text
68
+ "[Codertocat/Hello-World] Codertocat commented on commit `6113728f27ae82c7b1a177c8d03f9e96e0adf246`>: \"This is a really good change! :+1:\""
69
+ ```
70
+
71
+ For translating the event into its textual representation
72
+ `gh-event2text` uses a dictionary. The dictionary can be given as an
73
+ argument to `gh-event2text`, which can either be a name of a packaged
74
+ dict (currently `plain` (default) or `slack`) or a path to a
75
+ dictionary file.
76
+
77
+ Dictionary files are YAML files with ERB for templating. The playload
78
+ is fed to the templates as nested Ruby OpenStructs. For an elaborate
79
+ example have a look at the dictionary for Slack.
80
+
81
+ If you write your own dictionary for other target systems, please
82
+ consider to contribute.
83
+
84
+ TODO: elaborate on how the lookup of types works
85
+
86
+
87
+ ### Library
88
+
89
+ TODO: add an example
90
+
26
91
 
27
92
  ## References
28
93
 
@@ -5,4 +5,4 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  require 'gh/events'
7
7
 
8
- puts GH::Events::Slack.translate(ARGF.read)
8
+ puts GH::Events::Text.translate(STDIN.read, ARGV.first)
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path("../../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'gh/events'
7
+
8
+ ARGV.each do |file|
9
+ begin
10
+ type = GH::Events.typeof(File.read(file))
11
+ rescue
12
+ type = 'error'
13
+ end
14
+ puts "#{file}: #{type}"
15
+ end
@@ -38,4 +38,5 @@ Gem::Specification.new do |spec|
38
38
  spec.add_development_dependency "bundler", "~> 2.0"
39
39
  spec.add_development_dependency "rake", "~> 10.0"
40
40
  spec.add_development_dependency "rspec", "~> 3.0"
41
+ spec.add_development_dependency "rspec_junit_formatter", "~> 0.4"
41
42
  end
@@ -1,5 +1,6 @@
1
1
  require "gh/events/version"
2
- require "gh/events/slack"
2
+ require "gh/events/text"
3
+ require 'hash'
3
4
 
4
5
  require 'yaml'
5
6
  require 'ostruct'
@@ -14,8 +15,10 @@ module GH
14
15
  HEURISTICS = YAML.load_file(PATH)
15
16
 
16
17
  def typeof(payload)
18
+ payload = JSON.parse(payload) if payload.is_a?(String)
17
19
  payload = payload.marshal_dump if payload.is_a?(OpenStruct)
18
- keys = payload.keys.map(&:to_s)
20
+ payload = payload.deep_stringify_keys
21
+ keys = payload.keys
19
22
  HEURISTICS.each do |type, characteristics|
20
23
  # puts ("-" * 30) + " #{type}"
21
24
 
@@ -3,7 +3,7 @@ require 'erb'
3
3
  require 'ostruct'
4
4
  require 'json'
5
5
 
6
- module GH::Events::Slack
6
+ module GH::Events::Text
7
7
 
8
8
  extend self
9
9
 
@@ -11,7 +11,11 @@ module GH::Events::Slack
11
11
  # be helpful when filtering events
12
12
  ASPECTS = %i[type action state]
13
13
 
14
- def translate(payload)
14
+ def translate(payload, dict)
15
+ dict ||= 'plain'
16
+
17
+ templates = YAML.load_file(templates_file(dict))
18
+
15
19
  event = JSON.parse(payload, object_class: OpenStruct)
16
20
  type = GH::Events.typeof(event).to_s
17
21
 
@@ -38,20 +42,37 @@ module GH::Events::Slack
38
42
  template = _result[:ts].compact.last
39
43
 
40
44
  # if the event was set to `false` abort
41
- exit(1) if template === false
45
+ return nil if template === false
42
46
 
43
47
  # if there is no template use a default
44
48
  template ||= templates['no_template']
45
49
 
46
- render(template, event)
50
+ res = render(template, event).gsub(/[\n\r]+/, '\n')
51
+ validate(res, dict)
52
+ res
47
53
  end
48
54
 
49
- def templates_file
50
- File.expand_path(File.join(%w(.. .. .. .. res slack.yml)), __FILE__)
55
+ # Validate the format of the response in case it's JSON
56
+ def validate(response, channel)
57
+ return unless channel == "slack"
58
+ begin
59
+ JSON.parse(response)
60
+ rescue Exception => e
61
+ warn "Rendered template is not valid JSON"
62
+ warn e
63
+ exit 1
64
+ end
65
+ response
51
66
  end
52
67
 
53
- def templates
54
- @templates ||= YAML.load_file(templates_file)
68
+ def templates_file(dict)
69
+ preset = File.expand_path(File.join(%w(.. .. .. .. res) << "#{dict}.yml"), __FILE__)
70
+ return preset if File.exists?(preset)
71
+
72
+ return dict if File.exists?(dict.to_s)
73
+
74
+ warn "Could not find dict file: #{dict}"
75
+ exit(1)
55
76
  end
56
77
 
57
78
  class ErbBinding < OpenStruct
@@ -1,5 +1,5 @@
1
1
  module GH
2
2
  module Events
3
- VERSION = "0.6.2"
3
+ VERSION = "0.8.3"
4
4
  end
5
5
  end
@@ -0,0 +1,9 @@
1
+ class Hash
2
+ def deep_stringify_keys
3
+ Hash.new.tap do |h|
4
+ each do |k, v|
5
+ h[k.to_s] = v.is_a?(Hash) ? v.deep_stringify_keys : v
6
+ end
7
+ end
8
+ end
9
+ end
@@ -8,7 +8,7 @@ watch: # 49
8
8
  - action
9
9
  - repository
10
10
  exactly:
11
- :action: started
11
+ action: started
12
12
 
13
13
  # check_run # 1
14
14
 
@@ -0,0 +1,118 @@
1
+ # All refs are unified. So all events have `ref` and `ref_type`.
2
+ # Additionally all events have `type` and `stype`.
3
+
4
+ push: >-
5
+ [<%= repository.full_name %>]
6
+ <%= sender.login %> <%= forced ? 'force-' : '' %>pushed
7
+ <% if ref_type == 'branch' %><%= num = size || commits.count %> commit<%= num > 1 ? 's' : '' %> to<% end %>
8
+ <%= ref_type %> `<%= ref %>`
9
+
10
+ commit_comment: >-
11
+ [<%= repository.full_name %>]
12
+ <%= sender.login %>
13
+ commented on
14
+ commit `<%= comment.commit_id %>`>: "<%= comment.body %>"
15
+
16
+ create: >-
17
+ [<%= repository.full_name %>]
18
+ <%= sender.login %>
19
+ created
20
+ <%= ref_type %> `<%= ref %>`
21
+
22
+ delete: >-
23
+ [<%= repository.full_name %>]
24
+ <%= sender.login %>
25
+ deleted
26
+ <%= ref_type %> `<%= ref %>`
27
+
28
+ issue_comment: >-
29
+ [<%= repository.full_name %>]
30
+ <%= sender.login %>
31
+ commented
32
+ on issue "<%= issue.title %>": <%= comment.body %>
33
+
34
+ issues: >-
35
+ [<%= repository.full_name %>]
36
+ <%= sender.login %>
37
+ <%= action %>
38
+ issue "<%= issue.title %>"
39
+
40
+ issues.opened: >-
41
+ [<%= repository.full_name %>]
42
+ <%= sender.login %>
43
+ create the issue
44
+ "<%= issue.title %>": <%= repository.html_url %>
45
+
46
+ issues.labeled: >-
47
+ [<%= repository.full_name %>]
48
+ <%= sender.login %>
49
+ labeled
50
+ issue "<%= issue.title %>"
51
+ as `<%= label.name %>`
52
+
53
+ pull_request: >-
54
+ [<%= repository.full_name %>]
55
+ <%= sender.login %>
56
+ <%= action %>
57
+ PR "<%= pull_request.title %>"
58
+
59
+ pull_request.opened: >-
60
+ [<%= repository.full_name %>]
61
+ <%= sender.login %>
62
+ opened
63
+ PR <%= pull_request.title %>: <%= pull_request.body %>
64
+
65
+ pull_request.labeled: >-
66
+ [<%= repository.full_name %>]
67
+ <%= sender.login %>
68
+ labeled
69
+ PR "<%= pull_request.title %>"
70
+ as `<%= label.name %>`
71
+
72
+ pull_request_review_comment: >-
73
+ [<%= repository.full_name %>]
74
+ <%= sender.login %>
75
+ reviewed: <%= comment.body %>
76
+
77
+ star: >-
78
+ [<%= repository.full_name %>]
79
+ <%= sender.login %>
80
+ <%= action == 'created' ? 'starred' : 'unstarred' %>
81
+ <%= repository.full_name %>
82
+ (<%= repository.stargazers_count %>)
83
+
84
+ # Ignore other status udpates than CircleCI failures for the moment
85
+ status: false
86
+
87
+ status.failure: >-
88
+ [<%= repository.full_name %>]
89
+ CircleCI build failed
90
+ for commit "<%= commit.commit.message %>"
91
+ by "<%= sender.login %>"
92
+
93
+ fork: >-
94
+ [<%= repository.full_name %>]
95
+ <%= sender.login %>
96
+ forked <%= repository.full_name %>
97
+ (<%= repository.forks_count %>)
98
+
99
+ deployment: An event of type `deployment` occurred.
100
+ deployment_status: An event of type `deployment_status` occurred.
101
+ gollum: An event of type `gollum` occurred.
102
+ member: An event of type `member` occurred.
103
+ membership: An event of type `membership` occurred.
104
+ page_build: An event of type `page_build` occurred.
105
+ public: An event of type `public` occurred.
106
+ release: An event of type `release` occurred.
107
+ repository: An event of type `repository` occurred.
108
+ team_add: An event of type `team_add` occurred.
109
+
110
+ # `false` will make it end with exit code 1
111
+ watch: false
112
+
113
+ # `no_template` will be used for recognized events which have no
114
+ # template assigned.
115
+ no_template: No template for event of type `<%= type %>` (`<%= stype %>`).
116
+
117
+ # `unknown` will be used for events that could not be recognized.
118
+ unknown: "An unknown event occurred (stype: `<%= stype %>`)"
@@ -17,7 +17,7 @@ commit_comment:
17
17
  commit <<%= comment.html_url %>|`<%= comment.commit_id %>`>
18
18
  on <<%= repository.html_url %>|<%= repository.full_name %>>
19
19
  attachments:
20
- - fallback: <%= comment.body %>
20
+ - fallback: <%= comment.body.gsub(/"/,'\"') %>
21
21
  color: '#36a64f'
22
22
  # pretext: Optional text that appears above the attachment block
23
23
  author_name: <%= sender.login %>
@@ -25,7 +25,7 @@ commit_comment:
25
25
  author_icon: <%= sender.avatar_url %>
26
26
  # title: Slack API Documentation
27
27
  # title_link: https://api.slack.com/
28
- text: <%= comment.body %>
28
+ text: <%= comment.body.gsub(/"/,'\"') %>
29
29
  # fields:
30
30
  # - title: Priority
31
31
  # value: High
@@ -57,14 +57,14 @@ issue_comment:
57
57
  :left_speech_bubble:
58
58
  <<%= sender.html_url %>|<%= sender.login %>>
59
59
  commented
60
- on <<%= comment.html_url %>|<%= issue.title %>>
60
+ on <<%= comment.html_url %>|<%= issue.title.gsub(/"/,'\"') %>>
61
61
  attachments:
62
- - fallback: <%= comment.body %>
62
+ - fallback: <%= comment.body.gsub(/"/,'\"') %>
63
63
  color: '#36a64f'
64
64
  author_name: <%= sender.login %>
65
65
  author_link: <%= sender.html_url %>
66
66
  author_icon: <%= sender.avatar_url %>
67
- text: <%= comment.body %>
67
+ text: <%= comment.body.gsub(/"/,'\"') %>
68
68
 
69
69
  issues:
70
70
  text: >-
@@ -74,6 +74,15 @@ issues:
74
74
  issue <<%= issue.html_url %>|<%= issue.title %>>
75
75
  on <<%= repository.html_url %>|<%= repository.full_name %>>
76
76
 
77
+ issues.assigned:
78
+ text: >-
79
+ :inbox_tray:
80
+ <<%= sender.html_url %>|<%= sender.login %>>
81
+ <%= action %>
82
+ issue <<%= issue.html_url %>|<%= issue.title %>>
83
+ on <<%= repository.html_url %>|<%= repository.full_name %>>
84
+ to [TODO whom]
85
+
77
86
  issues.opened:
78
87
  text: >-
79
88
  :inbox_tray:
@@ -134,12 +143,12 @@ pull_request_review_comment:
134
143
  new review comment
135
144
  on <<%= comment.html_url %>|<%= pull_request.title %>>
136
145
  attachments:
137
- - fallback: <%= comment.body %>
146
+ - fallback: <%= comment.body.gsub(/"/,'\"') %>
138
147
  color: red
139
148
  author_name: <%= sender.login %>
140
149
  author_link: <%= sender.html_url %>
141
150
  author_icon: <%= sender.avatar_url %>
142
- text: <%= comment.body %>
151
+ text: <%= comment.body.gsub(/"/,'\"') %>
143
152
 
144
153
  star:
145
154
  text: >-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gh-events
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Phil Hofmann
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-27 00:00:00.000000000 Z
11
+ date: 2020-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,30 +52,50 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec_junit_formatter
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.4'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.4'
55
69
  description: Determine Github event types by their payload.
56
70
  email:
57
71
  - phil@200ok.ch
58
72
  executables:
59
- - gh-event2slack
73
+ - gh-event2text
74
+ - gh-events
60
75
  extensions: []
61
76
  extra_rdoc_files: []
62
77
  files:
78
+ - ".circleci/config.yml"
63
79
  - ".gitignore"
64
80
  - ".rspec"
65
81
  - ".ruby-version"
66
82
  - Gemfile
67
83
  - Gemfile.lock
84
+ - LICENSE.md
68
85
  - README.md
69
86
  - Rakefile
70
87
  - bin/console
71
88
  - bin/setup
72
- - exe/gh-event2slack
89
+ - exe/gh-event2text
90
+ - exe/gh-events
73
91
  - gh-events.gemspec
74
92
  - lib/gh-events.rb
75
93
  - lib/gh/events.rb
76
- - lib/gh/events/slack.rb
94
+ - lib/gh/events/text.rb
77
95
  - lib/gh/events/version.rb
96
+ - lib/hash.rb
78
97
  - res/events.yml
98
+ - res/plain.yml
79
99
  - res/slack.yml
80
100
  homepage: https://github.com/200ok-ch/gh-events
81
101
  licenses: []