hephaestus 0.3.1 → 0.5.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/bin/hephaestus +1 -0
- data/lib/hephaestus/app_builder.rb +6 -3
- data/lib/hephaestus/generators/app_generator.rb +46 -43
- data/lib/hephaestus/generators/config_generator.rb +2 -3
- data/lib/hephaestus/generators/core_generator.rb +1 -1
- data/lib/hephaestus/generators/deployment_generator.rb +6 -0
- data/lib/hephaestus/version.rb +1 -1
- data/lib/hephaestus.rb +8 -3
- data/templates/.github/workflows/licenses.yml +1 -1
- data/templates/.github/workflows/lint.yml +1 -1
- data/templates/.github/workflows/security.yml +1 -1
- data/templates/.github/workflows/sorbet.yml +1 -1
- data/templates/.licensed.yml +6 -0
- data/templates/Dockerfile +2 -2
- data/templates/Gemfile.erb +4 -1
- data/templates/app/controllers/app_controller.rb +3 -3
- data/templates/app/controllers/concerns/authable.rb +2 -2
- data/templates/app/controllers/settings_controller.rb +8 -0
- data/templates/app/controllers/yetto_controller.rb +11 -0
- data/templates/app/jobs/update_yetto_job.rb +6 -4
- data/templates/app/lib/body_parameter/yetto_parameters.rb +93 -9
- data/templates/app/lib/headers/yetto.rb +3 -1
- data/templates/app/lib/path_parameter/yetto_parameters.rb +6 -3
- data/templates/app/lib/plug_app/http.rb +3 -0
- data/templates/app/lib/plug_app/switches/message_created.jsonc +25 -0
- data/templates/app/services/yetto_service.rb +19 -14
- data/templates/compose.yml +1 -1
- data/templates/config/initializers/000-oj.rb +6 -0
- data/templates/config/initializers/environment.rb +5 -1
- data/templates/lib/plug_app/schemas/api/2023-03-06/components/parameters/headers/yetto.json +1 -1
- data/templates/lib/plug_app/schemas/api/2023-03-06/components/schemas/yetto.json +1 -1
- data/templates/lib/plug_app/schemas/api/2023-03-06/openapi.json +4 -4
- data/templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/{after_create_message.json → message_created.json} +1 -1
- data/templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/{after_create_plug_installation.json → plug_installation_created.json} +1 -1
- data/templates/test/controllers/yetto_controller_test.rb +7 -7
- data/templates/test/fixtures/files/plug_installation_settings/invalid.json +3 -0
- data/templates/test/fixtures/files/plug_installation_settings/valid.json +3 -0
- data/templates/test/fixtures/plug_installation_settings/invalid.json +3 -0
- data/templates/test/fixtures/plug_installation_settings/valid.json +3 -0
- data/templates/test/support/api.rb +6 -4
- data/templates/test/support/webmocks/yetto_webmock.rb +36 -17
- data/templates/vendor/fly/fly-production.toml +24 -22
- data/templates/vendor/fly/fly-staging.toml +24 -21
- metadata +11 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 35a7bffcd76ad59ed8a990221e201641e0931d5959d3a23eb1ff38e6cab6e196
|
|
4
|
+
data.tar.gz: 3a8041e10782f1feae394c607ff0b2884454bf2497973b204e1038d8318a8b19
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 343b21a22b01d3dec66e68ab5d807612930f2f46ed0fc5daa3d473745ce5db89978a3cd605b13ecb24cae51101e072dd5dbd891ed424855ce0724fd0233227c7
|
|
7
|
+
data.tar.gz: 8127efafa530a873c67a014ea0beef448b768c908bb4629a668eef1abcfe8b1527886447ad3757298d07f33483cab8e7a9c9b3f9839d7d0f88d7a04fb56f79ca
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [v0.4.0] - 29-09-2023
|
|
2
|
+
## What's Changed
|
|
3
|
+
* Yet more changes by @gjtorikian in https://github.com/yettoapp/hephaestus/pull/10
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
**Full Changelog**: https://github.com/yettoapp/hephaestus/compare/v0.3.1...v0.4.0
|
|
7
|
+
## [v0.3.1] - 18-09-2023
|
|
8
|
+
**Full Changelog**: https://github.com/yettoapp/hephaestus/compare/v0.3.0...v0.3.1
|
|
1
9
|
## [v0.3.0] - 12-09-2023
|
|
2
10
|
## What's Changed
|
|
3
11
|
* Bump actions/checkout from 3 to 4 by @dependabot in https://github.com/yettoapp/hephaestus/pull/8
|
data/bin/hephaestus
CHANGED
|
@@ -73,7 +73,7 @@ module Hephaestus
|
|
|
73
73
|
def setup_slack_logger
|
|
74
74
|
config = <<~EOD
|
|
75
75
|
config.after_initialize do
|
|
76
|
-
Rails.logger.
|
|
76
|
+
Rails.logger.broadcast_to(SlackWebhookLogger.logger)
|
|
77
77
|
end
|
|
78
78
|
EOD
|
|
79
79
|
configure_environment("production", config)
|
|
@@ -158,14 +158,17 @@ module Hephaestus
|
|
|
158
158
|
def replace_generic_variables
|
|
159
159
|
say(set_color("Replacing generic variable names...", :cyan))
|
|
160
160
|
replace_in_files(destination_root, /App(?!lication)/, short_app_name.capitalize)
|
|
161
|
-
replace_in_files(destination_root, %r{(?<!yetto)app(?!lication|/|roximate)}, short_app_name.downcase)
|
|
161
|
+
replace_in_files(destination_root, %r{(?<!yetto|sw|plugs\.yetto\.)app(?!lication|/|roximate)}, short_app_name.downcase)
|
|
162
162
|
replace_in_files(destination_root, "PlugApp", app_name.underscore.camelcase)
|
|
163
163
|
replace_in_files(destination_root, "plug-app", app_name.dasherize)
|
|
164
|
+
replace_in_files("destination_root}/.github/workflows/test.yml", "plug-app", app_name.dasherize)
|
|
164
165
|
replace_in_files(destination_root, "PLUG_APP", app_name.underscore.upcase)
|
|
165
166
|
replace_in_files(destination_root, "plug_app", app_name.underscore)
|
|
166
167
|
|
|
167
|
-
#
|
|
168
|
+
# these are erroneously changed
|
|
168
169
|
replace_in_file("script/server", "/usr/src/#{short_app_name.downcase}", "/usr/src/app")
|
|
170
|
+
replace_in_file("vendor/fly/fly-production.toml", "#{short_app_name.downcase} = ", "app = ")
|
|
171
|
+
replace_in_file("vendor/fly/fly-staging.toml", "#{short_app_name.downcase} = ", "app =")
|
|
169
172
|
end
|
|
170
173
|
|
|
171
174
|
private
|
|
@@ -28,37 +28,10 @@ module Hephaestus
|
|
|
28
28
|
super
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
# NOTE: this function name is important as it overrides
|
|
32
|
-
# a Rails function of the same name (that function performs work
|
|
33
|
-
# that we don't want to do)
|
|
34
|
-
def leftovers
|
|
35
|
-
build(:replace_generic_variables)
|
|
36
|
-
|
|
37
|
-
say(set_color("Generating `hephaestus:license`...", :cyan))
|
|
38
|
-
capture_stdout do
|
|
39
|
-
generate("hephaestus:license")
|
|
40
|
-
end
|
|
41
|
-
say(set_color("Generating `hephaestus:rubocop`...", :cyan))
|
|
42
|
-
capture_stdout do
|
|
43
|
-
generate("hephaestus:rubocop")
|
|
44
|
-
end
|
|
45
|
-
say(set_color("Generating `hephaestus:sorbet`...", :cyan))
|
|
46
|
-
capture_stdout do
|
|
47
|
-
generate("hephaestus:sorbet")
|
|
48
|
-
end
|
|
49
|
-
say(set_color("Creating first commit...", :cyan))
|
|
50
|
-
capture_stdout do
|
|
51
|
-
invoke(:commit)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
build(:restore_gemfile)
|
|
55
|
-
invoke(:outro)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
31
|
def hephaestus_customization
|
|
59
32
|
say(set_color("Invoking Hephaestus customizations...", :cyan))
|
|
60
33
|
|
|
61
|
-
run("rails app:update:bin"
|
|
34
|
+
run("rails app:update:bin")
|
|
62
35
|
invoke(:customize_gemfile)
|
|
63
36
|
|
|
64
37
|
invoke(:copy_github_actions)
|
|
@@ -79,6 +52,8 @@ module Hephaestus
|
|
|
79
52
|
build(:replace_gemfile)
|
|
80
53
|
capture_stdout do
|
|
81
54
|
bundle_command("install")
|
|
55
|
+
bundle_command("update")
|
|
56
|
+
bundle_command("binstub foreman")
|
|
82
57
|
bundle_command("lock --add-platform x86_64-linux")
|
|
83
58
|
end
|
|
84
59
|
end
|
|
@@ -171,6 +146,33 @@ module Hephaestus
|
|
|
171
146
|
end
|
|
172
147
|
end
|
|
173
148
|
|
|
149
|
+
# NOTE: this function name is important as it overrides
|
|
150
|
+
# a Rails function of the same name (that function performs work
|
|
151
|
+
# that we don't want to do)
|
|
152
|
+
def leftovers
|
|
153
|
+
build(:replace_generic_variables)
|
|
154
|
+
|
|
155
|
+
say(set_color("Generating `hephaestus:license`...", :cyan))
|
|
156
|
+
capture_stdout do
|
|
157
|
+
generate("hephaestus:license")
|
|
158
|
+
end
|
|
159
|
+
say(set_color("Generating `hephaestus:rubocop`...", :cyan))
|
|
160
|
+
capture_stdout do
|
|
161
|
+
generate("hephaestus:rubocop")
|
|
162
|
+
end
|
|
163
|
+
say(set_color("Generating `hephaestus:sorbet`...", :cyan))
|
|
164
|
+
capture_stdout do
|
|
165
|
+
generate("hephaestus:sorbet")
|
|
166
|
+
end
|
|
167
|
+
say(set_color("Creating first commit...", :cyan))
|
|
168
|
+
capture_stdout do
|
|
169
|
+
invoke(:commit)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
build(:restore_gemfile)
|
|
173
|
+
invoke(:outro)
|
|
174
|
+
end
|
|
175
|
+
|
|
174
176
|
def commit
|
|
175
177
|
run("git add .")
|
|
176
178
|
run("git commit -m 'Initial commit'", capture: true)
|
|
@@ -202,11 +204,12 @@ module Hephaestus
|
|
|
202
204
|
|
|
203
205
|
* Set `settings/branches` to protect `production`
|
|
204
206
|
* ✅ Require status checks to pass before merging
|
|
205
|
-
* 🖊️ Status checks that are required: `test`, `ruby / brakeman`, `ruby / bundle-audit`.
|
|
207
|
+
* 🖊️ Status checks that are required: `ruby / test_without_services`, `docker / test-build`, `ruby / brakeman`, `ruby / bundle-audit`.
|
|
208
|
+
|
|
206
209
|
You can only set those 👆 after you've opened the first PR on GitHub. Crazy, I know!!
|
|
207
210
|
But, doing so is *essential* for automerge to function properly.
|
|
208
211
|
|
|
209
|
-
*
|
|
212
|
+
* In `/settings`:
|
|
210
213
|
* ✅ Allow auto-merge
|
|
211
214
|
* ✅ Automatically delete head branches
|
|
212
215
|
OUTPUT
|
|
@@ -229,22 +232,22 @@ module Hephaestus
|
|
|
229
232
|
end
|
|
230
233
|
|
|
231
234
|
private def capture_stdout
|
|
232
|
-
stream = "stdout"
|
|
233
|
-
captured_stream = Tempfile.new(stream)
|
|
234
|
-
stream_io = eval("$#{stream}", binding, __FILE__, __LINE__)
|
|
235
|
-
origin_stream = stream_io.dup
|
|
236
|
-
stream_io.reopen(captured_stream)
|
|
235
|
+
# stream = "stdout"
|
|
236
|
+
# captured_stream = Tempfile.new(stream)
|
|
237
|
+
# stream_io = eval("$#{stream}", binding, __FILE__, __LINE__)
|
|
238
|
+
# origin_stream = stream_io.dup
|
|
239
|
+
# stream_io.reopen(captured_stream)
|
|
237
240
|
|
|
238
241
|
yield
|
|
239
242
|
|
|
240
|
-
stream_io.rewind
|
|
241
|
-
captured_stream.read
|
|
242
|
-
|
|
243
|
-
unless captured_stream.nil?
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
end
|
|
247
|
-
stream_io.reopen(origin_stream) unless stream_io.nil?
|
|
243
|
+
# stream_io.rewind
|
|
244
|
+
# captured_stream.read
|
|
245
|
+
|
|
246
|
+
# unless captured_stream.nil?
|
|
247
|
+
# captured_stream.close
|
|
248
|
+
# captured_stream.unlink
|
|
249
|
+
# end
|
|
250
|
+
# stream_io.reopen(origin_stream) unless stream_io.nil?
|
|
248
251
|
end
|
|
249
252
|
end
|
|
250
253
|
end
|
|
@@ -89,11 +89,10 @@ module Hephaestus
|
|
|
89
89
|
|
|
90
90
|
# events into the plug, usually from yetto
|
|
91
91
|
get "/api/2023-03-06/settings", to: "settings#new"
|
|
92
|
-
post "/api/2023-03-06/:event
|
|
92
|
+
post "/api/2023-03-06/:record_type/:event", to: "yetto#event"
|
|
93
93
|
|
|
94
94
|
# inbound message
|
|
95
|
-
post "
|
|
96
|
-
# post "/app/2023-03-06/webhook/inbound", to: "app#process_inbound" # for generic inbound pings
|
|
95
|
+
post "/$app/2023-03-06/webhook/inbound", to: "app#webhook"
|
|
97
96
|
|
|
98
97
|
# Staff pages
|
|
99
98
|
get "staff", to: "staff#index"
|
|
@@ -19,7 +19,7 @@ module Hephaestus
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def jobs
|
|
22
|
-
copy_file("app/jobs/application_job.rb", "app/jobs/application_job.rb")
|
|
22
|
+
copy_file("app/jobs/application_job.rb", "app/jobs/application_job.rb", force: true)
|
|
23
23
|
copy_file("app/jobs/update_yetto_job.rb", "app/jobs/update_yetto_job.rb")
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -20,5 +20,11 @@ module Hephaestus
|
|
|
20
20
|
copy_file("Dockerfile", "Dockerfile")
|
|
21
21
|
copy_file("bin/docker-entrypoint", "bin/docker-entrypoint")
|
|
22
22
|
end
|
|
23
|
+
|
|
24
|
+
def fly
|
|
25
|
+
directory("vendor/fly", "vendor/fly")
|
|
26
|
+
copy_file("Dockerfile", "Dockerfile")
|
|
27
|
+
copy_file("bin/docker-entrypoint", "bin/docker-entrypoint")
|
|
28
|
+
end
|
|
23
29
|
end
|
|
24
30
|
end
|
data/lib/hephaestus/version.rb
CHANGED
data/lib/hephaestus.rb
CHANGED
|
@@ -11,10 +11,15 @@ require "debug" if debugging?
|
|
|
11
11
|
|
|
12
12
|
require "hephaestus/version"
|
|
13
13
|
require "hephaestus/exit_on_failure"
|
|
14
|
+
|
|
14
15
|
require "hephaestus/generators/app_generator"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
require "hephaestus/generators/config_generator"
|
|
17
|
+
require "hephaestus/generators/core_generator"
|
|
18
|
+
require "hephaestus/generators/deployment_generator"
|
|
19
|
+
require "hephaestus/generators/lib_generator"
|
|
20
|
+
require "hephaestus/generators/license_generator"
|
|
21
|
+
require "hephaestus/generators/rubocop_generator"
|
|
22
|
+
require "hephaestus/generators/sorbet_generator"
|
|
18
23
|
|
|
19
24
|
require "hephaestus/actions"
|
|
20
25
|
require "hephaestus/actions/strip_comments_action"
|
data/templates/.licensed.yml
CHANGED
|
@@ -11,10 +11,16 @@ allowed:
|
|
|
11
11
|
|
|
12
12
|
ignored:
|
|
13
13
|
bundler:
|
|
14
|
+
- base64 # BSD-2-Clause ("This file is released under the same license as ruby.")
|
|
15
|
+
- bigdecimal # BSD-2-Clause ("This file is released under the same license as ruby.")
|
|
14
16
|
- bundler-audit # GPL-3.0; but also, only used in CI/test
|
|
15
17
|
- date # BSD-2-Clause
|
|
18
|
+
- drb # BSD-2-Clause ("This file is released under the same license as ruby.")
|
|
19
|
+
- io-console # BSD-2-Clause
|
|
20
|
+
- mutex_m # BSD-2-Clause ("This file is released under the same license as ruby.")
|
|
16
21
|
- net-protocol # BSD-2-Clause
|
|
17
22
|
- racc # BSD-2-Clause
|
|
23
|
+
- reline # BSD-2-Clause ("This file is released under the same license as ruby.")
|
|
18
24
|
- ruby2_keywords # BSD-2-Clause; ignored because of custom LICENSE text
|
|
19
25
|
- sidekiq # LGPL-3.0; ignored because of custom LICENSE text
|
|
20
26
|
|
data/templates/Dockerfile
CHANGED
data/templates/Gemfile.erb
CHANGED
|
@@ -44,6 +44,9 @@ gem "opentelemetry-instrumentation-active_job", "~> 0.5"
|
|
|
44
44
|
gem "opentelemetry-instrumentation-redis", "~> 0.25"
|
|
45
45
|
gem "opentelemetry-instrumentation-sidekiq", "~> 0.23"
|
|
46
46
|
|
|
47
|
+
# massively improved JSON parsing
|
|
48
|
+
gem "oj", "~> 3.16"
|
|
49
|
+
|
|
47
50
|
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
|
48
51
|
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
|
49
52
|
|
|
@@ -114,4 +117,4 @@ group :ci do
|
|
|
114
117
|
gem "bundle-audit", "~> 0.1"
|
|
115
118
|
end
|
|
116
119
|
|
|
117
|
-
gem "hephaestus", group: [:development, :test]
|
|
120
|
+
gem "hephaestus", group: [:development, :test]
|
|
@@ -8,12 +8,12 @@ class AppController < ApplicationController
|
|
|
8
8
|
include PathParameter::AppParameters
|
|
9
9
|
include BodyParameter::AppParameters
|
|
10
10
|
|
|
11
|
-
before_action :
|
|
11
|
+
before_action :from_app?
|
|
12
12
|
|
|
13
13
|
# Inbound message from ${App}
|
|
14
14
|
def webhook
|
|
15
|
-
# Error if
|
|
16
|
-
return bad_request unless
|
|
15
|
+
# Error if necessary parameters from ${App} are missing
|
|
16
|
+
return bad_request unless has_inbound_app_params?
|
|
17
17
|
|
|
18
18
|
response = YettoService.get_plug_installation(pparam_organization_id, pparam_inbox_id, pparam_plug_installation_id)
|
|
19
19
|
|
|
@@ -26,8 +26,8 @@ module Authable
|
|
|
26
26
|
|
|
27
27
|
# status is annoyingly set to 401, but we want
|
|
28
28
|
# to hide that an issue exists
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
self.status = PlugApp::HTTP::BAD_REQUEST_I
|
|
30
|
+
self.response_body = ::ErrorSerializer.format(PlugApp::HTTP::BAD_REQUEST)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
sig { void }
|
|
@@ -6,6 +6,14 @@ class SettingsController < ApplicationController
|
|
|
6
6
|
|
|
7
7
|
include PathParameter::SettingsParameters
|
|
8
8
|
|
|
9
|
+
before_action :ensure_json_request
|
|
10
|
+
sig { void }
|
|
11
|
+
def ensure_json_request
|
|
12
|
+
return if request.format.json?
|
|
13
|
+
|
|
14
|
+
not_acceptable
|
|
15
|
+
end
|
|
16
|
+
|
|
9
17
|
sig { void }
|
|
10
18
|
def new
|
|
11
19
|
@step = T.let(params.fetch(:step, 1).to_i || 1, T.nilable(Integer))
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
class YettoController < ApplicationController
|
|
5
5
|
include BodyParameter::YettoParameters
|
|
6
|
+
include PathParameter
|
|
6
7
|
include PathParameter::YettoParameters
|
|
7
8
|
include Authable
|
|
8
9
|
|
|
@@ -10,11 +11,21 @@ class YettoController < ApplicationController
|
|
|
10
11
|
|
|
11
12
|
before_action :from_yetto?
|
|
12
13
|
|
|
14
|
+
AFTER_CREATE_MESSAGE_SWITCH = JSON.parse(Rails.root.join("app/lib/plug_app/switches/message_created.jsonc").read)
|
|
15
|
+
|
|
13
16
|
def event
|
|
14
17
|
case pparam_yetto_event
|
|
15
18
|
when Headers::Yetto::EVENT_AFTER_CREATE
|
|
16
19
|
case pparam_yetto_record_type
|
|
17
20
|
when Headers::Yetto::RECORD_TYPE_PLUG_INSTALLATION
|
|
21
|
+
create_inbox_switch_data = {
|
|
22
|
+
type: "create_inbox_switch",
|
|
23
|
+
inbox: { id: bparam_inbox_id },
|
|
24
|
+
plug_installation: { id: bparam_plug_installation_id },
|
|
25
|
+
payload: AFTER_CREATE_MESSAGE_SWITCH,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
UpdateYettoJob.perform_later(create_inbox_switch_data)
|
|
18
29
|
|
|
19
30
|
no_content
|
|
20
31
|
when Headers::Yetto::RECORD_TYPE_MESSAGE
|
|
@@ -5,22 +5,24 @@
|
|
|
5
5
|
# This can be used to update installation data or message data
|
|
6
6
|
|
|
7
7
|
class UpdateYettoJob < ApplicationJob
|
|
8
|
-
queue_as :
|
|
8
|
+
queue_as :update_yetto
|
|
9
9
|
|
|
10
10
|
def perform(params)
|
|
11
11
|
type = params.delete(:type)
|
|
12
12
|
|
|
13
|
-
organization_id = params.fetch(:organization, {}).fetch(:id, nil)
|
|
14
13
|
inbox_id = params.fetch(:inbox, {}).fetch(:id, nil)
|
|
15
14
|
plug_installation_id = params.fetch(:plug_installation, {}).fetch(:id, nil)
|
|
15
|
+
message_id = params.fetch(:message, {}).fetch(:id, nil)
|
|
16
16
|
|
|
17
17
|
case type
|
|
18
18
|
when "update_plug_installation"
|
|
19
19
|
YettoService.update_installation(plug_installation_id, params)
|
|
20
20
|
when "create_inbox_switch"
|
|
21
21
|
YettoService.create_inbox_switch(inbox_id, plug_installation_id, params)
|
|
22
|
-
when "
|
|
23
|
-
YettoService.
|
|
22
|
+
when "create_message_reply"
|
|
23
|
+
YettoService.create_message_reply(message_id, plug_installation_id, params)
|
|
24
|
+
when "add_message_metadata"
|
|
25
|
+
YettoService.update_message(message_id, plug_installation_id, params)
|
|
24
26
|
end
|
|
25
27
|
end
|
|
26
28
|
end
|
|
@@ -5,25 +5,47 @@ module BodyParameter
|
|
|
5
5
|
module YettoParameters
|
|
6
6
|
extend T::Sig
|
|
7
7
|
|
|
8
|
-
sig { returns(
|
|
9
|
-
def
|
|
10
|
-
|
|
8
|
+
sig { returns(String) }
|
|
9
|
+
def bparam_organization_id
|
|
10
|
+
plug_installation_params[:organization][:id]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
sig { returns(String) }
|
|
14
|
+
def bparam_inbox_id
|
|
15
|
+
plug_installation_params[:inbox][:id]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
sig { returns(String) }
|
|
19
|
+
def bparam_plug_installation_id
|
|
20
|
+
plug_installation_params[:plug_installation][:id]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
sig { returns(String) }
|
|
24
|
+
def bparam_plug_id
|
|
25
|
+
plug_installation_params[:plug][:id]
|
|
26
|
+
end
|
|
11
27
|
|
|
12
|
-
|
|
28
|
+
sig { returns(T::Hash[Symbol, String]) }
|
|
29
|
+
def bparam_plug_installation_settings
|
|
30
|
+
plug_installation_params[:plug_installation][:settings]
|
|
13
31
|
end
|
|
14
32
|
|
|
15
33
|
sig { returns(T::Hash[Symbol, String]) }
|
|
16
|
-
def
|
|
34
|
+
def plug_installation_params
|
|
17
35
|
return {} if params.blank?
|
|
18
36
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
37
|
+
plug_installation = params.fetch(:plug_installation, {})
|
|
38
|
+
plug_installation_id = plug_installation.fetch(:id, "")
|
|
39
|
+
settings = plug_installation.fetch(:settings, {}).to_unsafe_hash
|
|
40
|
+
|
|
41
|
+
organization_id = params.fetch(:organization, {}).fetch(:id, "")
|
|
42
|
+
plug_id = params.fetch(:plug, {}).fetch(:id, "")
|
|
43
|
+
inbox_id = params.fetch(:inbox, {}).fetch(:id, "")
|
|
23
44
|
|
|
24
45
|
{
|
|
25
46
|
plug_installation: {
|
|
26
47
|
id: plug_installation_id,
|
|
48
|
+
settings: settings,
|
|
27
49
|
},
|
|
28
50
|
organization: {
|
|
29
51
|
id: organization_id,
|
|
@@ -36,5 +58,67 @@ module BodyParameter
|
|
|
36
58
|
},
|
|
37
59
|
}
|
|
38
60
|
end
|
|
61
|
+
|
|
62
|
+
sig { returns(String) }
|
|
63
|
+
def bparam_message_id
|
|
64
|
+
message_params[:message][:id]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
sig { returns(String) }
|
|
68
|
+
def bparam_message_text_content
|
|
69
|
+
message_params[:message][:text_content]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
sig { returns(String) }
|
|
73
|
+
def bparam_message_conversation_id
|
|
74
|
+
message_params[:message][:conversation][:id]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
sig { returns(String) }
|
|
78
|
+
def bparam_message_conversation_title
|
|
79
|
+
message_params[:message][:conversation][:title]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
sig { returns(String) }
|
|
83
|
+
def bparam_message_author_name
|
|
84
|
+
message_params[:message].fetch(:author, {}).fetch(:name, "Noone")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
sig { returns(T::Hash[Symbol, String]) }
|
|
88
|
+
def bparam_message_metadata
|
|
89
|
+
message_params[:message][:metadata]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
sig { returns(T::Hash[Symbol, String]) }
|
|
93
|
+
def message_params
|
|
94
|
+
return {} if params.blank?
|
|
95
|
+
|
|
96
|
+
message = params.fetch(:message, {})
|
|
97
|
+
message_id = message.fetch(:id, "")
|
|
98
|
+
text_content = message.fetch(:text_content, "")
|
|
99
|
+
conversation = message.fetch(:conversation, {})
|
|
100
|
+
conversation_id = conversation.fetch(:id, "")
|
|
101
|
+
title = conversation.fetch(:title, "")
|
|
102
|
+
created_by_user = message.fetch(:created_by_user, {})
|
|
103
|
+
created_by_plug = message.fetch(:created_by_plug, {})
|
|
104
|
+
author = (created_by_user.presence || created_by_plug)
|
|
105
|
+
name = author.fetch(:name, "")
|
|
106
|
+
metadata = message.fetch(:metadata, {}).to_unsafe_hash
|
|
107
|
+
|
|
108
|
+
{
|
|
109
|
+
message: {
|
|
110
|
+
id: message_id,
|
|
111
|
+
text_content: text_content,
|
|
112
|
+
conversation: {
|
|
113
|
+
id: conversation_id,
|
|
114
|
+
title: title,
|
|
115
|
+
},
|
|
116
|
+
author: {
|
|
117
|
+
name: name,
|
|
118
|
+
},
|
|
119
|
+
metadata: metadata,
|
|
120
|
+
},
|
|
121
|
+
}
|
|
122
|
+
end
|
|
39
123
|
end
|
|
40
124
|
end
|
|
@@ -6,7 +6,9 @@ module Headers
|
|
|
6
6
|
YETTO_DELIVERY_ID = "HTTP_X_YETTO_DELIVERY_ID"
|
|
7
7
|
|
|
8
8
|
HEADER_EVENT = "HTTP_X_YETTO_EVENT"
|
|
9
|
-
EVENT_AFTER_CREATE = "
|
|
9
|
+
EVENT_AFTER_CREATE = "created"
|
|
10
|
+
EVENT_AFTER_UPDATE = "updated"
|
|
11
|
+
EVENT_AFTER_DESTROY = "destroyed"
|
|
10
12
|
|
|
11
13
|
HEADER_RECORD_TYPE = "HTTP_X_YETTO_RECORD_TYPE"
|
|
12
14
|
RECORD_TYPE_PLUG_INSTALLATION = "plug_installation"
|
|
@@ -15,11 +15,14 @@ module PathParameter
|
|
|
15
15
|
yetto_path_params.fetch(:record_type, "")
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
sig { returns(
|
|
18
|
+
sig { returns(T::Hash[String, String]) }
|
|
19
19
|
def yetto_path_params
|
|
20
|
-
return
|
|
20
|
+
return {} if path_parameters.blank?
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
{
|
|
23
|
+
event: path_parameters.fetch(:event, ""),
|
|
24
|
+
record_type: path_parameters.fetch(:record_type, ""),
|
|
25
|
+
}
|
|
23
26
|
end
|
|
24
27
|
end
|
|
25
28
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Send internal comments to App",
|
|
3
|
+
"configuration": {
|
|
4
|
+
"version": "2023-03-06",
|
|
5
|
+
"events": {
|
|
6
|
+
"message.created": {
|
|
7
|
+
"conditions": {
|
|
8
|
+
"if": "{% data.message.visibility == 'internal' and data.message.text_content contains '@App' %}"
|
|
9
|
+
},
|
|
10
|
+
"actions": [
|
|
11
|
+
{
|
|
12
|
+
"name": "Send to App",
|
|
13
|
+
"uses": "send_to_plug",
|
|
14
|
+
"with": {
|
|
15
|
+
"plug_id": "{{ data.switch.created_by_plug.id }}",
|
|
16
|
+
"message": "{{ data.message }}",
|
|
17
|
+
"plug_installation": "{{ data.plug_installation }}",
|
|
18
|
+
"inbox": "{{ data.inbox }}"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -6,48 +6,53 @@ class YettoService
|
|
|
6
6
|
Httpsensible::Client.new(user_agent: "PlugApp/#{PlugApp::Application::GIT_SHA}")
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# explicitly different than what's in environment.rb, because local
|
|
10
|
+
# Yetto expects HTTP; environment.rb can use HTTPS because it passes through ngrok.io
|
|
11
|
+
PROTOCOL = Rails.env.development? ? "http://" : "https://"
|
|
10
12
|
YETTO_API_VERSION_TLD = "#{PROTOCOL}://#{YETTO_API_TLD}/#{YETTO_API_VERSION}"
|
|
11
13
|
JWT_ALGORITHM = "RS256"
|
|
12
14
|
|
|
13
15
|
class << self
|
|
14
16
|
def perform_token_exchange(plug_installation_id)
|
|
15
17
|
encoded_jwt = Httpsensible::JWT.encode_jwt(YETTO_PLUG_PEM, YETTO_PLUG_ID)
|
|
16
|
-
response = yetto_client.
|
|
18
|
+
response = yetto_client.with_headers({ "Authorization" => "Bearer #{encoded_jwt}" }).post("#{YETTO_API_VERSION_TLD}/plug/installations/#{plug_installation_id}/access_tokens")
|
|
17
19
|
body = response.parsed_json_body
|
|
18
20
|
body["token"]
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def get_plug_installation(plug_installation_id)
|
|
22
24
|
token = perform_token_exchange(plug_installation_id)
|
|
23
|
-
yetto_client.
|
|
25
|
+
yetto_client.with_headers("Authorization" => "Bearer #{token}").get("#{YETTO_API_VERSION_TLD}/installations/#{plug_installation_id}")
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
def update_installation(plug_installation_id, params)
|
|
27
29
|
plug_installation = {}
|
|
28
|
-
plug_installation[:settings] = params
|
|
29
|
-
plug_installation[:credentials] = params
|
|
30
|
+
plug_installation[:settings] = params.fetch(:settings, {})
|
|
31
|
+
plug_installation[:credentials] = params.fetch(:credentials, {})
|
|
30
32
|
|
|
31
33
|
token = perform_token_exchange(plug_installation_id)
|
|
32
|
-
yetto_client.
|
|
34
|
+
yetto_client.with_headers("Authorization" => "Bearer #{token}").patch("#{YETTO_API_VERSION_TLD}/installations/#{plug_installation_id}", json: plug_installation)
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def create_inbox_switch(inbox_id, plug_installation_id, params)
|
|
36
|
-
|
|
38
|
+
payload = params[:payload]
|
|
39
|
+
token = perform_token_exchange(plug_installation_id)
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
+
yetto_client.with_headers("Authorization" => "Bearer #{token}").post("#{YETTO_API_VERSION_TLD}/inboxes/#{inbox_id}/switches", json: payload)
|
|
42
|
+
end
|
|
41
43
|
|
|
44
|
+
def update_message(message_id, plug_installation_id, params)
|
|
45
|
+
payload = params[:payload]
|
|
42
46
|
token = perform_token_exchange(plug_installation_id)
|
|
43
|
-
|
|
47
|
+
|
|
48
|
+
yetto_client.with_headers("Authorization" => "Bearer #{token}").patch("#{YETTO_API_VERSION_TLD}/messages/#{message_id}", json: payload)
|
|
44
49
|
end
|
|
45
50
|
|
|
46
|
-
def
|
|
51
|
+
def create_message_reply(message_id, plug_installation_id, params)
|
|
47
52
|
payload = params[:payload]
|
|
48
|
-
|
|
49
53
|
token = perform_token_exchange(plug_installation_id)
|
|
50
|
-
|
|
54
|
+
|
|
55
|
+
yetto_client.with_headers("Authorization" => "Bearer #{token}").post("#{YETTO_API_VERSION_TLD}/messages/#{message_id}/replies", json: payload)
|
|
51
56
|
end
|
|
52
57
|
end
|
|
53
58
|
end
|
data/templates/compose.yml
CHANGED
|
@@ -16,7 +16,7 @@ YETTO_API_VERSION = ENV.fetch("YETTO_API_VERSION", "2023-03-06")
|
|
|
16
16
|
|
|
17
17
|
SLACK_LOG_URL = Rails.application.credentials.fetch(:SLACK_LOG_URL, ENV.fetch("SLACK_LOG_URL", "https://slack.com/the_log_room"))
|
|
18
18
|
|
|
19
|
-
PROTOCOL =
|
|
19
|
+
PROTOCOL = "https"
|
|
20
20
|
PLUG_APP_URL = if Rails.env.production?
|
|
21
21
|
"app.plugs.yetto.app"
|
|
22
22
|
elsif Rails.env.staging?
|
|
@@ -34,3 +34,7 @@ YETTO_PLUG_ID = Rails.application.credentials.fetch(:YETTO_PLUG_ID, ENV.fetch("Y
|
|
|
34
34
|
def productionish?
|
|
35
35
|
Rails.env.production? || Rails.env.staging?
|
|
36
36
|
end
|
|
37
|
+
|
|
38
|
+
def print_user_api_errors?
|
|
39
|
+
(Rails.env.development? || Rails.env.staging?) || ENV.fetch("DEBUG", false)
|
|
40
|
+
end
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
}
|
|
18
18
|
],
|
|
19
19
|
"paths": {
|
|
20
|
-
"/api/2023-03-06/
|
|
21
|
-
"$ref": "paths/yetto/
|
|
20
|
+
"/api/2023-03-06/plug_installation/created": {
|
|
21
|
+
"$ref": "paths/yetto/plug_installation_created.json"
|
|
22
22
|
},
|
|
23
|
-
"/api/2023-03-06/
|
|
24
|
-
"$ref": "paths/yetto/
|
|
23
|
+
"/api/2023-03-06/message/created": {
|
|
24
|
+
"$ref": "paths/yetto/message_created.json"
|
|
25
25
|
},
|
|
26
26
|
"/app/2023-03-06/{plugInstallationId}": {
|
|
27
27
|
"$ref": "paths/app.json"
|
|
@@ -60,37 +60,37 @@ class YettoControllerTest < ActionDispatch::IntegrationTest
|
|
|
60
60
|
|
|
61
61
|
def headers(body)
|
|
62
62
|
{
|
|
63
|
-
Headers::Yetto::HEADER_EVENT => "
|
|
63
|
+
Headers::Yetto::HEADER_EVENT => "created",
|
|
64
64
|
Headers::Yetto::HEADER_RECORD_TYPE => "plug_installation",
|
|
65
65
|
Headers::Yetto::HEADER_SIGNATURE => yetto_auth_header(body),
|
|
66
66
|
}
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
test "it handles null headers" do
|
|
70
|
-
api(:post, "/
|
|
70
|
+
api(:post, "/plug_installation/created", headers: nil)
|
|
71
71
|
|
|
72
72
|
assert_response :bad_request
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
test "it handles missing headers" do
|
|
76
|
-
api(:post, "/
|
|
76
|
+
api(:post, "/plug_installation/created", headers: {})
|
|
77
77
|
|
|
78
78
|
assert_response :bad_request
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
test "it handles incorrect headers" do
|
|
82
|
-
api(:post, "/
|
|
82
|
+
api(:post, "/plug_installation/created", headers: { "X-Yetto-Signature" => "Basic jabroni:lies" })
|
|
83
83
|
|
|
84
84
|
assert_response :bad_request
|
|
85
85
|
|
|
86
|
-
api(:post, "/
|
|
86
|
+
api(:post, "/plug_installation/created", headers: { "X-Yetto-Signature" => "sha256=123456" })
|
|
87
87
|
|
|
88
88
|
assert_response :bad_request
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
test "it handles missing body" do
|
|
92
92
|
body = {}
|
|
93
|
-
api(:post, "/
|
|
93
|
+
api(:post, "/plug_installation/created", headers: headers(body), body: body)
|
|
94
94
|
|
|
95
95
|
assert_response :bad_request
|
|
96
96
|
end
|
|
@@ -122,7 +122,7 @@ class YettoControllerTest < ActionDispatch::IntegrationTest
|
|
|
122
122
|
id: "inbx_#{Faker::Alphanumeric.alphanumeric(number: 26).upcase}",
|
|
123
123
|
},
|
|
124
124
|
}
|
|
125
|
-
api(:post, "/
|
|
125
|
+
api(:post, "/plug_installation/created", headers: headers_with_one_body, body: body_two)
|
|
126
126
|
|
|
127
127
|
assert_response :bad_request
|
|
128
128
|
end
|
|
@@ -5,11 +5,11 @@ module API
|
|
|
5
5
|
module TestHelpers
|
|
6
6
|
include Rack::Test::Methods
|
|
7
7
|
|
|
8
|
-
def plug(method, path, headers: {}, version: nil, body: {})
|
|
8
|
+
def plug(method, path, headers: {}, version: nil, body: {}, parse: true)
|
|
9
9
|
version ||= PlugApp::CURRENT_VERSION
|
|
10
10
|
prepended_path = prepend_plug_path(version, path)
|
|
11
11
|
|
|
12
|
-
http_call(method, prepended_path, headers: headers, version: version, body: body)
|
|
12
|
+
http_call(method, prepended_path, headers: headers, version: version, body: body, parse: parse)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def api(method, path, headers: {}, version: nil, body: {})
|
|
@@ -19,7 +19,7 @@ module API
|
|
|
19
19
|
http_call(method, prepended_path, headers: headers, version: version, body: body)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def http_call(method, path, headers: {}, version: nil, body: {})
|
|
22
|
+
def http_call(method, path, headers: {}, version: nil, body: {}, parse: true)
|
|
23
23
|
# explicitly assert headers cannot be nil
|
|
24
24
|
if headers.nil?
|
|
25
25
|
send(method, path, body.to_json)
|
|
@@ -29,7 +29,7 @@ module API
|
|
|
29
29
|
send(method, path, body.to_json, headers)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
JSON.parse(last_response.body) if last_response.body.present?
|
|
32
|
+
JSON.parse(last_response.body) if last_response.body.present? && parse
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def assert_response(expected_status, expected_body = nil)
|
|
@@ -42,6 +42,8 @@ module API
|
|
|
42
42
|
PlugApp::HTTP::OK_I
|
|
43
43
|
when :created
|
|
44
44
|
PlugApp::HTTP::CREATED_I
|
|
45
|
+
when :redirect
|
|
46
|
+
PlugApp::HTTP::FOUND_I
|
|
45
47
|
when :no_content
|
|
46
48
|
PlugApp::HTTP::NO_CONTENT_I
|
|
47
49
|
when :bad_request
|
|
@@ -8,28 +8,30 @@ module Webmocks
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def assert_requested_post_access_token(plug_installation_id)
|
|
11
|
-
assert_requested(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/
|
|
11
|
+
assert_requested(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/plug/installations/#{plug_installation_id}/access_tokens")
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def stub_post_access_token(plug_installation_id)
|
|
15
15
|
response = {
|
|
16
16
|
token: Faker::Alphanumeric.alphanumeric(number: 26).upcase,
|
|
17
17
|
}
|
|
18
|
-
stub_request(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/
|
|
18
|
+
stub_request(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/plug/installations/#{plug_installation_id}/access_tokens")
|
|
19
19
|
.to_return(
|
|
20
20
|
body: response.to_json,
|
|
21
21
|
)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def
|
|
24
|
+
def assert_requested_get_inbox_plug_installation(plug_installation_id)
|
|
25
25
|
assert_requested_post_access_token(plug_installation_id)
|
|
26
26
|
assert_requested(:get, "#{::YettoService::YETTO_API_VERSION_TLD}/installations/#{plug_installation_id}")
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def
|
|
29
|
+
def stub_get_inbox_plug_installation(organization_id, inbox_id, plug_installation_id, response = {}, valid: true, status: 200, expires_at: 8.hours.from_now)
|
|
30
30
|
stub_post_access_token(plug_installation_id)
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
github_installations = JSON.parse(file_fixture_path("plug_installation_settings", valid ? "valid.json" : "invalid.json").read).deep_symbolize_keys
|
|
33
|
+
|
|
34
|
+
response = {
|
|
33
35
|
installed_on_inbox: {
|
|
34
36
|
id: inbox_id,
|
|
35
37
|
organization: {
|
|
@@ -40,10 +42,13 @@ module Webmocks
|
|
|
40
42
|
plug: {
|
|
41
43
|
id: "plg_#{Faker::Alphanumeric.alphanumeric(number: 26).upcase}",
|
|
42
44
|
},
|
|
43
|
-
settings:
|
|
44
|
-
|
|
45
|
+
settings: github_installations,
|
|
46
|
+
credentials: {
|
|
47
|
+
access_token: Faker::Alphanumeric.alphanumeric(number: 26).upcase,
|
|
48
|
+
refresh_access_token: "refresher",
|
|
49
|
+
expires_at: expires_at.iso8601,
|
|
45
50
|
},
|
|
46
|
-
}
|
|
51
|
+
}.merge(response)
|
|
47
52
|
|
|
48
53
|
stub_request(:get, "#{::YettoService::YETTO_API_VERSION_TLD}/installations/#{plug_installation_id}")
|
|
49
54
|
.to_return(
|
|
@@ -73,16 +78,34 @@ module Webmocks
|
|
|
73
78
|
)
|
|
74
79
|
end
|
|
75
80
|
|
|
76
|
-
def assert_requested_create_message(
|
|
81
|
+
def assert_requested_create_message(plug_installation_id, message_id)
|
|
77
82
|
assert_requested_post_access_token(plug_installation_id)
|
|
78
83
|
|
|
79
|
-
assert_requested(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/
|
|
84
|
+
assert_requested(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/messages/#{message_id}/replies")
|
|
80
85
|
end
|
|
81
86
|
|
|
82
|
-
def stub_create_message(
|
|
87
|
+
def stub_create_message(plug_installation_id, message_id, payload)
|
|
83
88
|
stub_post_access_token(plug_installation_id)
|
|
84
89
|
|
|
85
|
-
stub_request(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/
|
|
90
|
+
stub_request(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/messages/#{message_id}/replies")
|
|
91
|
+
# .with(
|
|
92
|
+
# body: payload,
|
|
93
|
+
# )
|
|
94
|
+
# .to_return(
|
|
95
|
+
# status: 200,
|
|
96
|
+
# headers: { content_type: "application/json; charset=utf-8" },
|
|
97
|
+
# body: {}.to_json,
|
|
98
|
+
# )
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def assert_requested_update_message_metadata(plug_installation_id, message_id)
|
|
102
|
+
assert_requested_post_access_token(plug_installation_id)
|
|
103
|
+
assert_requested(:patch, "#{::YettoService::YETTO_API_VERSION_TLD}/messages/#{message_id}")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def stub_update_message_metadata(plug_installation_id, message_id, payload)
|
|
107
|
+
stub_post_access_token(plug_installation_id)
|
|
108
|
+
stub_request(:patch, "#{::YettoService::YETTO_API_VERSION_TLD}/messages/#{message_id}")
|
|
86
109
|
.with(
|
|
87
110
|
body: payload,
|
|
88
111
|
)
|
|
@@ -98,13 +121,9 @@ module Webmocks
|
|
|
98
121
|
assert_requested(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/inboxes/#{inbox_id}/switches")
|
|
99
122
|
end
|
|
100
123
|
|
|
101
|
-
def stub_create_inbox_switch(inbox_id, plug_installation_id,
|
|
124
|
+
def stub_create_inbox_switch(inbox_id, plug_installation_id, payload)
|
|
102
125
|
stub_post_access_token(plug_installation_id)
|
|
103
126
|
|
|
104
|
-
payload = {
|
|
105
|
-
name: "After install",
|
|
106
|
-
}
|
|
107
|
-
|
|
108
127
|
stub_request(:post, "#{::YettoService::YETTO_API_VERSION_TLD}/inboxes/#{inbox_id}/switches")
|
|
109
128
|
.with(
|
|
110
129
|
body: payload,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# fly.toml app configuration file generated for plug-app on 2023-05-05T07:11:14-04:00
|
|
2
1
|
#
|
|
3
2
|
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
|
|
4
3
|
#
|
|
@@ -7,32 +6,35 @@ app = "plug-app-production"
|
|
|
7
6
|
primary_region = "iad"
|
|
8
7
|
|
|
9
8
|
[env]
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
RAILS_ENV = "production"
|
|
10
|
+
LD_PRELOAD_PATH = "/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"
|
|
12
11
|
|
|
13
12
|
[processes]
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
web = "./bin/rails server"
|
|
14
|
+
worker = "bundle exec sidekiq"
|
|
16
15
|
|
|
17
16
|
[http_service]
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
internal_port = 3000
|
|
18
|
+
force_https = true
|
|
19
|
+
auto_stop_machines = true
|
|
20
|
+
auto_start_machines = true
|
|
21
|
+
min_machines_running = 1
|
|
22
|
+
processes = ["web"]
|
|
23
|
+
[http_service.concurrency]
|
|
24
|
+
type = "requests"
|
|
25
|
+
soft_limit = 200
|
|
26
|
+
hard_limit = 250
|
|
28
27
|
|
|
29
28
|
[checks]
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
[checks.alive]
|
|
30
|
+
type = "tcp"
|
|
31
|
+
interval = "15s"
|
|
32
|
+
timeout = "2s"
|
|
33
|
+
grace_period = "5s"
|
|
35
34
|
|
|
36
35
|
[[statics]]
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
guest_path = "/plug-app/public"
|
|
37
|
+
url_prefix = "/"
|
|
38
|
+
|
|
39
|
+
[deploy]
|
|
40
|
+
strategy = "bluegreen"
|
|
@@ -2,32 +2,35 @@ app = "plug-app-staging"
|
|
|
2
2
|
primary_region = "iad"
|
|
3
3
|
|
|
4
4
|
[env]
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
RAILS_ENV = "plug-app-staging"
|
|
6
|
+
LD_PRELOAD_PATH = "/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"
|
|
7
7
|
|
|
8
8
|
[processes]
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
web = "./bin/rails server"
|
|
10
|
+
worker = "bundle exec sidekiq"
|
|
11
11
|
|
|
12
12
|
[http_service]
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
internal_port = 3000
|
|
14
|
+
force_https = true
|
|
15
|
+
auto_stop_machines = true
|
|
16
|
+
auto_start_machines = true
|
|
17
|
+
min_machines_running = 0
|
|
18
|
+
processes = ["web"]
|
|
19
|
+
[http_service.concurrency]
|
|
20
|
+
type = "requests"
|
|
21
|
+
soft_limit = 200
|
|
22
|
+
hard_limit = 250
|
|
23
23
|
|
|
24
24
|
[checks]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
[checks.alive]
|
|
26
|
+
type = "tcp"
|
|
27
|
+
interval = "15s"
|
|
28
|
+
timeout = "2s"
|
|
29
|
+
grace_period = "5s"
|
|
30
30
|
|
|
31
31
|
[[statics]]
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
guest_path = "/plug-app/public"
|
|
33
|
+
url_prefix = "/"
|
|
34
|
+
|
|
35
|
+
[deploy]
|
|
36
|
+
strategy = "immediate"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hephaestus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Garen Torikian
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-10-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -171,6 +171,7 @@ files:
|
|
|
171
171
|
- templates/app/lib/plug_app/middleware/not_found.rb
|
|
172
172
|
- templates/app/lib/plug_app/middleware/openapi_validation.rb
|
|
173
173
|
- templates/app/lib/plug_app/middleware/tracing_attributes.rb
|
|
174
|
+
- templates/app/lib/plug_app/switches/message_created.jsonc
|
|
174
175
|
- templates/app/lib/query_parameter.rb
|
|
175
176
|
- templates/app/serializers/error_serializer.rb
|
|
176
177
|
- templates/app/services/http_service.rb
|
|
@@ -178,6 +179,7 @@ files:
|
|
|
178
179
|
- templates/app/views/settings/new.json.jbuilder
|
|
179
180
|
- templates/bin/docker-entrypoint
|
|
180
181
|
- templates/compose.yml
|
|
182
|
+
- templates/config/initializers/000-oj.rb
|
|
181
183
|
- templates/config/initializers/cors.rb
|
|
182
184
|
- templates/config/initializers/environment.rb
|
|
183
185
|
- templates/config/initializers/filter_parameter_logging.rb
|
|
@@ -197,8 +199,8 @@ files:
|
|
|
197
199
|
- templates/lib/plug_app/schemas/api/2023-03-06/components/schemas/yetto.json
|
|
198
200
|
- templates/lib/plug_app/schemas/api/2023-03-06/openapi.json
|
|
199
201
|
- templates/lib/plug_app/schemas/api/2023-03-06/paths/plug.json
|
|
200
|
-
- templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/
|
|
201
|
-
- templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/
|
|
202
|
+
- templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/message_created.json
|
|
203
|
+
- templates/lib/plug_app/schemas/api/2023-03-06/paths/yetto/plug_installation_created.json
|
|
202
204
|
- templates/lib/tasks/test_tasks.rake
|
|
203
205
|
- templates/script/ci
|
|
204
206
|
- templates/script/edit-credentials
|
|
@@ -214,6 +216,10 @@ files:
|
|
|
214
216
|
- templates/test/controllers/settings_controller_test.rb
|
|
215
217
|
- templates/test/controllers/yetto_controller_test.rb
|
|
216
218
|
- templates/test/fixtures/files/fake_pem_file/fake.pem
|
|
219
|
+
- templates/test/fixtures/files/plug_installation_settings/invalid.json
|
|
220
|
+
- templates/test/fixtures/files/plug_installation_settings/valid.json
|
|
221
|
+
- templates/test/fixtures/plug_installation_settings/invalid.json
|
|
222
|
+
- templates/test/fixtures/plug_installation_settings/valid.json
|
|
217
223
|
- templates/test/integration/.keep
|
|
218
224
|
- templates/test/jobs/update_yetto_job_test.rb
|
|
219
225
|
- templates/test/mailers/.keep
|
|
@@ -245,7 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
245
251
|
- !ruby/object:Gem::Version
|
|
246
252
|
version: 3.4.7
|
|
247
253
|
requirements: []
|
|
248
|
-
rubygems_version: 3.4.
|
|
254
|
+
rubygems_version: 3.4.20
|
|
249
255
|
signing_key:
|
|
250
256
|
specification_version: 4
|
|
251
257
|
summary: Generate a Rails app that can be used to create plugs for Yetto.
|