Guide for creating database migrations in the GitHub monolith (github/github). Use when creating new tables, adding columns, modifying indexes, or working with database schema changes. Covers required configuration files (tableowners.yaml, database_structure.rb, schema-domains.yml), migration-specific rubocop rules, database clusters, and testing patterns.
When creating migrations, multiple configuration files may need updating:
| File | New Table | Add Column | Purpose |
|---|---|---|---|
db/migrate/*.rb | Yes | Yes | The migration itself |
db/tableowners.yaml | Yes | No | Assign table ownership to a team |
lib/github/database_structure.rb | Yes | No | Register table in database cluster constant |
db/schema-domains.yml | Yes | No | Assign table to a schema domain |
sorbet/rbi/dsl/*.rbi | Yes | Yes | Regenerate with bin/tapioca dsl |
Always use the Rails generator to create migration files:
# Create a new table
bin/rails g migration CreateCopilotPolicies
# Add column to existing table
bin/rails g migration AddPolicyStudioAssignmentsToCopilotConfigurations
This ensures correct timestamp format and file naming conventions.
The monolith uses multiple database clusters. Migrations must specify which cluster to use.
Find the correct cluster by checking where similar tables are defined:
# Search for existing table definitions
grep -r "your_related_table" lib/github/database_structure.rb
Common clusters and their constants in database_structure.rb:
COPILOT_TABLES - Copilot-related tablesCOLLAB_TABLES - Collaboration featuresREPOSITORIES_TABLES - Repository dataBILLING_TABLES - Billing and subscriptionsSpecify the cluster in your migration:
class CreateCopilotPolicies < ActiveRecord::Migration[8.2]
self.use_connection_class(ApplicationRecord::Copilot)
def change
# ...
end
end
db/tableowners.yaml)Assign ownership to a GitHub team:
# Find insertion point (alphabetical by table name)
grep -n "copilot_" db/tableowners.yaml | head -10
Add entry in alphabetical order:
copilot_policies: github/copilot-policies
lib/github/database_structure.rb)Register the table in the appropriate cluster constant:
# Find the cluster constant
grep -n "COPILOT_TABLES" lib/github/database_structure.rb
Add table name in alphabetical order within the array:
COPILOT_TABLES = %w[
# ... existing tables ...
copilot_policies
# ... more tables ...
]
db/schema-domains.yml)Assign table to a domain for isolation:
# Find the domain section
grep -n "^copilot:" db/schema-domains.yml
Add table under the appropriate domain in alphabetical order: