modulorails 1.2.1 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
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