modulorails 1.2.1 → 1.3.1

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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/README.md +3 -0
  4. data/lib/generators/modulorails/docker/docker_generator.rb +8 -1
  5. data/lib/generators/modulorails/docker/templates/Dockerfile.prod.tt +9 -8
  6. data/lib/generators/modulorails/docker/templates/Dockerfile.tt +3 -4
  7. data/lib/generators/modulorails/docker/templates/config/cable.yml.tt +15 -0
  8. data/lib/generators/modulorails/docker/templates/config/database.yml.tt +12 -15
  9. data/lib/generators/modulorails/docker/templates/docker-compose.prod.yml.tt +9 -10
  10. data/lib/generators/modulorails/docker/templates/docker-compose.yml.tt +16 -18
  11. data/lib/generators/modulorails/docker/templates/entrypoints/docker-entrypoint.sh.tt +1 -1
  12. data/lib/generators/modulorails/docker/templates/entrypoints/webpack-entrypoint.sh.tt +1 -1
  13. data/lib/generators/modulorails/gitlabci/gitlabci_generator.rb +11 -0
  14. data/lib/generators/modulorails/gitlabci/templates/.gitlab-ci.yml.tt +45 -62
  15. data/lib/generators/modulorails/gitlabci/templates/config/deploy/production.yaml.tt +43 -0
  16. data/lib/generators/modulorails/gitlabci/templates/config/deploy/review.yaml.tt +42 -0
  17. data/lib/generators/modulorails/gitlabci/templates/config/deploy/staging.yaml.tt +42 -0
  18. data/lib/generators/modulorails/healthcheck/health_check_generator.rb +1 -5
  19. data/lib/generators/modulorails/healthcheck/templates/config/initializers/health_check.rb.tt +1 -1
  20. data/lib/generators/modulorails/rubocop/templates/rubocop.yml.tt +6 -2
  21. data/lib/generators/modulorails/service/USAGE +14 -0
  22. data/lib/generators/modulorails/service/service_generator.rb +12 -0
  23. data/lib/generators/modulorails/sidekiq/sidekiq_generator.rb +178 -0
  24. data/lib/generators/modulorails/sidekiq/templates/config/initializers/sidekiq.rb.tt +9 -0
  25. data/lib/generators/modulorails/sidekiq/templates/entrypoints/sidekiq-entrypoint.sh.tt +7 -0
  26. data/lib/modulorails/data.rb +4 -0
  27. data/lib/modulorails/version.rb +1 -1
  28. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47ac5a151c8230d9ff0e9b775d32bd2a27eddbea284cf30aacf0bc863eb65a47
4
- data.tar.gz: 180b663722790df15a3e180fbfe32a13f8743a57e28f6d74005d93ee08bf98b0
3
+ metadata.gz: 6a06133e9c157d574ab3cc83ffd931e7e61873d7c8deff63c22b8a0657def075
4
+ data.tar.gz: d345aa7aa32575496041762e43f198001260a003dc811c69ae704f889dde0411
5
5
  SHA512:
6
- metadata.gz: a90d84b0c21e644e07d097e6c00b77af37dbfe1d43b1e1b4f75fd614fc7bc87bf86a93343e1362ab78a4321f1f1081bad4e3605a7c10dee082ab31cc346d102d
7
- data.tar.gz: 9bcdf33285526a1ecca9dee4b05ab6d5f343280f8e9ec34427e428ab52786a11ab3235cf5ed77c5a1eb59163ff1dfb54d905c280068cf0f10032e47379c3c0e6
6
+ metadata.gz: 1594ae1f801bf28f08ec2a86ecc6040f48c513d2c47a2dfb9f0a8a3b69bf2dd7f04d6465aff1041faf80759fb70610ff57a8b02b83bddf4cbdc3ab9c553bdb9b
7
+ data.tar.gz: 4e4652c68c1ba65d1ce429c5acffbb5e11c8f82effdcdd55735d91cb8c12e442f6a00b5b5099a316b26f8620ef20873c96b5349df4ea58ec24566aaebe75abb1
data/CHANGELOG.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  This file is used to list changes made in each version of the gem.
4
4
 
5
+ # 1.3.1
6
+
7
+ - Update templates according to new devops standards:
8
+ - Add exec commands in entrypoints.
9
+ - Upgrade PG and Redis version in docker-compose files.
10
+ - Upgrade PG and Redis version in test stage in CI.
11
+ - Add default SECRET_KEY_BASE and optional `yarn install` in `Dockerfile.prod` templates.
12
+ - Add templates for Kubernetes values files.
13
+ - Append sidekiq in Kubernetes values files in Sidekiq generator.
14
+
15
+ # 1.3.0
16
+
17
+ - Update redis configuration in generators.
18
+ - Update mailcatcher docker image for better compatibility with ARM64.
19
+ - Remove possible suffix `Service` in service generator.
20
+ - Update rubocop configuration in template.
21
+ - Add a generator to add Sidekiq to a project.
22
+ - Update docker generator to use valid names for environment variables.
23
+
5
24
  # 1.2.1
6
25
 
7
26
  - Update rubocop configuration.
data/README.md CHANGED
@@ -28,6 +28,9 @@ Modulorails.configure do |config|
28
28
  config.project_manager 'The email of the project manager of the application'
29
29
  config.endpoint 'The url to the intranet'
30
30
  config.api_key 'The API key'
31
+ config.review_base_url 'The base url for the review environments' # optional
32
+ config.staging_url 'The url for the staging environment' # optional
33
+ config.production_url 'The url for the production environment' # optional
31
34
  end
