data-migration 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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).