diff --git a/.env b/.env new file mode 100644 index 00000000..62e1ed87 --- /dev/null +++ b/.env @@ -0,0 +1,20 @@ +# DO NOT STORE SECRETS HERE. +# Use .env.development for local secrets. + +REDIS_URL=redis://localhost:6379 + +# CI/CD +TEST_RETRY=0 +CI=false + +# Mail +MAILER_DEFAULT_HOST=localhost +MAILER_DEFAULT_PORT=3000 +MAILER_SENDER=Test + +# Locales +AVAILABLE_LOCALES=en +DEFAULT_LOCALE=en +FALLBACK_LOCALES=en + +SECRET_KEY_BASE=replace_with_lengthy_secure_hex diff --git a/.env.development.example b/.env.development.example new file mode 100644 index 00000000..6ab4e54b --- /dev/null +++ b/.env.development.example @@ -0,0 +1,5 @@ +# DO NOT COMMIT THIS FILE (`.env.development`) +# Rename it to `.env.development` and use it for local secrets only. + +# Used to verify the integrity of signed cookies. so ensure a secure value is set +SECRET_KEY_BASE=replace_with_lengthy_secure_hex diff --git a/.gitignore.rb b/.gitignore.rb index 5160ebf0..a6687030 100644 --- a/.gitignore.rb +++ b/.gitignore.rb @@ -10,5 +10,8 @@ # Ignore the test coverage results from SimpleCov /coverage + + # Ignore environment variables files + .env.development IGNORE end diff --git a/.template/addons/docker/.env.tt b/.template/addons/docker/.env.tt deleted file mode 100644 index 7be3e1c5..00000000 --- a/.template/addons/docker/.env.tt +++ /dev/null @@ -1,6 +0,0 @@ -DOCKER_REGISTRY_HOST=<%= DOCKER_REGISTRY_HOST %> -DOCKER_IMAGE=<%= DOCKER_IMAGE %> -BRANCH_TAG=latest -PORT=80 -CI=false -TEST_RETRY=0 diff --git a/.template/addons/docker/Dockerfile.tt b/.template/addons/docker/Dockerfile.tt index 22bb1f9e..aa9f41a9 100644 --- a/.template/addons/docker/Dockerfile.tt +++ b/.template/addons/docker/Dockerfile.tt @@ -98,8 +98,11 @@ COPY . ./ RUN rm -rf tmp/docker <%- if WEB_VARIANT -%> + # Compile assets -RUN bin/docker-assets-precompile +RUN bundle exec rails i18n:js:export +RUN bundle exec rails assets:precompile --trace +RUN yarn postcss <%- end -%> EXPOSE $PORT diff --git a/.template/addons/docker/template.rb b/.template/addons/docker/template.rb index 18b65679..a2ee54ce 100644 --- a/.template/addons/docker/template.rb +++ b/.template/addons/docker/template.rb @@ -6,5 +6,16 @@ template 'docker-compose.dev.yml.tt' template 'docker-compose.test.yml.tt' template 'docker-compose.yml.tt' -template '.env.tt' template '.dockerignore.tt' + +append_to_file '.env' do + <<~ENVEXAMPLE + + # Docker + APP_NAME=#{APP_NAME} + DOCKER_REGISTRY_HOST=#{DOCKER_REGISTRY_HOST} + DOCKER_IMAGE=#{DOCKER_IMAGE} + BRANCH_TAG=latest + PORT=80 + ENVEXAMPLE +end diff --git a/.template/spec/addons/base/docker/template_spec.rb b/.template/spec/addons/base/docker/template_spec.rb index 208b3741..875edc76 100644 --- a/.template/spec/addons/base/docker/template_spec.rb +++ b/.template/spec/addons/base/docker/template_spec.rb @@ -5,10 +5,6 @@ expect(file('Dockerfile')).to exist end - it 'creates the docker env file' do - expect(file('.env')).to exist - end - it 'creates the docker ignore file' do expect(file('.dockerignore')).to exist end diff --git a/.template/spec/base/bin/template_spec.rb b/.template/spec/base/bin/template_spec.rb index d5e7e629..4943515d 100644 --- a/.template/spec/base/bin/template_spec.rb +++ b/.template/spec/base/bin/template_spec.rb @@ -30,9 +30,4 @@ expect(file('bin/docker-prepare')).to exist expect(file('bin/docker-prepare')).to be_executable end - - it 'creates the docker asset precompile script' do - expect(file('bin/docker-assets-precompile')).to exist - expect(file('bin/docker-assets-precompile')).to be_executable - end end diff --git a/.template/spec/base/config/template_spec.rb b/.template/spec/base/config/template_spec.rb index 412862d1..8bbf2228 100644 --- a/.template/spec/base/config/template_spec.rb +++ b/.template/spec/base/config/template_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true describe '/config template' do - it 'creates the Figaro configuration for application variables' do - expect(file('config/application.yml')).to exist + it 'does NOT create the application.yml config' do + expect(file('config/application.yml')).not_to exist end it 'creates the database configuration' do diff --git a/.template/spec/base/template_spec.rb b/.template/spec/base/template_spec.rb index 430f1fef..68e015e9 100644 --- a/.template/spec/base/template_spec.rb +++ b/.template/spec/base/template_spec.rb @@ -30,4 +30,12 @@ it 'creates Reek configuration files' do expect(file('.reek.yml')).to exist end + + it 'creates .env file' do + expect(file('.env')).to exist + end + + it 'creates .env.development.example file' do + expect(file('.env.development.example')).to exist + end end diff --git a/.template/variants/web/package.json.rb b/.template/variants/web/package.json.rb index 8754d306..c0f2b80d 100644 --- a/.template/variants/web/package.json.rb +++ b/.template/variants/web/package.json.rb @@ -29,8 +29,9 @@ run 'yarn add postcss postcss-cli autoprefixer' run 'yarn add --dev @nimblehq/eslint-config-nimble@2.2.1' -run 'yarn add --dev stylelint' +run 'yarn add --dev stylelint@14' run 'yarn add --dev @nimblehq/stylelint-config-nimble' + # Setup scripts run 'npm set-script eslint "eslint . --color"' run 'npm set-script eslint:fix "eslint . --color --fix"' diff --git a/.template/variants/web/template.rb b/.template/variants/web/template.rb index 83660a38..fa1bdc3b 100644 --- a/.template/variants/web/template.rb +++ b/.template/variants/web/template.rb @@ -28,14 +28,13 @@ def apply_web_variant! after_bundle do use_source_path __dir__ - - # Generate translation file - run 'bin/rake i18n:js:export' - # Fix the default Rails template that does not put trailing commas run 'yarn run codebase:fix' apply 'spec/template.rb' + + # Generate translation file + run 'bundle exec rake i18n:js:export' end end diff --git a/Gemfile.tt b/Gemfile.tt index 8d603fe6..7a48a9fb 100644 --- a/Gemfile.tt +++ b/Gemfile.tt @@ -8,6 +8,7 @@ gem 'puma' # Use Puma as the app server gem 'mini_magick' # A ruby wrapper for ImageMagick or GraphicsMagick command line gem 'pagy' # A pagination gem that is very light and fast gem 'discard' # Soft deletes for ActiveRecord +gem 'dotenv-rails' # Shim to load environment variables from .env into ENV in development gem 'sidekiq' # background processing for Ruby gem 'sassc' # bootsnap dependency gem 'bootsnap', require: false # Reduces boot times through caching; required in config/boot.rb @@ -41,7 +42,6 @@ group :development, :test do # gem 'debug', platforms: %i[ mri mingw x64_mingw ] # Official debug # Utilities - gem 'figaro' # Simple Rails app configuration gem 'listen' # Listens to file modifications gem 'letter_opener' # Preview mail in the browser instead of sending gem 'ffaker' # A library for generating fake data such as names, addresses, and phone numbers diff --git a/Makefile b/Makefile index 4015127d..8a89c20e 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ test_template: if [ $(VARIANT) = web ]; then \ bundle exec rspec --pattern="${base_spec}, ${web_spec}, ${base_addon_spec}, ${web_addon_spec}" --format progress; \ elif [ $(VARIANT) = api ]; then \ - bundle exec rspec --pattern="${base_spec}, ${api_spec}, ${base_addon_spec}, ${api_addon_spec}" --format progress; \ + bundle exec rspec --pattern="${base_spec}, ${api_spec}, ${base_addon_spec}, ${api_addon_spec}"; \ fi; cleanup: diff --git a/bin/docker-assets-precompile b/bin/docker-assets-precompile deleted file mode 100755 index a5b95c27..00000000 --- a/bin/docker-assets-precompile +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# For building production docker image -# -# It sets the envs inside the docker image for precompiling the assets -# Because to precompile the assets, Rails initializes the app. -# And it requires the envs as we always use `ENV.fetch` to setup the variables -# -# Related issue: https://github.com/rails/rails/issues/32947 -# TODO: https://github.com/nimblehq/rails-templates/issues/326 - -require 'yaml' - -rails_env = ENV.fetch('RAILS_ENV', 'production') - -if rails_env == 'production' - docker_build_envs = YAML.load_file('config/application.yml')['docker_build'] - docker_build_envs.each { |name, value| ENV[name] = value } - - ENV['DATABASE_URL'] = 'postgres://postgres:postgres@postgres:5432/postgres' -end - -exit system('bin/rails i18n:js:export && bin/rails assets:precompile && yarn postcss') diff --git a/bin/start.sh b/bin/start.sh index 941c7423..9b28fbf4 100755 --- a/bin/start.sh +++ b/bin/start.sh @@ -7,6 +7,9 @@ if [ -f tmp/pids/server.pid ]; then rm -f tmp/pids/server.pid fi +bundle install +bundle update + # Run pending migrations (if any) and start rails bundle exec rails db:migrate bundle exec rails s -p $PORT -b 0.0.0.0 diff --git a/bin/template.rb b/bin/template.rb index eabab904..5a92ad14 100644 --- a/bin/template.rb +++ b/bin/template.rb @@ -7,4 +7,3 @@ copy_file 'bin/worker.sh', mode: :preserve copy_file 'bin/dev', mode: :preserve copy_file 'bin/docker-prepare', mode: :preserve -copy_file 'bin/docker-assets-precompile', mode: :preserve diff --git a/config/application.yml.tt b/config/application.yml.tt deleted file mode 100644 index cdc23963..00000000 --- a/config/application.yml.tt +++ /dev/null @@ -1,25 +0,0 @@ -default: &default - DB_NAME: "<%= APP_NAME %>" - DB_HOST: "localhost" - DB_PORT: "5432" - DB_USERNAME: "postgres" - DB_PASSWORD: "postgres" - MAILER_DEFAULT_HOST: "localhost" - MAILER_DEFAULT_PORT: "3000" - MAILER_SENDER: "Test " - AVAILABLE_LOCALES: "en" - DEFAULT_LOCALE: "en" - FALLBACK_LOCALES: "en" - -development: - <<: *default - -test: - <<: *default - TEST_RETRY: "0" - -# Set environment variables required in the initializers in order to precompile the assets. -# Because it initializes the app, so all variables need to exist in the Docker build stage (used in bin/docker-assets-precompile). -docker_build: - <<: *default - SECRET_KEY_BASE: dummy_secret_key_base diff --git a/config/database.yml b/config/database.yml deleted file mode 100644 index c75c989a..00000000 --- a/config/database.yml +++ /dev/null @@ -1,23 +0,0 @@ -default: &default - adapter: postgresql - encoding: unicode - pool: 5 - -development: - <<: *default - host: <%= ENV['DB_HOST'] %> - port: <%= ENV['DB_PORT'] %> - username: <%= ENV['DB_USERNAME'] %> - password: <%= ENV['DB_PASSWORD'] %> - database: <%= ENV['DB_NAME'] %>_development - -test: - <<: *default - host: <%= ENV['DB_HOST'] %> - port: <%= ENV['DB_PORT'] %> - username: <%= ENV['DB_USERNAME'] %> - password: <%= ENV['DB_PASSWORD'] %> - database: <%= ENV['DB_NAME'] %>_test - -production: - url: <%= ENV['DATABASE_URL'] %> diff --git a/config/database.yml.tt b/config/database.yml.tt new file mode 100644 index 00000000..2e473563 --- /dev/null +++ b/config/database.yml.tt @@ -0,0 +1,23 @@ +default: &default + adapter: postgresql + encoding: unicode + pool: 5 + +development: + <<: *default + host: <%= ENV.fetch('DB_HOST') { 'localhost' } %> + port: <%= ENV.fetch('DB_PORT') { 5432 } %> + username: <%= ENV.fetch('DB_USERNAME') { 'postgres' } %> + password: <%= ENV.fetch('DB_PASSWORD') { 'postgres' } %> + database: <%= ENV.fetch('DB_NAME') { APP_NAME } %>_development + +test: + <<: *default + host: <%= ENV.fetch('DB_HOST') { 'localhost' } %> + port: <%= ENV.fetch('DB_PORT') { 5432 } %> + username: <%= ENV.fetch('DB_USERNAME') { 'postgres' } %> + password: <%= ENV.fetch('DB_PASSWORD') { 'postgres' } %> + database: <%= ENV.fetch('DB_NAME') { APP_NAME } %>_test + +production: + url: <%= ENV.fetch('DATABASE_URL') { '' } %> diff --git a/config/template.rb b/config/template.rb index 74caecb6..69f0091d 100644 --- a/config/template.rb +++ b/config/template.rb @@ -2,8 +2,7 @@ apply 'config/application.rb' -template 'config/application.yml.tt' -copy_file 'config/database.yml', force: true +template 'config/database.yml.tt', force: true copy_file 'config/sidekiq.yml' apply 'config/environments/development.rb' diff --git a/template.rb b/template.rb index f8bb4a87..df16ab4c 100644 --- a/template.rb +++ b/template.rb @@ -34,6 +34,8 @@ def apply_template!(template_root) copy_file '.flayignore' copy_file 'Dangerfile' + copy_file '.env' + copy_file '.env.development.example' copy_file '.rubocop.yml' copy_file '.reek.yml'