Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,16 @@ When planning new features or architectural changes, use the `layered-rails` ski
- **Historical migrations**: All pre-2026 migrations were removed. New databases are bootstrapped from `db/schema.rb` via `db:prepare`. The 13 migrations from 2026 onwards remain and are audited by strong_migrations.
- **Seeds**: `db/seeds.rb` creates sample data for development

### Migrations and Heroku preboot

Production runs with [Heroku preboot](https://devcenter.heroku.com/articles/preboot): new web dynos boot before old ones stop, and traffic switches about 3 minutes after the deploy. The release phase (`rake db:prepare`) runs before new dynos boot, so old code serves against the new schema during that window. Migrations must therefore be forward-compatible:

- Expand first, contract later. Add columns without a default, then set the default in a second migration. Backfill in batches.
- Before `remove_column`, add the column to `ignored_columns` and deploy code that no longer reads or writes it, then remove the column in a separate deploy.
- Rename columns in two steps: add the new column, sync data, deploy code that uses the new name, then remove the old column.
- `safety_assured` around a destructive operation means "the old release tolerates this", not "this is fine". It does not make a migration forward-compatible.
- A migration that cannot be made forward-compatible needs preboot temporarily disabled for its deploy: `heroku features:disable preboot`, deploy, then `heroku features:enable preboot`.

## Deployment

This app uses Heroku. See `Makefile` for deployment commands (requires appropriate Heroku access):
Expand Down
15 changes: 14 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,17 @@ Syntax guidelines:
* `my_method(my_arg)` or `my_method` and _not_ `my_method( my_arg )`
* `a = b` and not `a=b`.
* Aim for 1.9 hash syntax - `{ dog: "Akira", cat: "Rocky" }` rather than `{ :dog => "Akira", :pug => "Rocky" }`
* Follow the conventions you see used in the source already.
* Follow the conventions you see used in the source already.

## Deploys and preboot

Production runs with [Heroku preboot](https://devcenter.heroku.com/articles/preboot). New web dynos start before the old ones stop, which avoids the brief 503 window of a normal restart deploy, provided the new dynos boot successfully. Traffic switches to the new dynos about 3 minutes after the deploy completes (whether or not they boot cleanly), and the old dynos shut down then.

What this means when you deploy:

* New code starts serving about 3 minutes after the deploy. Wait for the switchover before you verify a fix on production.
* During the overlap two code versions run side by side, but only one serves traffic. `heroku ps` shows only the new dynos; the still-serving old dynos do not appear in it. Watch `heroku logs --tail` to see the old dynos shut down after the switch.
* To stop a bad dyno immediately, use `heroku ps:stop`. With preboot, a plain `heroku restart` only fully takes effect after restarts have stopped for about 3 minutes.
* A migration that cannot run against the old code needs preboot temporarily disabled: `heroku features:disable preboot`, deploy, then `heroku features:enable preboot`. See the migration guidance in `AGENTS.md`.

Only the `web` process type is affected. One-off dynos and scheduled jobs behave as before.
Loading