This is the documentation for maintainers and developers of the name.pn web app.
This app follows the Twelve-Factor specification, and this should be kept in mind when developing for it.
The app is configured using environment variables. On Heroku these can be configured using the heroku:config
command, and on your development environment they can be added to config/application.yml
as described in the Figaro documentation.
Variables that can be used to configure the app are:
- RAILS_MAX_THREADS: Number of threads the puma server will use
- DOMAIN_NAME: The canonical domain name of the site.
- DOMAIN_IN_EMAIL_LINKS: Override the above for email links specifically (e.g. if you need to add a port number or email links have a short domain name). Leave unset to use DOMAIN_NAME.
- EMAIL_FROM: The name and email address that will be used for 'From' in emails sent by this platform. Make sure the DKIM & SPF settings are correct for this domain with respect to your email sending service (e.g. SendGrid; see below).
- AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_REGION / S3_BUCKET: Creds for a user who has SES access to send mail and S3 permission to read/write the given bucket.
- GA_ID: Google Analytics ID
- MAILCHIMP_API_KEY / MAILCHIMP_LIST_ID: If set, enables the mailing list integration on the user's settings page and allows them to opt in when creating an account.
- JWT_SECRET: A secret (e.g. generated with
rails secret
) used in signing of JWT keys used with the name.pn public API.
Getting a development environment is easy on a Linux or Mac computer. You'll need the Docker and Docker Compose tools installed to proceed.
Assuming you have the docker
and docker-compose
tools in your path, all you need to do to create a development environment is:
cd ~/path/to/name_pn
./bin/bootstrap
What this does:
- Creates a docker image for your development environment, based on the provided
Dockerfile
- Installs the gems in
Gemfile
to your local repo invendor/bundle
. - Installs the yarn packages in
package.json
to your local repo innode_modules
. - Creates a database and populates it with an initial admin user.
Once you've created your development environment, you can bring it online with:
docker-compose up
This starts the database, the web server, and a webpack-dev-server with hot module replacement (so you can edit JS/CSS files without having to reload the page).
You can then access your development environment at http://localhost:3000/
If you need to get a shell, for example to run the Rails console, you can do:
docker-compose run web bash
The bootstrap script create an admin user who should be able to access the admin interface at http://localhost:3000/admin. The email is [email protected] and the password is password.
After updating the Gemfile
or package.json
, you'll need to install the new gem or yarn package. To do this:
docker-compose run web bundle
# or
docker-compose run web yarn
The app already conforms to the Twelve-Factor specification and has a Procfile with all the information Heroku needs to get going.
You'll need the Heroku CLI installed to run these commands.
The apt buildpack is used to install libvips, which is a prerequisite of the default ActiveStorage configuration for 7+.
To deploy it to Heroku, you can do:
cd ~/path/to/name.pn
# Replace name_pn with the name of the new heroku app
heroku apps:create --region eu name-pn
heroku buildpacks:add --index 1 heroku-community/apt
git push heroku main
The app should install all its dependencies and create the database automatically.
To get a Rails console on Heroku (e.g. for assigning the admin role to a user):
heroku run rails c
To deploy a new version:
git push heroku main
Or you can set up automatic deploys through the Heroku dashboard. If you're using GitHub & Codeship you can integrate this with your Codeship CI, so the new version is only deployed if the tests pass.
The app is configured for continuous integration using GitHub Actions. There are two workflows:
audits
: runs a security audit on the gem & yarn dependenciestests
: sets up a vaguely production-like environment and runs the rspec & spinach tests on it
No special configuration should be necessary - just using GitHub for this repo should be enough to enable the actions on every push.
If you're using Heroku it's a good idea to set it to only allow automatic deploys after CI passes.
This is a Rails 7.x application, and comes with all the usual Rails stuff, plus the following additional important components.
The user interface is derived from Bulma, in its modular Sass mode. The CSS is compiled in Webpack from the app/javascript/scss/application.scss
file and everything it includes. Remember to include Bulma features before you use them.
Frontend Javascript is based on the Stimulus framework. You can create a new JS controller by adding a file to app/javascript/controllers
and then naming that controller in your HTML by adding a data-controller
attribute to the parent element of the UI feature you want to control.
Because this is Webpack, Babel is enabled so you can use all the features of ES7 which will then be transpiled down to a browser-compatible form.
Most web views are written in the concise Haml templating language. This is a concise version of HTML but should be instantly familiar to anyone who knows HTML.
User management and authorization is provided by Devise and is subject to all the documentation there.
The administration interface is based on Active Admin and is accessible on your site at the /admin
URL.
You will need to be signed in as a user with role :admin
to access the admin interface. If you need to assign this role to an existing user from the Rails console you can do it like this:
User.find_by(email: '[email protected]').update(role: :admin)
All controller actions are authorized by Pundit policies. This allows us to ensure only the right users are allowed to do the right things at any given time.
Policies are located in app/policies
and can be applied using the policy_scope
method (for indexes) and the authorize
method (for other controller actions). There are some guards to ensure these methods are called. If you write a new controller action that definitely doesn't need authorization, you can skip these: see the HomeController
for an example.
Forms are normally managed by Simple Form, with a custom integration into the Bulma widget set. The customizations are in the config/initializers/simple_form_bulma.rb
file.
Meta tags are automatically provided by the MetaTags gem.
Titles for pages are normally set in the views using the title
helper with an I18n string called title
at an appropriate place on the page; for example:
= title t('.title')
Unit tests, API tests (if any) and policy tests are all done in regular rspec. All the config can be found in spec/spec_helper.rb
and spec/rails_helper.rb
.
To run these tests:
./bin/rspec
Integration tests are written in Spinach, using the acceptance criteria (in Gherkin format) in the features/
directory. Spinach is extremely similar to Cucumber, but encourages the use of one-time steps which are scoped to a specific feature.
The development environment integrates a headless Chromium browser, which can be used to test JavaScript. If you want to use this, just add the @javascript
tag to the feature and it will be automatically enabled in Capybara.
To run these tests:
./bin/spinach
Bundler Audit is a tool that looks for security advisories against any of the gems in your Gemfile. It's recomended to run this regularly (such as in the Codeship CI) and update the gems when it reports issues.
improved-yarn-audit does the same things for the JavaScript packages and is configured to run as part of
the Codeship steps. There's an .iyarc
file for configuring exceptions.
The app is configured to work with Datadog for tracing/debugging, including correlation of logs and traces.
To get this working in development, you'll need an account (a free plan one will do) and an API key. Set the DD_API_KEY
environment variable to your key before running docker-compose up
and the rest should sort itself out.
To get it working in Heroku, you'll need to follow the buildpack instructions for APM and the log drain instructions for logs.