data-migration 1.0.0

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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +14 -0
  3. data/.github/dependabot.yml +27 -0
  4. data/.github/workflows/_trunk_check.yml +15 -0
  5. data/.github/workflows/test.yml +42 -0
  6. data/.gitignore +24 -0
  7. data/.ruby-version +1 -0
  8. data/.trunk/.gitignore +9 -0
  9. data/.trunk/configs/.markdownlint.yaml +2 -0
  10. data/.trunk/configs/.shellcheckrc +7 -0
  11. data/.trunk/configs/.yamllint.yaml +7 -0
  12. data/.trunk/trunk.yaml +39 -0
  13. data/.vscode/extensions.json +18 -0
  14. data/.vscode/settings.json +7 -0
  15. data/CHANGELOG.md +3 -0
  16. data/Gemfile +3 -0
  17. data/Gemfile.lock +246 -0
  18. data/LICENSE.md +21 -0
  19. data/README.md +141 -0
  20. data/data-migration.gemspec +44 -0
  21. data/lib/data_migration/config.rb +84 -0
  22. data/lib/data_migration/job.rb +63 -0
  23. data/lib/data_migration/task.rb +127 -0
  24. data/lib/data_migration.rb +37 -0
  25. data/lib/generators/data_migration_generator.rb +13 -0
  26. data/lib/generators/install_generator.rb +17 -0
  27. data/lib/generators/templates/data_migration.rb.tt +26 -0
  28. data/lib/generators/templates/install_data_migration_tasks.rb.tt +27 -0
  29. data/spec/data_migration/config_spec.rb +116 -0
  30. data/spec/data_migration/job_spec.rb +96 -0
  31. data/spec/data_migration/task_spec.rb +152 -0
  32. data/spec/data_migration_spec.rb +65 -0
  33. data/spec/fixtures/data_migrations/20241206200111_create_users.rb +17 -0
  34. data/spec/fixtures/data_migrations/20241206200112_create_bad_users.rb +5 -0
  35. data/spec/fixtures/data_migrations/20241206200113_change_users.rb +5 -0
  36. data/spec/fixtures/data_migrations/20241206200114_create_batch_users.rb +9 -0
  37. data/spec/fixtures/schema.rb +26 -0
  38. data/spec/generators/install_generator_spec.rb +48 -0
  39. data/spec/generators/migration_generator_spec.rb +50 -0
  40. data/spec/rails_helper.rb +21 -0
  41. data/spec/spec_helper.rb +30 -0
  42. data/spec/support/junit_formatter.rb +6 -0
  43. data/spec/support/rails_helpers.rb +53 -0
  44. data/usr/bin/release.sh +35 -0
  45. metadata +246 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c310b238ffce7232c8d7e043b3bb05c22c7fc9feb1a202653172152e0eafe54f
