hephaestus 0.8.11 → 0.8.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +6 -0
- data/README.md +3 -1
- data/bin/hephaestus +31 -13
- data/lib/hephaestus/app_builder.rb +23 -145
- data/lib/hephaestus/app_name.rb +33 -0
- data/lib/hephaestus/generators/app_generator.rb +70 -72
- data/lib/hephaestus/generators/config_generator.rb +3 -114
- data/lib/hephaestus/generators/core_generator.rb +18 -58
- data/lib/hephaestus/generators/db_generator.rb +12 -0
- data/lib/hephaestus/generators/deployment_generator.rb +1 -6
- data/lib/hephaestus/generators/lib_generator.rb +0 -10
- data/lib/hephaestus/generators/license_generator.rb +4 -1
- data/lib/hephaestus/generators/rubocop_generator.rb +1 -1
- data/lib/hephaestus/version.rb +1 -1
- data/lib/hephaestus.rb +2 -0
- data/templates/Dockerfile +7 -75
- data/templates/Gemfile +73 -0
- data/templates/Procfile +2 -0
- data/templates/app/controllers/app_controller.rb.tt +35 -0
- data/templates/app/controllers/application_controller.rb +1 -7
- data/templates/app/controllers/concerns/authable.rb.tt +50 -0
- data/templates/app/controllers/settings_controller.rb +5 -28
- data/templates/app/controllers/yetto_controller.rb +9 -10
- data/templates/app/lib/body_parameter/yetto_parameters.rb +8 -29
- data/templates/app/lib/{constants/app.rb → constants.rb} +1 -3
- data/templates/app/services/{http_service.rb → app_service.rb.tt} +6 -6
- data/templates/app/views/settings/new.json.jbuilder.tt +18 -0
- data/templates/bin/bundle +115 -0
- data/templates/bin/docker-entrypoint +20 -10
- data/templates/bin/foreman +27 -0
- data/templates/bin/jobs +7 -0
- data/templates/bin/rails +6 -0
- data/templates/bin/rake +6 -0
- data/templates/bin/setup +28 -0
- data/templates/bin/tapioca +27 -0
- data/templates/config/application.rb.tt +36 -0
- data/templates/config/boot.rb +7 -0
- data/templates/config/environment.rb +8 -0
- data/templates/config/environments/blank.rb +7 -0
- data/templates/config/initializers/environment.rb +2 -36
- data/templates/config/locales/en.yml +5 -31
- data/templates/config/puma.rb +5 -0
- data/templates/config/routes.rb.tt +28 -0
- data/templates/config.ru +9 -0
- data/templates/db/queue_schema.rb +132 -0
- data/templates/db/schema.rb +17 -0
- data/templates/lib/schemas/api/2023-03-06/components/parameters/headers/yetto.json +42 -0
- data/templates/lib/schemas/api/2023-03-06/components/parameters/plugInstallation.json +12 -0
- data/templates/lib/schemas/api/2023-03-06/components/schemas/plug.json +9 -0
- data/templates/lib/schemas/api/2023-03-06/components/schemas/responses.json +64 -0
- data/templates/lib/schemas/api/2023-03-06/components/schemas/yetto.json +116 -0
- data/templates/lib/schemas/api/2023-03-06/openapi.json +30 -0
- data/templates/lib/schemas/api/2023-03-06/paths/app.json +90 -0
- data/templates/lib/schemas/api/2023-03-06/paths/yetto/message_created.json +51 -0
- data/templates/lib/schemas/api/2023-03-06/paths/yetto/plug_installation_created.json +51 -0
- data/templates/script/docker-build-prod.tt +11 -0
- data/templates/script/docker-run.tt +8 -0
- data/templates/script/edit-credentials +12 -3
- data/templates/script/hmac_text +1 -1
- data/templates/script/ngrok.tt +7 -0
- data/templates/script/server +6 -45
- data/templates/test/controllers/app_controller_test.rb.tt +188 -0
- data/templates/test/controllers/settings_controller_test.rb.tt +125 -0
- data/templates/test/controllers/yetto_controller_test.rb +100 -71
- data/templates/test/fixtures/files/plug_installation_settings/valid.json +1 -1
- data/templates/test/support/rails.rb +16 -36
- data/templates/test/support/webmocks/app_webmock.rb.tt +29 -0
- data/templates/test/test_helper.rb +1 -31
- data/templates/vendor/fly/{fly-production.toml → fly-production.toml.tt} +24 -11
- data/templates/vendor/fly/{fly-staging.toml → fly-staging.toml.tt} +18 -15
- metadata +46 -71
- data/templates/Gemfile.erb +0 -120
- data/templates/Procfile.debug +0 -2
- data/templates/Procfile.dev +0 -2
- data/templates/app/controllers/app_controller.rb +0 -72
- data/templates/app/controllers/concerns/authable.rb +0 -50
- data/templates/app/controllers/staff_controller.rb +0 -15
- data/templates/app/jobs/update_yetto_job.rb +0 -26
- data/templates/app/lib/headers/yetto.rb +0 -19
- data/templates/app/lib/headers.rb +0 -5
- data/templates/app/lib/path_parameter/settings_parameters.rb +0 -22
- data/templates/app/lib/path_parameter/yetto_parameters.rb +0 -28
- data/templates/app/lib/path_parameter.rb +0 -8
- data/templates/app/lib/plug_app/http.rb +0 -37
- data/templates/app/lib/plug_app/middleware/malformed_request.rb +0 -110
- data/templates/app/lib/plug_app/middleware/openapi_validation.rb +0 -83
- data/templates/app/lib/plug_app/middleware/tracing_attributes.rb +0 -46
- data/templates/app/lib/query_parameter.rb +0 -6
- data/templates/app/serializers/error_serializer.rb +0 -16
- data/templates/app/services/yetto_service.rb +0 -51
- data/templates/app/views/settings/new.json.jbuilder +0 -21
- data/templates/compose.yml +0 -5
- data/templates/config/initializers/000-oj.rb +0 -6
- data/templates/config/initializers/cors.rb +0 -19
- data/templates/config/initializers/filter_parameter_logging.rb +0 -25
- data/templates/config/initializers/inflections.rb +0 -20
- data/templates/config/initializers/lograge.rb +0 -25
- data/templates/config/initializers/opentelemetry.rb +0 -32
- data/templates/config/initializers/sidekiq.rb +0 -11
- data/templates/config/initializers/slack_webhook_logger.rb +0 -17
- data/templates/config/sidekiq.yml +0 -20
- data/templates/script/ngrok +0 -5
- data/templates/test/controllers/settings_controller_test.rb +0 -27
- data/templates/test/fixtures/plug_installation_settings/invalid.json +0 -3
- data/templates/test/fixtures/plug_installation_settings/valid.json +0 -3
- data/templates/test/jobs/update_yetto_job_test.rb +0 -26
- data/templates/test/support/api.rb +0 -76
- data/templates/test/support/webmocks/slack_webmock.rb +0 -24
- data/templates/test/support/webmocks/yetto_webmock.rb +0 -119
- data/templates/test/support/webmocks.rb +0 -5
@@ -5,121 +5,10 @@ require_relative "base"
|
|
5
5
|
|
6
6
|
module Hephaestus
|
7
7
|
class ConfigGenerator < Generators::Base
|
8
|
-
|
9
|
-
config = <<~CONFIG
|
8
|
+
include Hephaestus::AppName
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
require "debug/open_nonstop"
|
14
|
-
end
|
15
|
-
|
16
|
-
CONFIG
|
17
|
-
|
18
|
-
inject_into_file(
|
19
|
-
"config/application.rb",
|
20
|
-
config,
|
21
|
-
after: "require \"rails/test_unit/railtie\"",
|
22
|
-
)
|
23
|
-
inject_into_file(
|
24
|
-
"config/application.rb",
|
25
|
-
"\n CURRENT_VERSION = \"2023-03-06\"\n\n",
|
26
|
-
before: "class Application < Rails::Application",
|
27
|
-
)
|
28
|
-
|
29
|
-
raltie_overload = <<~CONFIG
|
30
|
-
|
31
|
-
# Load dotenv only in development environment
|
32
|
-
Dotenv::Rails.overwrite = true if Rails.env.development?
|
33
|
-
CONFIG
|
34
|
-
inject_into_file(
|
35
|
-
"config/application.rb",
|
36
|
-
raltie_overload,
|
37
|
-
after: "Bundler.require(*Rails.groups)",
|
38
|
-
)
|
39
|
-
|
40
|
-
config = <<~CONFIG
|
41
|
-
|
42
|
-
# Only loads a smaller set of middleware suitable for API-only Rails.
|
43
|
-
# Middleware like session, flash, cookies can be added back manually.
|
44
|
-
# Skip views, helpers and assets when generating a new resource.
|
45
|
-
config.api_only = true
|
46
|
-
|
47
|
-
Rails.root.glob("app/lib/#{app_name.underscore}/middleware/*.{rb}").each { |file| require_relative file }
|
48
|
-
|
49
|
-
config.middleware.insert(0, PlugApp::Middleware::TracingAttributes)
|
50
|
-
config.middleware.insert(0, PlugApp::Middleware::MalformedRequest)
|
51
|
-
|
52
|
-
config.middleware.use(PlugApp::Middleware::OpenapiValidation)
|
53
|
-
|
54
|
-
GIT_SHA = %x(git rev-parse HEAD).chomp
|
55
|
-
CONFIG
|
56
|
-
|
57
|
-
inject_into_file(
|
58
|
-
"config/application.rb",
|
59
|
-
config,
|
60
|
-
before: "\n end",
|
61
|
-
)
|
62
|
-
|
63
|
-
replace_in_file(
|
64
|
-
"config/application.rb",
|
65
|
-
"require \"rails\"\n",
|
66
|
-
"",
|
67
|
-
)
|
68
|
-
|
69
|
-
comment_lines("config/application.rb", "require \"active_model/railtie\"")
|
70
|
-
uncomment_lines("config/application.rb", "require \"active_job/railtie\"")
|
71
|
-
end
|
72
|
-
|
73
|
-
def boot
|
74
|
-
boot = "require \"bootsnap/setup\" # Speed up boot time by caching expensive operations."
|
75
|
-
inject_into_file(
|
76
|
-
"config/boot.rb",
|
77
|
-
boot,
|
78
|
-
)
|
79
|
-
end
|
80
|
-
|
81
|
-
def initializers
|
82
|
-
remove_dir("config/initializers")
|
83
|
-
directory("config/initializers", "config/initializers")
|
84
|
-
end
|
85
|
-
|
86
|
-
def configure_routes
|
87
|
-
routes = <<~ROUTES
|
88
|
-
root "root#index"
|
89
|
-
|
90
|
-
# events into the plug, usually from yetto
|
91
|
-
get "/api/2023-03-06/settings", to: "settings#new"
|
92
|
-
post "/api/2023-03-06/:record_type/:event", to: "yetto#event"
|
93
|
-
|
94
|
-
# inbound message
|
95
|
-
post "/$app/2023-03-06/webhook/inbound", to: "app#webhook"
|
96
|
-
|
97
|
-
# Staff pages
|
98
|
-
get "staff", to: "staff#index"
|
99
|
-
require "sidekiq/web"
|
100
|
-
constraints ->(request) { StaffController.staff_request?(request) } do
|
101
|
-
mount Sidekiq::Web => "staff/sidekiq"
|
102
|
-
end
|
103
|
-
|
104
|
-
#############################################
|
105
|
-
# error pages -- these MUST be at the end! ##
|
106
|
-
#############################################
|
107
|
-
|
108
|
-
get "/500", to: "application#render500" if Rails.env.production? || Rails.env.staging?
|
109
|
-
|
110
|
-
match "/", to: "application#not_found", via: :all
|
111
|
-
match "/*unmatched_route", to: "application#not_found", via: :all
|
112
|
-
ROUTES
|
113
|
-
|
114
|
-
replace_in_file(
|
115
|
-
"config/routes.rb",
|
116
|
-
"# root \"articles#index\"",
|
117
|
-
routes,
|
118
|
-
)
|
119
|
-
end
|
120
|
-
|
121
|
-
def sidekiq
|
122
|
-
copy_file("config/sidekiq.yml", "config/sidekiq.yml")
|
10
|
+
def config_application
|
11
|
+
directory("config", "config", force: true, exclude_pattern: /blank.rb/)
|
123
12
|
end
|
124
13
|
|
125
14
|
def credentials
|
@@ -1,78 +1,38 @@
|
|
1
1
|
# typed: false
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require_relative "base"
|
4
|
+
# require_relative "base"
|
5
5
|
|
6
6
|
module Hephaestus
|
7
7
|
class CoreGenerator < Generators::Base
|
8
|
-
|
9
|
-
remove_file("app/controllers/application_controller.rb")
|
10
|
-
copy_file("app/controllers/application_controller.rb", "app/controllers/application_controller.rb")
|
11
|
-
|
12
|
-
copy_file("app/controllers/root_controller.rb", "app/controllers/root_controller.rb")
|
13
|
-
copy_file("app/controllers/settings_controller.rb", "app/controllers/settings_controller.rb")
|
14
|
-
copy_file("app/controllers/staff_controller.rb", "app/controllers/staff_controller.rb")
|
15
|
-
copy_file("app/controllers/yetto_controller.rb", "app/controllers/yetto_controller.rb")
|
16
|
-
copy_file("app/controllers/app_controller.rb", "app/controllers/#{short_app_name}_controller.rb")
|
17
|
-
|
18
|
-
copy_file("app/controllers/concerns/authable.rb", "app/controllers/concerns/authable.rb")
|
19
|
-
end
|
8
|
+
include Hephaestus::AppName
|
20
9
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
10
|
+
def gemfile
|
11
|
+
# we do this to specify the template source, otherwise the generator wants to use Rails own `controllers` dir
|
12
|
+
source = File.join(Hephaestus::Engine.root, "templates", "Gemfile")
|
13
|
+
copy_file(source, "Gemfile", force: true)
|
24
14
|
end
|
25
15
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
path_parameters_content = <<~CONTENT
|
32
|
-
# typed: false
|
33
|
-
# frozen_string_literal: true
|
34
|
-
|
35
|
-
module PathParameter
|
36
|
-
module AppParameters
|
37
|
-
extend T::Sig
|
38
|
-
end
|
39
|
-
end
|
40
|
-
CONTENT
|
41
|
-
|
42
|
-
create_file("app/lib/path_parameter/#{short_app_name}_parameters.rb", path_parameters_content)
|
43
|
-
|
44
|
-
body_parameters_content = <<~CONTENT
|
45
|
-
# typed: false
|
46
|
-
# frozen_string_literal: true
|
47
|
-
|
48
|
-
module BodyParameter
|
49
|
-
module AppParameters
|
50
|
-
extend T::Sig
|
51
|
-
end
|
52
|
-
end
|
53
|
-
CONTENT
|
54
|
-
|
55
|
-
create_file("app/lib/body_parameter/#{short_app_name}_parameters.rb", body_parameters_content)
|
56
|
-
|
57
|
-
copy_file("app/lib/path_parameter/settings_parameters.rb", "app/lib/path_parameter/settings_parameters.rb")
|
58
|
-
copy_file("app/lib/path_parameter/yetto_parameters.rb", "app/lib/path_parameter/yetto_parameters.rb")
|
59
|
-
directory("app/lib/plug_app", "app/lib/#{app_name.underscore}")
|
60
|
-
|
61
|
-
copy_file("app/lib/body_parameter.rb", "app/lib/body_parameter.rb")
|
62
|
-
copy_file("app/lib/headers.rb", "app/lib/headers.rb")
|
63
|
-
copy_file("app/lib/path_parameter.rb", "app/lib/path_parameter.rb")
|
16
|
+
def controllers
|
17
|
+
# we do this to specify the template source, otherwise the generator wants to use Rails own `controllers` dir
|
18
|
+
source = File.join(Hephaestus::Engine.root, "templates", "app", "controllers")
|
19
|
+
directory(source, "app/controllers", force: true)
|
64
20
|
end
|
65
21
|
|
66
|
-
def
|
67
|
-
|
22
|
+
def jobs
|
23
|
+
# we do this to specify the template source, otherwise the generator wants to use Rails own `jobs` dir
|
24
|
+
source = File.join(Hephaestus::Engine.root, "templates", "app", "jobs")
|
25
|
+
directory(source, "app/jobs", force: true)
|
68
26
|
end
|
69
27
|
|
70
28
|
def services
|
71
|
-
|
29
|
+
source = File.join(Hephaestus::Engine.root, "templates", "app", "services")
|
30
|
+
directory(source, "app/services", force: true)
|
72
31
|
end
|
73
32
|
|
74
33
|
def views
|
75
|
-
|
34
|
+
source = File.join(Hephaestus::Engine.root, "templates", "app", "views")
|
35
|
+
directory(source, "app/views", force: true)
|
76
36
|
end
|
77
37
|
end
|
78
38
|
end
|
@@ -6,8 +6,7 @@ require_relative "base"
|
|
6
6
|
module Hephaestus
|
7
7
|
class DeploymentGenerator < Generators::Base
|
8
8
|
def procfile
|
9
|
-
copy_file("Procfile
|
10
|
-
copy_file("Procfile.debug", "Procfile.debug")
|
9
|
+
copy_file("Procfile", "Procfile")
|
11
10
|
end
|
12
11
|
|
13
12
|
def dotenv
|
@@ -16,15 +15,11 @@ module Hephaestus
|
|
16
15
|
end
|
17
16
|
|
18
17
|
def docker
|
19
|
-
copy_file("compose.yml", "compose.yml")
|
20
18
|
copy_file("Dockerfile", "Dockerfile")
|
21
|
-
copy_file("bin/docker-entrypoint", "bin/docker-entrypoint")
|
22
19
|
end
|
23
20
|
|
24
21
|
def fly
|
25
22
|
directory("vendor/fly", "vendor/fly")
|
26
|
-
copy_file("Dockerfile", "Dockerfile")
|
27
|
-
copy_file("bin/docker-entrypoint", "bin/docker-entrypoint")
|
28
23
|
end
|
29
24
|
end
|
30
25
|
end
|
@@ -5,18 +5,8 @@ require_relative "base"
|
|
5
5
|
|
6
6
|
module Hephaestus
|
7
7
|
class LibGenerator < Generators::Base
|
8
|
-
def lib_plug
|
9
|
-
directory("lib/plug_app", "lib/#{app_name.underscore}")
|
10
|
-
remove_file("lib/constants/plug-#{short_app_name}.rb")
|
11
|
-
end
|
12
|
-
|
13
8
|
def lib_tasks
|
14
9
|
directory("lib/tasks", "lib/tasks")
|
15
10
|
end
|
16
|
-
|
17
|
-
def plug_schema
|
18
|
-
copy_file("lib/plug_app/schemas/api/2023-03-06/paths/plug.json", "lib/#{app_name.underscore}/schemas/api/2023-03-06/paths/#{short_app_name.underscore}.json")
|
19
|
-
remove_file("lib/#{app_name.underscore}/schemas/api/2023-03-06/paths/plug.json") # cleanup
|
20
|
-
end
|
21
11
|
end
|
22
12
|
end
|
@@ -10,7 +10,10 @@ module Hephaestus
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def generate_licenses
|
13
|
-
run("script/licenses --update")
|
13
|
+
unless run("script/licenses --update", abort_on_failure: false)
|
14
|
+
say(set_color("Error generating licenses. When this is all over, run `script/licenses --update`.", :red))
|
15
|
+
sleep(3)
|
16
|
+
end
|
14
17
|
end
|
15
18
|
end
|
16
19
|
end
|
data/lib/hephaestus/version.rb
CHANGED
data/lib/hephaestus.rb
CHANGED
@@ -16,6 +16,7 @@ require "hephaestus/exit_on_failure"
|
|
16
16
|
require "hephaestus/generators/app_generator"
|
17
17
|
require "hephaestus/generators/config_generator"
|
18
18
|
require "hephaestus/generators/core_generator"
|
19
|
+
require "hephaestus/generators/db_generator"
|
19
20
|
require "hephaestus/generators/deployment_generator"
|
20
21
|
require "hephaestus/generators/lib_generator"
|
21
22
|
require "hephaestus/generators/license_generator"
|
@@ -23,6 +24,7 @@ require "hephaestus/generators/rubocop_generator"
|
|
23
24
|
require "hephaestus/generators/sorbet_generator"
|
24
25
|
|
25
26
|
require "hephaestus/actions"
|
27
|
+
require "hephaestus/app_name"
|
26
28
|
require "hephaestus/actions/strip_comments_action"
|
27
29
|
require "hephaestus/app_builder"
|
28
30
|
|
data/templates/Dockerfile
CHANGED
@@ -1,79 +1,11 @@
|
|
1
|
-
# syntax = docker/dockerfile:1
|
1
|
+
# syntax = docker/dockerfile:1.11
|
2
2
|
|
3
|
-
|
4
|
-
ARG RUBY_VERSION=3.3.0
|
5
|
-
FROM ruby:$RUBY_VERSION-slim as base
|
3
|
+
ARG REGISTRY
|
6
4
|
|
7
|
-
#
|
8
|
-
|
5
|
+
# Base Rails Image
|
6
|
+
FROM ${REGISTRY}yettoapp/base-rails:main AS builder
|
9
7
|
|
10
|
-
#
|
11
|
-
|
12
|
-
ENV RAILS_ENV=${RAILS_ENV} \
|
13
|
-
BUNDLE_WITHOUT="staging:development:test" \
|
14
|
-
BUNDLE_DEPLOYMENT="1"
|
8
|
+
# App Plug Image
|
9
|
+
FROM ${REGISTRY}yettoapp/app-plug-ruby:main AS base
|
15
10
|
|
16
|
-
|
17
|
-
RUN gem update --system --no-document && \
|
18
|
-
gem install -N bundler
|
19
|
-
|
20
|
-
|
21
|
-
# Throw-away build stages to reduce size of final image
|
22
|
-
FROM base as prebuild
|
23
|
-
|
24
|
-
# Install packages needed to build gems
|
25
|
-
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
|
26
|
-
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
|
27
|
-
apt-get update -qq && \
|
28
|
-
apt-get install --no-install-recommends -y build-essential curl git libpq-dev libvips pkg-config python-is-python3 ca-certificates iptables iproute2
|
29
|
-
|
30
|
-
|
31
|
-
FROM prebuild as build
|
32
|
-
|
33
|
-
# Install application gems
|
34
|
-
COPY --link Gemfile Gemfile.lock .ruby-version ./
|
35
|
-
RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
|
36
|
-
bundle config set app_config .bundle && \
|
37
|
-
bundle config set path /srv/vendor && \
|
38
|
-
bundle install && \
|
39
|
-
bundle exec bootsnap precompile --gemfile && \
|
40
|
-
bundle clean && \
|
41
|
-
mkdir -p vendor && \
|
42
|
-
bundle config set path vendor && \
|
43
|
-
cp -ar /srv/vendor .
|
44
|
-
|
45
|
-
# Copy application code
|
46
|
-
COPY --link . .
|
47
|
-
|
48
|
-
# Precompile bootsnap code for faster boot times
|
49
|
-
RUN bundle exec bootsnap precompile app/ lib/
|
50
|
-
|
51
|
-
# Adjust binfiles to set current working directory
|
52
|
-
RUN grep -l '#!/usr/bin/env ruby' /plug-app/bin/* | xargs sed -i '/^#!/aDir.chdir File.expand_path("..", __dir__)'
|
53
|
-
|
54
|
-
# Final stage for app image
|
55
|
-
FROM base
|
56
|
-
|
57
|
-
# Install packages needed for deployment
|
58
|
-
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
|
59
|
-
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
|
60
|
-
apt-get update -qq && \
|
61
|
-
apt-get install --no-install-recommends -y imagemagick libvips postgresql-client sudo git
|
62
|
-
|
63
|
-
# Copy built artifacts: gems, application
|
64
|
-
COPY --from=build /usr/local/bundle /usr/local/bundle
|
65
|
-
COPY --from=build /plug-app /plug-app
|
66
|
-
|
67
|
-
# Deployment options
|
68
|
-
ENV RAILS_LOG_TO_STDOUT="1" \
|
69
|
-
RAILS_SERVE_STATIC_FILES="true" \
|
70
|
-
RUBY_YJIT_ENABLE="1" \
|
71
|
-
LD_PRELOAD=${LD_PRELOAD_PATH} \
|
72
|
-
MALLOC_CONF="dirty_decay_ms:1000,narenas:2,background_thread:true"
|
73
|
-
|
74
|
-
# Entrypoint sets up the container.
|
75
|
-
ENTRYPOINT ["/plug-app/bin/docker-entrypoint"]
|
76
|
-
|
77
|
-
# Start the server by default, this can be overwritten at runtime
|
78
|
-
EXPOSE 3000
|
79
|
-
CMD ["./bin/rails", "server"]
|
11
|
+
USER app
|
data/templates/Gemfile
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
git_source(:github) do |repo_name|
|
6
|
+
repo_name = "#{repo_name}/#{repo_name}" if repo_name.exclude?("/")
|
7
|
+
"https://github.com/#{repo_name}.git"
|
8
|
+
end
|
9
|
+
|
10
|
+
ruby File.read(".ruby-version").strip
|
11
|
+
|
12
|
+
gem "hephaestus", "~> 0.8"
|
13
|
+
|
14
|
+
# !!! TODO: put your platform's dependencies here !!!
|
15
|
+
|
16
|
+
# the one and only
|
17
|
+
gem "octokit", "~> 9.1"
|
18
|
+
gem "faraday-retry", "~> 2.2"
|
19
|
+
|
20
|
+
group :development, :test do
|
21
|
+
# better debug output with `ap`
|
22
|
+
gem "amazing_print"
|
23
|
+
|
24
|
+
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
|
25
|
+
gem "debug", platforms: [:mri, :mingw, :x64_mingw], require: false
|
26
|
+
|
27
|
+
gem "faker", "~> 3.4"
|
28
|
+
gem "rubocop", require: false
|
29
|
+
gem "rubocop-standard", require: false
|
30
|
+
end
|
31
|
+
|
32
|
+
group :development do
|
33
|
+
gem "dotenv-rails"
|
34
|
+
|
35
|
+
gem "foreman", "~> 0.88"
|
36
|
+
|
37
|
+
gem "licensed", "~> 4.4"
|
38
|
+
|
39
|
+
gem "ruby-lsp", "~> 0.17", require: false
|
40
|
+
|
41
|
+
gem "spoom"
|
42
|
+
gem "sorbet"
|
43
|
+
gem "tapioca", require: false
|
44
|
+
end
|
45
|
+
gem "sorbet-runtime"
|
46
|
+
|
47
|
+
group :test do
|
48
|
+
gem "simplecov", "~> 0.18", require: false
|
49
|
+
gem "simplecov-console", "~> 0.7", require: false
|
50
|
+
|
51
|
+
# track down flakey tests
|
52
|
+
gem "minitest-bisect"
|
53
|
+
|
54
|
+
# mocking lib
|
55
|
+
gem "mocha"
|
56
|
+
|
57
|
+
# allow easier middleware testing
|
58
|
+
gem "rack-test", "~> 2.0"
|
59
|
+
|
60
|
+
# navigate website
|
61
|
+
gem "selenium-webdriver"
|
62
|
+
|
63
|
+
# jump around through time
|
64
|
+
gem "timecop", "~> 0.9"
|
65
|
+
|
66
|
+
# prevents real http requests
|
67
|
+
gem "webmock", "~> 3.23"
|
68
|
+
end
|
69
|
+
|
70
|
+
group :ci do
|
71
|
+
gem "brakeman", "~> 6.1"
|
72
|
+
gem "bundle-audit", "~> 0.1"
|
73
|
+
end
|
data/templates/Procfile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
class <%= capital_plug_name %>Controller < ApplicationController
|
5
|
+
include Authable
|
6
|
+
|
7
|
+
include Constants
|
8
|
+
|
9
|
+
before_action :webhook_from_<%= plug_name %>?, only: [:webhook]
|
10
|
+
before_action :<%= plug_name %>_calling_back?, only: [:callback]
|
11
|
+
|
12
|
+
def webhook
|
13
|
+
body = request.body.read
|
14
|
+
|
15
|
+
payload = JSON.parse(body, symbolize_names: true)
|
16
|
+
# TODO: Get the event and action that triggered the webhook
|
17
|
+
#
|
18
|
+
# Then, queue up some work to be done in a background job
|
19
|
+
|
20
|
+
okay
|
21
|
+
end
|
22
|
+
|
23
|
+
def callback
|
24
|
+
code = params[:code]
|
25
|
+
state = params[:state]
|
26
|
+
|
27
|
+
state_obj = parse_state(state)
|
28
|
+
plug_installation_id = state_obj.fetch(:plug_installation_id, "")
|
29
|
+
redirect_to = state_obj.fetch(:redirect_to, "")
|
30
|
+
|
31
|
+
# TODO: Store access credentials you've been given back in Yetto
|
32
|
+
|
33
|
+
redirect_to(redirect_to, allow_other_host: true)
|
34
|
+
end
|
35
|
+
end
|
@@ -1,13 +1,7 @@
|
|
1
1
|
# typed: false
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
class ApplicationController <
|
5
|
-
include ActionController::MimeResponds
|
6
|
-
|
7
|
-
include Hephaestus::Responses
|
8
|
-
|
9
|
-
rescue_from ActionController::UnknownFormat, with: :not_acceptable
|
10
|
-
|
4
|
+
class ApplicationController < Hephaestus::ApplicationController
|
11
5
|
before_action :set_request_span_context
|
12
6
|
def set_request_span_context
|
13
7
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Authable
|
5
|
+
extend T::Sig
|
6
|
+
|
7
|
+
include ActionDispatch::Http::Cache::Response
|
8
|
+
|
9
|
+
include ActionController::Helpers::ClassMethods
|
10
|
+
include ActionController::HttpAuthentication::Basic::ControllerMethods
|
11
|
+
include BodyParameter::YettoParameters
|
12
|
+
|
13
|
+
SHA256_DIGEST = OpenSSL::Digest.new("sha256")
|
14
|
+
|
15
|
+
sig { void }
|
16
|
+
def <%= plug_name %>_calling_back?
|
17
|
+
state = params.fetch(:state, "")
|
18
|
+
state = params.fetch(:state, "")
|
19
|
+
|
20
|
+
state_obj = parse_state(state)
|
21
|
+
nonce = state_obj.fetch(:nonce, "")
|
22
|
+
|
23
|
+
return true if ActiveSupport::SecurityUtils.secure_compare(nonce, <%= upcase_plug_name %>_APP_NONCE)
|
24
|
+
|
25
|
+
self.status = Hephaestus::HTTP::BAD_REQUEST_I
|
26
|
+
self.response_body = ::Hephaestus::ErrorSerializer.format(Hephaestus::HTTP::BAD_REQUEST)
|
27
|
+
end
|
28
|
+
|
29
|
+
sig { void }
|
30
|
+
def webhook_from_<%= plug_name %>?
|
31
|
+
# TODO: do whatever needs to be done to ensure that the webhook is coming from <%= plug_name %>
|
32
|
+
|
33
|
+
# github_header = request.headers[::Constants::GITHUB_HTTP_X_HUB_SIGNATURE_256_HEADER]
|
34
|
+
|
35
|
+
# if github_header.blank?
|
36
|
+
# self.status = Hephaestus::HTTP::NOT_FOUND_I
|
37
|
+
# self.response_body = ::Hephaestus::ErrorSerializer.format(Hephaestus::HTTP::NOT_FOUND)
|
38
|
+
|
39
|
+
# return false
|
40
|
+
# end
|
41
|
+
|
42
|
+
# body = request.body.read
|
43
|
+
# signature = "sha256=#{OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), GITHUB_SECRET_TOKEN, body)}"
|
44
|
+
|
45
|
+
# return true if Rack::Utils.secure_compare(signature, github_header)
|
46
|
+
|
47
|
+
# self.status = Hephaestus::HTTP::BAD_REQUEST_I
|
48
|
+
# self.response_body = ::Hephaestus::ErrorSerializer.format(Hephaestus::HTTP::BAD_REQUEST)
|
49
|
+
end
|
50
|
+
end
|
@@ -1,45 +1,22 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: false
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
class SettingsController < ApplicationController
|
5
5
|
extend T::Sig
|
6
6
|
|
7
|
-
include PathParameter::SettingsParameters
|
8
|
-
|
9
7
|
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
|
-
|
17
|
-
sig { void }
|
18
|
-
def new
|
19
|
-
@step = T.let(params.fetch(:step, 1).to_i || 1, T.nilable(Integer))
|
20
|
-
end
|
21
8
|
|
22
9
|
sig { void }
|
23
10
|
def edit
|
24
11
|
@step = params.fetch(:step, 1).to_i || 1
|
25
12
|
|
26
|
-
|
13
|
+
plug_installation_id = params[:plug_installation_id]
|
14
|
+
response = ::Hephaestus::YettoService.get_plug_installation(plug_installation_id)
|
27
15
|
|
28
16
|
if response.unavailable?
|
29
|
-
logger.error("Fetching
|
30
|
-
|
31
|
-
return not_acceptable
|
32
|
-
end
|
17
|
+
logger.error("Fetching plug installation failed: `#{response}`")
|
33
18
|
|
34
|
-
|
35
|
-
access_token = plug_installation.fetch("credentials", {}).fetch("access_token", "")
|
36
|
-
|
37
|
-
if access_token.blank?
|
38
|
-
logger.error("Fetching Yetto access_token failed: `#{response}`")
|
39
|
-
|
40
|
-
return not_acceptable
|
19
|
+
not_acceptable
|
41
20
|
end
|
42
|
-
|
43
|
-
not_found
|
44
21
|
end
|
45
22
|
end
|