rodbot 0.4.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/test.yml +1 -1
  4. data/CHANGELOG.md +6 -1
  5. data/README.md +22 -23
  6. data/checksums/rodbot-0.5.0.gem.sha512 +1 -0
  7. data/guardfile.rb +2 -0
  8. data/lib/roda/plugins/rodbot.rb +2 -0
  9. data/lib/rodbot/async.rb +1 -1
  10. data/lib/rodbot/cli/command.rb +1 -1
  11. data/lib/rodbot/cli/commands/console.rb +1 -1
  12. data/lib/rodbot/cli/commands/credentials.rb +1 -1
  13. data/lib/rodbot/cli/commands/deploy.rb +1 -1
  14. data/lib/rodbot/cli/commands/new.rb +1 -1
  15. data/lib/rodbot/cli/commands/simulator.rb +1 -1
  16. data/lib/rodbot/cli/commands/start.rb +1 -1
  17. data/lib/rodbot/cli/commands/stop.rb +1 -1
  18. data/lib/rodbot/cli/commands/version.rb +1 -1
  19. data/lib/rodbot/cli/commands.rb +1 -1
  20. data/lib/rodbot/cli.rb +1 -2
  21. data/lib/rodbot/config.rb +3 -1
  22. data/lib/rodbot/constants.rb +1 -1
  23. data/lib/rodbot/dispatcher.rb +1 -1
  24. data/lib/rodbot/env.rb +1 -1
  25. data/lib/rodbot/error.rb +1 -1
  26. data/lib/rodbot/generator.rb +1 -1
  27. data/lib/rodbot/log.rb +1 -1
  28. data/lib/rodbot/memoize.rb +1 -2
  29. data/lib/rodbot/message.rb +2 -2
  30. data/lib/rodbot/plugins/github_webhook/README.github_webhook.md +29 -5
  31. data/lib/rodbot/plugins/github_webhook/app.rb +26 -16
  32. data/lib/rodbot/plugins/gitlab_webhook/README.gitlab_webhook.md +29 -6
  33. data/lib/rodbot/plugins/gitlab_webhook/app.rb +25 -15
  34. data/lib/rodbot/plugins/hal/README.hal.md +1 -1
  35. data/lib/rodbot/plugins/matrix/README.matrix.md +1 -1
  36. data/lib/rodbot/plugins/otp/README.otp.md +1 -1
  37. data/lib/rodbot/plugins/slack/README.slack.md +1 -1
  38. data/lib/rodbot/plugins/word_of_the_day/README.word_of_the_day.md +1 -2
  39. data/lib/rodbot/plugins.rb +1 -1
  40. data/lib/rodbot/rack.rb +1 -1
  41. data/lib/rodbot/refinements.rb +2 -2
  42. data/lib/rodbot/relay.rb +1 -1
  43. data/lib/rodbot/serializer.rb +1 -1
  44. data/lib/rodbot/services/app.rb +1 -1
  45. data/lib/rodbot/services/relay.rb +1 -1
  46. data/lib/rodbot/services/schedule.rb +1 -1
  47. data/lib/rodbot/services.rb +1 -1
  48. data/lib/rodbot/simulator.rb +1 -1
  49. data/lib/rodbot/version.rb +1 -1
  50. data/lib/templates/new/app/app.rb +2 -0
  51. data/lib/templates/new/app/routes/healthz.rb +2 -0
  52. data/lib/templates/new/app/routes/help.rb +2 -0
  53. data/lib/templates/new/config/rodbot.rb +2 -0
  54. data/lib/templates/new/config/schedule.rb +2 -0
  55. data/lib/templates/new/gems.rb +2 -0
  56. data/lib/templates/new/guardfile.rb +2 -0
  57. data/lib/templates/new/rakefile.rb +2 -0
  58. data/rakefile.rb +2 -0
  59. data.tar.gz.sig +0 -0
  60. metadata +4 -3
  61. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02eb97ad68d203c57522ea612cfc2f7ad1038c554927f7434c1e4f977bfc8453
