ros-apartment 3.4.0 → 3.4.1
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/RELEASING.md +106 -0
- data/context7.json +4 -0
- data/lib/apartment/migrator.rb +27 -17
- data/lib/apartment/tasks/enhancements.rb +77 -10
- data/lib/apartment/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8c1a77f61c7ac94816e7f0a0d906435cf2f9f06d7efc979a7308ac41a99c4247
|
|
4
|
+
data.tar.gz: '08bdfedeaba0107f0931a2a1f438b2dffebcdd4df89381b5be97f7bd9de5b7d3'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c09415eddebce74732c14bf8f71ec3a4d8dab0e53f6df5d15439068964b2de79ac57c36253878456866e2021d6c8faf1a6f1a3ae12961b33d33a4118536128e3
|
|
7
|
+
data.tar.gz: db8413aa220b089dd0ab874051a5bf990e2f02b9a10da80e7e2356b8fbfd4a908346811ce6f8da0d9fc028c111fe9829ab495807e481a8b268353332d2e0c2bd
|
data/RELEASING.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Releasing ros-apartment
|
|
2
|
+
|
|
3
|
+
This document describes the release process for the `ros-apartment` gem.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Releases are automated via GitHub Actions. Pushing to `main` triggers the `gem-publish.yml` workflow, which publishes to RubyGems using trusted publishing (no API key required).
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
- All changes merged to `development` branch
|
|
12
|
+
- CI passing on `development`
|
|
13
|
+
- Version number updated in `lib/apartment/version.rb`
|
|
14
|
+
|
|
15
|
+
## Release Steps
|
|
16
|
+
|
|
17
|
+
### 1. Bump the version
|
|
18
|
+
|
|
19
|
+
Update `lib/apartment/version.rb` on the `development` branch:
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
module Apartment
|
|
23
|
+
VERSION = 'X.Y.Z'
|
|
24
|
+
end
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Follow [Semantic Versioning](https://semver.org/):
|
|
28
|
+
- **MAJOR** (X): Breaking changes
|
|
29
|
+
- **MINOR** (Y): New features, backwards compatible
|
|
30
|
+
- **PATCH** (Z): Bug fixes, backwards compatible
|
|
31
|
+
|
|
32
|
+
### 2. Create release PR
|
|
33
|
+
|
|
34
|
+
Create a PR from `development` to `main`:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
gh pr create --base main --head development --title "Release vX.Y.Z"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Include a summary of changes in the PR description.
|
|
41
|
+
|
|
42
|
+
### 3. Merge the release PR
|
|
43
|
+
|
|
44
|
+
Once CI passes and the PR is approved, merge it. This triggers the publish workflow.
|
|
45
|
+
|
|
46
|
+
**Important**: The workflow creates the git tag automatically. Do not create the tag manually beforehand or the workflow will fail.
|
|
47
|
+
|
|
48
|
+
### 4. Verify the publish
|
|
49
|
+
|
|
50
|
+
Monitor the `gem-publish.yml` workflow run. It will:
|
|
51
|
+
1. Build the gem
|
|
52
|
+
2. Create and push the `vX.Y.Z` tag
|
|
53
|
+
3. Publish to RubyGems
|
|
54
|
+
4. Wait for RubyGems indexes to update
|
|
55
|
+
|
|
56
|
+
Verify at: https://rubygems.org/gems/ros-apartment
|
|
57
|
+
|
|
58
|
+
### 5. Create GitHub Release
|
|
59
|
+
|
|
60
|
+
After the workflow completes:
|
|
61
|
+
|
|
62
|
+
1. Go to https://github.com/rails-on-services/apartment/releases/new
|
|
63
|
+
2. Select the `vX.Y.Z` tag (created by the workflow)
|
|
64
|
+
3. Click "Generate release notes" for a starting point
|
|
65
|
+
4. Edit the release notes to highlight key changes
|
|
66
|
+
5. Publish the release
|
|
67
|
+
|
|
68
|
+
We use GitHub Releases as our changelog (no CHANGELOG.md file).
|
|
69
|
+
|
|
70
|
+
### 6. Sync branches
|
|
71
|
+
|
|
72
|
+
Merge `main` back into `development` to keep them in sync:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
git checkout development
|
|
76
|
+
git pull origin development
|
|
77
|
+
git merge origin/main --no-edit
|
|
78
|
+
git push
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Workflow Details
|
|
82
|
+
|
|
83
|
+
The `gem-publish.yml` workflow uses:
|
|
84
|
+
- **Trusted publishing**: Configured via RubyGems.org OIDC, no API key needed
|
|
85
|
+
- **rubygems/release-gem@v1**: Official RubyGems action
|
|
86
|
+
- **rake release**: Builds gem, creates tag, pushes to RubyGems
|
|
87
|
+
|
|
88
|
+
## Troubleshooting
|
|
89
|
+
|
|
90
|
+
### Workflow fails with "tag already exists"
|
|
91
|
+
|
|
92
|
+
The tag was created manually before the workflow ran. Delete the tag and re-run:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git push origin --delete vX.Y.Z
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Then re-trigger the workflow by pushing to main again (or re-run from GitHub Actions UI).
|
|
99
|
+
|
|
100
|
+
### Gem published but GitHub Release missing
|
|
101
|
+
|
|
102
|
+
The GitHub Release is created manually (step 5). The gem is already available on RubyGems; the release is just for documentation.
|
|
103
|
+
|
|
104
|
+
### RubyGems trusted publishing fails
|
|
105
|
+
|
|
106
|
+
Verify the GitHub environment `production` is configured correctly in repository settings, and that RubyGems.org has the trusted publisher configured for this repository.
|
data/context7.json
ADDED
data/lib/apartment/migrator.rb
CHANGED
|
@@ -8,37 +8,47 @@ module Apartment
|
|
|
8
8
|
|
|
9
9
|
# Migrate to latest
|
|
10
10
|
def migrate(database)
|
|
11
|
-
Tenant.switch
|
|
12
|
-
|
|
11
|
+
# Pin a connection for the entire migration to ensure Tenant.switch
|
|
12
|
+
# sets search_path on the same connection used by migration_context.
|
|
13
|
+
# Without this, connection pool may return different connections
|
|
14
|
+
# for the switch vs the actual migration operations.
|
|
15
|
+
ActiveRecord::Base.connection_pool.with_connection do
|
|
16
|
+
Tenant.switch(database) do
|
|
17
|
+
version = ENV['VERSION']&.to_i
|
|
13
18
|
|
|
14
|
-
|
|
19
|
+
migration_scope_block = ->(migration) { ENV['SCOPE'].blank? || (ENV['SCOPE'] == migration.scope) }
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
if ActiveRecord.version >= Gem::Version.new('7.2.0')
|
|
22
|
+
ActiveRecord::Base.connection_pool.migration_context.migrate(version, &migration_scope_block)
|
|
23
|
+
else
|
|
24
|
+
ActiveRecord::Base.connection.migration_context.migrate(version, &migration_scope_block)
|
|
25
|
+
end
|
|
20
26
|
end
|
|
21
27
|
end
|
|
22
28
|
end
|
|
23
29
|
|
|
24
30
|
# Migrate up/down to a specific version
|
|
25
31
|
def run(direction, database, version)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
ActiveRecord::
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
ActiveRecord::Base.connection_pool.with_connection do
|
|
33
|
+
Tenant.switch(database) do
|
|
34
|
+
if ActiveRecord.version >= Gem::Version.new('7.2.0')
|
|
35
|
+
ActiveRecord::Base.connection_pool.migration_context.run(direction, version)
|
|
36
|
+
else
|
|
37
|
+
ActiveRecord::Base.connection.migration_context.run(direction, version)
|
|
38
|
+
end
|
|
31
39
|
end
|
|
32
40
|
end
|
|
33
41
|
end
|
|
34
42
|
|
|
35
43
|
# rollback latest migration `step` number of times
|
|
36
44
|
def rollback(database, step = 1)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
ActiveRecord::
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
ActiveRecord::Base.connection_pool.with_connection do
|
|
46
|
+
Tenant.switch(database) do
|
|
47
|
+
if ActiveRecord.version >= Gem::Version.new('7.2.0')
|
|
48
|
+
ActiveRecord::Base.connection_pool.migration_context.rollback(step)
|
|
49
|
+
else
|
|
50
|
+
ActiveRecord::Base.connection.migration_context.rollback(step)
|
|
51
|
+
end
|
|
42
52
|
end
|
|
43
53
|
end
|
|
44
54
|
end
|
|
@@ -2,12 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
# Require this file to append Apartment rake tasks to ActiveRecord db rake tasks
|
|
4
4
|
# Enabled by default in the initializer
|
|
5
|
+
#
|
|
6
|
+
# ## Multi-Database Support (Rails 7+)
|
|
7
|
+
#
|
|
8
|
+
# When a Rails app has multiple databases configured in database.yml, Rails creates
|
|
9
|
+
# namespaced rake tasks like `db:migrate:primary`, `db:rollback:primary`, etc.
|
|
10
|
+
# This enhancer automatically detects databases with `database_tasks: true` and
|
|
11
|
+
# enhances their namespaced tasks to also run the corresponding apartment task.
|
|
12
|
+
#
|
|
13
|
+
# Example: Running `rails db:rollback:primary` will also invoke `apartment:rollback`
|
|
14
|
+
# to rollback all tenant schemas.
|
|
5
15
|
|
|
6
16
|
module Apartment
|
|
7
17
|
class RakeTaskEnhancer
|
|
8
18
|
module TASKS
|
|
9
19
|
ENHANCE_BEFORE = %w[db:drop].freeze
|
|
10
20
|
ENHANCE_AFTER = %w[db:migrate db:rollback db:migrate:up db:migrate:down db:migrate:redo db:seed].freeze
|
|
21
|
+
|
|
22
|
+
# Base tasks that have namespaced variants in multi-database setups
|
|
23
|
+
# db:seed is excluded because Rails doesn't create db:seed:primary
|
|
24
|
+
NAMESPACED_AFTER = %w[db:migrate db:rollback db:migrate:up db:migrate:down db:migrate:redo].freeze
|
|
11
25
|
freeze
|
|
12
26
|
end
|
|
13
27
|
|
|
@@ -18,36 +32,89 @@ module Apartment
|
|
|
18
32
|
def enhance!
|
|
19
33
|
return unless should_enhance?
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
enhance_base_tasks!
|
|
36
|
+
enhance_namespaced_tasks!
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def should_enhance?
|
|
40
|
+
Apartment.db_migrate_tenants
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
# Enhance standard db:* tasks (backward compatible behavior)
|
|
46
|
+
def enhance_base_tasks!
|
|
22
47
|
TASKS::ENHANCE_BEFORE.each do |name|
|
|
23
|
-
|
|
24
|
-
enhance_before_task(task)
|
|
48
|
+
enhance_task_before(name)
|
|
25
49
|
end
|
|
26
50
|
|
|
27
|
-
# insert task after
|
|
28
51
|
TASKS::ENHANCE_AFTER.each do |name|
|
|
29
|
-
|
|
30
|
-
enhance_after_task(task)
|
|
52
|
+
enhance_task_after(name)
|
|
31
53
|
end
|
|
32
54
|
end
|
|
33
55
|
|
|
34
|
-
|
|
35
|
-
|
|
56
|
+
# Enhance namespaced db:*:database_name tasks for multi-database setups
|
|
57
|
+
# Maps namespaced tasks to base apartment tasks:
|
|
58
|
+
# db:migrate:primary -> apartment:migrate
|
|
59
|
+
# db:rollback:primary -> apartment:rollback
|
|
60
|
+
# db:migrate:up:primary -> apartment:migrate:up
|
|
61
|
+
def enhance_namespaced_tasks!
|
|
62
|
+
database_names_with_tasks.each do |db_name|
|
|
63
|
+
TASKS::NAMESPACED_AFTER.each do |base_task|
|
|
64
|
+
namespaced_task = "#{base_task}:#{db_name}"
|
|
65
|
+
next unless task_defined?(namespaced_task)
|
|
66
|
+
|
|
67
|
+
apartment_task = base_task.sub('db:', 'apartment:')
|
|
68
|
+
enhance_namespaced_task_after(namespaced_task, apartment_task)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
36
71
|
end
|
|
37
72
|
|
|
38
|
-
def
|
|
73
|
+
def enhance_task_before(name)
|
|
74
|
+
return unless task_defined?(name)
|
|
75
|
+
|
|
76
|
+
task = Rake::Task[name]
|
|
39
77
|
task.enhance([inserted_task_name(task)])
|
|
40
78
|
end
|
|
41
79
|
|
|
42
|
-
def
|
|
80
|
+
def enhance_task_after(name)
|
|
81
|
+
return unless task_defined?(name)
|
|
82
|
+
|
|
83
|
+
task = Rake::Task[name]
|
|
43
84
|
task.enhance do
|
|
44
85
|
Rake::Task[inserted_task_name(task)].invoke
|
|
45
86
|
end
|
|
46
87
|
end
|
|
47
88
|
|
|
89
|
+
def enhance_namespaced_task_after(namespaced_task_name, apartment_task_name)
|
|
90
|
+
Rake::Task[namespaced_task_name].enhance do
|
|
91
|
+
Rake::Task[apartment_task_name].invoke
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
48
95
|
def inserted_task_name(task)
|
|
49
96
|
task.name.sub('db:', 'apartment:')
|
|
50
97
|
end
|
|
98
|
+
|
|
99
|
+
def task_defined?(name)
|
|
100
|
+
Rake::Task.task_defined?(name)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Returns database names that have database_tasks enabled and are not replicas.
|
|
104
|
+
# These are the databases for which Rails creates namespaced rake tasks.
|
|
105
|
+
#
|
|
106
|
+
# @return [Array<String>] database names (e.g., ['primary', 'secondary'])
|
|
107
|
+
def database_names_with_tasks
|
|
108
|
+
return [] unless defined?(Rails) && Rails.respond_to?(:env)
|
|
109
|
+
|
|
110
|
+
configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
|
|
111
|
+
configs
|
|
112
|
+
.select { |c| c.database_tasks? && !c.replica? }
|
|
113
|
+
.map(&:name)
|
|
114
|
+
rescue StandardError
|
|
115
|
+
# Fail gracefully if configurations unavailable (e.g., during early boot)
|
|
116
|
+
[]
|
|
117
|
+
end
|
|
51
118
|
end
|
|
52
119
|
end
|
|
53
120
|
end
|
data/lib/apartment/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ros-apartment
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.4.
|
|
4
|
+
version: 3.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryan Brunner
|
|
@@ -129,7 +129,9 @@ files:
|
|
|
129
129
|
- Gemfile
|
|
130
130
|
- Guardfile
|
|
131
131
|
- README.md
|
|
132
|
+
- RELEASING.md
|
|
132
133
|
- Rakefile
|
|
134
|
+
- context7.json
|
|
133
135
|
- docs/adapters.md
|
|
134
136
|
- docs/architecture.md
|
|
135
137
|
- docs/elevators.md
|