pg_multitenant_schemas 0.1.3 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.actrc +17 -0
- data/.env.local.example +21 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +86 -0
- data/LOCAL_TESTING_SUMMARY.md +141 -0
- data/README.md +269 -16
- data/TESTING_LOCALLY.md +208 -0
- data/docs/README.md +81 -0
- data/docs/configuration.md +340 -0
- data/docs/context.md +292 -0
- data/docs/errors.md +498 -0
- data/docs/github_actions_permissions_fix.md +136 -0
- data/docs/github_actions_setup.md +181 -0
- data/docs/integration_testing.md +454 -0
- data/docs/local_workflow_testing.md +314 -0
- data/docs/migrator.md +291 -0
- data/docs/rails_integration.md +468 -0
- data/docs/schema_switcher.md +182 -0
- data/docs/tenant_resolver.md +394 -0
- data/docs/testing.md +358 -0
- data/examples/context_management.rb +198 -0
- data/examples/migration_workflow.rb +50 -0
- data/examples/rails_integration/controller_examples.rb +368 -0
- data/examples/schema_operations.rb +124 -0
- data/lib/pg_multitenant_schemas/configuration.rb +4 -4
- data/lib/pg_multitenant_schemas/migration_display_reporter.rb +30 -0
- data/lib/pg_multitenant_schemas/migration_executor.rb +81 -0
- data/lib/pg_multitenant_schemas/migration_schema_operations.rb +54 -0
- data/lib/pg_multitenant_schemas/migration_status_reporter.rb +65 -0
- data/lib/pg_multitenant_schemas/migrator.rb +89 -0
- data/lib/pg_multitenant_schemas/schema_switcher.rb +40 -66
- data/lib/pg_multitenant_schemas/tasks/advanced_tasks.rake +21 -0
- data/lib/pg_multitenant_schemas/tasks/basic_tasks.rake +20 -0
- data/lib/pg_multitenant_schemas/tasks/pg_multitenant_schemas.rake +53 -143
- data/lib/pg_multitenant_schemas/tasks/tenant_tasks.rake +65 -0
- data/lib/pg_multitenant_schemas/tenant_task_helpers.rb +102 -0
- data/lib/pg_multitenant_schemas/version.rb +1 -1
- data/lib/pg_multitenant_schemas.rb +10 -5
- data/pg_multitenant_schemas.gemspec +10 -9
- data/pre-push-check.sh +95 -0
- data/rails_integration/app/controllers/application_controller.rb +6 -0
- data/rails_integration/app/models/tenant.rb +6 -0
- data/test-github-setup.sh +85 -0
- data/validate-github-commands.sh +47 -0
- metadata +49 -17
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
# Testing GitHub Workflows Locally
|
|
2
|
+
|
|
3
|
+
This guide shows you how to test GitHub Actions workflows locally before pushing to GitHub.
|
|
4
|
+
|
|
5
|
+
## 🚀 Method 1: Using `act` (Recommended)
|
|
6
|
+
|
|
7
|
+
`act` is the most popular tool for running GitHub Actions locally using Docker.
|
|
8
|
+
|
|
9
|
+
### Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# macOS (using Homebrew)
|
|
13
|
+
brew install act
|
|
14
|
+
|
|
15
|
+
# Linux (using curl)
|
|
16
|
+
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
|
|
17
|
+
|
|
18
|
+
# Windows (using Chocolatey)
|
|
19
|
+
choco install act-cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Basic Usage
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# List all workflows
|
|
26
|
+
act -l
|
|
27
|
+
|
|
28
|
+
# Run all workflows
|
|
29
|
+
act
|
|
30
|
+
|
|
31
|
+
# Run specific workflow
|
|
32
|
+
act push
|
|
33
|
+
|
|
34
|
+
# Run specific job
|
|
35
|
+
act -j test
|
|
36
|
+
|
|
37
|
+
# Run with specific event
|
|
38
|
+
act pull_request
|
|
39
|
+
|
|
40
|
+
# Dry run (show what would be executed)
|
|
41
|
+
act -n
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Testing Our Workflows
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Test the main CI workflow
|
|
48
|
+
act push
|
|
49
|
+
|
|
50
|
+
# Test the release workflow (simulates a push to main)
|
|
51
|
+
act push --env GITHUB_REF=refs/heads/main
|
|
52
|
+
|
|
53
|
+
# Test pull request workflow
|
|
54
|
+
act pull_request
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Configuration
|
|
58
|
+
|
|
59
|
+
Create `.actrc` file in project root for default settings:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# .actrc
|
|
63
|
+
--container-architecture linux/amd64
|
|
64
|
+
--artifact-server-path /tmp/act-artifacts
|
|
65
|
+
--env-file .env.local
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Environment Variables
|
|
69
|
+
|
|
70
|
+
Create `.env.local` for local testing:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# .env.local
|
|
74
|
+
GITHUB_TOKEN=your_github_token_here
|
|
75
|
+
RUBYGEMS_API_KEY=your_rubygems_key_here
|
|
76
|
+
GITHUB_REPOSITORY=rubenpazch/pg_multitenant_schemas
|
|
77
|
+
GITHUB_ACTOR=your_username
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## 🔧 Method 2: Manual Testing Components
|
|
81
|
+
|
|
82
|
+
### Test RuboCop Locally
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Run RuboCop (same as in CI)
|
|
86
|
+
bundle exec rubocop
|
|
87
|
+
|
|
88
|
+
# Auto-fix issues
|
|
89
|
+
bundle exec rubocop -A
|
|
90
|
+
|
|
91
|
+
# Check specific files
|
|
92
|
+
bundle exec rubocop lib/ spec/
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Test RSpec Locally
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Run all tests
|
|
99
|
+
bundle exec rspec
|
|
100
|
+
|
|
101
|
+
# Run with coverage (if configured)
|
|
102
|
+
COVERAGE=true bundle exec rspec
|
|
103
|
+
|
|
104
|
+
# Run integration tests
|
|
105
|
+
bundle exec rspec --tag integration
|
|
106
|
+
|
|
107
|
+
# Run tests with different Ruby versions (using rbenv/rvm)
|
|
108
|
+
rbenv shell 3.2.0 && bundle exec rspec
|
|
109
|
+
rbenv shell 3.3.0 && bundle exec rspec
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Test Gem Building
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Build gem locally
|
|
116
|
+
gem build pg_multitenant_schemas.gemspec
|
|
117
|
+
|
|
118
|
+
# Install locally built gem
|
|
119
|
+
gem install pg_multitenant_schemas-*.gem
|
|
120
|
+
|
|
121
|
+
# Test gem installation
|
|
122
|
+
gem list | grep pg_multitenant_schemas
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Test PostgreSQL Setup
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Start PostgreSQL (macOS with Homebrew)
|
|
129
|
+
brew services start postgresql@15
|
|
130
|
+
|
|
131
|
+
# Create test database
|
|
132
|
+
createdb pg_multitenant_test
|
|
133
|
+
|
|
134
|
+
# Run integration tests
|
|
135
|
+
PGDATABASE=pg_multitenant_test bundle exec rspec --tag integration
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## 🐳 Method 3: Docker-based Testing
|
|
139
|
+
|
|
140
|
+
Create a local testing environment that mirrors CI:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Create Dockerfile.test
|
|
144
|
+
cat > Dockerfile.test << 'EOF'
|
|
145
|
+
FROM ruby:3.3
|
|
146
|
+
|
|
147
|
+
# Install PostgreSQL client
|
|
148
|
+
RUN apt-get update && apt-get install -y postgresql-client
|
|
149
|
+
|
|
150
|
+
# Set working directory
|
|
151
|
+
WORKDIR /app
|
|
152
|
+
|
|
153
|
+
# Copy Gemfile
|
|
154
|
+
COPY Gemfile* ./
|
|
155
|
+
RUN bundle install
|
|
156
|
+
|
|
157
|
+
# Copy source code
|
|
158
|
+
COPY . .
|
|
159
|
+
|
|
160
|
+
# Run tests
|
|
161
|
+
CMD ["bundle", "exec", "rspec"]
|
|
162
|
+
EOF
|
|
163
|
+
|
|
164
|
+
# Build and run
|
|
165
|
+
docker build -f Dockerfile.test -t pg_multitenant_test .
|
|
166
|
+
docker run --rm pg_multitenant_test
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## 🔍 Method 4: GitHub CLI for Remote Testing
|
|
170
|
+
|
|
171
|
+
Use GitHub CLI to trigger workflows manually:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Install GitHub CLI
|
|
175
|
+
brew install gh
|
|
176
|
+
|
|
177
|
+
# Authenticate
|
|
178
|
+
gh auth login
|
|
179
|
+
|
|
180
|
+
# Trigger workflow manually
|
|
181
|
+
gh workflow run main.yml
|
|
182
|
+
|
|
183
|
+
# Check workflow status
|
|
184
|
+
gh run list
|
|
185
|
+
|
|
186
|
+
# View workflow logs
|
|
187
|
+
gh run view --log
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## 📋 Pre-Push Checklist
|
|
191
|
+
|
|
192
|
+
Before pushing to GitHub, run these commands locally:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
#!/bin/bash
|
|
196
|
+
# pre-push-check.sh
|
|
197
|
+
|
|
198
|
+
echo "🔍 Running pre-push checks..."
|
|
199
|
+
|
|
200
|
+
# 1. RuboCop
|
|
201
|
+
echo "Running RuboCop..."
|
|
202
|
+
bundle exec rubocop || exit 1
|
|
203
|
+
|
|
204
|
+
# 2. RSpec
|
|
205
|
+
echo "Running RSpec..."
|
|
206
|
+
bundle exec rspec || exit 1
|
|
207
|
+
|
|
208
|
+
# 3. Security audit
|
|
209
|
+
echo "Running security audit..."
|
|
210
|
+
bundle audit || exit 1
|
|
211
|
+
|
|
212
|
+
# 4. Gem build test
|
|
213
|
+
echo "Testing gem build..."
|
|
214
|
+
gem build pg_multitenant_schemas.gemspec || exit 1
|
|
215
|
+
|
|
216
|
+
# 5. Integration tests (if PostgreSQL available)
|
|
217
|
+
if command -v psql &> /dev/null; then
|
|
218
|
+
echo "Running integration tests..."
|
|
219
|
+
bundle exec rspec --tag integration || exit 1
|
|
220
|
+
fi
|
|
221
|
+
|
|
222
|
+
echo "✅ All checks passed! Ready to push."
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Make it executable:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
chmod +x pre-push-check.sh
|
|
229
|
+
./pre-push-check.sh
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## 🎯 Specific Workflow Testing
|
|
233
|
+
|
|
234
|
+
### Testing CI Workflow (main.yml)
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# Using act
|
|
238
|
+
act push -W .github/workflows/main.yml
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# Manual simulation
|
|
242
|
+
bundle install
|
|
243
|
+
bundle exec rubocop
|
|
244
|
+
bundle exec rspec --exclude-pattern '**/integration/**/*_spec.rb'
|
|
245
|
+
bundle audit
|
|
246
|
+
```
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Testing Release Workflow (release.yml)
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# Simulate version bump
|
|
253
|
+
# 1. Update version in lib/pg_multitenant_schemas/version.rb
|
|
254
|
+
# 2. Test locally
|
|
255
|
+
act push -W .github/workflows/release.yml --env GITHUB_REF=refs/heads/main
|
|
256
|
+
|
|
257
|
+
# Manual simulation (without actual publishing)
|
|
258
|
+
gem build pg_multitenant_schemas.gemspec
|
|
259
|
+
# Note: Don't run 'gem push' in testing
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## 🛠️ Troubleshooting
|
|
263
|
+
|
|
264
|
+
### Common Issues with `act`
|
|
265
|
+
|
|
266
|
+
1. **Docker not running**: Start Docker Desktop
|
|
267
|
+
2. **Permission issues**: Run with `sudo` or fix Docker permissions
|
|
268
|
+
3. **Platform issues**: Use `--container-architecture linux/amd64`
|
|
269
|
+
4. **Secret errors**: Provide secrets via `.env.local` file
|
|
270
|
+
|
|
271
|
+
### PostgreSQL Issues
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
# Check if PostgreSQL is running
|
|
275
|
+
pg_isready
|
|
276
|
+
|
|
277
|
+
# Start PostgreSQL service
|
|
278
|
+
brew services start postgresql@15
|
|
279
|
+
|
|
280
|
+
# Create test database
|
|
281
|
+
createdb pg_multitenant_test
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Ruby Version Issues
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Install required Ruby versions
|
|
288
|
+
rbenv install 3.2.0
|
|
289
|
+
rbenv install 3.3.0
|
|
290
|
+
rbenv install 3.4.0
|
|
291
|
+
|
|
292
|
+
# Test with specific version
|
|
293
|
+
rbenv shell 3.3.0
|
|
294
|
+
bundle install
|
|
295
|
+
bundle exec rspec
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## 📚 Additional Resources
|
|
299
|
+
|
|
300
|
+
- [act Documentation](https://github.com/nektos/act)
|
|
301
|
+
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
|
|
302
|
+
- [Local Development Best Practices](https://docs.github.com/en/actions/using-workflows/about-workflows#best-practices)
|
|
303
|
+
|
|
304
|
+
## 🔗 Integration with Git Hooks
|
|
305
|
+
|
|
306
|
+
Add to `.git/hooks/pre-push`:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
#!/bin/bash
|
|
310
|
+
./pre-push-check.sh
|
|
311
|
+
exit $?
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
This ensures checks run automatically before every push.
|
data/docs/migrator.md
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# Migrator - Automated Migration Management
|
|
2
|
+
|
|
3
|
+
**File**: `lib/pg_multitenant_schemas/migrator.rb`
|
|
4
|
+
|
|
5
|
+
## 📋 Overview
|
|
6
|
+
|
|
7
|
+
The `Migrator` class provides comprehensive automated migration management for multi-tenant applications. It handles running migrations across all tenant schemas, setting up new tenants, and tracking migration status.
|
|
8
|
+
|
|
9
|
+
## 🎯 Purpose
|
|
10
|
+
|
|
11
|
+
- **Bulk Migration**: Run migrations across all tenant schemas with single command
|
|
12
|
+
- **Tenant Setup**: Automated tenant creation with schema and migrations
|
|
13
|
+
- **Status Tracking**: Monitor migration status across all tenants
|
|
14
|
+
- **Error Resilience**: Handle migration failures gracefully per tenant
|
|
15
|
+
- **Progress Reporting**: Detailed feedback during migration operations
|
|
16
|
+
|
|
17
|
+
## 🔧 Key Methods
|
|
18
|
+
|
|
19
|
+
### Core Migration Operations
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
# Migrate all tenant schemas
|
|
23
|
+
Migrator.migrate_all
|
|
24
|
+
|
|
25
|
+
# Migrate specific tenant
|
|
26
|
+
Migrator.migrate_tenant('acme_corp')
|
|
27
|
+
|
|
28
|
+
# Check migration status across all tenants
|
|
29
|
+
Migrator.migration_status
|
|
30
|
+
|
|
31
|
+
# Setup new tenant (create schema + run migrations)
|
|
32
|
+
Migrator.setup_tenant('new_tenant')
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Tenant Management
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
# Setup all existing tenants
|
|
39
|
+
Migrator.setup_all_tenants
|
|
40
|
+
|
|
41
|
+
# Create tenant with attributes and schema
|
|
42
|
+
Migrator.create_tenant_with_schema({
|
|
43
|
+
subdomain: 'acme',
|
|
44
|
+
name: 'ACME Corporation'
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
# Rollback specific tenant
|
|
48
|
+
Migrator.rollback_tenant('tenant_name', steps: 2)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 🏗️ Implementation Details
|
|
52
|
+
|
|
53
|
+
### Migration Execution Flow
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
def migrate_all
|
|
57
|
+
puts "🚀 Starting migration for all tenant schemas..."
|
|
58
|
+
|
|
59
|
+
tenant_schemas.each do |schema|
|
|
60
|
+
puts "📦 Migrating schema: #{schema}"
|
|
61
|
+
|
|
62
|
+
migrate_tenant(schema)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
puts "✅ Migration completed for all schemas"
|
|
66
|
+
end
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Error Handling Strategy
|
|
70
|
+
|
|
71
|
+
The Migrator implements robust error handling:
|
|
72
|
+
|
|
73
|
+
- **Per-Tenant Isolation**: Failures in one tenant don't affect others
|
|
74
|
+
- **Detailed Error Reporting**: Specific error messages per tenant
|
|
75
|
+
- **Continue on Error**: Migration continues for remaining tenants
|
|
76
|
+
- **Transaction Safety**: Each tenant migration is self-contained
|
|
77
|
+
|
|
78
|
+
### Progress Tracking
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
def migration_status
|
|
82
|
+
puts "📊 Migration Status Report"
|
|
83
|
+
|
|
84
|
+
tenant_schemas.each do |schema|
|
|
85
|
+
pending = pending_migrations_for_schema(schema)
|
|
86
|
+
|
|
87
|
+
if pending.empty?
|
|
88
|
+
puts "▸ #{schema}: ✅ Up to date"
|
|
89
|
+
else
|
|
90
|
+
puts "▸ #{schema}: ⚠️ #{pending.count} pending migrations"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 🔄 Usage Patterns
|
|
97
|
+
|
|
98
|
+
### Daily Operations
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
# Check what needs migration
|
|
102
|
+
PgMultitenantSchemas::Migrator.migration_status
|
|
103
|
+
|
|
104
|
+
# Run migrations across all tenants
|
|
105
|
+
PgMultitenantSchemas::Migrator.migrate_all
|
|
106
|
+
|
|
107
|
+
# Setup new tenant
|
|
108
|
+
PgMultitenantSchemas::Migrator.setup_tenant('new_client')
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Deployment Workflow
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
# In deployment script
|
|
115
|
+
namespace :deploy do
|
|
116
|
+
task :migrate_tenants do
|
|
117
|
+
PgMultitenantSchemas::Migrator.migrate_all
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### New Tenant Onboarding
|
|
123
|
+
|
|
124
|
+
```ruby
|
|
125
|
+
# Complete tenant setup
|
|
126
|
+
tenant_attributes = {
|
|
127
|
+
subdomain: 'newco',
|
|
128
|
+
name: 'New Company Ltd',
|
|
129
|
+
domain: 'newco.com'
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
tenant = PgMultitenantSchemas::Migrator.create_tenant_with_schema(tenant_attributes)
|
|
133
|
+
puts "✅ Tenant #{tenant.subdomain} ready for use"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Rollback Operations
|
|
137
|
+
|
|
138
|
+
```ruby
|
|
139
|
+
# Rollback specific tenant
|
|
140
|
+
PgMultitenantSchemas::Migrator.rollback_tenant('acme_corp', steps: 1)
|
|
141
|
+
|
|
142
|
+
# Check status after rollback
|
|
143
|
+
PgMultitenantSchemas::Migrator.migration_status
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## 🎛️ Configuration Integration
|
|
147
|
+
|
|
148
|
+
The Migrator respects global configuration:
|
|
149
|
+
|
|
150
|
+
```ruby
|
|
151
|
+
PgMultitenantSchemas.configure do |config|
|
|
152
|
+
config.default_schema = 'public'
|
|
153
|
+
config.tenant_model = 'Tenant'
|
|
154
|
+
config.connection_class = 'ApplicationRecord'
|
|
155
|
+
end
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## 📊 Status Reporting
|
|
159
|
+
|
|
160
|
+
### Migration Status Output
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
📊 Migration Status Report
|
|
164
|
+
▸ acme_corp: ✅ Up to date (5 migrations)
|
|
165
|
+
▸ beta_corp: ⚠️ 2 pending migrations
|
|
166
|
+
- 20241201120000_add_feature_flags
|
|
167
|
+
- 20241202100000_update_user_fields
|
|
168
|
+
▸ demo_corp: ✅ Up to date (5 migrations)
|
|
169
|
+
|
|
170
|
+
📈 Overall: 2/3 tenants current, 2 migrations pending
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Migration Progress Output
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
🚀 Starting migration for all tenant schemas...
|
|
177
|
+
|
|
178
|
+
📦 Migrating schema: acme_corp
|
|
179
|
+
✓ Running migration 20241201120000_add_feature_flags
|
|
180
|
+
✓ Running migration 20241202100000_update_user_fields
|
|
181
|
+
✅ Completed migration for acme_corp
|
|
182
|
+
|
|
183
|
+
📦 Migrating schema: beta_corp
|
|
184
|
+
✓ Running migration 20241201120000_add_feature_flags
|
|
185
|
+
✗ Error in migration 20241202100000_update_user_fields: column already exists
|
|
186
|
+
⚠️ Continuing with next tenant...
|
|
187
|
+
|
|
188
|
+
✅ Migration completed for all schemas
|
|
189
|
+
📊 Summary: 1/2 tenants migrated successfully
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## 🔍 Advanced Features
|
|
193
|
+
|
|
194
|
+
### Custom Migration Paths
|
|
195
|
+
|
|
196
|
+
```ruby
|
|
197
|
+
# Override migration paths if needed
|
|
198
|
+
class CustomMigrator < PgMultitenantSchemas::Migrator
|
|
199
|
+
private
|
|
200
|
+
|
|
201
|
+
def migration_paths
|
|
202
|
+
[
|
|
203
|
+
Rails.root.join('db', 'migrate'),
|
|
204
|
+
Rails.root.join('db', 'tenant_migrations')
|
|
205
|
+
]
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Migration Callbacks
|
|
211
|
+
|
|
212
|
+
```ruby
|
|
213
|
+
# Add hooks for migration events
|
|
214
|
+
module MigrationHooks
|
|
215
|
+
def self.before_tenant_migration(schema_name)
|
|
216
|
+
Rails.logger.info "Starting migration for #{schema_name}"
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def self.after_tenant_migration(schema_name, success)
|
|
220
|
+
status = success ? "SUCCESS" : "FAILED"
|
|
221
|
+
Rails.logger.info "Migration for #{schema_name}: #{status}"
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Batch Processing
|
|
227
|
+
|
|
228
|
+
```ruby
|
|
229
|
+
# Process tenants in batches for large installations
|
|
230
|
+
def migrate_all_batched(batch_size: 10)
|
|
231
|
+
tenant_schemas.each_slice(batch_size) do |batch|
|
|
232
|
+
batch.each { |schema| migrate_tenant(schema) }
|
|
233
|
+
sleep(1) # Brief pause between batches
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## 🚨 Important Considerations
|
|
239
|
+
|
|
240
|
+
### Performance
|
|
241
|
+
|
|
242
|
+
- **Parallel Processing**: Consider parallelization for large tenant counts
|
|
243
|
+
- **Resource Usage**: Monitor database connections during bulk operations
|
|
244
|
+
- **Timing**: Run during low-traffic periods for production
|
|
245
|
+
|
|
246
|
+
### Data Integrity
|
|
247
|
+
|
|
248
|
+
- **Backup Strategy**: Ensure proper backups before major migrations
|
|
249
|
+
- **Testing**: Test migrations on staging environment with production data
|
|
250
|
+
- **Rollback Plan**: Have rollback procedures for failed migrations
|
|
251
|
+
|
|
252
|
+
### Monitoring
|
|
253
|
+
|
|
254
|
+
- **Log Analysis**: Monitor migration logs for patterns and issues
|
|
255
|
+
- **Alert Setup**: Set up alerts for migration failures
|
|
256
|
+
- **Performance Metrics**: Track migration duration and resource usage
|
|
257
|
+
|
|
258
|
+
## 🔧 Troubleshooting
|
|
259
|
+
|
|
260
|
+
### Common Issues
|
|
261
|
+
|
|
262
|
+
**Migration Stuck**
|
|
263
|
+
```ruby
|
|
264
|
+
# Check for long-running queries
|
|
265
|
+
ActiveRecord::Base.connection.execute("SELECT * FROM pg_stat_activity WHERE state = 'active'")
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Schema Not Found**
|
|
269
|
+
```ruby
|
|
270
|
+
# Verify schema exists
|
|
271
|
+
if !PgMultitenantSchemas::SchemaSwitcher.schema_exists?('tenant_name')
|
|
272
|
+
PgMultitenantSchemas::Migrator.setup_tenant('tenant_name')
|
|
273
|
+
end
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**Permission Errors**
|
|
277
|
+
```ruby
|
|
278
|
+
# Check database permissions
|
|
279
|
+
ActiveRecord::Base.connection.execute("SELECT has_schema_privilege('tenant_schema', 'USAGE')")
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## 🔗 Related Components
|
|
283
|
+
|
|
284
|
+
- **[SchemaSwitcher](schema_switcher.md)**: Core schema operations used by Migrator
|
|
285
|
+
- **[Context](context.md)**: Tenant context management during migrations
|
|
286
|
+
- **[Configuration](configuration.md)**: Migrator configuration options
|
|
287
|
+
- **[Rails Integration](rails_integration.md)**: Framework integration features
|
|
288
|
+
|
|
289
|
+
## 📝 Examples
|
|
290
|
+
|
|
291
|
+
See [examples/migration_workflow.rb](../examples/) for complete usage examples and [rake tasks documentation](../lib/pg_multitenant_schemas/tasks/) for command-line usage.
|