lolcommits-slack 0.4.0 → 0.6.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: 6d77773938a5773f12564cc239a705d97986fafb66c4e503a27037360fb61e1b
4
- data.tar.gz: b65fb0c9d387b57a722c3053c90f3c90f8de3ebbd2691285643bddfebc2399b2
3
+ metadata.gz: fdd2793a3a713d8bebcb1c64940469385c756802bd1ba4a77a0e206d53cd9958
4
+ data.tar.gz: ee6af55125e45994a7339f4d828d16290aa23b56c7f75af061c7f8a9471e285c
5
5
  SHA512:
6
- metadata.gz: 6a52a5e59bc467f3dc89c268f05debbf1d046e937b794ad33ce439dac3750a4adf8aaae2d685568d26c5253786e22fa83de6a23d075a66182b70759225b2b1f4
7
- data.tar.gz: 35d6f5d8febb3538d0a92c8c4fb629cdf4c76376f84d9ebe889d06c42b63ac654b81173449b2065ff18ec8126e0e696bbec0ac65d78ad7a9d280390da8693482
6
+ metadata.gz: d86dd41fc503ff860955697a563cedc1aebfda2547d5ce3b08ad40e64798e96b3569fe2fc4dda3b1430737004479126fa5818a54569fca9db119f46bb2b04556
7
+ data.tar.gz: acbdb890e1df388215c1fcfc5cd4627f7f720053a284c26d906f37ae261a340b62340f836d358027859520f8849cda5698ac28207c66789dadebdbe984d2df4f
data/.travis.yml CHANGED
@@ -2,10 +2,10 @@ sudo: false
2
2
  language: ruby
3
3
  cache: bundler
4
4
  rvm:
5
- - 2.3.8
6
- - 2.4.6
7
- - 2.5.5
8
- - 2.6.3
5
+ - 2.5.8
6
+ - 2.6.6
7
+ - 2.7.2
8
+ - 3.0.0
9
9
  - ruby-head
10
10
 
11
11
  before_install:
data/CHANGELOG.md CHANGED
@@ -9,6 +9,15 @@ project adheres to [Semantic Versioning][Semver].
9
9
 
10
10
  - Your contribution here!
11
11
 
12
+ ## [0.6.0] - 2025-12-09
13
+ ### Changed
14
+ - Switch to multi-step file uploads (files.upload no longer supported)
15
+ - Reword config instructions for Oauth app tokens
16
+
17
+ ## [0.5.0] - 2020-01-24
18
+ ### Removed
19
+ - Support for Ruby < 2.4 (older rubies no longer supported)
20
+
12
21
  ## [0.4.0] - 2019-08-25
13
22
  ### Changed
14
23
  - Require an up-to-date `rest-client` (`>= 2.1.0`)
@@ -59,7 +68,9 @@ project adheres to [Semantic Versioning][Semver].
59
68
  ### Changed
60
69
  - Initial release
61
70
 
62
- [Unreleased]: https://github.com/lolcommits/lolcommits-slack/compare/v0.4.0...HEAD
71
+ [Unreleased]: https://github.com/lolcommits/lolcommits-slack/compare/v0.6.0...HEAD
72
+ [0.6.0]: https://github.com/lolcommits/lolcommits-slack/compare/v0.5.0...v0.6.0
73
+ [0.5.0]: https://github.com/lolcommits/lolcommits-slack/compare/v0.4.0...v0.5.0
63
74
  [0.4.0]: https://github.com/lolcommits/lolcommits-slack/compare/v0.3.0...v0.4.0
64
75
  [0.3.0]: https://github.com/lolcommits/lolcommits-slack/compare/v0.2.0...v0.3.0
65
76
  [0.2.0]: https://github.com/lolcommits/lolcommits-slack/compare/v0.1.1...v0.2.0
data/README.md CHANGED
@@ -11,11 +11,12 @@ webcam every time you git commit code, and archives a lolcat style image
11
11
  with it. Git blame has never been so much fun!
12
12
 
13
13
  This plugin automatically posts your lolcommits to one (or more)