4
- data.tar.gz: afd384622ee6b2750fff08aff3fd5f121779bafcf5be09454eaf266fe134bd76
3
+ metadata.gz: 0ef0e8aac1acb78dff6f468e08dcb92661ae7c4a4c95e98e40f19588a423939d
4
+ data.tar.gz: 6c16909cb0ce8808379483c45a88f932573740c43ecf569fc52e45a23230a9a7
5
5
  SHA512:
6
- metadata.gz: 3103408d98e855a86d5c01dc2265a76ec31cd7e76b222f06d92910a8fa645d4c9082479d80da5f8605a858c7c8bd321e5b2a91b618815b9857f07215e2aa9fb0
7
- data.tar.gz: bef7568b5e629a2bb6528ff72f4dadb5e2016678d4329b14e9bcb81d544ffe17d1126f561759fae3a43183670b02cfb0bcdca0958b376221be0f7729e40acd27
6
+ metadata.gz: 91b12ad2a3a2bbda920c4f7de33481c990e686302a86de5c9e9366bee11d416550690afafcb1586f38ec9831dbfdca743801280c956617693f25746300557fae
7
+ data.tar.gz: 57a5d280e4e536d36ca2d044ecd17a9aba62b53cc10d3466904697916c55bc06dc0faafb572c4e4c3e4c065868f7d440c3966f0d67ca0287f34a75f5a49eeaba
checksums.yaml.gz.sig CHANGED
Binary file
@@ -6,7 +6,7 @@ jobs:
6
6
  fail-fast: false
7
7
  matrix:
8
8
  os: [ubuntu-latest]
9
- ruby: ['3.0', '3.1', '3.2', '3.3', '3.3']
9
+ ruby: ['3.1', '3.2', '3.3', '3.4']
10
10
  name: test (Ruby ${{ matrix.ruby }} on ${{ matrix.os }})
11
11
  runs-on: ${{ matrix.os }}
12
12
  steps:
data/CHANGELOG.md CHANGED
@@ -2,10 +2,15 @@
2
2
 
3
3
  Nothing so far
4
4
 
5
+ ## 0.5.0
6
+
7
+ #### Changes
8
+ * Make GitLab and GitHub plugins customizable
9
+
5
10
  ## 0.4.5
6
11
 
7
12
  #### Changes
8
- * Update Ruby to 3.3
13
+ * Update Ruby to 3.4
9
14
 
10
15
  ## 0.4.4
11
16
 
data/README.md CHANGED
@@ -17,22 +17,22 @@ Minimalistic yet polyglot framework to build chat bots on top of a Roda backend
17
17
 
