modulorails 1.5.2.pre.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -1
- data/CHANGELOG.md +40 -7
- data/README.md +69 -9
- data/lib/generators/modulorails/claude_code/claude_code_generator.rb +64 -0
- data/lib/generators/modulorails/claude_code/templates/.gitlab-ci.yml.tt +120 -0
- data/lib/generators/modulorails/claude_code/templates/.modulorails-gitlab-ci +6 -0
- data/lib/generators/modulorails/claude_code/templates/bin/init-firewall.sh.tt +118 -0
- data/lib/generators/modulorails/docker/compose/compose_generator.rb +7 -6
- data/lib/generators/modulorails/docker/config/config_generator.rb +11 -5
- data/lib/generators/modulorails/docker/config/templates/config/database.yml.tt +7 -2
- data/lib/generators/modulorails/docker/devcontainer/devcontainer_generator.rb +52 -0
- data/lib/generators/modulorails/docker/devcontainer/templates/devcontainer/Dockerfile.tt +53 -0
- data/lib/generators/modulorails/docker/devcontainer/templates/devcontainer/compose.yml.tt +97 -0
- data/lib/generators/modulorails/docker/devcontainer/templates/devcontainer/devcontainer.json.tt +80 -0
- data/lib/generators/modulorails/docker/docker_generator.rb +7 -0
- data/lib/generators/modulorails/docker/dockerfile/dockerfile_generator.rb +15 -11
- data/lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/{rails/Dockerfile.prod.tt → Dockerfile.prod.tt} +31 -12
- data/lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/dockerignore.tt +120 -0
- data/lib/generators/modulorails/docker/entrypoint/entrypoint_generator.rb +11 -5
- data/lib/generators/modulorails/docker/entrypoint/templates/entrypoints/docker-entrypoint.sh.tt +5 -0
- data/lib/generators/modulorails/githooks/githooks_generator.rb +5 -3
- data/lib/generators/modulorails/githooks/templates/dc.sh +30 -0
- data/lib/generators/modulorails/githooks/templates/dcr.sh +47 -0
- data/lib/generators/modulorails/githooks/templates/post-rewrite.sh +1 -1
- data/lib/generators/modulorails/githooks/templates/pre-merge-commit.sh +1 -1
- data/lib/generators/modulorails/githooks/templates/refresh_generations.sh +17 -9
- data/lib/generators/modulorails/gitlabci/gitlabci_generator.rb +7 -1
- data/lib/generators/modulorails/gitlabci/templates/.gitlab-ci.yml.tt +15 -13
- data/lib/generators/modulorails/gitlabci/templates/bin/test.sh.tt +36 -0
- data/lib/generators/modulorails/gitlabci/templates/config/deploy/production.yaml.tt +4 -4
- data/lib/generators/modulorails/gitlabci/templates/config/deploy/review.yaml.tt +4 -4
- data/lib/generators/modulorails/gitlabci/templates/config/deploy/staging.yaml.tt +7 -7
- data/lib/generators/modulorails/moduloproject/moduloproject_generator.rb +8 -3
- data/lib/generators/modulorails/moduloproject/templates/config/environments/production.rb.tt +21 -51
- data/lib/generators/modulorails/rubocop/templates/rubocop.yml.tt +7 -1
- data/lib/generators/modulorails/self_update/self_update_generator.rb +4 -0
- data/lib/generators/modulorails/sidekiq/sidekiq_generator.rb +95 -38
- data/lib/generators/modulorails/sidekiq/templates/config/initializers/sidekiq.rb.tt +4 -4
- data/lib/modulorails/configuration.rb +17 -7
- data/lib/modulorails/data.rb +39 -12
- data/lib/modulorails/generators/base.rb +1 -1
- data/lib/modulorails/railtie.rb +7 -0
- data/lib/modulorails/services/base_service.rb +1 -1
- data/lib/modulorails/services/logs_for_method_service.rb +1 -1
- data/lib/modulorails/version.rb +1 -1
- data/lib/modulorails.rb +13 -0
- metadata +16 -13
- data/lib/generators/modulorails/docker/compose/templates/docker-compose.yml.tt +0 -81
- data/lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/modulotech/Dockerfile.prod.tt +0 -66
- data/lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/modulotech/Dockerfile.tt +0 -30
- data/lib/generators/modulorails/docker/entrypoint/templates/entrypoints/webpack-entrypoint.sh.tt +0 -7
- data/lib/generators/modulorails/githooks/templates/dockeruby.rb +0 -124
- data/lib/generators/modulorails/sidekiq/templates/entrypoints/sidekiq-entrypoint.sh.tt +0 -7
|
@@ -4,13 +4,18 @@ require 'modulorails/generators/base'
|
|
|
4
4
|
|
|
5
5
|
class Modulorails::GitlabciGenerator < Modulorails::Generators::Base
|
|
6
6
|
|
|
7
|
-
VERSION =
|
|
7
|
+
VERSION = 2
|
|
8
8
|
|
|
9
9
|
desc 'This generator creates a template for a .gitlab-ci.yml file at root'
|
|
10
10
|
|
|
11
11
|
protected
|
|
12
12
|
|
|
13
13
|
def create_config
|
|
14
|
+
Modulorails.deprecator.warn(<<~MESSAGE)
|
|
15
|
+
Modulorails::GitlabciGenerator is deprecated and will be removed in version 2.0.
|
|
16
|
+
Use Moduloproject 3.0 (available later) to initialize new projects with GitLab CI configuration.
|
|
17
|
+
MESSAGE
|
|
18
|
+
|
|
14
19
|
remove_old_keepfile('.modulorails-gitlab-ci')
|
|
15
20
|
remove_old_keepfile('.modulorails-gitlabci')
|
|
16
21
|
|
|
@@ -24,6 +29,7 @@ class Modulorails::GitlabciGenerator < Modulorails::Generators::Base
|
|
|
24
29
|
|
|
25
30
|
# Update the gitlab-ci template
|
|
26
31
|
template '.gitlab-ci.yml'
|
|
32
|
+
template 'bin/test.sh', 'bin/test'
|
|
27
33
|
template 'config/deploy/production.yaml' if @production_url.present?
|
|
28
34
|
template 'config/deploy/staging.yaml' if @staging_url.present?
|
|
29
35
|
template 'config/deploy/review.yaml' if @review_base_url.present?
|
|
@@ -7,16 +7,6 @@ include:
|
|
|
7
7
|
|
|
8
8
|
variables:
|
|
9
9
|
IMAGE_NAME: <%= @image_name %>
|
|
10
|
-
<%- if @adapter =~ /mysql/ -%>
|
|
11
|
-
MYSQL_DATABASE: <%= @image_name %>_test
|
|
12
|
-
MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
|
|
13
|
-
<%= @environment_name %>_DATABASE_HOST: mysql
|
|
14
|
-
<%- else -%>
|
|
15
|
-
POSTGRES_DB: <%= @image_name %>_test
|
|
16
|
-
POSTGRES_USER: postgres
|
|
17
|
-
POSTGRES_PASSWORD: postgres
|
|
18
|
-
<%= @environment_name %>_DATABASE_HOST: postgres
|
|
19
|
-
<%- end -%>
|
|
20
10
|
|
|
21
11
|
stages:
|
|
22
12
|
- test
|
|
@@ -25,6 +15,8 @@ stages:
|
|
|
25
15
|
|
|
26
16
|
build_integration_image:
|
|
27
17
|
extends: .build_integration_image
|
|
18
|
+
variables:
|
|
19
|
+
DOCKERFILE: .devcontainer/Dockerfile
|
|
28
20
|
|
|
29
21
|
test:
|
|
30
22
|
extends: .test
|
|
@@ -37,13 +29,23 @@ test:
|
|
|
37
29
|
- redis:7-alpine
|
|
38
30
|
variables:
|
|
39
31
|
RAILS_ENV: test
|
|
32
|
+
<%- if @adapter =~ /mysql/ -%>
|
|
33
|
+
MYSQL_DATABASE: <%= @image_name %>-test
|
|
34
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
|
|
35
|
+
DATABASE_TEST_URL: 'mysql2://root@mysql/<%= @image_name %>-test'
|
|
36
|
+
<%- else -%>
|
|
37
|
+
POSTGRES_DB: <%= @image_name %>-test
|
|
38
|
+
POSTGRES_USER: postgres
|
|
39
|
+
POSTGRES_PASSWORD: postgres
|
|
40
|
+
DATABASE_TEST_URL: 'postgresql://postgres:postgres@postgres/<%= @image_name %>-test'
|
|
41
|
+
<%- end -%>
|
|
40
42
|
script:
|
|
41
|
-
-
|
|
42
|
-
- bundle exec rake db:migrate:reset
|
|
43
|
-
- bundle exec rspec --format progress --format RspecJunitFormatter --out rspec.xml
|
|
43
|
+
- bin/test
|
|
44
44
|
|
|
45
45
|
docker_build:
|
|
46
46
|
extends: .docker_buildx_push
|
|
47
|
+
variables:
|
|
48
|
+
DOCKERFILE: Dockerfile
|
|
47
49
|
only:
|
|
48
50
|
- merge_requests
|
|
49
51
|
- staging
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
|
|
3
|
+
export RAILS_ENV=test
|
|
4
|
+
|
|
5
|
+
if ! grep -q rspec Gemfile
|
|
6
|
+
then
|
|
7
|
+
echo 'Install RSpec and add some tests:'
|
|
8
|
+
echo ' bundle add rspec-rails rspec_junit_formatter'
|
|
9
|
+
echo ' bundle exec rails generate rspec:install'
|
|
10
|
+
exit 0
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if [ -z "$1" ]
|
|
14
|
+
then
|
|
15
|
+
bundle exec rake db:drop db:create db:schema:load db:migrate
|
|
16
|
+
<%- case @js_engine -%>
|
|
17
|
+
<%- when :webpacker -%>
|
|
18
|
+
bundle exec yarn install
|
|
19
|
+
bundle exec rails webpacker:compile
|
|
20
|
+
<%- when :bun -%>
|
|
21
|
+
bun install
|
|
22
|
+
bun run build
|
|
23
|
+
bun run build:css
|
|
24
|
+
<%- end -%>
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
if [ -z "$CI" ]
|
|
28
|
+
then
|
|
29
|
+
# For dev environment, we use the options specified in `.rspec` file
|
|
30
|
+
bundle exec rspec --profile "$@"
|
|
31
|
+
elif grep -q rspec_junit_formatter Gemfile
|
|
32
|
+
then
|
|
33
|
+
bundle exec rspec --format progress --format RspecJunitFormatter --out rspec.xml --profile "$@"
|
|
34
|
+
else
|
|
35
|
+
bundle exec rspec --format progress --profile "$@"
|
|
36
|
+
fi
|
|
@@ -18,9 +18,9 @@ ingress:
|
|
|
18
18
|
resources:
|
|
19
19
|
requests:
|
|
20
20
|
cpu: 100m
|
|
21
|
-
memory:
|
|
21
|
+
memory: 1024Mi
|
|
22
22
|
limits:
|
|
23
|
-
memory:
|
|
23
|
+
memory: 1024Mi
|
|
24
24
|
|
|
25
25
|
autoscaling:
|
|
26
26
|
enabled: true
|
|
@@ -47,10 +47,10 @@ sidekiq:
|
|
|
47
47
|
# resources:
|
|
48
48
|
# requests:
|
|
49
49
|
# cpu: 100m
|
|
50
|
-
# memory:
|
|
50
|
+
# memory: 1024Mi
|
|
51
51
|
# limits:
|
|
52
52
|
# cpu: 100m
|
|
53
|
-
# memory:
|
|
53
|
+
# memory: 1024Mi
|
|
54
54
|
# autoscaling:
|
|
55
55
|
# enabled: true
|
|
56
56
|
# minReplicas: 1
|
|
@@ -18,9 +18,9 @@ ingress:
|
|
|
18
18
|
resources:
|
|
19
19
|
requests:
|
|
20
20
|
cpu: 100m
|
|
21
|
-
memory:
|
|
21
|
+
memory: 1024Mi
|
|
22
22
|
limits:
|
|
23
|
-
memory:
|
|
23
|
+
memory: 1024Mi
|
|
24
24
|
|
|
25
25
|
autoscaling:
|
|
26
26
|
enabled: true
|
|
@@ -46,10 +46,10 @@ sidekiq:
|
|
|
46
46
|
# resources:
|
|
47
47
|
# requests:
|
|
48
48
|
# cpu: 100m
|
|
49
|
-
# memory:
|
|
49
|
+
# memory: 1024Mi
|
|
50
50
|
# limits:
|
|
51
51
|
# cpu: 100m
|
|
52
|
-
# memory:
|
|
52
|
+
# memory: 1024Mi
|
|
53
53
|
# autoscaling:
|
|
54
54
|
# enabled: true
|
|
55
55
|
# minReplicas: 1
|
|
@@ -18,14 +18,14 @@ ingress:
|
|
|
18
18
|
resources:
|
|
19
19
|
requests:
|
|
20
20
|
cpu: 100m
|
|
21
|
-
memory:
|
|
21
|
+
memory: 1024Mi
|
|
22
22
|
limits:
|
|
23
|
-
memory:
|
|
23
|
+
memory: 1024Mi
|
|
24
24
|
|
|
25
25
|
autoscaling:
|
|
26
26
|
enabled: true
|
|
27
27
|
minReplicas: 1
|
|
28
|
-
maxReplicas:
|
|
28
|
+
maxReplicas: 2
|
|
29
29
|
targetCPUUtilizationPercentage: 80
|
|
30
30
|
|
|
31
31
|
database:
|
|
@@ -42,16 +42,16 @@ redis:
|
|
|
42
42
|
enabled: true
|
|
43
43
|
|
|
44
44
|
sidekiq:
|
|
45
|
-
enabled:
|
|
45
|
+
enabled: false
|
|
46
46
|
# resources:
|
|
47
47
|
# requests:
|
|
48
48
|
# cpu: 100m
|
|
49
|
-
# memory:
|
|
49
|
+
# memory: 1024Mi
|
|
50
50
|
# limits:
|
|
51
51
|
# cpu: 100m
|
|
52
|
-
# memory:
|
|
52
|
+
# memory: 1024Mi
|
|
53
53
|
# autoscaling:
|
|
54
54
|
# enabled: true
|
|
55
55
|
# minReplicas: 1
|
|
56
|
-
# maxReplicas:
|
|
56
|
+
# maxReplicas: 2
|
|
57
57
|
# targetCPUUtilizationPercentage: 80
|
|
@@ -4,16 +4,21 @@ require 'rails/generators'
|
|
|
4
4
|
|
|
5
5
|
class Modulorails::ModuloprojectGenerator < Modulorails::Generators::Base
|
|
6
6
|
|
|
7
|
-
VERSION =
|
|
7
|
+
VERSION = 2
|
|
8
8
|
|
|
9
9
|
desc 'This generator creates templates for Moduloproject'
|
|
10
10
|
|
|
11
11
|
def create_config
|
|
12
|
+
Modulorails.deprecator.warn(<<~MESSAGE)
|
|
13
|
+
Modulorails::ModuloprojectGenerator is deprecated and will be removed in version 2.0.
|
|
14
|
+
This generator will be moved to Moduloproject 3.0 (available later).
|
|
15
|
+
MESSAGE
|
|
16
|
+
|
|
12
17
|
remove_old_keepfile(".modulorails-#{generator_name}")
|
|
13
|
-
template 'config/environments/production.rb'
|
|
18
|
+
template 'config/environments/production.rb', force: true
|
|
14
19
|
copy_file('config/environments/production.rb', 'config/environments/staging.rb')
|
|
15
20
|
update_application_rb
|
|
16
|
-
create_file('config/locales/fr.yml', "
|
|
21
|
+
create_file('config/locales/fr.yml', "fr: {}\n")
|
|
17
22
|
rescue StandardError => e
|
|
18
23
|
warn("[Modulorails] Error: cannot generate Moduloproject configuration: #{e.message}")
|
|
19
24
|
end
|
data/lib/generators/modulorails/moduloproject/templates/config/environments/production.rb.tt
CHANGED
|
@@ -6,55 +6,25 @@ Rails.application.configure do
|
|
|
6
6
|
# Code is not reloaded between requests.
|
|
7
7
|
config.enable_reloading = false
|
|
8
8
|
|
|
9
|
-
# Eager load code on boot
|
|
10
|
-
# your application in memory, allowing both threaded web servers
|
|
11
|
-
# and those relying on copy on write to perform better.
|
|
12
|
-
# Rake tasks automatically ignore this option for performance.
|
|
9
|
+
# Eager load code on boot for better performance and memory savings (ignored by Rake tasks).
|
|
13
10
|
config.eager_load = true
|
|
14
11
|
|
|
15
|
-
#
|
|
16
|
-
# config.eager_load_paths += %W[
|
|
17
|
-
# #{config.root}/lib/constraints
|
|
18
|
-
# ]
|
|
19
|
-
|
|
20
|
-
# Full error reports are disabled and caching is turned on.
|
|
12
|
+
# Full error reports are disabled.
|
|
21
13
|
config.consider_all_requests_local = false
|
|
22
|
-
config.action_controller.perform_caching = true
|
|
23
|
-
|
|
24
|
-
# Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
|
|
25
|
-
# key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
|
|
26
|
-
# config.require_master_key = true
|
|
27
|
-
|
|
28
|
-
# Disable serving static files from `public/`, relying on NGINX/Apache to do so instead.
|
|
29
|
-
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
|
|
30
14
|
|
|
31
|
-
#
|
|
32
|
-
|
|
15
|
+
# Turn on fragment caching in view templates.
|
|
16
|
+
config.action_controller.perform_caching = true
|
|
33
17
|
|
|
34
|
-
#
|
|
35
|
-
config.
|
|
18
|
+
# Cache assets for far-future expiry since they are all digest stamped.
|
|
19
|
+
config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" }
|
|
36
20
|
|
|
37
21
|
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
|
38
22
|
# config.asset_host = "http://assets.example.com"
|
|
39
23
|
|
|
40
|
-
# Specifies the header that your server uses for sending files.
|
|
41
|
-
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
|
|
42
|
-
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX
|
|
43
|
-
|
|
44
24
|
# Store uploaded files on the local file system (see config/storage.yml for options).
|
|
45
25
|
config.active_storage.service = :local
|
|
46
26
|
|
|
47
|
-
# Mount Action Cable outside main process or domain.
|
|
48
|
-
# config.action_cable.mount_path = nil
|
|
49
|
-
# host = URI(ENV.fetch('URL', 'http://localhost:3000/')).host
|
|
50
|
-
# config.action_cable.url = "wss://#{host}/cable"
|
|
51
|
-
# config.action_cable.disable_request_forgery_protection = true
|
|
52
|
-
# config.action_cable.allowed_request_origins = [
|
|
53
|
-
# %r{(https|wss)://host}
|
|
54
|
-
# ]
|
|
55
|
-
|
|
56
27
|
# Assume all access to the app is happening through a SSL-terminating reverse proxy.
|
|
57
|
-
# Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
|
|
58
28
|
config.assume_ssl = true
|
|
59
29
|
|
|
60
30
|
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
|
@@ -63,27 +33,26 @@ Rails.application.configure do
|
|
|
63
33
|
# Skip http-to-https redirect for the default health check endpoint.
|
|
64
34
|
# config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } }
|
|
65
35
|
|
|
66
|
-
# Log to STDOUT
|
|
36
|
+
# Log to STDOUT with the current request id as a default log tag.
|
|
37
|
+
config.log_tags = [ :request_id ]
|
|
67
38
|
config.logger = ActiveSupport::Logger.new(STDOUT)
|
|
68
39
|
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
|
|
69
40
|
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }
|
|
70
41
|
|
|
71
|
-
#
|
|
72
|
-
config.log_tags = [:request_id]
|
|
73
|
-
|
|
74
|
-
# Info include generic and useful information about system operation, but avoids logging too much
|
|
75
|
-
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
|
|
76
|
-
# want to log everything, set the level to "debug".
|
|
42
|
+
# Change to "debug" to log everything (including potentially personally-identifiable information!)
|
|
77
43
|
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
|
|
78
44
|
|
|
79
|
-
#
|
|
45
|
+
# Prevent health checks from clogging up the logs.
|
|
46
|
+
config.silence_healthcheck_path = "/up"
|
|
47
|
+
|
|
48
|
+
# Don't log any deprecations.
|
|
49
|
+
config.active_support.report_deprecations = false
|
|
50
|
+
|
|
51
|
+
# Use Redis as a cache store
|
|
80
52
|
config.cache_store = :redis_cache_store, { url: ENV['REDIS_URL'], expires_in: 6.hours }
|
|
81
53
|
|
|
82
|
-
#
|
|
54
|
+
# Replace the default in-process and non-durable queuing backend for Active Job.
|
|
83
55
|
# config.active_job.queue_adapter = :sidekiq
|
|
84
|
-
# config.active_job.queue_name_prefix = "<%= Modulorails.data.rails_name.underscore %>_production"
|
|
85
|
-
|
|
86
|
-
config.action_mailer.perform_caching = false
|
|
87
56
|
|
|
88
57
|
# Ignore bad email addresses and do not raise email delivery errors.
|
|
89
58
|
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
|
|
@@ -93,17 +62,18 @@ Rails.application.configure do
|
|
|
93
62
|
# the I18n.default_locale when a translation cannot be found).
|
|
94
63
|
config.i18n.fallbacks = true
|
|
95
64
|
|
|
96
|
-
# Don't log any deprecations.
|
|
97
|
-
config.active_support.report_deprecations = false
|
|
98
|
-
|
|
99
65
|
# Do not dump schema after migrations.
|
|
100
66
|
config.active_record.dump_schema_after_migration = false
|
|
101
67
|
|
|
68
|
+
# Only use :id for inspections in production.
|
|
69
|
+
config.active_record.attributes_for_inspect = [ :id ]
|
|
70
|
+
|
|
102
71
|
# Enable DNS rebinding protection and other `Host` header attacks.
|
|
103
72
|
# config.hosts = [
|
|
104
73
|
# "example.com", # Allow requests from example.com
|
|
105
74
|
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
|
|
106
75
|
# ]
|
|
76
|
+
#
|
|
107
77
|
# Skip DNS rebinding protection for the default health check endpoint.
|
|
108
78
|
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
|
|
109
79
|
end
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
# See https://docs.rubocop.org/rubocop/configuration
|
|
11
11
|
|
|
12
12
|
# Enabling Rails-specific cops.
|
|
13
|
-
|
|
13
|
+
plugins:
|
|
14
|
+
- rubocop-rails
|
|
14
15
|
|
|
15
16
|
inherit_mode:
|
|
16
17
|
merge:
|
|
@@ -102,6 +103,7 @@ Metrics/CyclomaticComplexity:
|
|
|
102
103
|
# Commonly used screens these days easily fit more than 80 characters.
|
|
103
104
|
Layout/LineLength:
|
|
104
105
|
Max: 120
|
|
106
|
+
AllowedPatterns: ['\A\s*#']
|
|
105
107
|
|
|
106
108
|
# Too short methods lead to extraction of single-use methods, which can make
|
|
107
109
|
# the code easier to read (by naming things), but can also clutter the class
|
|
@@ -235,6 +237,10 @@ Metrics/BlockLength:
|
|
|
235
237
|
Exclude:
|
|
236
238
|
- 'app/admin/**/*'
|
|
237
239
|
- 'lib/tasks/**/*'
|
|
240
|
+
# Allow big blocks for Concerns
|
|
241
|
+
AllowedMethods:
|
|
242
|
+
- class_methods
|
|
243
|
+
- included
|
|
238
244
|
|
|
239
245
|
# Checks if empty lines around the bodies of classes match the configuration.
|
|
240
246
|
Layout/EmptyLinesAroundClassBody:
|
|
@@ -12,6 +12,10 @@ class Modulorails::SelfUpdateGenerator < Rails::Generators::Base
|
|
|
12
12
|
LATEST_VERSION_URL = 'https://rubygems.org/api/v1/versions/modulorails.json'
|
|
13
13
|
|
|
14
14
|
def create_config_file
|
|
15
|
+
Modulorails.deprecator.warn(<<~MESSAGE)
|
|
16
|
+
Modulorails::SelfUpdateGenerator is deprecated and will be removed in version 2.0.
|
|
17
|
+
MESSAGE
|
|
18
|
+
|
|
15
19
|
# Get the last published version
|
|
16
20
|
versions = HTTParty.get(LATEST_VERSION_URL).parsed_response
|
|
17
21
|
last_published_version = versions&.reject { |version| Gem::Version.new(version['number']).prerelease? }&.first
|
|
@@ -8,12 +8,15 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
8
8
|
|
|
9
9
|
desc 'This generator adds Sidekiq to the project'
|
|
10
10
|
|
|
11
|
+
def deprecation_warning
|
|
12
|
+
Modulorails.deprecator.warn(<<~MESSAGE)
|
|
13
|
+
Modulorails::SidekiqGenerator is deprecated and will be removed in version 2.0.
|
|
14
|
+
Use Moduloproject 3.0 (available later) to initialize new projects with Sidekiq configuration.
|
|
15
|
+
MESSAGE
|
|
16
|
+
end
|
|
17
|
+
|
|
11
18
|
def add_to_docker_compose
|
|
12
|
-
|
|
13
|
-
add_to_docker_compose_yml_file(Rails.root.join('compose.yml'))
|
|
14
|
-
elsif Rails.root.join('docker-compose.yml').exist?
|
|
15
|
-
add_to_docker_compose_yml_file(Rails.root.join('docker-compose.yml'))
|
|
16
|
-
end
|
|
19
|
+
add_to_docker_compose_yml_file(Rails.root.join('.devcontainer/compose.yml'))
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
def add_to_deploy_files
|
|
@@ -26,12 +29,15 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
26
29
|
gemfile_path = Rails.root.join('Gemfile')
|
|
27
30
|
|
|
28
31
|
# Add gem redis unless already present
|
|
29
|
-
append_to_file(gemfile_path, "
|
|
32
|
+
append_to_file(gemfile_path, "\ngem 'redis'\n") unless File.read(gemfile_path).match?(/^\s*gem ['"]redis['"]/)
|
|
30
33
|
|
|
31
34
|
# Add gem sidekiq unless already present
|
|
32
|
-
|
|
35
|
+
append_to_file(gemfile_path, "\ngem 'sidekiq'\n") unless File.read(gemfile_path).match?(/^\s*gem ['"]sidekiq['"]/)
|
|
36
|
+
|
|
37
|
+
# Add gem sidekiq-datadog-error-tracking unless already present
|
|
38
|
+
return if File.read(gemfile_path).match?(/^\s*gem ['"]sidekiq-datadog-error-tracking['"]/)
|
|
33
39
|
|
|
34
|
-
append_to_file(gemfile_path, "
|
|
40
|
+
append_to_file(gemfile_path, "\ngem 'sidekiq-datadog-error-tracking'\n")
|
|
35
41
|
end
|
|
36
42
|
|
|
37
43
|
def add_to_config
|
|
@@ -46,20 +52,19 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
46
52
|
|
|
47
53
|
def add_routes
|
|
48
54
|
routes_path = Rails.root.join('config/routes.rb')
|
|
49
|
-
|
|
50
55
|
return if File.read(routes_path).match?(%r{require ['"]sidekiq/web["']})
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
RUBY
|
|
57
|
+
authentication_type = Modulorails.data.authentication_type
|
|
58
|
+
if respond_to?("add_#{authentication_type}_authenticated_route")
|
|
59
|
+
send("add_#{authentication_type}_authenticated_route", routes_path)
|
|
60
|
+
else
|
|
61
|
+
add_unauthenticated_route(routes_path)
|
|
58
62
|
end
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
def add_health_check
|
|
62
66
|
file_path = Rails.root.join('config/initializers/health_check.rb')
|
|
67
|
+
return unless File.exist?(file_path)
|
|
63
68
|
|
|
64
69
|
return if File.read(file_path).match?(/add_custom_check\s*\(?\s*['"]sidekiq-queues['"]\s*\)?/)
|
|
65
70
|
|
|
@@ -73,10 +78,10 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
73
78
|
# No queues, means no jobs, ok!
|
|
74
79
|
next '' if queues.empty?
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
global_latency = queues.each.map { |queue| queue.latency }.sum
|
|
77
82
|
|
|
78
|
-
#
|
|
79
|
-
|
|
83
|
+
# Global latency is less than 5 minutes, ok!
|
|
84
|
+
global_latency < 5.minutes ? '' : "Global latency (\#{global_latency}) is too high."
|
|
80
85
|
end
|
|
81
86
|
|
|
82
87
|
# Add one or more custom checks that return a blank string if ok, or an error message if there is an error
|
|
@@ -90,9 +95,9 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
90
95
|
end
|
|
91
96
|
end
|
|
92
97
|
|
|
93
|
-
def
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
def remove_entrypoint
|
|
99
|
+
remove_file 'entrypoints/sidekiq-entrypoint.sh'
|
|
100
|
+
remove_file 'bin/sidekiq-entrypoint'
|
|
96
101
|
end
|
|
97
102
|
|
|
98
103
|
private
|
|
@@ -100,31 +105,43 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
100
105
|
def add_to_docker_compose_yml_file(file_path)
|
|
101
106
|
@image_name ||= Modulorails.data.name.parameterize
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
unless File.exist?(file_path)
|
|
109
|
+
puts("Compose file not found at #{file_path}. Ignoring.")
|
|
110
|
+
return
|
|
111
|
+
end
|
|
105
112
|
|
|
106
|
-
|
|
113
|
+
# Update existing Sidekiq service
|
|
114
|
+
if File.read(file_path).match?(/^ {2}sidekiq:$/)
|
|
115
|
+
pattern = /^(\s*)entrypoint:(\s*).\/(bin\/sidekiq-entrypoint|entrypoints\/sidekiq-entrypoint\.sh)/
|
|
116
|
+
gsub_file file_path, pattern, '\1command:\2./bin/bundle exec sidekiq'
|
|
117
|
+
return
|
|
118
|
+
end
|
|
107
119
|
|
|
120
|
+
add_sidekiq_service(file_path)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def add_sidekiq_service(file_path)
|
|
108
124
|
insert_into_file file_path, after: /^services:/ do
|
|
125
|
+
# Using `<<-` Heredoc syntax to preserve YAML indentation
|
|
109
126
|
<<-YAML
|
|
110
127
|
|
|
111
128
|
sidekiq:
|
|
112
129
|
image: modulotechgroup/#{@image_name}:dev
|
|
113
130
|
build:
|
|
114
|
-
context:
|
|
115
|
-
dockerfile: Dockerfile
|
|
131
|
+
context: ..
|
|
132
|
+
dockerfile: .devcontainer/Dockerfile
|
|
116
133
|
depends_on:
|
|
117
134
|
- database
|
|
118
135
|
- redis
|
|
119
136
|
volumes:
|
|
120
|
-
-
|
|
137
|
+
- ..:/rails
|
|
121
138
|
environment:
|
|
122
139
|
RAILS_ENV: development
|
|
123
140
|
URL: http://app:3000
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
141
|
+
env_file:
|
|
142
|
+
- path: .env
|
|
143
|
+
required: false
|
|
144
|
+
command: ./bin/bundle exec sidekiq
|
|
128
145
|
stdin_open: true
|
|
129
146
|
tty: true
|
|
130
147
|
YAML
|
|
@@ -146,8 +163,9 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
146
163
|
end
|
|
147
164
|
|
|
148
165
|
def add_to_deploy_file(file_path)
|
|
149
|
-
# Do nothing if file does not
|
|
150
|
-
return
|
|
166
|
+
# Do nothing if file does not exist or Sidekiq is already enabled
|
|
167
|
+
return unless File.exist?(file_path)
|
|
168
|
+
return if File.read(file_path).match?(/^sidekiq:\n {2}enabled: true$/m)
|
|
151
169
|
|
|
152
170
|
# Add sidekiq to deploy file
|
|
153
171
|
insert_into_file file_path do
|
|
@@ -158,17 +176,56 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
158
176
|
resources:
|
|
159
177
|
requests:
|
|
160
178
|
cpu: 100m
|
|
161
|
-
memory:
|
|
179
|
+
memory: 1024Mi
|
|
162
180
|
limits:
|
|
163
|
-
|
|
164
|
-
memory: 512Mi
|
|
181
|
+
memory: 1024Mi
|
|
165
182
|
autoscaling:
|
|
166
183
|
enabled: true
|
|
167
|
-
minReplicas: 1
|
|
168
|
-
maxReplicas: 10
|
|
184
|
+
minReplicas: #{file_path.to_s.match?('production.y') ? 2 : 1}
|
|
185
|
+
maxReplicas: #{file_path.to_s.match?('production.y') ? 10 : 2}
|
|
169
186
|
targetCPUUtilizationPercentage: 80
|
|
187
|
+
command: ["./bin/bundle", "exec", "sidekiq"]
|
|
170
188
|
YAML
|
|
171
189
|
end
|
|
172
190
|
end
|
|
173
191
|
|
|
192
|
+
RAILS_AUTHENTICATION_TEMPLATE = <<~RUBY.freeze
|
|
193
|
+
require 'sidekiq/web'
|
|
194
|
+
constraints lambda { |request| Session.find_by(id: request.cookie_jar.signed[:session_id])&.user&.role == 'admin' } do
|
|
195
|
+
mount Sidekiq::Web => '/admin/sidekiq'
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
RUBY
|
|
200
|
+
|
|
201
|
+
def add_devise_authenticated_route(routes_path)
|
|
202
|
+
template = <<~RUBY
|
|
203
|
+
require 'sidekiq/web'
|
|
204
|
+
authenticate :user, lambda { |u| u.respond_to?('role') && u.role == 'admin' } do
|
|
205
|
+
mount Sidekiq::Web => '/admin/sidekiq'
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
RUBY
|
|
209
|
+
puts("Injecting #{template} into #{routes_path}: update the authentication block.")
|
|
210
|
+
inject_into_file routes_path, template, after: "Rails.application.routes.draw do\n"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def add_rails_authenticated_route(routes_path)
|
|
214
|
+
template = RAILS_AUTHENTICATION_TEMPLATE
|
|
215
|
+
puts("Injecting #{template} into #{routes_path}: update the authentication block.")
|
|
216
|
+
inject_into_file routes_path, template, after: "Rails.application.routes.draw do\n"
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def add_unauthenticated_route(routes_path)
|
|
220
|
+
template = <<~RUBY
|
|
221
|
+
require 'sidekiq/web'
|
|
222
|
+
mount Sidekiq::Web => '/admin/sidekiq'
|
|
223
|
+
|
|
224
|
+
RUBY
|
|
225
|
+
puts("Injecting #{template} into #{routes_path}: you should add authentication to the route.")
|
|
226
|
+
puts("If you do not have authentication, execute `rails generate authentication` and replace \
|
|
227
|
+
the route by #{RAILS_AUTHENTICATION_TEMPLATE}.")
|
|
228
|
+
inject_into_file routes_path, template, after: "Rails.application.routes.draw do\n"
|
|
229
|
+
end
|
|
230
|
+
|
|
174
231
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
redis_url = Rails.application.config_for('cable')['url']
|
|
2
|
-
|
|
3
1
|
Sidekiq.configure_server do |config|
|
|
4
|
-
config.redis = { url:
|
|
2
|
+
config.redis = { url: REDIS_URL }
|
|
3
|
+
config.logger.formatter = Sidekiq::Logger::Formatters::Datadog.new
|
|
4
|
+
config.error_handlers << Sidekiq::Datadog::Error::Tracking
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
Sidekiq.configure_client do |config|
|
|
8
|
-
config.redis = { url:
|
|
8
|
+
config.redis = { url: REDIS_URL }
|
|
9
9
|
end
|
|
@@ -16,14 +16,8 @@ module Modulorails
|
|
|
16
16
|
# config.project_manager 'pm@modulotech.fr'
|
|
17
17
|
# config.endpoint "intranet's endpoint"
|
|
18
18
|
# config.api_key "intranet's api key"
|
|
19
|
-
# config.production_url "production.app.com"
|
|
20
|
-
# config.staging_url "staging.app.com"
|
|
21
|
-
# config.review_base_url "review.app.com"
|
|
22
19
|
# end
|
|
23
|
-
%i[
|
|
24
|
-
name main_developer project_manager endpoint api_key no_auto_update production_url staging_url
|
|
25
|
-
review_base_url
|
|
26
|
-
].each do |field|
|
|
20
|
+
%i[name main_developer project_manager endpoint api_key].each do |field|
|
|
27
21
|
define_method(field) do |value=nil|
|
|
28
22
|
# No value means we want to get the field
|
|
29
23
|
return send("_#{field}") unless value
|
|
@@ -33,6 +27,22 @@ module Modulorails
|
|
|
33
27
|
end
|
|
34
28
|
end
|
|
35
29
|
|
|
30
|
+
# Deprecated configuration options - will be removed in 2.0
|
|
31
|
+
%i[no_auto_update production_url staging_url review_base_url].each do |field|
|
|
32
|
+
define_method(field) do |value=nil|
|
|
33
|
+
# No value means we want to get the field
|
|
34
|
+
return send("_#{field}") unless value
|
|
35
|
+
|
|
36
|
+
# Warn only when setting the value (i.e., in the initializer)
|
|
37
|
+
Modulorails.deprecator.warn(
|
|
38
|
+
"Modulorails configuration `#{field}` is deprecated and will be removed in version 2.0."
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Else we want to set the field
|
|
42
|
+
send("_#{field}=", value)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
36
46
|
end
|
|
37
47
|
|
|
38
48
|
end
|