14
- [Slack](https://slack.com) channels.
14
+ [Slack](https://slack.com) channels using Slack's modern [file upload
15
+ API](https://docs.slack.dev/messaging/working-with-files).
15
16
 
16
17
  The Slack post will contain the git commit message and repo name. The
17
- SHA is used as the uploaded file name. Posting will be retried (once)
18
- should any error occur.
18
+ SHA is used as the uploaded file name. Each upload step will be retried
19
+ (twice) should any error occur.
19
20
 
20
21
  ## Requirements
21
22
 
@@ -38,24 +39,29 @@ Next configure and enable with:
38
39
 
39
40
  $ lolcommits --config -p slack
40
41
  # set enabled to `true`
41
- # enter your access token and Slack channel ID list (see below)
42
+ # enter your Oauth User token and Slack channel ID list (see below)
42
43
 
43
44
  That's it! Every lolcommit will now be posted to these Slack channels.
44
45
  To disable simply reconfigure with `enabled: false`.
45
46
 
46
- ### Access Token
47
+ ### Authentication
47
48
 
48
- This plugin uses Slack [legacy
49
- tokens](https://api.slack.com/custom-integrations/legacy-tokens) for
50
- authentication. Create (or grab) them
51
- [here](https://api.slack.com/custom-integrations/legacy-tokens).
49
+ **NOTE**: This plugin no longer supports Slack [legacy
50
+ tokens](https://api.slack.com/custom-integrations/legacy-tokens), a Slack app
51
+ with OAuth is now required.
52
+
53
+ * Open [this URL](https://api.slack.com/apps?new_app=1") to create a new Slack app (or view existing)
54
+ * Ensure OAuth User Token Scopes includes `files:write`
55
+ * Install the app to your Slack workspace
56
+ * Use the app's User OAuth Token (e.g. xxxx-xxxxxxxxx-xxxx) when configuring
57
+ with `lolcommits --config -p slack`
52
58
 
53
59
  ### Channel List
54
60
 
55
- You must supply one or more Slack channel *IDs*. You can use Slack's own
56
- [API testing tool](https://api.slack.com/methods/channels.list/test) to
57
- list all Slack channels in your account, and grab the IDs from the JSON
58
- response presented.
61
+ You must supply one or more Slack channel *IDs*.
62
+
63
+ Grab a channel ID: right-click channel in side bar, select `View Channel
64
+ Details` and look for a Channel ID e.g. `C0FPKDOJJ`
59
65
 
60
66
  ## Development
61
67
 
@@ -86,7 +92,6 @@ moment to check it hasn't been raised in the past (and possibly closed).
86
92
 
87
93
  ## TODO
88
94
 
89
- - [ ] Use new Oauth / App (instead of legacy tokens)
90
95
  - [ ] Query for channel list and let user select
91
96
 
92
97
  ## Contributing
@@ -2,12 +2,14 @@
2
2
 
3
3
  require 'lolcommits/plugin/base'
4
4
  require 'rest_client'
5
+ require 'json'
5
6
 
6
7
  module Lolcommits
7
8
  module Plugin
8
9
  class Slack < Base
9
- # Slack API File upload endpoint
10
- ENDPOINT_URL = 'https://slack.com/api/files.upload'.freeze
10
+ # Slack API endpoints
11
+ GET_UPLOAD_URL_ENDPOINT = 'https://slack.com/api/files.getUploadURLExternal'.freeze
12
+ COMPLETE_UPLOAD_ENDPOINT = 'https://slack.com/api/files.completeUploadExternal'.freeze
11
13
 
12
14
  # Number of times to retry if RestClient.post fails
13
15
  RETRY_COUNT = 2
@@ -16,41 +18,25 @@ module Lolcommits
16
18
  # Capture ready hook, runs after lolcommits captures a snapshot.
17
19
  #
18
20
  # Uses `RestClient` to post the lolcommit to (one or more) Slack
19
- # channels. Posting will be retried (`RETRY_COUNT`) times if any
20
- # error occurs.
21
+ # channels using the new 3-step upload process. Each step will be
22
+ # retried (`RETRY_COUNT`) times if any error occurs.
21
23
  #
22
24
  # The post contains the git commit message, repo name and the SHA
23
- # is used for the filename. The response from the POST
25
+ # is used for the filename. The response from the final POST
24
26
  # request is sent to the debug log.
25
27
  #
26
28
  def run_capture_ready
27
- retries = RETRY_COUNT
28
- begin
29
- print "Posting to Slack ... "
30
- response = RestClient.post(
31
- ENDPOINT_URL,
32
- file: File.new(runner.lolcommit_path),
33
- token: configuration[:access_token],
34
- filetype: 'jpg',
35
- filename: runner.sha,
36
- title: runner.message + "[#{runner.vcs_info.repo}]",
37
- channels: configuration[:channels]
38
- )
29
+ print "Posting to Slack ... "
39
30
 
40
- debug response
41
- print "done!\n"
42
- rescue => e
43
- retries -= 1
44
- print "failed! #{e.message}"
45
- if retries > 0
46
- print " - retrying ...\n"
47
- retry
48
- else
49
- print " - giving up ...\n"
50
- puts 'Try running config again:'
51
- puts "\tlolcommits --config -p slack"
52
- end
53
- end
31
+ upload_url, file_id = get_upload_url
32
+ upload_file(upload_url)
33
+ complete_upload(file_id)
34
+
35
+ print "done!\n"
36
+ rescue => e
37
+ print "failed! #{e.message}\n"
38
+ puts 'Try running config again:'
39
+ puts "\tlolcommits --config -p slack"
54
40
  end
55
41
 
56
42
  ##
@@ -65,13 +51,15 @@ module Lolcommits
65
51
  options = super
66
52
 
67
53
  if options[:enabled]
68
- print "open the url below and issue a token for your user:\n"
69
- print "https://api.slack.com/custom-integrations/legacy-tokens\n"
70
- print "enter the generated token below, then press enter: (e.g. xxxx-xxxxxxxxx-xxxx) \n"
54
+ print "Open the URL below to create a new Slack app (or view existing):\n"
55
+ print "https://api.slack.com/apps?new_app=1\n"
56
+ print "Ensure OAuth User Token Scopes includes files:write\n"
57
+ print "Install the app to your Slack workspace\n"
58
+ print "Paste the app's User OAuth Token below: (e.g. xxxx-xxxxxxxxx-xxxx)\n"
71
59
  code = parse_user_input(gets.strip)
72
60
 
73
- print "enter a comma-seperated list of channel ids to post lolcommits in, then press enter: (e.g. c1234567890,c1234567890)\n"
74
- print "note: you must use channel ids (not channel names). grab them from here; https://api.slack.com/methods/channels.list/test\n"
61
+ print "Enter a comma-seperated list of channel IDs to post into: (e.g. C0FPKDOJJ,C0APK3PPK)\n"
62
+ print "Note: you must use channel IDs (not names). Right-click channel -> View Channel Details -> look for a Channel ID\n"
75
63
  channels = parse_user_input(gets.strip)
76
64
 
77
65
  options.merge!(
@@ -82,6 +70,110 @@ module Lolcommits
82
70
 
83
71
  options
84
72
  end
73
+
74
+ private
75
+
76
+ ##
77
+ # Step 1: Get upload URL from Slack
78
+ #
79
+ # @return [Array<String>] upload_url and file_id
80
+ #
81
+ def get_upload_url
82
+ retries = RETRY_COUNT
83
+ begin
84
+ response = RestClient.post(
85
+ GET_UPLOAD_URL_ENDPOINT,
86
+ {
87
+ filename: runner.sha,
88
+ length: File.size(runner.lolcommit_path)
89
+ },
90
+ {
91
+ Authorization: "Bearer #{configuration[:access_token]}"
92
+ }
93
+ )
94
+
95
+ result = JSON.parse(response.body)
96
+ debug "Step 1 response: #{result}"
97
+
98
+ unless result['ok']
99
+ raise "Slack API error: #{result['error']}"
100
+ end
101
+
102
+ [result['upload_url'], result['file_id']]
103
+ rescue => e
104
+ retries -= 1
105
+ if retries > 0
106
+ retry
107
+ else
108
+ raise e
109
+ end
110
+ end
111
+ end
112
+
113
+ ##
114
+ # Step 2: Upload file binary to the upload URL
115
+ #
116
+ # @param upload_url [String] the upload URL from step 1
117
+ #
118
+ def upload_file(upload_url)
119
+ retries = RETRY_COUNT
120
+ begin
121
+ RestClient.post(
122
+ upload_url,
123
+ {
124
+ file: File.new(runner.lolcommit_path)
125
+ }
126
+ )
127
+
128
+ debug "Step 2: File uploaded successfully"
129
+ rescue => e
130
+ retries -= 1
131
+ if retries > 0
132
+ retry
133
+ else
134
+ raise e
135
+ end
136
+ end
137
+ end
138
+
139
+ ##
140
+ # Step 3: Complete the upload and share to channels
141
+ #
142
+ # @param file_id [String] the file_id from step 1
143
+ #
144
+ def complete_upload(file_id)
145
+ retries = RETRY_COUNT
146
+ begin
147
+ title = runner.message + "[#{runner.vcs_info.repo}]"
148
+ files_json = JSON.generate([{ id: file_id, title: title }])
149
+
150
+ response = RestClient.post(
151
+ COMPLETE_UPLOAD_ENDPOINT,
152
+ {
153
+ files: files_json,
154
+ channels: configuration[:channels]
155
+ },
156
+ {
157
+ Authorization: "Bearer #{configuration[:access_token]}"
158
+ }
159
+ )
160
+
161
+ result = JSON.parse(response.body)
162
+ debug "Step 3 response: #{result}"
163
+
164
+ unless result['ok']
165
+ raise "Slack API error: #{result['error']}"
166
+ end
167
+ rescue => e
168
+ retries -= 1
169
+ if retries > 0
170
+ retry
171
+ else
172
+ raise e
173
+ end
174
+ end
175
+ end
176
+
85
177
  end
86
178
  end
87
179
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lolcommits
4
4
  module Slack
5
- VERSION = "0.4.0".freeze
5
+ VERSION = "0.6.0".freeze
6
6
  end
7
7
  end
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.executables = []
27
27
  spec.require_paths = ["lib"]
28
28
 
29
- spec.required_ruby_version = ">= 2.3"
29
+ spec.required_ruby_version = ">= 2.4"
30
30
 
31
31
  spec.add_runtime_dependency "rest-client", ">= 2.1.0"
32
32
  spec.add_runtime_dependency "lolcommits", ">= 0.14.2"
@@ -34,28 +34,133 @@ describe Lolcommits::Plugin::Slack do
34
34
  end
35
35
 
36
36
  it 'should post the message to slack' do
37
- stub_request(:any, plugin.class::ENDPOINT_URL)
37
+ # Step 1: Stub getting upload URL
38
+ stub_request(:post, plugin.class::GET_UPLOAD_URL_ENDPOINT)
39
+ .to_return(
40
+ status: 200,
41
+ body: { ok: true, upload_url: "https://files.slack.com/upload/v1/ABC123", file_id: "F123ABC" }.to_json,
42
+ headers: { 'Content-Type' => 'application/json' }
43
+ )
44
+
45
+ # Step 2: Stub file upload to Slack's upload URL
46
+ stub_request(:post, /files\.slack\.com/)
47
+ .to_return(status: 200, body: '')
48
+
49
+ # Step 3: Stub completing the upload
50
+ stub_request(:post, plugin.class::COMPLETE_UPLOAD_ENDPOINT)
51
+ .to_return(
52
+ status: 200,
53
+ body: { ok: true }.to_json,
54
+ headers: { 'Content-Type' => 'application/json' }
55
+ )
56
+
38
57
  in_repo do
39
58
  plugin.configuration = valid_enabled_config
40
59
  output = fake_io_capture { plugin.run_capture_ready }
41
60
  assert_equal output, "Posting to Slack ... done!\n"
42
61
 
43
- assert_requested :post, plugin.class::ENDPOINT_URL,
44
- headers: { 'Content-Type' => /multipart\/form-data;/ },
62
+ # Verify Step 1: Get upload URL was called with Authorization header and correct parameters
63
+ assert_requested :post, plugin.class::GET_UPLOAD_URL_ENDPOINT,
64
+ headers: { 'Authorization' => 'Bearer acbd-1234-wxyz-5678' },
65
+ times: 1 do |req|
66
+ # Verify filename and length parameters are sent
67
+ req.body.include?('filename=') && req.body.include?('length=')
68
+ end
69
+
70
+ # Verify Step 2: File upload was called
71
+ assert_requested :post, /files\.slack\.com/,
45
72
  times: 1
73
+
74
+ # Verify Step 3: Complete upload was called with correct parameters
75
+ assert_requested :post, plugin.class::COMPLETE_UPLOAD_ENDPOINT,
76
+ headers: { 'Authorization' => 'Bearer acbd-1234-wxyz-5678' },
77
+ times: 1 do |req|
78
+ # Verify channels and files (as JSON) parameters are sent
79
+ req.body.include?('channels=c123%2Cc456') && req.body.include?('files=')
80
+ end
81
+ end
82
+ end
83
+
84
+ it 'should retry (and explain) if step 1 fails' do
85
+ in_repo do
86
+ # Stub step 1 to timeout
87
+ stub_request(:post, plugin.class::GET_UPLOAD_URL_ENDPOINT).to_timeout
88
+
89
+ plugin.configuration = valid_enabled_config
90
+
91
+ _(Proc.new { plugin.run_capture_ready }).
92
+ must_output("Posting to Slack ... failed! Timed out connecting to server\nTry running config again:\n\tlolcommits --config -p slack\n")
93
+
94
+ # Verify Step 1 was retried RETRY_COUNT times before giving up
95
+ assert_requested :post, plugin.class::GET_UPLOAD_URL_ENDPOINT,
96
+ headers: { 'Authorization' => 'Bearer acbd-1234-wxyz-5678' },
97
+ times: plugin.class::RETRY_COUNT
46
98
  end
47
99
  end
48
100
 
49
- it 'should retry (and explain) if there is a failure (req timeout)' do
101
+ it 'should retry (and explain) if step 2 fails' do
50
102
  in_repo do
51
- stub_request(:any, plugin.class::ENDPOINT_URL).to_timeout
103
+ # Step 1 succeeds
104
+ stub_request(:post, plugin.class::GET_UPLOAD_URL_ENDPOINT)
105
+ .to_return(
106
+ status: 200,
107
+ body: { ok: true, upload_url: "https://files.slack.com/upload/v1/ABC123", file_id: "F123ABC" }.to_json,
108
+ headers: { 'Content-Type' => 'application/json' }
109
+ )
110
+
111
+ # Step 2 times out
112
+ stub_request(:post, /files\.slack\.com/).to_timeout
113
+
52
114
  plugin.configuration = valid_enabled_config
53
115
 
54
- Proc.new { plugin.run_capture_ready }.
55
- must_output("Posting to Slack ... failed! Timed out connecting to server - retrying ...\nPosting to Slack ... failed! Timed out connecting to server - giving up ...\nTry running config again:\n\tlolcommits --config -p slack\n")
116
+ _(Proc.new { plugin.run_capture_ready }).
117
+ must_output("Posting to Slack ... failed! Timed out connecting to server\nTry running config again:\n\tlolcommits --config -p slack\n")
118
+
119
+ # Verify Step 1 was called once
120
+ assert_requested :post, plugin.class::GET_UPLOAD_URL_ENDPOINT,
121
+ headers: { 'Authorization' => 'Bearer acbd-1234-wxyz-5678' },
122
+ times: 1
123
+
124
+ # Verify Step 2 was retried RETRY_COUNT times
125
+ assert_requested :post, /files\.slack\.com/,
126
+ times: plugin.class::RETRY_COUNT
127
+ end
128
+ end
129
+
130
+ it 'should retry (and explain) if step 3 fails' do
131
+ in_repo do
132
+ # Step 1 succeeds
133
+ stub_request(:post, plugin.class::GET_UPLOAD_URL_ENDPOINT)
134
+ .to_return(
135
+ status: 200,
136
+ body: { ok: true, upload_url: "https://files.slack.com/upload/v1/ABC123", file_id: "F123ABC" }.to_json,
137
+ headers: { 'Content-Type' => 'application/json' }
138
+ )
139
+
140
+ # Step 2 succeeds
141
+ stub_request(:post, /files\.slack\.com/)
142
+ .to_return(status: 200, body: '')
143
+
144
+ # Step 3 times out
145
+ stub_request(:post, plugin.class::COMPLETE_UPLOAD_ENDPOINT).to_timeout
146
+
147
+ plugin.configuration = valid_enabled_config
148
+
149
+ _(Proc.new { plugin.run_capture_ready }).
150
+ must_output("Posting to Slack ... failed! Timed out connecting to server\nTry running config again:\n\tlolcommits --config -p slack\n")
151
+
152
+ # Verify Step 1 was called once
153
+ assert_requested :post, plugin.class::GET_UPLOAD_URL_ENDPOINT,
154
+ headers: { 'Authorization' => 'Bearer acbd-1234-wxyz-5678' },
155
+ times: 1
156
+
157
+ # Verify Step 2 was called once
158
+ assert_requested :post, /files\.slack\.com/,
159
+ times: 1
56
160
 
57
- assert_requested :post, plugin.class::ENDPOINT_URL,
58
- headers: { 'Content-Type' => /multipart\/form-data;/ },
161
+ # Verify Step 3 was retried RETRY_COUNT times
162
+ assert_requested :post, plugin.class::COMPLETE_UPLOAD_ENDPOINT,
163
+ headers: { 'Authorization' => 'Bearer acbd-1234-wxyz-5678' },
59
164
  times: plugin.class::RETRY_COUNT
60
165
  end
61
166
  end
@@ -65,12 +170,12 @@ describe Lolcommits::Plugin::Slack do
65
170
 
66
171
  describe '#enabled?' do
67
172
  it 'should be false by default' do
68
- plugin.enabled?.must_equal false
173
+ _(plugin.enabled?).must_equal false
69
174
  end
70
175
 
71
176
  it 'should true when configured' do
72
177
  plugin.configuration = valid_enabled_config
73
- plugin.enabled?.must_equal true
178
+ _(plugin.enabled?).must_equal true
74
179
  end
75
180
  end
76
181
 
@@ -78,11 +183,12 @@ describe Lolcommits::Plugin::Slack do
78
183
  it 'should allow plugin options to be configured' do
79
184
  configured_plugin_options = {}
80
185
 
81
- fake_io_capture(inputs: %w(true abc-def c1,c3,c4)) do
82
- configured_plugin_options = plugin.configure_options!
186
+ # Use .dup to create mutable strings (frozen_string_literal compatibility)
187
+ fake_io_capture(inputs: %w(true abc-def c1,c3,c4).map(&:dup)) do
188
+ configured_plugin_options = plugin.send(:configure_options!)
83
189
  end
84
190
 
85
- configured_plugin_options.must_equal({
191
+ _(configured_plugin_options).must_equal({
86
192
  enabled: true,
87
193
  access_token: 'abc-def',
88
194
  channels: 'c1,c3,c4'
@@ -91,12 +197,12 @@ describe Lolcommits::Plugin::Slack do
91
197
 
92
198
  describe '#valid_configuration?' do
93
199
  it 'should be false without config set' do
94
- plugin.valid_configuration?.must_equal(false)
200
+ _(plugin.valid_configuration?).must_equal(false)
95
201
  end
96
202
 
97
203
  it 'should be true for a valid configuration' do
98
204
  plugin.configuration = valid_enabled_config
99
- plugin.valid_configuration?.must_equal true
205
+ _(plugin.valid_configuration?).must_equal true
100
206
  end
101
207
  end
102
208
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lolcommits-slack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Hutchinson
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2019-08-25 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rest-client
@@ -143,7 +142,6 @@ metadata:
143
142
  source_code_uri: https://github.com/lolcommits/lolcommits-slack
144
143
  bug_tracker_uri: https://github.com/lolcommits/lolcommits-slack/issues
145
144
  allowed_push_host: https://rubygems.org
146
- post_install_message:
147
145
  rdoc_options: []
148
146
  require_paths:
149
147
  - lib
@@ -151,15 +149,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
151
149
  requirements:
152
150
  - - ">="
153
151
  - !ruby/object:Gem::Version
154
- version: '2.3'
152
+ version: '2.4'
155
153
  required_rubygems_version: !ruby/object:Gem::Requirement
156
154
  requirements:
157
155
  - - ">="
158
156
  - !ruby/object:Gem::Version
159
157
  version: '0'
160
158
  requirements: []
161
- rubygems_version: 3.0.3
162
- signing_key:
159
+ rubygems_version: 3.7.2
163
160
  specification_version: 4
164
161
  summary: Sends lolcommits to one (or more) Slack channels
165
162
  test_files: