Skip to main content

How-to-create-a-new-Rails-application

These are the steps that I used to create the store-integration Rails application from scratch:

  1. Check that cd uala-backend && rails -v is the same of cd uala-backend/uala-core && bundle exec rails -v. If it doesn't, run gem uninstall railties and select the version not matching with uala-core's one
  2. Generate a new Rails application. I used the following options:
    cd uala-backend && rails new store-integration --database postgresql --api \
    --skip-git --skip-action-mailer --skip-action-mailbox --skip-action-cable \
    --skip-asset-pipeline --skip-javascript --skip-test
    cd store-integration
  3. Delete redundant files
    # Already defined and/or configured elsewhere
    rm app/models/application_record.rb config/initializers/cors.rb config/initializers/inflections.rb
  4. Copy several files from a sibling application. For the store-integration, I copied them from uala-internal-tools:
    cp ../uala-internal-tools/{Gemfile,.env.development,.env.test,.rubocop.yml,.undercover,.rspec} .
    cp ../uala-internal-tools/config/{sidekiq.yml,database.yml,database.ci.yml,puma.rb} config
    cp ../uala-internal-tools/config/environments/* config/environments
    cp --no-dereference ../uala-internal-tools/lib/hairdressr lib
    cp --no-dereference ../uala-internal-tools/db/schema.rb db
    cp --no-dereference ../uala-internal-tools/app/main_models app
    cp ../uala-internal-tools/bin/* bin
    mkdir -p spec/support
    cp ../uala-internal-tools/spec/{spec_helper.rb,rails_helper.rb} spec
    cp ../uala-internal-tools/spec/support/factory_bot.rb spec/support/
    cp --no-dereference ../uala-internal-tools/spec/main_factories spec
  5. Manually update some files. That's what I did for store-integration:
    1. Remove .rubocop_todo.yml reference from .rubocop.yml as the app is new so it doesn't have existing RuboCop errors
    2. Update uala-backend.code-workspace and .github/workflows/pull_request_title.yml copying sections from another existing app
    3. Copy Dockerfile from an existing sibling application and update it properly
    4. Update lefthook.yml properly
  6. Fix RuboCop offenses related to generated files:
    bundle
    bundle exec rubocop -A
  7. Customize config/application.rb adding the following lines:
    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    config.time_zone = "Rome"

    # Eager load `lib` path
    config.eager_load_paths << Rails.root.join("lib")
  8. Add mount Uala::Core::Engine => '/' to config/routes.rb, to provide routes necessary for the infrastructure (f.e. /ping)
  9. Wire the new app into the GitHub Actions pipelines:
    1. Add the new project to ci.yml's ci-lint and ci-tests-coverage matrices.
    2. Add a new per-app job block to each relevant cd-*.yml (cd-staging.yml, cd-production.yml, cd-on-demand.yml), copying an existing app's block and updating ecr_repository_name, dockerfile_path, overlay_base_path, and overlay_service_infix — see this for what these workflows do.
    3. Scaffold the new app's overlay in k8s-gitops-twpro. If it needs runtime secrets, list them in twpro-infra's config/<env>.yaml, then give the overlay a SecretProviderClass, a twpro-app serviceaccount.yaml and a csi-patch.yaml that mounts the class — an unmounted class produces nothing for envFrom to read. See Deployment secrets flow. A new namespace also needs adding to tofu/pod-identity/<cluster>/main.tf, or nothing in it can read a secret.