32
35
  ```
33
36
 
@@ -8,6 +8,12 @@ class Modulorails::DockerGenerator < Rails::Generators::Base
8
8
  desc 'This generator creates Dockerfiles for an app'
9
9
 
10
10
  def create_config_file
11
+ @data = Modulorails.data
12
+ @adapter = data.adapter
13
+ @webpack_container_needed = data.webpacker_version.present?
14
+ @image_name = @data.name.parameterize
15
+ @environment_name = @data.environment_name
16
+
11
17
  template 'Dockerfile'
12
18
  template 'Dockerfile.prod'
13
19
  template 'docker-compose.yml'
@@ -15,9 +21,10 @@ class Modulorails::DockerGenerator < Rails::Generators::Base
15
21
  template 'entrypoints/docker-entrypoint.sh'
16
22
  chmod 'entrypoints/docker-entrypoint.sh', 0755
17
23
  template 'config/database.yml'
24
+ template 'config/cable.yml'
18
25
 
19
26
  # Useless unless project is using Webpacker
20
- if Modulorails.data.webpacker_version.present?
27
+ if @webpack_container_needed
21
28
  template 'entrypoints/webpack-entrypoint.sh'
22
29
  chmod 'entrypoints/webpack-entrypoint.sh', 0755
23
30
  end
@@ -1,7 +1,8 @@
1
1
  # BUILD IMAGE
2
- FROM ruby:<%= Modulorails.data.ruby_version %>-alpine as builder
2
+ FROM ruby:<%= @data.ruby_version %>-alpine as builder
3
3
 
4
- ENV RAILS_ENV=production
4
+ ENV RAILS_ENV=production \
5
+ SECRET_KEY_BASE=1
5
6
  WORKDIR /app
6
7
 
7
8
  RUN apk add --update --no-cache \
@@ -11,27 +12,28 @@ RUN apk add --update --no-cache \
11
12
  yarn \
12
13
  shared-mime-info \
13
14
  gcompat \
14
- <%- adapter = Modulorails.data.adapter -%>
15
- <%- if adapter =~ /mysql/ -%>
15
+ <%- if @adapter =~ /mysql/ -%>
16
16
  mysql-dev
17
17
  <%- else -%>
18
18
  postgresql-dev
19
19
  <%- end -%>
20
- RUN gem install bundler -v <%= Modulorails.data.bundler_version %>
20
+ RUN gem install bundler -v <%= @data.bundler_version %>
21
21
 
22
22
  COPY Gemfile Gemfile.lock ./
23
23
  RUN bundle config set --local deployment 'true'
24
24
  RUN bundle check || bundle install --jobs=2 \
25
25
  && rm -rf vendor/bundle/ruby/*/cache/*
26
26
 
27
+ <%- if @webpack_container_needed -%>
27
28
  COPY package.json yarn.lock ./
28
29
  RUN yarn install
30
+ <%- end-%>
29
31
 
30
32
  COPY . .
31
33
  RUN bundle exec rake assets:precompile
32
34
 
33
35
  # FINAL IMAGE
34
- FROM ruby:<%= Modulorails.data.ruby_version %>-alpine
36
+ FROM ruby:<%= @data.ruby_version %>-alpine
35
37
 
36
38
  ENV RAILS_ENV=development
37
39
  ENV EDITOR=vim
@@ -44,8 +46,7 @@ RUN apk add --update --no-cache \
44
46
  tzdata \
45
47
  shared-mime-info \
46
48
  vim \
47
- <%- adapter = Modulorails.data.adapter -%>
48
- <%- if adapter =~ /mysql/ -%>
49
+ <%- if @adapter =~ /mysql/ -%>
49
50
  mysql-dev \
50
51
  <%- else -%>
51
52
  postgresql-dev \
@@ -1,4 +1,4 @@
1
- FROM ruby:<%= Modulorails.data.ruby_version %>-alpine
1
+ FROM ruby:<%= @data.ruby_version %>-alpine
2
2
 
3
3
  ENV RAILS_ENV=development
4
4
  ENV EDITOR=vim
@@ -11,13 +11,12 @@ RUN apk add --update --no-cache \
11
11
  tzdata \
12
12
  gcompat \
13
13
  vim \
14
- <%- adapter = Modulorails.data.adapter -%>
15
- <%- if adapter =~ /mysql/ -%>
14
+ <%- if @adapter =~ /mysql/ -%>
16
15
  mysql-dev
17
16
  <%- else -%>
18
17
  postgresql-dev
19
18
  <%- end -%>
20
- RUN gem install bundler -v <%= Modulorails.data.bundler_version %>
19
+ RUN gem install bundler -v <%= @data.bundler_version %>
21
20
 
22
21
  COPY Gemfile Gemfile.lock ./
23
22
  RUN bundle install --jobs=2
@@ -0,0 +1,15 @@
1
+ redis_local: &redis_local
2
+ adapter: redis
3
+ url: <%= ENV.fetch('REDIS_URL', 'redis://redis:6379') %>
4
+
5
+ development:
6
+ <<: *redis_local
7
+
8
+ test:
9
+ <<: *redis_local
10
+
11
+ staging:
12
+ <<: *redis_local
13
+
14
+ production:
15
+ <<: *redis_local
@@ -1,29 +1,26 @@
1
- <%- image_name = Modulorails.data.name.parameterize -%>
2
- <%- upper_image_name = image_name.upcase -%>
3
- <%- adapter = Modulorails.data.adapter -%>
4
- <%- if adapter =~ /mysql/ -%>
1
+ <%- if @adapter =~ /mysql/ -%>
5
2
  development: &default
6
3
  adapter: mysql2
7
4
  encoding: utf8mb4
8
5
  collation: utf8mb4_unicode_ci
9
- database: <%%= ENV.fetch('<%= upper_image_name %>_DATABASE_NAME', '<%= image_name %>') %>
10
- username: <%%= ENV.fetch('<%= upper_image_name %>_DATABASE_USERNAME', 'root') %>
11
- password: <%%= ENV.fetch('<%= upper_image_name %>_DATABASE_PASSWORD', '') %>
12
- host: <%%= ENV.fetch('<%= upper_image_name %>_DATABASE_HOST', 'database') %>
13
- port: <%%= ENV.fetch('<%= upper_image_name %>_DATABASE_PORT', 3306) %>
6
+ database: <%%= ENV.fetch('<%= @environment_name %>_DATABASE_NAME', '<%= @image_name %>') %>
7
+ username: <%%= ENV.fetch('<%= @environment_name %>_DATABASE_USERNAME', 'root') %>
8
+ password: <%%= ENV.fetch('<%= @environment_name %>_DATABASE_PASSWORD', '') %>
9
+ host: <%%= ENV.fetch('<%= @environment_name %>_DATABASE_HOST', 'database') %>
10
+ port: <%%= ENV.fetch('<%= @environment_name %>_DATABASE_PORT', 3306) %>
14
11
  <%- else -%>
15
12
  development: &default
16
13
  adapter: postgresql
17
- database: <%%= ENV.fetch('<%= upper_image_name %>_DATABASE_NAME', '<%= image_name %>') %>
18
- username: <%%= ENV.fetch('<%= upper_image_name %>_DATABASE_USERNAME', 'postgres') %>
19
- password: <%%= ENV.fetch('<%= upper_image_name %>_DATABASE_PASSWORD', 'postgres') %>
20
- host: <%%= ENV.fetch('<%= upper_image_name %>_DATABASE_HOST', 'database') %>
21
- port: <%%= ENV.fetch('<%= upper_image_name %>_DATABASE_PORT', 5432) %>
14
+ database: <%%= ENV.fetch('<%= @environment_name %>_DATABASE_NAME', '<%= @image_name %>') %>
15
+ username: <%%= ENV.fetch('<%= @environment_name %>_DATABASE_USERNAME', 'postgres') %>
16
+ password: <%%= ENV.fetch('<%= @environment_name %>_DATABASE_PASSWORD', 'postgres') %>
17
+ host: <%%= ENV.fetch('<%= @environment_name %>_DATABASE_HOST', 'database') %>
18
+ port: <%%= ENV.fetch('<%= @environment_name %>_DATABASE_PORT', 5432) %>
22
19
  <%- end -%>
23
20
 
24
21
  test:
25
22
  <<: *default
26
- database: <%%= ENV.fetch('<%= upper_image_name %>_TEST_DATABASE_NAME', '<%= image_name %>_test') %>
23
+ database: <%%= ENV.fetch('<%= @environment_name %>_TEST_DATABASE_NAME', '<%= @image_name %>_test') %>
27
24
 
28
25
  staging:
29
26
  <<: *default
@@ -1,9 +1,8 @@
1
1
  version: '3.7'
2
2
 
3
- <%- image_name = Modulorails.data.name.parameterize -%>
4
3
  services:
5
4
  app:
6
- image: modulotechgroup/<%= image_name %>
5
+ image: modulotechgroup/<%= @image_name %>
7
6
  build:
8
7
  context: .
9
8
  dockerfile: Dockerfile.prod
@@ -15,35 +14,35 @@ services:
15
14
  environment:
16
15
  RAILS_ENV: production
17
16
  URL: http://localhost:3000
18
- <%= image_name.upcase %>_DATABASE_HOST: database
19
- <%= image_name.upcase %>_DATABASE_NAME: <%= image_name %>
17
+ <%= @environment_name %>_DATABASE_HOST: database
18
+ <%= @environment_name %>_DATABASE_NAME: <%= @image_name %>
20
19
  RAILS_SERVE_STATIC_FILES: 'true'
20
+ REDIS_URL: redis://redis:6379/1
21
21
 
22
- <%- adapter = Modulorails.data.adapter -%>
23
- <%- if adapter =~ /mysql/ -%>
22
+ <%- if @adapter =~ /mysql/ -%>
24
23
  database:
25
24
  image: mysql/mysql-server:8.0
26
25
  volumes:
27
26
  - db_data:/var/lib/mysql
28
27
  environment:
29
28
  MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
30
- MYSQL_DATABASE: <%= image_name %>
29
+ MYSQL_DATABASE: <%= @image_name %>
31
30
  MYSQL_ROOT_HOST: '%'
32
31
  <%- else -%>
33
32
  database:
34
- image: postgres:13.5
33
+ image: postgres:15-alpine
35
34
  volumes:
36
35
  - db_data:/var/lib/postgresql/data
37
36
  environment:
38
37
  POSTGRES_USER: postgres
39
38
  POSTGRES_PASSWORD: postgres
40
- POSTGRES_DB: <%= image_name %>
39
+ POSTGRES_DB: <%= @image_name %>
41
40
  LC_COLLATE: 'en_US.UTF-8'
42
41
  LC_CTYPE: 'en_US.UTF-8'
43
42
  <%- end -%>
44
43
 
45
44
  redis:
46
- image: redis:6.2-alpine
45
+ image: redis:7-alpine
47
46
 
48
47
  # Define the volumes references in the services
49
48
  volumes:
@@ -1,9 +1,8 @@
1
1
  version: '3.7'
2
2
 
3
- <%- image_name = Modulorails.data.name.parameterize -%>
4
3
  services:
5
4
  app:
6
- image: modulotechgroup/<%= image_name %>:dev
5
+ image: modulotechgroup/<%= @image_name %>:dev
7
6
  build:
8
7
  context: .
9
8
  dockerfile: Dockerfile
@@ -17,47 +16,46 @@ services:
17
16
  environment:
18
17
  RAILS_ENV: development
19
18
  URL: http://localhost:3000
20
- <%= image_name.upcase %>_DATABASE_HOST: database
21
- <%= image_name.upcase %>_DATABASE_NAME: <%= image_name %>
19
+ <%= @environment_name %>_DATABASE_HOST: database
20
+ <%= @environment_name %>_DATABASE_NAME: <%= @image_name %>
21
+ REDIS_URL: redis://redis:6379/1
22
22
  entrypoint: ./entrypoints/docker-entrypoint.sh
23
23
  stdin_open: true
24
24
  tty: true
25
25
 
26
- <%- adapter = Modulorails.data.adapter -%>
27
- <%- if adapter =~ /mysql/ -%>
26
+ <%- if @adapter =~ /mysql/ -%>
28
27
  database:
29
28
  image: mysql/mysql-server:8.0
30
29
  volumes:
31
30
  - db_data:/var/lib/mysql
32
31
  environment:
33
32
  MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
34
- MYSQL_DATABASE: <%= image_name %>
33
+ MYSQL_DATABASE: <%= @image_name %>
35
34
  MYSQL_ROOT_HOST: '%'
36
- <%- else-%>
35
+ <%- else -%>
37
36
  database:
38
- image: postgres:13.5
37
+ image: postgres:15-alpine
39
38
  volumes:
40
39
  - db_data:/var/lib/postgresql/data
41
40
  environment:
42
41
  POSTGRES_USER: postgres
43
42
  POSTGRES_PASSWORD: postgres
44
- POSTGRES_DB: <%= image_name %>
43
+ POSTGRES_DB: <%= @image_name %>
45
44
  LC_COLLATE: 'en_US.UTF-8'
46
45
  LC_CTYPE: 'en_US.UTF-8'
47
- <%- end-%>
46
+ <%- end -%>
48
47
 
49
48
  redis:
50
- image: redis:6.2-alpine
49
+ image: redis:7-alpine
51
50
 
52
51
  mailcatcher:
53
- image: tophfr/mailcatcher
52
+ image: dockage/mailcatcher
54
53
  ports:
55
- - 1080:80
54
+ - 1080:1080
56
55
 
57
- <%- webpack_container_needed = Modulorails.data.webpacker_version.present? -%>
58
- <%- if webpack_container_needed -%>
56
+ <%- if @webpack_container_needed -%>
59
57
  webpack:
60
- image: modulotechgroup/<%= image_name %>:dev
58
+ image: modulotechgroup/<%= @image_name %>:dev
61
59
  build:
62
60
  context: .
63
61
  dockerfile: Dockerfile
@@ -70,7 +68,7 @@ services:
70
68
  NODE_ENV: development
71
69
  RAILS_ENV: development
72
70
  WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
73
- <%- end-%>
71
+ <%- end -%>
74
72
 
75
73
  volumes:
76
74
  db_data:
@@ -17,4 +17,4 @@ then
17
17
  fi
18
18
 
19
19
  # Launch the application listening from all origins on port 3000
20
- ./bin/bundle exec rails s -b 0.0.0.0 -p 3000
20
+ exec ./bin/bundle exec rails s -b 0.0.0.0 -p 3000
@@ -4,4 +4,4 @@
4
4
  set -e
5
5
 
6
6
  # Launch webpack
7
- ./bin/webpack-dev-server
7
+ exec ./bin/webpack-dev-server
@@ -8,8 +8,19 @@ class Modulorails::GitlabciGenerator < Rails::Generators::Base
8
8
  desc 'This generator creates a template for a .gitlab-ci.yml file at root'
9
9
 
10
10
  def create_config_file
11
+ @data = Modulorails.data
12
+ @image_name = @data.name.parameterize
13
+ @environment_name = @data.environment_name
14
+ @adapter = data.adapter
15
+ @review_base_url = @data.review_base_url
16
+ @staging_url = @data.staging_url
17
+ @production_url = @data.production_url
18
+
11
19
  # Update the gitlab-ci template
12
20
  template '.gitlab-ci.yml'
21
+ template 'config/deploy/production.yaml' if @production_url.present?
22
+ template 'config/deploy/staging.yaml' if @staging_url.present?
23
+ template 'config/deploy/review.yaml' if @review_base_url.present?
13
24
 
14
25
  # Remove the database-ci template if it exists.
15
26
  # It used to be referenced by the gitlab-ci template.
@@ -1,4 +1,3 @@
1
- <%- image_name = Modulorails.data.name.parameterize -%>
2
1
  include:
3
2
  - project: 'modulosource/modulotech/devops/gitlab-ci-templates'
4
3
  file:
@@ -6,26 +5,17 @@ include:
6
5
  - '/templates/integration.gitlab-ci.yml'
7
6
  - '/templates/docker-buildx.gitlab-ci.yml'
8
7
 
9
- services:
10
- <%- adapter = Modulorails.data.adapter -%>
11
- <%- if adapter =~ /mysql/ -%>
12
- - mysql:8.0
13
- <%- else -%>
14
- - postgres:13.5
15
- <%- end -%>
16
- - redis:6.2
17
-
18
8
  variables:
19
- IMAGE_NAME: <%= image_name %>
20
- <%- if adapter =~ /mysql/ -%>
21
- MYSQL_DATABASE: <%= image_name %>_test
9
+ IMAGE_NAME: <%= @image_name %>
10
+ <%- if @adapter =~ /mysql/ -%>
11
+ MYSQL_DATABASE: <%= @image_name %>_test
22
12
  MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
23
- <%= image_name.upcase %>_DATABASE_HOST: mysql
13
+ <%= @environment_name %>_DATABASE_HOST: mysql
24
14
  <%- else -%>
25
- POSTGRES_DB: <%= image_name %>_test
15
+ POSTGRES_DB: <%= @image_name %>_test
26
16
  POSTGRES_USER: postgres
27
17
  POSTGRES_PASSWORD: postgres
28
- <%= image_name.upcase %>_DATABASE_HOST: postgres
18
+ <%= @environment_name %>_DATABASE_HOST: postgres
29
19
  <%- end -%>
30
20
 
31
21
  stages:
@@ -33,35 +23,44 @@ stages:
33
23
  - build
34
24
  - deploy
35
25
 
26
+ build_integration_image:
27
+ extends: .build_integration_image
28
+
36
29
  test:
37
30
  extends: .test
31
+ services:
32
+ <%- if @adapter =~ /mysql/ -%>
33
+ - mysql:8-alpine
34
+ <%- else -%>
35
+ - postgres:15-alpine
36
+ <%- end -%>
37
+ - redis:7-alpine
38
+ variables:
39
+ RAILS_ENV: test
38
40
  script:
39
- - "bundle exec rake db:create RAILS_ENV=test"
40
- - "RAILS_ENV=test bundle exec rake db:migrate:reset"
41
- - RAILS_ENV=test bundle exec rspec --format progress --format RspecJunitFormatter --out rspec.xml
42
-
43
- build_integration_image:
44
- extends: .build_integration_image
41
+ - bundle exec rake db:create
42
+ - bundle exec rake db:migrate:reset
43
+ - bundle exec rspec --format progress --format RspecJunitFormatter --out rspec.xml
45
44
 
46
45
  docker_build:
47
46
  extends: .docker_buildx_push
48
47
  only:
49
48
  - merge_requests
50
49
  - staging
50
+ - master
51
51
 
52
- <%- review_base_url = Modulorails.data.review_base_url -%>
53
- <%- if review_base_url.present? -%>
52
+ <%- if @review_base_url.present? -%>
54
53
  deploy_review:
55
54
  extends: .deploy_helm
56
55
  variables:
57
- NAMESPACE: <%= image_name %>-$CI_ENVIRONMENT_SLUG
58
- NAME: <%= image_name %>
59
- CHART_NAME: <%= image_name %>
60
- CONFIG_FILE: config/deploy/kubernetes/review.yaml
61
- EXTRA_VARS: --set image.tag=$CI_COMMIT_SHORT_SHA --set ingress.hosts[0].host=${CI_ENVIRONMENT_SLUG}.<%= review_base_url %> --set ingress.tls[0].hosts[0]=${CI_ENVIRONMENT_SLUG}.<%= review_base_url %> --set env.url=${CI_ENVIRONMENT_SLUG}.<%= review_base_url %> --set database.password=$DB_PASSWORD --set encryption.key=$ENCRYPTION_KEY
56
+ NAMESPACE: <%= @image_name %>-$CI_ENVIRONMENT_SLUG
57
+ NAME: <%= @image_name %>
58
+ CHART_NAME: <%= @image_name %>
59
+ CONFIG_FILE: config/deploy/review.yaml
60
+ EXTRA_VARS: --set image.tag=$CI_COMMIT_SHORT_SHA --set ingress.hosts[0].host=${CI_ENVIRONMENT_SLUG}.<%= @review_base_url %> --set ingress.tls[0].hosts[0]=${CI_ENVIRONMENT_SLUG}.<%= @review_base_url %> --set env.url=${CI_ENVIRONMENT_SLUG}.<%= @review_base_url %> --set database.url=$DATABASE_URL --set master_key.key=$MASTER_KEY
62
61
  environment:
63
62
  name: review/$CI_COMMIT_REF_SLUG
64
- url: https://${CI_ENVIRONMENT_SLUG}.<%= review_base_url %>
63
+ url: https://${CI_ENVIRONMENT_SLUG}.<%= @review_base_url %>
65
64
  on_stop: stop_review
66
65
  auto_stop_in: 3 days
67
66
  only:
@@ -70,56 +69,40 @@ deploy_review:
70
69
  stop_review:
71
70
  extends: .stop_review
72
71
  variables:
73
- NAMESPACE: <%= image_name %>-$CI_ENVIRONMENT_SLUG
74
- NAME: <%= image_name %>
72
+ NAMESPACE: <%= @image_name %>-$CI_ENVIRONMENT_SLUG
73
+ NAME: <%= @image_name %>
75
74
  only:
76
75
  - merge_requests
77
76
  <%- end -%>
78
77
 
79
- <%- staging_url = Modulorails.data.staging_url -%>
80
- <%- if staging_url.present? -%>
78
+ <%- if @staging_url.present? -%>
81
79
  deploy_staging:
82
80
  extends: .deploy_helm
83
81
  variables:
84
- NAMESPACE: <%= image_name %>
85
- NAME: <%= image_name %>
86
- CHART_NAME: <%= image_name %>
87
- CONFIG_FILE: config/deploy/kubernetes/staging.yaml
88
- EXTRA_VARS: --set image.tag=$CI_COMMIT_SHORT_SHA --set database.password=$DB_PASSWORD
82
+ NAMESPACE: <%= @image_name %>
83
+ NAME: <%= @image_name %>
84
+ CHART_NAME: <%= @image_name %>
85
+ CONFIG_FILE: config/deploy/staging.yaml
86
+ EXTRA_VARS: --set image.tag=$CI_COMMIT_SHORT_SHA --set database.url=$DATABASE_URL --set master_key.key=$MASTER_KEY
89
87
  environment:
90
88
  name: staging
91
- url: https://<%= staging_url %>
92
- only:
93
- - staging
94
- <%- else -%>
95
- deploy_staging:
96
- extends: .deploy_capistrano
97
- variables:
98
- STAGE: staging
89
+ url: https://<%= @staging_url %>
99
90
  only:
100
91
  - staging
101
92
  <%- end -%>
102
93
 
103
- <%- production_url = Modulorails.data.production_url -%>
104
- <%- if production_url.present? -%>
94
+ <%- if @production_url.present? -%>
105
95
  deploy_production:
106
96
  extends: .deploy_helm
107
97
  variables:
108
- NAMESPACE: <%= image_name %>
109
- NAME: <%= image_name %>
110
- CHART_NAME: <%= image_name %>
111
- CONFIG_FILE: config/deploy/kubernetes/production.yaml
112
- EXTRA_VARS: --set image.tag=$CI_COMMIT_SHORT_SHA --set database.password=$DB_PASSWORD
98
+ NAMESPACE: <%= @image_name %>
99
+ NAME: <%= @image_name %>
100
+ CHART_NAME: <%= @image_name %>
101
+ CONFIG_FILE: config/deploy/production.yaml
102
+ EXTRA_VARS: --set image.tag=$CI_COMMIT_SHORT_SHA
113
103
  environment:
114
104
  name: production
115
- url: https://<%= production_url %>
116
- only:
117
- - master
118
- <%- else -%>
119
- deploy_production:
120
- extends: .deploy_capistrano
121
- variables:
122
- STAGE: production
105
+ url: https://<%= @production_url %>
123
106
  only:
124
107
  - master
125
108
  <%- end -%>
@@ -0,0 +1,43 @@
1
+ imagePullSecrets:
2
+ - name: regcred
3
+
4
+ ingress:
5
+ enabled: true
6
+ annotations:
7
+ kubernetes.io/ingress.class: nginx
8
+ kubernetes.io/tls-acme: 'true'
9
+ hosts:
10
+ - host: <%= @production_url %>
11
+ paths:
12
+ - path: /
13
+ tls:
14
+ - secretName: <%= @image_name %>
15
+ hosts:
16
+ - <%= @production_url %>
17
+
18
+ resources:
19
+ requests:
20
+ cpu: 100m
21
+ memory: 512Mi
22
+ limits:
23
+ memory: 512Mi
24
+
25
+ autoscaling:
26
+ enabled: true
27
+ minReplicas: 2
28
+ maxReplicas: 10
29
+ targetCPUUtilizationPercentage: 80
30
+
31
+ database:
32
+ existingSecret: 'database-credential'
33
+
34
+ master_key:
35
+ existingSecret: 'masterkey-credential'
36
+
37
+ env:
38
+ RAILS_ENV: production
39
+ URL: https://<%= @production_url %>/
40
+
41
+ redis:
42
+ enabled: false
43
+ existingSecret: 'redis-credential'
@@ -0,0 +1,42 @@
1
+ imagePullSecrets:
2
+ - name: regcred
3
+
4
+ ingress:
5
+ enabled: true
6
+ annotations:
7
+ kubernetes.io/ingress.class: nginx
8
+ kubernetes.io/tls-acme: 'true'
9
+ hosts:
10
+ - host: $REVIEW_URL
11
+ paths:
12
+ - path: /
13
+ tls:
14
+ - secretName: <%= @image_name %>
15
+ hosts:
16
+ - $REVIEW_URL
17
+
18
+ resources:
19
+ requests:
20
+ cpu: 100m
21
+ memory: 512Mi
22
+ limits:
23
+ memory: 512Mi
24
+
25
+ autoscaling:
26
+ enabled: true
27
+ minReplicas: 1
28
+ maxReplicas: 10
29
+ targetCPUUtilizationPercentage: 80
30
+
31
+ database:
32
+ url: $DATABASE_URL
33
+
34
+ master_key:
35
+ key: $MASTER_KEY
36
+
37
+ env:
38
+ RAILS_ENV: staging
39
+ URL: https://$REVIEW_URL/
40
+
41
+ redis:
42
+ enabled: true
@@ -0,0 +1,42 @@
1
+ imagePullSecrets:
2
+ - name: regcred
3
+
4
+ ingress:
5
+ enabled: true
6
+ annotations:
7
+ kubernetes.io/ingress.class: nginx
8
+ kubernetes.io/tls-acme: 'true'
9
+ hosts:
10
+ - host: <%= @staging_url %>
11
+ paths:
12
+ - path: /
13
+ tls:
14
+ - secretName: <%= @image_name %>
15
+ hosts:
16
+ - <%= @staging_url %>
17
+
18
+ resources:
19
+ requests:
20
+ cpu: 100m
21
+ memory: 512Mi
22
+ limits:
23
+ memory: 512Mi
24
+
25
+ autoscaling:
26
+ enabled: true
27
+ minReplicas: 1
28
+ maxReplicas: 10
29
+ targetCPUUtilizationPercentage: 80
30
+
31
+ database:
32
+ url: $DATABASE_URL
33
+
34
+ master_key:
35
+ key: $MASTER_KEY
36
+
37
+ env:
38
+ RAILS_ENV: staging
39
+ URL: https://<%= @staging_url %>/
40
+
41
+ redis:
42
+ enabled: true
@@ -13,11 +13,7 @@ class Modulorails::HealthCheckGenerator < Rails::Generators::Base
13
13
 
14
14
  # Add the route
15
15
  unless File.read(Rails.root.join('config/routes.rb')).match?('health_check_routes')
16
- inject_into_file 'config/routes.rb', after: "Rails.application.routes.draw do\n" do
17
- <<~'RUBY'
18
- health_check_routes
19
- RUBY
20
- end
16
+ inject_into_file 'config/routes.rb', " health_check_routes\n\n", after: "Rails.application.routes.draw do\n"
21
17
  end
22
18
 
23
19
  # Update the gem and the Gemfile.lock
@@ -83,7 +83,7 @@ HealthCheck.setup do |config|
83
83
  # config.rabbitmq_config = {}
84
84
 
85
85
  # When redis url/password is non-standard
86
- config.redis_url = ENV['REDIS_URL']
86
+ config.redis_url = ENV.fetch('REDIS_URL', 'redis://redis:6379')
87
87
  # Only included if set, as url can optionally include passwords as well
88
88
  # config.redis_password = 'redis_password' # default ENV['REDIS_PASSWORD']
89
89
 
@@ -101,12 +101,12 @@ Metrics/CyclomaticComplexity:
101
101
 
102
102
  # Commonly used screens these days easily fit more than 80 characters.
103
103
  Layout/LineLength:
104
- Max: 100
104
+ Max: 120
105
105
 
106
106
  # Too short methods lead to extraction of single-use methods, which can make
107
107
  # the code easier to read (by naming things), but can also clutter the class
108
108
  Metrics/MethodLength:
109
- Max: 20
109
+ Max: 25
110
110
 
111
111
  # The guiding principle of classes is SRP, SRP can't be accurately measured by LoC
112
112
  Metrics/ClassLength:
@@ -265,3 +265,7 @@ Style/ParallelAssignment:
265
265
  # Checks the style of children definitions at classes and modules.
266
266
  Style/ClassAndModuleChildren:
267
267
  Enabled: false
268
+
269
+ # Useful to display but it really is a bother to change it: hence the `info` severity.
270
+ Rails/I18nLocaleTexts:
271
+ Severity: info
@@ -0,0 +1,14 @@
1
+ Description:
2
+ Generates a new Modulorails service. Pass the service name, either
3
+ CamelCased or under_scored, and a list of parameters as arguments.
4
+
5
+ To create a service within a module, specify the service name as a
6
+ path like 'parent_module/service_name'.
7
+
8
+ This generates a service class in app/services.
9
+
10
+ Example:
11
+ `bin/rails generate modulorails:service Missions::Search word page per`
12
+
13
+ Mission::Search service with positional parameters word, page and per.
14
+ Service: app/services/missions/search_service.rb
@@ -8,8 +8,20 @@ class Modulorails::ServiceGenerator < Rails::Generators::NamedBase
8
8
  desc 'This generator creates a service inheriting Modulorails::BaseService'
9
9
  argument :arguments, type: :array, default: [], banner: 'argument argument'
10
10
 
11
+ check_class_collision suffix: "Service"
12
+
11
13
  def create_service_files
12
14
  template 'service.rb', File.join('app/services', class_path, "#{file_name}_service.rb")
13
15
  end
14
16
 
17
+ private
18
+
19
+ def file_name
20
+ @_file_name ||= remove_possible_suffix(super)
21
+ end
22
+
23
+ def remove_possible_suffix(name)
24
+ name.sub(/_?service$/i, '')
25
+ end
26
+
15
27
  end
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+
5
+ class Modulorails::SidekiqGenerator < Rails::Generators::Base
6
+
7
+ source_root File.expand_path('templates', __dir__)
8
+
9
+ desc 'This generator adds Sidekiq to the project'
10
+
11
+ def add_to_docker_compose
12
+ add_to_docker_compose_yml_file(Rails.root.join('docker-compose.yml'))
13
+ end
14
+
15
+ def add_to_docker_compose_prod
16
+ add_to_docker_compose_yml_file(Rails.root.join('docker-compose.prod.yml'))
17
+ end
18
+
19
+ def add_to_deploy_files
20
+ add_to_deploy_file(Rails.root.join('config/deploy/production.yaml'))
21
+ add_to_deploy_file(Rails.root.join('config/deploy/staging.yaml'))
22
+ add_to_deploy_file(Rails.root.join('config/deploy/review.yaml'))
23
+ end
24
+
25
+ def add_to_gemfile
26
+ gemfile_path = Rails.root.join('Gemfile')
27
+
28
+ # Add gem redis unless already present
29
+ unless File.read(gemfile_path).match?(/^\s*gem ['"]redis['"]/)
30
+ append_to_file(gemfile_path, "gem 'redis'\n")
31
+ end
32
+
33
+ # Add gem sidekiq unless already present
34
+ unless File.read(gemfile_path).match?(/^\s*gem ['"]sidekiq['"]/)
35
+ append_to_file(gemfile_path, "gem 'sidekiq'\n")
36
+ end
37
+ end
38
+
39
+ def add_to_config
40
+ Dir.glob(Rails.root.join('config/environments/*.rb')) do |file|
41
+ add_to_config_file(file)
42
+ end
43
+ end
44
+
45
+ def add_initializer
46
+ template 'config/initializers/sidekiq.rb'
47
+ end
48
+
49
+ def add_routes
50
+ routes_path = Rails.root.join('config/routes.rb')
51
+
52
+ unless File.read(routes_path).match?(%r{require ['"]sidekiq/web["']})
53
+ inject_into_file routes_path, after: "Rails.application.routes.draw do\n" do
54
+ <<-RUBY
55
+ require 'sidekiq/web'
56
+ mount Sidekiq::Web => '/sidekiq'
57
+
58
+ RUBY
59
+ end
60
+ end
61
+ end
62
+
63
+ def add_health_check
64
+ file_path = Rails.root.join('config/initializers/health_check.rb')
65
+
66
+ unless File.read(file_path).match?(%r{add_custom_check\s*\(?\s*['"]sidekiq-queues['"]\s*\)?})
67
+ inject_into_file file_path, after: /^HealthCheck.setup do \|config\|\n$/ do
68
+ <<-RUBY
69
+
70
+ # Add one or more custom checks that return a blank string if ok, or an error message if there is an error
71
+ config.add_custom_check('sidekiq-queues') do
72
+ queues = Sidekiq::Queue.all
73
+
74
+ # No queues, means no jobs, ok!
75
+ next '' if queues.empty?
76
+
77
+ enqueued_jobs_count = queues.each.map { |queue| queue.count }.sum
78
+
79
+ # Less than 200 enqueued jobs, ok!
80
+ enqueued_jobs_count < 200 ? '' : "\#{enqueued_jobs_count} are currently enqueued."
81
+ end
82
+
83
+ # Add one or more custom checks that return a blank string if ok, or an error message if there is an error
84
+ config.add_custom_check('sidekiq-retries') do
85
+ retry_jobs_count = Sidekiq::RetrySet.new.count
86
+
87
+ # Less than 200 jobs to retry, ok!
88
+ retry_jobs_count < 200 ? '' : "\#{retry_jobs_count} are waiting for retry."
89
+ end
90
+ RUBY
91
+ end
92
+ end
93
+ end
94
+
95
+ def add_entrypoint
96
+ template 'entrypoints/sidekiq-entrypoint.sh'
97
+ chmod 'entrypoints/sidekiq-entrypoint.sh', 0755
98
+ end
99
+
100
+ private
101
+
102
+ def add_to_docker_compose_yml_file(file_path)
103
+ @image_name ||= Modulorails.data.name.parameterize
104
+
105
+ # Create docker-compose.yml unless present
106
+ unless File.exist?(file_path)
107
+ # Modulorails::GitlabciGenerator.new([], {}, {}).invoke_all
108
+ invoke(Modulorails::DockerGenerator, [])
109
+ end
110
+
111
+ return if File.read(file_path).match?(/^ {2}sidekiq:$/)
112
+
113
+ insert_into_file file_path, after: /^services:/ do
114
+ <<-YAML
115
+
116
+ sidekiq:
117
+ image: modulotechgroup/#{@image_name}:dev
118
+ build:
119
+ context: .
120
+ dockerfile: Dockerfile
121
+ depends_on:
122
+ - database
123
+ - redis
124
+ volumes:
125
+ - .:/app
126
+ environment:
127
+ RAILS_ENV: development
128
+ URL: http://app:3000
129
+ #{@image_name.upcase}_DATABASE_HOST: database
130
+ #{@image_name.upcase}_DATABASE_NAME: #{@image_name}
131
+ REDIS_URL: redis://redis:6379/1
132
+ entrypoint: ./entrypoints/sidekiq-entrypoint.sh
133
+ stdin_open: true
134
+ tty: true
135
+ YAML
136
+ end
137
+ end
138
+
139
+ def add_to_config_file(file_path)
140
+ pattern = /^(?>\s*)(?>#\s*)?(\w+)\.active_job\.queue_adapter = .+$/
141
+
142
+ if File.read(file_path).match?(pattern)
143
+ gsub_file file_path, pattern, ' \1.active_job.queue_adapter = :sidekiq'
144
+ else
145
+ append_file file_path, after: "configure do\n" do
146
+ <<-RUBY
147
+ config.active_job.queue_adapter = :sidekiq
148
+ RUBY
149
+ end
150
+ end
151
+ end
152
+
153
+ def add_to_deploy_file(file_path)
154
+ # Do nothing if file does not exists or Sidekiq is already enabled
155
+ return if !File.exist?(file_path) || File.read(file_path).match?(/^ {2}sidekiq:$/)
156
+
157
+ # Add sidekiq to deploy file
158
+ insert_into_file file_path do
159
+ <<-YAML
160
+
161
+ sidekiq:
162
+ enabled: true
163
+ resources:
164
+ requests:
165
+ cpu: 100m
166
+ memory: 512Mi
167
+ limits:
168
+ cpu: 100m
169
+ memory: 512Mi
170
+ autoscaling:
171
+ enabled: true
172
+ minReplicas: 1
173
+ maxReplicas: 10
174
+ targetCPUUtilizationPercentage: 80
175
+ YAML
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,9 @@
1
+ redis_url = Rails.application.config_for('cable')['url']
2
+
3
+ Sidekiq.configure_server do |config|
4
+ config.redis = { url: redis_url }
5
+ end
6
+
7
+ Sidekiq.configure_client do |config|
8
+ config.redis = { url: redis_url }
9
+ end
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ # Exit immediately if a command exits with a non-zero status
4
+ set -e
5
+
6
+ # Launch Sidekiq
7
+ exec ./bin/bundle exec sidekiq
@@ -15,6 +15,7 @@ module Modulorails
15
15
  bundler_version modulorails_version adapter db_version adapter_version webpacker_version
16
16
  importmap_version jsbundling_version
17
17
  production_url staging_url review_base_url
18
+ environment_name
18
19
  ].freeze
19
20
 
20
21
  # Useful if the gem's user need to read one of the data
@@ -73,6 +74,9 @@ module Modulorails
73
74
  # The name is the usual name of the project, the one used in conversations at Modulotech
74
75
  @name = configuration.name
75
76
 
77
+ # A version of the name suitable to name environment variables
78
+ @environment_name = @name.parameterize.gsub('-', '_').gsub(/\b(\d)/, 'MT_\1').upcase
79
+
76
80
  # The main developer, the lead developer, in short the developer to call when something's
77
81
  # wrong with the application ;)
78
82
  @main_developer = configuration.main_developer
@@ -1,6 +1,6 @@
1
1
  module Modulorails
2
2
 
3
- VERSION = '1.2.1'.freeze
3
+ VERSION = '1.3.1'.freeze
4
4
 
5
5
  # Useful to compare the current Ruby version
6
6
  COMPARABLE_RUBY_VERSION = Gem::Version.new(RUBY_VERSION)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modulorails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthieu Ciappara
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-09 00:00:00.000000000 Z
11
+ date: 2023-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: git
@@ -202,6 +202,7 @@ files:
202
202
  - lib/generators/modulorails/docker/docker_generator.rb
203
203
  - lib/generators/modulorails/docker/templates/Dockerfile.prod.tt
204
204
  - lib/generators/modulorails/docker/templates/Dockerfile.tt
205
+ - lib/generators/modulorails/docker/templates/config/cable.yml.tt
205
206
  - lib/generators/modulorails/docker/templates/config/database.yml.tt
206
207
  - lib/generators/modulorails/docker/templates/docker-compose.prod.yml.tt
207
208
  - lib/generators/modulorails/docker/templates/docker-compose.yml.tt
@@ -210,14 +211,21 @@ files:
210
211
  - lib/generators/modulorails/gitlabci/gitlabci_generator.rb
211
212
  - lib/generators/modulorails/gitlabci/templates/.gitlab-ci.yml.tt
212
213
  - lib/generators/modulorails/gitlabci/templates/.modulorails-gitlab-ci
214
+ - lib/generators/modulorails/gitlabci/templates/config/deploy/production.yaml.tt
215
+ - lib/generators/modulorails/gitlabci/templates/config/deploy/review.yaml.tt
216
+ - lib/generators/modulorails/gitlabci/templates/config/deploy/staging.yaml.tt
213
217
  - lib/generators/modulorails/healthcheck/health_check_generator.rb
214
218
  - lib/generators/modulorails/healthcheck/templates/.modulorails-health_check
215
219
  - lib/generators/modulorails/healthcheck/templates/config/initializers/health_check.rb.tt
216
220
  - lib/generators/modulorails/rubocop/rubocop_generator.rb
217
221
  - lib/generators/modulorails/rubocop/templates/rubocop.yml.tt
218
222
  - lib/generators/modulorails/self_update/self_update_generator.rb
223
+ - lib/generators/modulorails/service/USAGE
219
224
  - lib/generators/modulorails/service/service_generator.rb
220
225
  - lib/generators/modulorails/service/templates/service.rb.tt
226
+ - lib/generators/modulorails/sidekiq/sidekiq_generator.rb
227
+ - lib/generators/modulorails/sidekiq/templates/config/initializers/sidekiq.rb.tt
228
+ - lib/generators/modulorails/sidekiq/templates/entrypoints/sidekiq-entrypoint.sh.tt
221
229
  - lib/modulorails.rb
222
230
  - lib/modulorails/configuration.rb
223
231
  - lib/modulorails/data.rb