4
+ data.tar.gz: c177a8be4fb4805a0cdac0683ea2b1711f8e78df14176f271d834869c9d7eb0f
5
+ SHA512:
6
+ metadata.gz: 5c3653642986c3de1ac483875541c433f44fc604fe648dcf3b22a9065b16d0370b83c6a55ad20c7a41ed78dee646c14f69eacd9cf2f3f3fa49f7e9b8e944fb44
7
+ data.tar.gz: f604aa6ac2c1993c04b7f993eabf4f56f81c0db9b1c0a892e46f390a75fe4c11a0f8d237b2e80de190b497a07b68d0f7e3d08b162682245234120e1e40a6e58f
data/.editorconfig ADDED
@@ -0,0 +1,14 @@
1
+ # Editor configuration, see https://editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ charset = utf-8
6
+ indent_style = space
7
+ indent_size = 2
8
+ insert_final_newline = true
9
+ trim_trailing_whitespace = true
10
+ quote_type = double
11
+
12
+ [*.md]
13
+ max_line_length = off
14
+ trim_trailing_whitespace = false
@@ -0,0 +1,27 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5
+
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: github-actions
9
+ directory: /
10
+ open-pull-requests-limit: 10
11
+ schedule:
12
+ interval: weekly
13
+ - package-ecosystem: bundler
14
+ directory: /
15
+ open-pull-requests-limit: 10
16
+ schedule:
17
+ interval: weekly
18
+ - package-ecosystem: npm
19
+ directory: /
20
+ open-pull-requests-limit: 10
21
+ schedule:
22
+ interval: weekly
23
+ - package-ecosystem: docker
24
+ directory: /
25
+ open-pull-requests-limit: 10
26
+ schedule:
27
+ interval: weekly
@@ -0,0 +1,15 @@
1
+ name: _trunk_check
2
+ on: [pull_request]
3
+ concurrency:
4
+ group: ${{ github.head_ref || github.run_id }}
5
+ cancel-in-progress: true
6
+ permissions: read-all
7
+ jobs:
8
+ run_trunk_action:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ checks: write
12
+ contents: read
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: trunk-io/trunk-action@v1
@@ -0,0 +1,42 @@
1
+ name: test
2
+ permissions: read-all
3
+ on: [push, pull_request]
4
+ concurrency:
5
+ group: ${{ github.workflow }}-${{ github.ref_name }}
6
+ cancel-in-progress: false
7
+ jobs:
8
+ rspec:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ ruby: [ruby, jruby, truffleruby]
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: ${{ matrix.ruby }}
18
+ bundler-cache: true
19
+ - run: bundle exec rspec
20
+ coverage:
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: ruby/setup-ruby@v1
25
+ with:
26
+ bundler-cache: true
27
+ - run: bundle exec rspec
28
+ - uses: codecov/codecov-action@v5
29
+ continue-on-error: true
30
+ env:
31
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
32
+ - uses: codecov/test-results-action@v1
33
+ if: ${{ !cancelled() }}
34
+ continue-on-error: true
35
+ with:
36
+ token: ${{ secrets.CODECOV_TOKEN }}
37
+ files: coverage/junit-coverage.xml
38
+ - uses: codacy/codacy-coverage-reporter-action@v1.3.0
39
+ continue-on-error: true
40
+ with:
41
+ project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
42
+ coverage-reports: coverage/coverage.xml
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+ /vendor/bundle
10
+
11
+ .byebug_history
12
+
13
+ /coverage
14
+ /coverage/*
15
+
16
+ /spec/examples.txt
17
+ /tmp/*
18
+
19
+ .DS_Store
20
+ .idea
21
+ .lh
22
+
23
+ *.local
24
+ *.gem
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.3.4
data/.trunk/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ *out
2
+ *logs
3
+ *actions
4
+ *notifications
5
+ *tools
6
+ plugins
7
+ user_trunk.yaml
8
+ user.yaml
9
+ tmp
@@ -0,0 +1,2 @@
1
+ # Prettier friendly markdownlint config (all formatting rules disabled)
2
+ extends: markdownlint/style/prettier
@@ -0,0 +1,7 @@
1
+ enable=all
2
+ source-path=SCRIPTDIR
3
+ disable=SC2154
4
+
5
+ # If you're having issues with shellcheck following source, disable the errors via:
6
+ # disable=SC1090
7
+ # disable=SC1091
@@ -0,0 +1,7 @@
1
+ rules:
2
+ quoted-strings:
3
+ required: only-when-needed
4
+ extra-allowed: ["{|}"]
5
+ key-duplicates: {}
6
+ octal-values:
7
+ forbid-implicit-octal: true
data/.trunk/trunk.yaml ADDED
@@ -0,0 +1,39 @@
1
+ # This file controls the behavior of Trunk: https://docs.trunk.io/cli
2
+ # To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
3
+ version: 0.1
4
+ cli:
5
+ version: 1.22.8
6
+ # Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins)
7
+ plugins:
8
+ sources:
9
+ - id: trunk
10
+ ref: v1.6.5
11
+ uri: https://github.com/trunk-io/plugins
12
+ # Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
13
+ runtimes:
14
+ enabled:
15
+ - ruby@3.1.4
16
+ - go@1.21.0
17
+ - node@18.12.1
18
+ - python@3.10.8
19
+ # This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
20
+ lint:
21
+ enabled:
22
+ - standardrb@1.3.0
23
+ - actionlint@1.7.4
24
+ - checkov@3.2.332
25
+ - git-diff-check
26
+ - markdownlint@0.43.0
27
+ - osv-scanner@1.9.1
28
+ - prettier@3.4.2
29
+ - shellcheck@0.10.0
30
+ - shfmt@3.6.0
31
+ - trufflehog@3.85.0
32
+ - yamllint@1.35.1
33
+ actions:
34
+ disabled:
35
+ - trunk-announce
36
+ - trunk-check-pre-push
37
+ - trunk-fmt-pre-commit
38
+ enabled:
39
+ - trunk-upgrade-available
@@ -0,0 +1,18 @@
1
+ {
2
+ "recommendations": [
3
+ "donjayamanne.githistory",
4
+ "editorconfig.editorconfig",
5
+ "mikestead.dotenv",
6
+ "anweber.vscode-httpyac",
7
+ "shopify.ruby-lsp",
8
+ "bung87.vscode-gemfile",
9
+ "wayou.vscode-todo-highlight",
10
+ "vscode-icons-team.vscode-icons",
11
+ "koichisasada.vscode-rdbg",
12
+ "fooo.ruby-spec-runner",
13
+ "nhoizey.gremlins",
14
+ "streetsidesoftware.code-spell-checker",
15
+ "dewski.simplecov",
16
+ "trunk.io"
17
+ ]
18
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "editor.defaultFormatter": "trunk.io",
3
+ "editor.formatOnSave": false,
4
+ "editor.detectIndentation": false,
5
+ "editor.tabSize": 2,
6
+ "editor.insertSpaces": true
7
+ }
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # 1.0.0
2
+
3
+ - Initial version
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,246 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ data-migration (1.0.0)
5
+ activejob (> 5)
6
+ activerecord (> 5)
7
+ activesupport (> 5)
8
+ rails (> 5)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ actioncable (8.0.0)
14
+ actionpack (= 8.0.0)
15
+ activesupport (= 8.0.0)
16
+ nio4r (~> 2.0)
17
+ websocket-driver (>= 0.6.1)
18
+ zeitwerk (~> 2.6)
19
+ actionmailbox (8.0.0)
20
+ actionpack (= 8.0.0)
21
+ activejob (= 8.0.0)
22
+ activerecord (= 8.0.0)
23
+ activestorage (= 8.0.0)
24
+ activesupport (= 8.0.0)
25
+ mail (>= 2.8.0)
26
+ actionmailer (8.0.0)
27
+ actionpack (= 8.0.0)
28
+ actionview (= 8.0.0)
29
+ activejob (= 8.0.0)
30
+ activesupport (= 8.0.0)
31
+ mail (>= 2.8.0)
32
+ rails-dom-testing (~> 2.2)
33
+ actionpack (8.0.0)
34
+ actionview (= 8.0.0)
35
+ activesupport (= 8.0.0)
36
+ nokogiri (>= 1.8.5)
37
+ rack (>= 2.2.4)
38
+ rack-session (>= 1.0.1)
39
+ rack-test (>= 0.6.3)
40
+ rails-dom-testing (~> 2.2)
41
+ rails-html-sanitizer (~> 1.6)
42
+ useragent (~> 0.16)
43
+ actiontext (8.0.0)
44
+ actionpack (= 8.0.0)
45
+ activerecord (= 8.0.0)
46
+ activestorage (= 8.0.0)
47
+ activesupport (= 8.0.0)
48
+ globalid (>= 0.6.0)
49
+ nokogiri (>= 1.8.5)
50
+ actionview (8.0.0)
51
+ activesupport (= 8.0.0)
52
+ builder (~> 3.1)
53
+ erubi (~> 1.11)
54
+ rails-dom-testing (~> 2.2)
55
+ rails-html-sanitizer (~> 1.6)
56
+ activejob (8.0.0)
57
+ activesupport (= 8.0.0)
58
+ globalid (>= 0.3.6)
59
+ activemodel (8.0.0)
60
+ activesupport (= 8.0.0)
61
+ activerecord (8.0.0)
62
+ activemodel (= 8.0.0)
63
+ activesupport (= 8.0.0)
64
+ timeout (>= 0.4.0)
65
+ activestorage (8.0.0)
66
+ actionpack (= 8.0.0)
67
+ activejob (= 8.0.0)
68
+ activerecord (= 8.0.0)
69
+ activesupport (= 8.0.0)
70
+ marcel (~> 1.0)
71
+ activesupport (8.0.0)
72
+ base64
73
+ benchmark (>= 0.3)
74
+ bigdecimal
75
+ concurrent-ruby (~> 1.0, >= 1.3.1)
76
+ connection_pool (>= 2.2.5)
77
+ drb
78
+ i18n (>= 1.6, < 2)
79
+ logger (>= 1.4.2)
80
+ minitest (>= 5.1)
81
+ securerandom (>= 0.3)
82
+ tzinfo (~> 2.0, >= 2.0.5)
83
+ uri (>= 0.13.1)
84
+ base64 (0.2.0)
85
+ benchmark (0.4.0)
86
+ bigdecimal (3.1.8)
87
+ bigdecimal (3.1.8-java)
88
+ builder (3.3.0)
89
+ concurrent-ruby (1.3.4)
90
+ connection_pool (2.4.1)
91
+ crass (1.0.6)
92
+ date (3.4.1)
93
+ date (3.4.1-java)
94
+ diff-lcs (1.5.1)
95
+ docile (1.4.1)
96
+ drb (2.2.1)
97
+ erubi (1.13.0)
98
+ globalid (1.2.1)
99
+ activesupport (>= 6.1)
100
+ i18n (1.14.6)
101
+ concurrent-ruby (~> 1.0)
102
+ io-console (0.8.0)
103
+ io-console (0.8.0-java)
104
+ irb (1.14.1)
105
+ rdoc (>= 4.0.0)
106
+ reline (>= 0.4.2)
107
+ jar-dependencies (0.5.0)
108
+ logger (1.6.2)
109
+ loofah (2.23.1)
110
+ crass (~> 1.0.2)
111
+ nokogiri (>= 1.12.0)
112
+ mail (2.8.1)
113
+ mini_mime (>= 0.1.1)
114
+ net-imap
115
+ net-pop
116
+ net-smtp
117
+ marcel (1.0.4)
118
+ mini_mime (1.1.5)
119
+ mini_portile2 (2.8.8)
120
+ minitest (5.25.4)
121
+ net-imap (0.5.1)
122
+ date
123
+ net-protocol
124
+ net-pop (0.1.2)
125
+ net-protocol
126
+ net-protocol (0.2.2)
127
+ timeout
128
+ net-smtp (0.5.0)
129
+ net-protocol
130
+ nio4r (2.7.4)
131
+ nio4r (2.7.4-java)
132
+ nokogiri (1.16.8-arm64-darwin)
133
+ racc (~> 1.4)
134
+ nokogiri (1.16.8-java)
135
+ racc (~> 1.4)
136
+ nokogiri (1.16.8-x86_64-linux)
137
+ racc (~> 1.4)
138
+ psych (5.2.1)
139
+ date
140
+ stringio
141
+ psych (5.2.1-java)
142
+ date
143
+ jar-dependencies (>= 0.1.7)
144
+ racc (1.8.1)
145
+ racc (1.8.1-java)
146
+ rack (3.1.8)
147
+ rack-session (2.0.0)
148
+ rack (>= 3.0.0)
149
+ rack-test (2.1.0)
150
+ rack (>= 1.3)
151
+ rackup (2.2.1)
152
+ rack (>= 3)
153
+ rails (8.0.0)
154
+ actioncable (= 8.0.0)
155
+ actionmailbox (= 8.0.0)
156
+ actionmailer (= 8.0.0)
157
+ actionpack (= 8.0.0)
158
+ actiontext (= 8.0.0)
159
+ actionview (= 8.0.0)
160
+ activejob (= 8.0.0)
161
+ activemodel (= 8.0.0)
162
+ activerecord (= 8.0.0)
163
+ activestorage (= 8.0.0)
164
+ activesupport (= 8.0.0)
165
+ bundler (>= 1.15.0)
166
+ railties (= 8.0.0)
167
+ rails-dom-testing (2.2.0)
168
+ activesupport (>= 5.0.0)
169
+ minitest
170
+ nokogiri (>= 1.6)
171
+ rails-html-sanitizer (1.6.1)
172
+ loofah (~> 2.21)
173
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
174
+ railties (8.0.0)
175
+ actionpack (= 8.0.0)
176
+ activesupport (= 8.0.0)
177
+ irb (~> 1.13)
178
+ rackup (>= 1.0.0)
179
+ rake (>= 12.2)
180
+ thor (~> 1.0, >= 1.2.2)
181
+ zeitwerk (~> 2.6)
182
+ rake (13.2.1)
183
+ rdoc (6.8.1)
184
+ psych (>= 4.0.0)
185
+ reline (0.5.12)
186
+ io-console (~> 0.5)
187
+ rexml (3.3.9)
188
+ rspec (3.13.0)
189
+ rspec-core (~> 3.13.0)
190
+ rspec-expectations (~> 3.13.0)
191
+ rspec-mocks (~> 3.13.0)
192
+ rspec-core (3.13.2)
193
+ rspec-support (~> 3.13.0)
194
+ rspec-expectations (3.13.3)
195
+ diff-lcs (>= 1.2.0, < 2.0)
196
+ rspec-support (~> 3.13.0)
197
+ rspec-mocks (3.13.2)
198
+ diff-lcs (>= 1.2.0, < 2.0)
199
+ rspec-support (~> 3.13.0)
200
+ rspec-support (3.13.2)
201
+ rspec_junit_formatter (0.6.0)
202
+ rspec-core (>= 2, < 4, != 2.12.0)
203
+ securerandom (0.4.0)
204
+ simplecov (0.22.0)
205
+ docile (~> 1.1)
206
+ simplecov-html (~> 0.11)
207
+ simplecov_json_formatter (~> 0.1)
208
+ simplecov-cobertura (2.1.0)
209
+ rexml
210
+ simplecov (~> 0.19)
211
+ simplecov-html (0.13.1)
212
+ simplecov_json_formatter (0.1.4)
213
+ sqlite3 (2.4.0)
214
+ mini_portile2 (~> 2.8.0)
215
+ sqlite3 (2.4.0-arm64-darwin)
216
+ sqlite3 (2.4.0-x86_64-linux-gnu)
217
+ stringio (3.1.2)
218
+ thor (1.3.2)
219
+ timeout (0.4.2)
220
+ tzinfo (2.0.6)
221
+ concurrent-ruby (~> 1.0)
222
+ uri (1.0.2)
223
+ useragent (0.16.11)
224
+ websocket-driver (0.7.6)
225
+ websocket-extensions (>= 0.1.0)
226
+ websocket-driver (0.7.6-java)
227
+ websocket-extensions (>= 0.1.0)
228
+ websocket-extensions (0.1.5)
229
+ zeitwerk (2.7.1)
230
+
231
+ PLATFORMS
232
+ arm64-darwin
233
+ universal-java-11
234
+ x86_64-linux
235
+
236
+ DEPENDENCIES
237
+ bundler (~> 2)
238
+ data-migration!
239
+ rspec (~> 3)
240
+ rspec_junit_formatter (~> 0.6)
241
+ simplecov (~> 0.21)
242
+ simplecov-cobertura (~> 2)
243
+ sqlite3 (~> 2.4)
244
+
245
+ BUNDLED WITH
246
+ 2.5.20
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 amkisko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # data-migration.rb
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/data-migration.svg)](https://badge.fury.io/rb/data-migration) [![Test Status](https://github.com/amkisko/data-migration.rb/actions/workflows/test.yml/badge.svg)](https://github.com/amkisko/data-migration.rb/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/amkisko/data-migration.rb/graph/badge.svg?token=881AFPL643)](https://codecov.io/gh/amkisko/data-migration.rb)
4
+
5
+ Data migrations kit for ActiveRecord and ActiveJob.
6
+
7
+ Sponsored by [Kisko Labs](https://www.kiskolabs.com).
8
+
9
+ ## Data migrations concept
10
+
11
+ - A short-living script that is manually applied to database
12
+ - Not reversible
13
+ - Can be applied multiple times
14
+ - Accompanied by ActiveJob for background and batch operations
15
+ - Accompanied by ActiveRecord to control and audit migrations progress
16
+ - Operator's responsibility to ensure data consistency, notifications, monitoring and quality of implementation
17
+
18
+ ### Data migrations process
19
+
20
+ 1. Avoid implementing and running data migrations within schema migrations
21
+ 2. Data migrations should be planned beforehand, reserve time in the calendar
22
+ 3. Data migrations should be always controlled by operator
23
+ 4. Wrapping queries to transactions might lead to large memory consumption, unexpected exceptions and database unresponsiveness
24
+ 5. Large data migrations should have batching implemented which will lower memory consumption and database load
25
+ 6. Critical data migrations should be covered with tests, by finding consensus developers decide if migration is critical
26
+ 7. Before running critical data migrations, make sure that you have fresh backup of the database and you are ready to rollback in case of failure
27
+
28
+ ## Installation
29
+
30
+ Using Bundler:
31
+
32
+ ```sh
33
+ bundle add data-migration
34
+ ```
35
+
36
+ Using RubyGems:
37
+
38
+ ```sh
39
+ gem install data-migration
40
+ ```
41
+
42
+ ## Gemfile
43
+
44
+ ```ruby
45
+ gem "data-migration"
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ ### Run data migrations
51
+
52
+ ```sh
53
+ bin/rails db:migrate:data 20241207120000_create_users
54
+ ```
55
+
56
+ ### Generate data migration job
57
+
58
+ ```sh
59
+ bin/rails g data_migration create_users
60
+ ```
61
+
62
+ ## Configuration
63
+
64
+ ### Set data migrations directory
65
+
66
+ Absolute path will be resolved by using `Rails.root`.
67
+
68
+ ```ruby
69
+ DataMigration.config.data_migrations_path = "db/data_migrations"
70
+ ```
71
+
72
+ ### Turn off test script generation
73
+
74
+ ```ruby
75
+ DataMigration.config.generate_spec = false
76
+ ```
77
+
78
+ ## Batch operations
79
+
80
+ Batch operations are supported by using `enqueue` method, it will automatically enqueue or perform next job depending on `background` option.
81
+
82
+ `enqueue` method calls are tracked within a single Thread, it should be used within a single job execution, also all `enqueue` calls rewrite each other and only last call will be used for enqueuing next job after the current job is completed.
83
+
84
+ ```ruby
85
+ def perform(index: 1, background: true)
86
+ return if index > 2
87
+
88
+ User.find_or_create_by(email: "test_#{index}@example.com")
89
+
90
+ enqueue(index: index + 1, background:)
91
+ end
92
+ ```
93
+
94
+ ## Specification checklist
95
+
96
+ - [x] User can generate data migration file under `db/data_migrations` directory with common format
97
+ - [x] User can generate data migration file with test script included
98
+ - [x] User can run specific data migration using Rails console
99
+ - [ ] User can run specific data migration using shell command
100
+ - [x] User can run data migration in background
101
+ - [x] User can run data migration in foreground
102
+ - [x] User can specify operator for data migration
103
+ - [x] User can specify monitoring context for data migration
104
+ - [x] User can specify pause time for data migration
105
+ - [x] User can specify jobs limit for data migration
106
+ - [ ] User receives an error when data migration is applied within schema migration
107
+
108
+ ## Limitations & explanations
109
+
110
+ - ActiveRecord migrations generator is used to generate data migration files
111
+ - Data migrations are not reversible, it is operator's responsibility to ensure that data migration has correct effect
112
+ - Keep migrations logic stable and predictable, e.g. by checking uniqueness of created/updated records
113
+
114
+ ## Contributing
115
+
116
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/amkisko/data-migration.rb>
117
+
118
+ Contribution policy:
119
+
120
+ - New features are not necessarily added to the gem
121
+ - Pull request should have test coverage for affected parts
122
+ - Pull request should have changelog entry
123
+ - It might take up to 2 calendar weeks to review and merge critical fixes
124
+ - It might take up to 6 calendar months to review and merge pull request
125
+ - It might take up to 1 calendar year to review an issue
126
+
127
+ ## Publishing
128
+
129
+ Prefer using script `usr/bin/release.sh`, it will ensure that repository is synced and after publishing gem will create a tag.
130
+
131
+ ```sh
132
+ GEM_VERSION=$(grep -Eo "VERSION\s*=\s*\".+\"" lib/data_migration.rb | grep -Eo "[0-9.]{5,}")
133
+ rm data-migration-*.gem
134
+ gem build data-migration.gemspec
135
+ gem push data-migration-$GEM_VERSION.gem
136
+ git tag $GEM_VERSION && git push --tags && gh release create $GEM_VERSION --generate-notes
137
+ ```
138
+
139
+ ## License
140
+
141
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).