chat_notifier 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 +7 -0
- data/CHANGELOG.md +12 -0
- data/LICENSE.txt +19 -0
- data/README.md +41 -0
- data/lib/chat_notifier/chatter/debug.rb +15 -0
- data/lib/chat_notifier/chatter/slack.rb +59 -0
- data/lib/chat_notifier/chatter.rb +71 -0
- data/lib/chat_notifier/messenger.rb +103 -0
- data/lib/chat_notifier/repository/debug.rb +15 -0
- data/lib/chat_notifier/repository/github.rb +15 -0
- data/lib/chat_notifier/repository.rb +26 -0
- data/lib/chat_notifier/rspec_formatter.rb +18 -0
- data/lib/chat_notifier/test_environment/debug.rb +15 -0
- data/lib/chat_notifier/test_environment/github.rb +15 -0
- data/lib/chat_notifier/test_environment.rb +34 -0
- data/lib/chat_notifier/version.rb +5 -0
- data/lib/chat_notifier.rb +56 -0
- metadata +60 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 11bbd1390ca03c1f99d0ff66a5e3a361f259f40704575db73ae255e67e48b94b
|
4
|
+
data.tar.gz: 24781a89995cf1384962fb46b5a60d8ed5095e442af92162a85e5e82489007ee
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a2584238466e94fc1efba40198f83761464f6bf399b9e99b8b640eb21a074a13699fe18bb42a4c1be049e1d0ccdb5950d721ce1342c04f1bfbc277f4195be189
|
7
|
+
data.tar.gz: f6e4ac759352ba03f7a21a283f3e43eb4202f0fad8ddd7125b1024713fe96bdac3b283a9bc3f5555495005c96bc92b5438307f55cf1b318556b79674c7143f32
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## 0.1.0
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- Initial code
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2023 SOFware LLC
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# ChatNotifier
|
2
|
+
|
3
|
+
Notify a chat room with data from your test run.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
```
|
8
|
+
gem "chat_notifier", git: "https://github.com/SOFware/chat_notifier.git"
|
9
|
+
```
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
Add to your `spec_helper.rb` or `rails_helper.rb`:
|
14
|
+
|
15
|
+
```
|
16
|
+
require "chat_notifier/rspec_formatter"
|
17
|
+
```
|
18
|
+
|
19
|
+
### Debug your Slack setup
|
20
|
+
|
21
|
+
Create rake task to test the connection to your Slack channel
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
namespace :chat_notifier do
|
25
|
+
task debug: :environment do
|
26
|
+
unless ENV["SLACK_WEBHOOK_URL"]
|
27
|
+
puts "You MUST set the environment variables for:\nSLACK_WEBHOOK_URL"
|
28
|
+
return
|
29
|
+
end
|
30
|
+
ENV["DEBUG"] = "1"
|
31
|
+
ENV["CURRENT_REPOSITORY_URL"] = "https://example.com"
|
32
|
+
ENV["TEST_RUN_ID"] = "9999"
|
33
|
+
require "chat_notifier"
|
34
|
+
|
35
|
+
failure = ChatNotifier::DebugExceptionLocation.new(location: "fake/path.rb")
|
36
|
+
summary = ChatNotifier::DebugSummary.new(failed_examples: [failure])
|
37
|
+
|
38
|
+
ChatNotifier.debug!(ENV, summary:)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
```
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ChatNotifier
|
4
|
+
class Chatter
|
5
|
+
class Slack < self
|
6
|
+
Chatter.register self
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def handles?(settings)
|
10
|
+
!settings.keys.grep(/SLACK/).empty?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def webhook_url
|
15
|
+
settings.fetch("SLACK_WEBHOOK_URL", nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
def channel
|
19
|
+
settings.fetch("SLACK_NOTIFY_CHANNEL", nil)
|
20
|
+
end
|
21
|
+
|
22
|
+
def payload(data)
|
23
|
+
super(Configuration.for(data, self).to_h)
|
24
|
+
end
|
25
|
+
|
26
|
+
class Configuration
|
27
|
+
def self.for(messenger, communicator)
|
28
|
+
if messenger.failure?
|
29
|
+
FailureConfiguration
|
30
|
+
else
|
31
|
+
self
|
32
|
+
end.new(messenger, communicator).to_h
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(messenger, communicator)
|
36
|
+
@messenger = messenger
|
37
|
+
@communicator = communicator
|
38
|
+
end
|
39
|
+
attr_reader :messenger, :communicator
|
40
|
+
|
41
|
+
def icon_emoji = ":green_circle:"
|
42
|
+
|
43
|
+
def to_h
|
44
|
+
{
|
45
|
+
channel: communicator.channel,
|
46
|
+
icon_emoji: icon_emoji
|
47
|
+
}.merge(messenger.to_h)
|
48
|
+
end
|
49
|
+
|
50
|
+
class FailureConfiguration < self
|
51
|
+
def icon_emoji = ":red_circle:"
|
52
|
+
end
|
53
|
+
|
54
|
+
private_constant :FailureConfiguration
|
55
|
+
end
|
56
|
+
private_constant :Configuration
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "net/http"
|
4
|
+
require "uri"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
module ChatNotifier
|
8
|
+
# All behavior for interacting with a notification platform
|
9
|
+
class Chatter
|
10
|
+
def initialize(settings:, repository:, environment:)
|
11
|
+
@settings = settings
|
12
|
+
@repository = repository
|
13
|
+
@environment = environment
|
14
|
+
end
|
15
|
+
|
16
|
+
attr :settings, :repository, :environment
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def handlers
|
20
|
+
@handlers ||= []
|
21
|
+
end
|
22
|
+
|
23
|
+
def handles?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
def register(klass)
|
28
|
+
handlers << klass
|
29
|
+
end
|
30
|
+
|
31
|
+
def handling(settings, repository:, environment:)
|
32
|
+
handlers.select { |handler| handler.handles?(settings) }.map do |klass|
|
33
|
+
klass.new(
|
34
|
+
settings: settings,
|
35
|
+
repository: repository,
|
36
|
+
environment: environment
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def webhook_url
|
43
|
+
end
|
44
|
+
|
45
|
+
def body
|
46
|
+
end
|
47
|
+
|
48
|
+
def post(messenger)
|
49
|
+
uri = URI(webhook_url)
|
50
|
+
|
51
|
+
Net::HTTP.post(uri, payload(messenger))
|
52
|
+
end
|
53
|
+
|
54
|
+
def conditional_post(messenger)
|
55
|
+
return if messenger.success? && !verbose?
|
56
|
+
|
57
|
+
post(messenger)
|
58
|
+
end
|
59
|
+
|
60
|
+
def verbose?
|
61
|
+
!!settings.fetch("NOTIFIER_VERBOSE", false)
|
62
|
+
end
|
63
|
+
|
64
|
+
def payload(data)
|
65
|
+
data.to_json
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
require_relative "chatter/slack"
|
71
|
+
require_relative "chatter/debug"
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "forwardable"
|
4
|
+
|
5
|
+
module ChatNotifier
|
6
|
+
class Messenger
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def for(summary, repository:, environment:, app:)
|
11
|
+
if summary.failed_examples.empty?
|
12
|
+
self
|
13
|
+
else
|
14
|
+
Failure
|
15
|
+
end.new(
|
16
|
+
summary:,
|
17
|
+
app:,
|
18
|
+
repository:,
|
19
|
+
environment:
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def debug=(val)
|
24
|
+
prepend Debug if val
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Debug
|
29
|
+
def message = "This is only a test…"
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(summary:, app:, repository:, environment:)
|
33
|
+
@summary = summary
|
34
|
+
@app = app
|
35
|
+
@repository = repository
|
36
|
+
@environment = environment
|
37
|
+
end
|
38
|
+
|
39
|
+
attr :summary, :app, :repository, :environment
|
40
|
+
|
41
|
+
def failures = summary.failed_examples
|
42
|
+
|
43
|
+
def_delegator :failures, :count
|
44
|
+
def_delegators :app, :branch, :sha
|
45
|
+
def_delegator :environment, :ruby_version
|
46
|
+
|
47
|
+
def message
|
48
|
+
"#{message_prefix} #{identifier} is OK on branch #{repository.link(branch)}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def lede = message
|
52
|
+
|
53
|
+
def body = ""
|
54
|
+
|
55
|
+
def identifier
|
56
|
+
"#{app} #{ruby_version} #{sha}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def message_prefix = ":thumbsup:"
|
60
|
+
|
61
|
+
def success? = true
|
62
|
+
|
63
|
+
def failure? = !success?
|
64
|
+
|
65
|
+
def to_h
|
66
|
+
{
|
67
|
+
text: message
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_hash = to_h
|
72
|
+
|
73
|
+
class Failure < self
|
74
|
+
def count = "#{failures.size} times!"
|
75
|
+
|
76
|
+
def message_prefix = ":boom:"
|
77
|
+
|
78
|
+
def success? = false
|
79
|
+
|
80
|
+
def failure? = !success?
|
81
|
+
|
82
|
+
def lede
|
83
|
+
<<~LEDE.chomp
|
84
|
+
#{message_prefix} #{identifier} has failed #{count} in #{branch}
|
85
|
+
|
86
|
+
#{environment.test_run_url}
|
87
|
+
LEDE
|
88
|
+
end
|
89
|
+
|
90
|
+
def message
|
91
|
+
<<~MESSAGE.chomp
|
92
|
+
#{lede}
|
93
|
+
|
94
|
+
#{body}
|
95
|
+
MESSAGE
|
96
|
+
end
|
97
|
+
|
98
|
+
def body
|
99
|
+
failures.flat_map(&:location).join("\n")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ChatNotifier
|
4
|
+
# All information about the location of the source code
|
5
|
+
class Repository
|
6
|
+
def initialize(settings:)
|
7
|
+
@settings = settings
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :settings
|
11
|
+
|
12
|
+
def self.for(settings)
|
13
|
+
if settings["DEBUG"]
|
14
|
+
Debug
|
15
|
+
else
|
16
|
+
Github
|
17
|
+
end.new(settings: settings)
|
18
|
+
end
|
19
|
+
|
20
|
+
def link(_sha)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require_relative "repository/github"
|
26
|
+
require_relative "repository/debug"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rspec/core/formatters"
|
4
|
+
RSpec::Support.require_rspec_core "formatters/base_formatter"
|
5
|
+
|
6
|
+
require "chat_notifier"
|
7
|
+
|
8
|
+
module ChatNotifier
|
9
|
+
# Formatter for RSpec tests to receive the summary of a test
|
10
|
+
# run after the suite has finished.
|
11
|
+
class RspecFormatter < RSpec::Core::Formatters::BaseFormatter
|
12
|
+
RSpec::Core::Formatters.register self, :dump_summary
|
13
|
+
|
14
|
+
def dump_summary(summary)
|
15
|
+
ChatNotifier.call(summary:)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ChatNotifier
|
4
|
+
# All information about the place where the test was run
|
5
|
+
class TestEnvironment
|
6
|
+
def initialize(settings:)
|
7
|
+
@settings = settings
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :settings
|
11
|
+
|
12
|
+
def self.for(settings)
|
13
|
+
if settings["DEBUG"]
|
14
|
+
Debug
|
15
|
+
else
|
16
|
+
Github
|
17
|
+
end.new(settings: settings)
|
18
|
+
end
|
19
|
+
|
20
|
+
def ruby_version
|
21
|
+
"Ruby #{::RUBY_VERSION}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def url
|
25
|
+
settings.fetch("CURRENT_REPOSITORY_URL")
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_run_url
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require_relative "test_environment/github"
|
34
|
+
require_relative "test_environment/debug"
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "chat_notifier/version"
|
4
|
+
|
5
|
+
require_relative "chat_notifier/messenger"
|
6
|
+
require_relative "chat_notifier/repository"
|
7
|
+
require_relative "chat_notifier/test_environment"
|
8
|
+
require_relative "chat_notifier/chatter"
|
9
|
+
|
10
|
+
module ChatNotifier
|
11
|
+
DebugExceptionLocation = Data.define(:location)
|
12
|
+
DebugSummary = Data.define(:failed_examples)
|
13
|
+
|
14
|
+
class << self
|
15
|
+
# In order to test this locally see `rake chat_notifier:debug`
|
16
|
+
def debug!(env, summary:, notifier: :Debug)
|
17
|
+
repository = Repository.for(env)
|
18
|
+
environment = TestEnvironment.for(env)
|
19
|
+
|
20
|
+
chatter = Chatter.const_get(notifier).new(
|
21
|
+
settings: env,
|
22
|
+
repository: repository,
|
23
|
+
environment: environment
|
24
|
+
)
|
25
|
+
messenger = Messenger.for(
|
26
|
+
summary,
|
27
|
+
app: Rails.application.class.module_parent,
|
28
|
+
repository: repository,
|
29
|
+
environment: environment
|
30
|
+
)
|
31
|
+
|
32
|
+
chatter.post(messenger)
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(summary:)
|
36
|
+
repository = Repository.for(ENV)
|
37
|
+
environment = TestEnvironment.for(ENV)
|
38
|
+
chatter = Chatter.handling(
|
39
|
+
ENV,
|
40
|
+
repository:,
|
41
|
+
environment:
|
42
|
+
)
|
43
|
+
|
44
|
+
messenger = Messenger.for(
|
45
|
+
summary,
|
46
|
+
app: Rails.application.class.module_parent,
|
47
|
+
repository:,
|
48
|
+
environment:
|
49
|
+
)
|
50
|
+
|
51
|
+
chatter.each do |box|
|
52
|
+
box.conditional_post(messenger)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chat_notifier
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jim Gay
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-04-19 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Send test results to chat
|
14
|
+
email:
|
15
|
+
- jim@saturnflyer.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- CHANGELOG.md
|
21
|
+
- LICENSE.txt
|
22
|
+
- README.md
|
23
|
+
- lib/chat_notifier.rb
|
24
|
+
- lib/chat_notifier/chatter.rb
|
25
|
+
- lib/chat_notifier/chatter/debug.rb
|
26
|
+
- lib/chat_notifier/chatter/slack.rb
|
27
|
+
- lib/chat_notifier/messenger.rb
|
28
|
+
- lib/chat_notifier/repository.rb
|
29
|
+
- lib/chat_notifier/repository/debug.rb
|
30
|
+
- lib/chat_notifier/repository/github.rb
|
31
|
+
- lib/chat_notifier/rspec_formatter.rb
|
32
|
+
- lib/chat_notifier/test_environment.rb
|
33
|
+
- lib/chat_notifier/test_environment/debug.rb
|
34
|
+
- lib/chat_notifier/test_environment/github.rb
|
35
|
+
- lib/chat_notifier/version.rb
|
36
|
+
homepage:
|
37
|
+
licenses: []
|
38
|
+
metadata:
|
39
|
+
source_code_uri: https://github.com/SOFware/chat_notifier.git
|
40
|
+
changelog_uri: https://github.com/SOFWare/chat_notifier/blob/master/CHANGELOG.md
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 3.2.0
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
requirements: []
|
56
|
+
rubygems_version: 3.4.6
|
57
|
+
signing_key:
|
58
|
+
specification_version: 4
|
59
|
+
summary: Notify chat of test results
|
60
|
+
test_files: []
|