18
18
  Thank you for supporting free and open-source software by sponsoring on [GitHub](https://github.com/sponsors/svoop) or on [Donorbox](https://donorbox.com/bitcetera). Any gesture is appreciated, from a single Euro for a ☕️ cup of coffee to 🍹 early retirement.
19
19
 
20
- ## Table of Contents
20
+ ## Table of contents
21
21
 
22
22
  [Install](#install) <br>
23
23
  [Anatomy](#anatomy) <br>
24
- &emsp;&emsp;&emsp;[App Service](#app-service) <br>
25
- &emsp;&emsp;&emsp;[Relay Services](#relay-services) <br>
26
- &emsp;&emsp;&emsp;[Schedule Service](#schedule-service) <br>
24
+ &emsp;&emsp;&emsp;[App service](#app-service) <br>
25
+ &emsp;&emsp;&emsp;[Relay services](#relay-services) <br>
26
+ &emsp;&emsp;&emsp;[Schedule service](#schedule-service) <br>
27
27
  [CLI](#CLI) <br>
28
28
  [Request](#request)<br>
29
29
  [Say](#say)<br>
30
- [Routes and Commands](#routes-and-commands) <br>
30
+ [Routes and commands](#routes-and-commands) <br>
31
31
  [Database](#database) <br>
32
32
  [Environments](#environments) <br>
33
33
  [Credentials](#credentials) <br>
34
34
  [Plugins](#plugins) <br>
35
- [Environment Variables](#environment-variables) <br>
35
+ [Environment variables](#environment-variables) <br>
36
36
  [Development](#development) <br>
37
37
 
38
38
  ## Install
@@ -45,7 +45,7 @@ This gem is [cryptographically signed](https://guides.rubygems.org/security/#usi
45
45
  gem cert --add <(curl -Ls https://raw.github.com/svoop/rodbot/main/certs/svoop.pem)
46
46
  ```
47
47
 
48
- ### Generate New Bot
48
+ ### Generate new bot
49
49
 
50
50
  Similar to other frameworks, generate the files for your new bot as follows:
51
51
 
@@ -106,7 +106,7 @@ RODBOT EXTERNAL
106
106
  ╰╴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╶╯
107
107
  ```
108
108
 
109
- ### App Service
109
+ ### App service
110
110
 
111
111
  The **app service** is a [Roda app](https://roda.jeremyevans.net) where the real action happens. It acts on and responds to HTTP requests from:
112
112
 
@@ -177,11 +177,11 @@ Tag | Replaced with
177
177
  `[[SENDER]]` | Mention the sender of the command.
178
178
  `[[EVERYBODY]]` | Mention everybody.
179
179
 
180
- #### Other Routes
180
+ #### Other routes
181
181
 
182
182
  All higher level requests such as `GET /foo/bar` are not accessible by relays. Use them to implement other aspects of your bot such as webhooks or schedule tasks.
183
183
 
184
- ### Relay Services
184
+ ### Relay services
185
185
 
186
186
  The **relay service** act as glue between the **app service** and external communication networks such as Matrix.
187
187
 
@@ -199,7 +199,7 @@ rodbot simulator
199
199
 
200
200
  Enter the command `!pay EUR 123` and you see the request `GET /pay?argument=EUR+123` hitting the **app service**.
201
201
 
202
- #### TCP Socket
202
+ #### TCP socket
203
203
 
204
204
  The TCP socket is primarily used by other Rodbot services to forward messages to the corresponding external communication network. However, you can use these sockets for non-Rodbot processes as well e.g. to issue notifications when events happen on the host running Rodbot.
205
205
 
@@ -207,7 +207,7 @@ Simply connect to a socket and submit the message as plain text or Markdown in U
207
207
 
208
208
  Such simple messages are always posted to the primary room (aka: channel, group etc) of the communication network. For more complex scenarios, please take a look at [message objects](https://www.rubydoc.info/gems/rodbot/Rodbot/Message) which may contain meta information as well.
209
209
 
210
- ### Schedule Service
210
+ ### Schedule service
211
211
 
212
212
  The **schedule service** is a [Clockwork process](https://github.com/Rykian/clockwork) which triggers Ruby code asynchronously as configured in `config/schedule.rb`.
213
213
 
@@ -227,7 +227,7 @@ The `rodbot` CLI is the main tool to manage your bot. For a full list of functio
227
227
  rodbot --help
228
228
  ```
229
229
 
230
- ### Starting and Stopping Services
230
+ ### Starting and stopping services
231
231
 
232
232
  While working on the app service, you certainly want to try routes:
233
233
 
@@ -364,7 +364,7 @@ You can further narrow where to post the message if you specify the relay plugin
364
364
  say("Hello, Slack!", on: :slack)
365
365
  ```
366
366
 
367
- ## Routes and Commands
367
+ ## Routes and commands
368
368
 
369
369
  Adding new tricks to your bot boils down to adding routes to the app service which is powered by Roda, a simple yet very powerful framework for web applications: Easy to learn (like Sinatra) but really fast and efficient. Take a minute and [get familiar with the basics of Roda](http://roda.jeremyevans.net/).
370
370
 
@@ -430,7 +430,7 @@ The Hash backend is not thread-safe and therefore shouldn't be used in productio
430
430
  db 'hash'
431
431
  ```
432
432
 
433
- ### Write and Read Data
433
+ ### Write and read data
434
434
 
435
435
  With this in place, you can access the database with `Rodbot.db`:
436
436
 
@@ -480,7 +480,7 @@ In order not to commit secrets to repositories or environment variables, Rodbot
480
480
 
481
481
  Rodbot aims to keep its core small and add features via plugins, either built-in or provided by gems.
482
482
 
483
- ### Built-In Plugins
483
+ ### Built-in plugins
484
484
 
485
485
  Name | Dependencies | Description
486
486
  -----|--------------|------------
@@ -499,7 +499,7 @@ bundle config set --local with otp
499
499
  bundle install
500
500
  ```
501
501
 
502
- ### How Plugins Work
502
+ ### How plugins work
503
503
 
504
504
  Given the following `config/rodbot.rb`:
505
505
 
@@ -519,7 +519,7 @@ Whenever a service boots, the corresponding file is required.
519
519
 
520
520
  In order to keep these plugin files slim, you should extract functionality into service classes. Just put them into `rodbot/plugins/my_plugin/lib/` and use `require_relative` where you need them.
521
521
 
522
- ### Create Plugins
522
+ ### Create plugins
523
523
 
524
524
  You can create plugins in any of the following places:
525
525
 
@@ -529,7 +529,7 @@ You can create plugins in any of the following places:
529
529
 
530
530
  Please adhere to common naming conventions and use the dashed prefix `rodbot-` (and Module `Rodbot`), however, underscores in case the remaining gem name consists of several words.
531
531
 
532
- #### App Extension
532
+ #### App extension
533
533
 
534
534
  An app extension `rodbot/plugins/my_plugin/app.rb` defines the module `App` and looks something like this:
535
535
 
@@ -569,7 +569,7 @@ The `App` module can be used to [extend all aspects of Roda](https://github.com/
569
569
 
570
570
  For an example, take a look at the [:hal plugin](https://github.com/svoop/rodbot/tree/main/lib/rodbot/plugins/hal).
571
571
 
572
- #### Relay Extension
572
+ #### Relay extension
573
573
 
574
574
  A relay extension `rodbot/plugins/my_plugin/relay.rb` defines the class `Relay` and looks something like this:
575
575
 
@@ -610,7 +610,7 @@ Proactive messages require other parts of Rodbot to forward a message directly.
610
610
 
611
611
  For an example, take a look at the [:matrix plugin](https://github.com/svoop/rodbot/tree/main/lib/rodbot/plugins/matrix).
612
612
 
613
- #### Schedule Extension
613
+ #### Schedule extension
614
614
 
615
615
  A schedule extension `rodbot/plugins/my_plugin/schedule.rb` defines the class `Schedule` and looks something like this:
616
616
 
@@ -647,7 +647,7 @@ Before you write a plugin, familiarise yourself with the following bundled helpe
647
647
  * [Rodbot::Refinements](https://www.rubydoc.info/gems/rodbot/Rodbot/Refinements.html) – just a few handy extensions to Ruby core classes
648
648
  * [Rodbot::Memoize](https://www.rubydoc.info/gems/rodbot/Rodbot/Memoize.html) – environment-aware memoization for method return values
649
649
 
650
- ## Environment Variables
650
+ ## Environment variables
651
651
 
652
652
  Environment variables are used for the configuration bits which cannot or should not be part of `config/rodbot.rb` mainly because they have to be set on the infrastructure level.
653
653
 
@@ -677,4 +677,3 @@ export RODBOT_SPEC_REDIS_URL=redis://localhost:6379/10
677
677
  ```
678
678
 
679
679
  You're welcome to join the [discussion forum](https://github.com/svoop/rodbot/discussions) to ask questions or drop feature ideas, [submit issues](https://github.com/svoop/rodbot/issues) you may encounter or contribute code by [forking this project and submitting pull requests](https://docs.github.com/en/get-started/quickstart/fork-a-repo).
680
-
@@ -0,0 +1 @@
1
+ d48b784395edc8f74c84bd058cb67ff471a7d24023fff0a25b085ef15886820d4623f8f4a1c8023a0850b1b31f857960747df54f457bb9f96c06d7f781ede150
data/guardfile.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  clearing :on
2
4
 
3
5
  guard :minitest do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Roda
2
4
  module RodaPlugins
3
5
 
data/lib/rodbot/async.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'sucker_punch'
4
4
 
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  class CLI
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  using Rodbot::Refinements
4
4
 
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  class CLI
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  class CLI
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  class CLI
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  class CLI
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  class CLI
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  class CLI
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  class CLI
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  class CLI
data/lib/rodbot/cli.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'dry/cli'
4
4
 
@@ -6,4 +6,3 @@ module Rodbot
6
6
  class CLI < Dry::CLI
7
7
  end
8
8
  end
9
-
data/lib/rodbot/config.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
 
@@ -115,6 +115,8 @@ module Rodbot
115
115
  # @param strings [String, nil] one or more strings to evaluate
116
116
  # @return [self]
117
117
  def eval_strings(*strings)
118
+ # TODO: filter magic comment until they are no longer requred to prevent warning
119
+ strings = strings.map { _1&.sub(/# frozen_string_literal: true/, '') }
118
120
  instance_eval(strings.compact.join("\n"))
119
121
  self
120
122
  end
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  module Constants
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
 
data/lib/rodbot/env.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
 
data/lib/rodbot/error.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
  class Error < StandardError
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'fileutils'
4
4
  require 'erb'
data/lib/rodbot/log.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
 
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
 
@@ -95,4 +95,3 @@ module Rodbot
95
95
  end
96
96
 
97
97
  end
98
-
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
4
 
@@ -58,7 +58,7 @@ module Rodbot
58
58
  fail(ArgumentError, "not a dumped message") unless hash['class'] == self.class.to_s
59
59
  initialize(hash['text'], room: room || hash['room'])
60
60
  else
61
- initialize(string.force_encoding('UTF-8'), room: room)
61
+ initialize(string.encode('UTF-8'), room: room)
62
62
  end
63
63
  self
64
64
  end
@@ -1,4 +1,4 @@
1
- # Rodbot Plugin – GitHub Webhook
1
+ # Rodbot plugin – GitHub webhook
2
2
 
3
3
  Pipeline event announcements from GitHub
4
4
 
@@ -18,9 +18,7 @@ To authenticate the webhook calls from GitHub, create a new random secret token:
18
18
  ruby -r securerandom -e "puts SecureRandom.alphanumeric(20)"
19
19
  ```
20
20
 
21
- ## Activation
22
-
23
- Activate and configure this plugin in `config/rodbot.rb`:
21
+ Configure this plugin in `config/rodbot.rb`:
24
22
 
25
23
  ```ruby
26
24
  plugin :github_webhook do
@@ -30,7 +28,7 @@ end
30
28
 
31
29
  You can set any number of secure tokens here separated with colons.
32
30
 
33
- ## Add Repositories
31
+ ## Activation
34
32
 
35
33
  Add a webhook to every GitHub repository you'd like to see pipeline event announcements for. Go to `https://github.com/<USER>/<REPO>/settings/hooks` and create a new webhook with the following properties:
36
34
 
@@ -40,3 +38,29 @@ Add a webhook to every GitHub repository you'd like to see pipeline event announ
40
38
  * SSL verification: (o) Enable SSL verification
41
39
  * Which events? (o) Let me select individual events: [x] Workflow runs
42
40
  * And... [x] Active
41
+
42
+ Use the test tool to verify your setup and to see what the JSON payloads look like in case you'd like to customize the handler.
43
+
44
+ ## Customization
45
+
46
+ You can change how the plugin reacts to which webhook requests by configuring a custom handler proc. Here's the default one:
47
+
48
+ ```ruby
49
+ plugin :github_webhook do
50
+ handler: ->(request) do
51
+ if request.env['HTTP_X_GITHUB_EVENT'] == 'workflow_run'
52
+ json = JSON.parse(request.body.read)
53
+ project = json.dig('repository', 'full_name')
54
+ status = json.dig('workflow_run', 'status')
55
+ status = json.dig('workflow_run', 'conclusion') if status == 'completed'
56
+ emoji = case status
57
+ when 'requested' then '🟡'
58
+ when 'success' then '🟢'
59
+ when 'failure' then '🔴'
60
+ else '⚪️'
61
+ end
62
+ [emoji, project, status.gsub('_', ' ')].join(' ')
63
+ end
64
+ end
65
+ end
66
+ ```
@@ -6,18 +6,37 @@ module Rodbot
6
6
  module App
7
7
 
8
8
  class Routes < ::App
9
- route do |r|
10
- r.post '' do
11
- r.halt 200 if request.env['HTTP_X_GITHUB_EVENT'] == 'ping'
12
- r.halt 400 unless request.env['HTTP_X_GITHUB_EVENT'] == 'workflow_run'
13
- r.halt 401 unless authorized?
9
+ DEFAULT_HANDLER = ->(request) do
10
+ if request.env['HTTP_X_GITHUB_EVENT'] == 'workflow_run'
14
11
  json = JSON.parse(request.body.read)
15
12
  project = json.dig('repository', 'full_name')
16
13
  status = json.dig('workflow_run', 'status')
17
14
  status = json.dig('workflow_run', 'conclusion') if status == 'completed'
18
- Rodbot.say [emoji_for(status), project, status.gsub('_', ' ')].join(' ')
19
- r.halt 200
15
+ emoji = case status
16
+ when 'requested' then '🟡'
17
+ when 'success' then '🟢'
18
+ when 'failure' then '🔴'
19
+ else '⚪️'
20
+ end
21
+ [emoji, project, status.gsub('_', ' ')].join(' ')
22
+ end
23
+ end
24
+
25
+ route do |r|
26
+ r.post '' do
27
+ r.halt 200 if request.env['HTTP_X_GITHUB_EVENT'] == 'ping'
28
+ r.halt 401 unless authorized?
29
+ handler = Rodbot.config(:plugin, :github_webhook, :handler) || DEFAULT_HANDLER
30
+ message = handler.call(r)
31
+ if message&.empty?
32
+ r.halt 204
33
+ else
34
+ Rodbot.say message
35
+ r.halt 200
36
+ end
20
37
  end
38
+ rescue => error
39
+ r.halt 500, error.message
21
40
  end
22
41
 
23
42
  private
@@ -30,15 +49,6 @@ module Rodbot
30
49
  end
31
50
  end
32
51
 
33
- def emoji_for(status)
34
- case status
35
- when 'requested' then '🟡'
36
- when 'success' then '🟢'
37
- when 'failure' then '🔴'
38
- else '⚪️'
39
- end
40
- end
41
-
42
52
  end
43
53
  end
44
54
  end
@@ -1,4 +1,4 @@
1
- # Rodbot Plugin – GitLab Webhook
1
+ # Rodbot plugin – GitLab webhook
2
2
 
3
3
  Pipeline event announcements from GitLab
4
4
 
@@ -18,9 +18,7 @@ To authenticate the webhook calls from GitLab, create a new random secret token:
18
18
  ruby -r securerandom -e "puts SecureRandom.alphanumeric(20)"
19
19
  ```
20
20
 
21
- ## Activation
22
-
23
- Activate and configure this plugin in `config/rodbot.rb`:
21
+ Configure this plugin in `config/rodbot.rb`:
24
22
 
25
23
  ```ruby
26
24
  plugin :gitlab_webhook do
@@ -30,11 +28,36 @@ end
30
28
 
31
29
  You can set any number of secure tokens here separated with colons.
32
30
 
33
- ## Add Repositories
31
+ ## Activation
34
32
 
35
- Add a webhook to every GitLab repository you'd like to see pipeline event announcements for. Go to `https://gitlab.com/<USER>/<REPO>/-/hooks` and create a new webhook with the following properties:
33
+ Set up a webhook to every GitLab repository you'd like to see pipeline event announcements for. Go to `https://gitlab.com/<USER>/<REPO>/-/hooks` and create a new webhook with the following properties:
36
34
 
37
35
  * URL: `https://<RODBOT-APP>/gitlab_webhook`
38
36
  * Secret token: `<TOKEN>`
39
37
  * Trigger: [x] Pipeline events
40
38
  * SSL verification: [x] Enable SSL verification
39
+
40
+ Use the test tool to verify your setup and to see what the JSON payloads look like in case you'd like to customize the handler.
41
+
42
+ ## Customization
43
+
44
+ You can change how the plugin reacts to which webhook requests by configuring a custom handler proc. Here's the default one:
45
+
46
+ ```ruby
47
+ plugin :gitlab_webhook do
48
+ handler: ->(request) do
49
+ json = JSON.parse(request.body.read)
50
+ if json['object_kind'] == 'pipeline'
51
+ project = json.dig('project', 'path_with_namespace')
52
+ status = json.dig('object_attributes', 'detailed_status')
53
+ emoji = case status
54
+ when 'running' then '🟡'
55
+ when 'passed' then '🟢'
56
+ when 'failed' then '🔴'
57
+ else '⚪️'
58
+ end
59
+ [emoji, project, status.gsub('_', ' ')].join(' ')
60
+ end
61
+ end
62
+ end
63
+ ```
@@ -6,16 +6,35 @@ module Rodbot
6
6
  module App
7
7
 
8
8
  class Routes < ::App
9
+ DEFAULT_HANDLER = ->(request) do
10
+ json = JSON.parse(request.body.read)
11
+ if json['object_kind'] == 'pipeline'
12
+ project = json.dig('project', 'path_with_namespace')
13
+ status = json.dig('object_attributes', 'detailed_status')
14
+ emoji = case status
15
+ when 'running' then '🟡'
16
+ when 'passed' then '🟢'
17
+ when 'failed' then '🔴'
18
+ else '⚪️'
19
+ end
20
+ [emoji, project, status.gsub('_', ' ')].join(' ')
21
+ end
22
+ end
23
+
9
24
  route do |r|
10
25
  r.post '' do
11
26
  r.halt 401 unless authorized?
12
- json = JSON.parse(request.body.read)
13
- r.halt 400 unless json['object_kind'] == 'pipeline'
14
- project = json.dig('project', 'path_with_namespace')
15
- status = json.dig('object_attributes', 'detailed_status')
16
- Rodbot.say [emoji_for(status), project, status.gsub('_', ' ')].join(' ')
17
- r.halt 200
27
+ handler = Rodbot.config(:plugin, :gitlab_webhook, :handler) || DEFAULT_HANDLER
28
+ message = handler.call(r)
29
+ if message&.empty?
30
+ r.halt 204
31
+ else
32
+ Rodbot.say message
33
+ r.halt 200
34
+ end
18
35
  end
36
+ rescue => error
37
+ r.halt 500, error.message
19
38
  end
20
39
 
21
40
  private
@@ -24,15 +43,6 @@ module Rodbot
24
43
  Rodbot.config(:plugin, :gitlab_webhook, :secret_tokens).to_s.split(':').include?(request.env['HTTP_X_GITLAB_TOKEN'])
25
44
  end
26
45
 
27
- def emoji_for(status)
28
- case status
29
- when 'running' then '🟡'
30
- when 'passed' then '🟢'
31
- when 'failed' then '🔴'
32
- else '⚪️'
33
- end
34
- end
35
-
36
46
  end
37
47
  end
38
48
  end
@@ -1,4 +1,4 @@
1
- # Rodbot Plugin – HAL 9000
1
+ # Rodbot plugin – HAL 9000
2
2
 
3
3
  Feel like Dave
4
4
 
@@ -1,4 +1,4 @@
1
- # Rodbot Plugin – Matrix
1
+ # Rodbot plugin – Matrix
2
2
 
3
3
  Relay with the Matrix communication network
4
4
 
@@ -1,4 +1,4 @@
1
- # Rodbot Plugin – OTP
1
+ # Rodbot plugin – OTP
2
2
 
3
3
  Guard commands with one-time passwords
4
4
 
@@ -1,4 +1,4 @@
1
- # Rodbot Plugin – Slack
1
+ # Rodbot plugin – Slack
2
2
 
3
3
  Relay with the Slack communication network
4
4
 
@@ -1,4 +1,4 @@
1
- # Rodbot PluginWord of the Day
1
+ # Rodbot pluginword of the day
2
2
 
3
3
  Word of the day announcements
4
4
 
@@ -37,4 +37,3 @@ Word of the day: foobar (English) / foobâr (French) / foobår (Swedish)
37
37
  ```
38
38
 
39
39
  In case the word of the day is not available, the message will contain the missing language struck through.
40
-
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  using Rodbot::Refinements
4
4
 
data/lib/rodbot/rack.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'httpx'
4
4
 
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'uri'
4
4
  require 'kramdown'
@@ -52,7 +52,7 @@ module Rodbot
52
52
  # @return [String] concatted URI
53
53
  refine String do
54
54
  def uri_concat(*segments)
55
- parser = URI::Parser.new
55
+ parser = URI::RFC2396_PARSER
56
56
  segments.inject(URI(self)) do |uri, segment|
57
57
  uri + parser.escape(segment)
58
58
  end.to_s
data/lib/rodbot/relay.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'digest'
4
4
  require 'socket'
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
4
  require 'base64'
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'rack'
4
4
  require 'puma'
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  using Rodbot::Refinements
4
4
 
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'clockwork'
4
4
  require 'active_support/time'
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  using Rodbot::Refinements
4
4
 
@@ -1,4 +1,4 @@
1
- # frozen-string-literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'readline'
4
4
  require 'httpx'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rodbot
4
- VERSION = "0.4.5"
4
+ VERSION = "0.5.0"
5
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class App < Roda
2
4
  plugin :rodbot
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Routes
2
4
  class Healthz < App
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Routes
2
4
  class Help < App
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  name 'Rodbot'
2
4
  time_zone 'Etc/UTC'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Regular jobs performed asynchronously at a given time
2
4
  module Clockwork
3
5
  # every 1.hour, -> { Rodbot.say 'Ping!' }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gem 'rodbot', '~> 0'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  clearing :on
2
4
 
3
5
  guard :minitest do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake/testtask'
2
4
 
3
5
  Rake::TestTask.new do |t|
data/rakefile.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+ #
1
3
  require 'bundler/gem_tasks'
2
4
 
3
5
  require 'rake/testtask'
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Schwyn
@@ -28,7 +28,7 @@ cert_chain:
28
28
  jTyRsT1gymASS2KHe+BaCTwD74GqO8q4woYLZgXnJ/PvgcFgY2FEi2Kn/sXLp4JE
29
29
  boIgxQCMT+nxBHCD
30
30
  -----END CERTIFICATE-----
31
- date: 2024-12-26 00:00:00.000000000 Z
31
+ date: 2025-01-25 00:00:00.000000000 Z
32
32
  dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: zeitwerk
@@ -502,6 +502,7 @@ files:
502
502
  - checksums/rodbot-0.4.3.gem.sha512
503
503
  - checksums/rodbot-0.4.4.gem.sha512
504
504
  - checksums/rodbot-0.4.5.gem.sha512
505
+ - checksums/rodbot-0.5.0.gem.sha512
505
506
  - doc/rodbot.afphoto
506
507
  - doc/rodbot.avif
507
508
  - exe/rodbot
@@ -624,7 +625,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
624
625
  - !ruby/object:Gem::Version
625
626
  version: '0'
626
627
  requirements: []
627
- rubygems_version: 3.6.2
628
+ rubygems_version: 3.6.3
628
629
  specification_version: 4
629
630
  summary: Minimalistic framework to build chat bots on top of a Roda backend
630
631
  test_files: []
metadata.gz.sig CHANGED
Binary file