prodder 1.8.2 → 1.9.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.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/Gemfile +4 -2
- data/Gemfile.lock +122 -0
- data/LICENSE.txt +5 -7
- data/README.md +173 -81
- data/compose.yml +2 -2
- data/cucumber.yml +1 -0
- data/features/step_definitions/git_steps.rb +18 -18
- data/features/step_definitions/prodder_steps.rb +26 -26
- data/features/support/blog.git/HEAD +1 -0
- data/features/support/blog.git/config +7 -0
- data/features/support/blog.git/description +1 -0
- data/features/support/blog.git/hooks/applypatch-msg.sample +15 -0
- data/features/support/blog.git/hooks/commit-msg.sample +24 -0
- data/features/support/blog.git/hooks/post-commit.sample +8 -0
- data/features/support/blog.git/hooks/post-receive.sample +15 -0
- data/features/support/blog.git/hooks/post-update.sample +8 -0
- data/features/support/blog.git/hooks/pre-applypatch.sample +14 -0
- data/features/support/blog.git/hooks/pre-commit.sample +46 -0
- data/features/support/blog.git/hooks/pre-rebase.sample +169 -0
- data/features/support/blog.git/hooks/prepare-commit-msg.sample +36 -0
- data/features/support/blog.git/hooks/update.sample +128 -0
- data/features/support/blog.git/info/exclude +6 -0
- data/features/support/blog.git/objects/2c/0dfde112cb834fc1bd166454bf0e23f35aec0b +0 -0
- data/features/support/blog.git/objects/5f/344dad802e30fce4f8b84e094a52a0a3c1ef9a +0 -0
- data/features/support/blog.git/objects/c0/7cd3c46c7a18b6b2c44f4efea77554d0840056 +0 -0
- data/features/support/blog.git/packed-refs +2 -0
- data/features/support/env.rb +22 -10
- data/lib/prodder/cli.rb +0 -2
- data/lib/prodder/pg.rb +8 -6
- data/lib/prodder/prodder.rake +9 -9
- data/lib/prodder/version.rb +1 -1
- data/prodder.gemspec +6 -4
- data/rspec_test.log +5 -0
- metadata +45 -10
- data/.dockerignore +0 -2
- data/.github/workflows/ci.yml +0 -69
- data/.gitignore +0 -2
- data/entrypoints/entry.sh +0 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 16388fe0003353484889449561b321aeacdbf4c7fbac924695cfa6d147586cc7
|
|
4
|
+
data.tar.gz: 44da9a1bdd4ad9a9d1443e61a8e98bd8123f3a323b9cd6fc6a9c7b4979335c22
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 788a35ce10f96838d34349988d704d8f39fe3bfa42979938b7ec9a2e0a655fb758f62045885a961f680fcb6e6b5cee64d99c48aef3512f3f120467508fc9ed26
|
|
7
|
+
data.tar.gz: ee2a63269aeebd1cc3036be44558e9ff4aac5e1d38ce6aa436d71fdd3e863dfe65fa18335131b50aa87315bf08ebd2013dd80edb89c91dfd97394962cdb633a9
|
data/Dockerfile
CHANGED
data/Gemfile
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
|
+
gemspec
|
|
4
|
+
|
|
3
5
|
gem 'deject'
|
|
4
6
|
gem 'thor'
|
|
5
7
|
gem 'cocaine'
|
|
@@ -10,7 +12,7 @@ group :development, :test do
|
|
|
10
12
|
gem 'pry'
|
|
11
13
|
gem 'pry-remote'
|
|
12
14
|
gem 'rspec'
|
|
13
|
-
gem 'cucumber'
|
|
14
|
-
gem 'aruba'
|
|
15
|
+
gem 'cucumber'
|
|
16
|
+
gem 'aruba'
|
|
15
17
|
gem 'pg'
|
|
16
18
|
end
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
prodder (1.8.3)
|
|
5
|
+
deject
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
aruba (2.3.3)
|
|
11
|
+
bundler (>= 1.17)
|
|
12
|
+
contracts (>= 0.16.0, < 0.18.0)
|
|
13
|
+
cucumber (>= 8.0, < 11.0)
|
|
14
|
+
rspec-expectations (>= 3.4, < 5.0)
|
|
15
|
+
thor (~> 1.0)
|
|
16
|
+
base64 (0.3.0)
|
|
17
|
+
benzo (2.1.0)
|
|
18
|
+
cocaine (~> 0.5.8)
|
|
19
|
+
bigdecimal (3.3.1)
|
|
20
|
+
builder (3.3.0)
|
|
21
|
+
climate_control (0.2.0)
|
|
22
|
+
cocaine (0.5.8)
|
|
23
|
+
climate_control (>= 0.0.3, < 1.0)
|
|
24
|
+
coderay (1.1.3)
|
|
25
|
+
contracts (0.17.2)
|
|
26
|
+
cucumber (10.1.1)
|
|
27
|
+
base64 (~> 0.2)
|
|
28
|
+
builder (~> 3.2)
|
|
29
|
+
cucumber-ci-environment (> 9, < 11)
|
|
30
|
+
cucumber-core (> 15, < 17)
|
|
31
|
+
cucumber-cucumber-expressions (> 17, < 19)
|
|
32
|
+
cucumber-html-formatter (> 20.3, < 22)
|
|
33
|
+
diff-lcs (~> 1.5)
|
|
34
|
+
logger (~> 1.6)
|
|
35
|
+
mini_mime (~> 1.1)
|
|
36
|
+
multi_test (~> 1.1)
|
|
37
|
+
sys-uname (~> 1.3)
|
|
38
|
+
cucumber-ci-environment (10.0.1)
|
|
39
|
+
cucumber-core (15.3.0)
|
|
40
|
+
cucumber-gherkin (> 27, < 35)
|
|
41
|
+
cucumber-messages (> 26, < 30)
|
|
42
|
+
cucumber-tag-expressions (> 5, < 9)
|
|
43
|
+
cucumber-cucumber-expressions (18.0.1)
|
|
44
|
+
bigdecimal
|
|
45
|
+
cucumber-gherkin (34.0.0)
|
|
46
|
+
cucumber-messages (> 25, < 29)
|
|
47
|
+
cucumber-html-formatter (21.15.1)
|
|
48
|
+
cucumber-messages (> 19, < 28)
|
|
49
|
+
cucumber-messages (27.2.0)
|
|
50
|
+
cucumber-tag-expressions (8.1.0)
|
|
51
|
+
deject (0.2.3)
|
|
52
|
+
diff-lcs (1.6.2)
|
|
53
|
+
ffi (1.17.2)
|
|
54
|
+
ffi (1.17.2-aarch64-linux-gnu)
|
|
55
|
+
ffi (1.17.2-aarch64-linux-musl)
|
|
56
|
+
ffi (1.17.2-arm64-darwin)
|
|
57
|
+
ffi (1.17.2-x86_64-darwin)
|
|
58
|
+
ffi (1.17.2-x86_64-linux-gnu)
|
|
59
|
+
ffi (1.17.2-x86_64-linux-musl)
|
|
60
|
+
logger (1.7.0)
|
|
61
|
+
memoist3 (1.0.0)
|
|
62
|
+
method_source (1.1.0)
|
|
63
|
+
mini_mime (1.1.5)
|
|
64
|
+
multi_test (1.1.0)
|
|
65
|
+
pg (1.6.2)
|
|
66
|
+
pg (1.6.2-aarch64-linux)
|
|
67
|
+
pg (1.6.2-aarch64-linux-musl)
|
|
68
|
+
pg (1.6.2-arm64-darwin)
|
|
69
|
+
pg (1.6.2-x86_64-darwin)
|
|
70
|
+
pg (1.6.2-x86_64-linux)
|
|
71
|
+
pg (1.6.2-x86_64-linux-musl)
|
|
72
|
+
pry (0.15.2)
|
|
73
|
+
coderay (~> 1.1)
|
|
74
|
+
method_source (~> 1.0)
|
|
75
|
+
pry-remote (0.1.8)
|
|
76
|
+
pry (~> 0.9)
|
|
77
|
+
slop (~> 3.0)
|
|
78
|
+
rake (13.3.1)
|
|
79
|
+
rspec (3.13.2)
|
|
80
|
+
rspec-core (~> 3.13.0)
|
|
81
|
+
rspec-expectations (~> 3.13.0)
|
|
82
|
+
rspec-mocks (~> 3.13.0)
|
|
83
|
+
rspec-core (3.13.6)
|
|
84
|
+
rspec-support (~> 3.13.0)
|
|
85
|
+
rspec-expectations (3.13.5)
|
|
86
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
87
|
+
rspec-support (~> 3.13.0)
|
|
88
|
+
rspec-mocks (3.13.7)
|
|
89
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
90
|
+
rspec-support (~> 3.13.0)
|
|
91
|
+
rspec-support (3.13.6)
|
|
92
|
+
slop (3.6.0)
|
|
93
|
+
sys-uname (1.4.1)
|
|
94
|
+
ffi (~> 1.1)
|
|
95
|
+
memoist3 (~> 1.0.0)
|
|
96
|
+
thor (1.4.0)
|
|
97
|
+
|
|
98
|
+
PLATFORMS
|
|
99
|
+
aarch64-linux
|
|
100
|
+
aarch64-linux-musl
|
|
101
|
+
arm64-darwin
|
|
102
|
+
ruby
|
|
103
|
+
x86_64-darwin
|
|
104
|
+
x86_64-linux
|
|
105
|
+
x86_64-linux-musl
|
|
106
|
+
|
|
107
|
+
DEPENDENCIES
|
|
108
|
+
aruba
|
|
109
|
+
benzo
|
|
110
|
+
cocaine
|
|
111
|
+
cucumber
|
|
112
|
+
deject
|
|
113
|
+
pg
|
|
114
|
+
prodder!
|
|
115
|
+
pry
|
|
116
|
+
pry-remote
|
|
117
|
+
rake
|
|
118
|
+
rspec
|
|
119
|
+
thor
|
|
120
|
+
|
|
121
|
+
BUNDLED WITH
|
|
122
|
+
4.0.1
|
data/LICENSE.txt
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2016 Enova
|
|
1
|
+
Copyright (c) 2025 Enova International
|
|
4
2
|
|
|
5
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
4
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -9,13 +7,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
9
7
|
copies of the Software, and to permit persons to whom the Software is
|
|
10
8
|
furnished to do so, subject to the following conditions:
|
|
11
9
|
|
|
12
|
-
The above copyright notice and this permission notice shall be included in
|
|
13
|
-
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
14
12
|
|
|
15
13
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
14
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
15
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
16
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
17
|
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
|
|
21
|
-
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -1,53 +1,111 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
# Prodder
|
|
3
|
+
|
|
4
|
+
[](https://www.ruby-lang.org)
|
|
5
|
+
[](https://www.postgresql.org)
|
|
4
6
|
|
|
5
7
|
A tool to maintain and load your Rails application's database structure, seed
|
|
6
8
|
table contents, permissions and database settings based on its migration history
|
|
7
9
|
and the current state in production databases.
|
|
8
10
|
|
|
9
|
-
In short
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
11
|
+
**In short:** Synchronize your development database with production structure without re-running all migrations.
|
|
12
|
+
|
|
13
|
+
## Why Prodder?
|
|
14
|
+
|
|
15
|
+
Traditional Rails development requires running all migrations from scratch, which:
|
|
16
|
+
|
|
17
|
+
- ❌ Becomes slow as your migration history grows
|
|
18
|
+
- ❌ Can fail if old migrations are incompatible with current code
|
|
19
|
+
- ❌ Doesn't reflect actual production database state
|
|
20
|
+
|
|
21
|
+
Prodder solves this by:
|
|
22
|
+
|
|
23
|
+
- ✅ Loading production database structure directly
|
|
24
|
+
- ✅ Running only new migrations not yet deployed to production
|
|
25
|
+
- ✅ Maintaining permissions and quality checks from production
|
|
26
|
+
- ✅ Automatically syncing structure files from production databases
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
- **Ruby 2.7+** - This gem requires Ruby 2.7.0 or later
|
|
31
|
+
- **Bundler 2.0+** - For dependency management
|
|
32
|
+
- **PostgreSQL 15+** - Requires PostgreSQL 15.0 or later
|
|
33
|
+
|
|
34
|
+
**Note:** Support for Ruby 2.6 and PostgreSQL versions older than 15 has been removed as of the latest version. If you need to use older versions, please use a previous version of this gem.
|
|
35
|
+
|
|
36
|
+
## Overview
|
|
37
|
+
|
|
38
|
+
Prodder follows a simple workflow:
|
|
39
|
+
|
|
40
|
+
1. **Maintain structure files**: Your project keeps `db/structure.sql`, `db/seeds.sql`, and optionally `db/quality_checks.sql` and `db/permissions.sql` in version control.
|
|
41
|
+
|
|
42
|
+
2. **Include migrations table**: Ensure `db/seeds.sql` includes the `schema_migrations` table from production.
|
|
43
|
+
|
|
44
|
+
3. **Run new migrations only**: Only migrations not yet in production's `schema_migrations` table will run locally.
|
|
45
|
+
|
|
46
|
+
4. **Update structure files**: After deploying a migration to production, update your structure files by running `prodder dump` against production.
|
|
47
|
+
|
|
48
|
+
5. **Delete old migrations**: Once a migration is deployed and the structure files are updated, the migration file can be safely removed.
|
|
49
|
+
|
|
50
|
+
6. **Track permissions**: Application permission changes are captured in `db/permissions.sql` for consistent development environments.
|
|
51
|
+
|
|
52
|
+
### The Prodder Workflow
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
Production DB → prodder dump → db/*.sql files → Git → Development
|
|
56
|
+
↓
|
|
57
|
+
db:reset + new migrations
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Replacing `rake db:*` Tasks
|
|
61
|
+
|
|
62
|
+
Prodder can be included as a Railtie in your Rails application to automatically
|
|
63
|
+
replace many of Rails' `db:*` tasks with versions that work with production-sourced
|
|
64
|
+
structure files.
|
|
65
|
+
|
|
66
|
+
### Prerequisites
|
|
67
|
+
|
|
68
|
+
- `db/structure.sql` - Base database structure
|
|
69
|
+
- `db/seeds.sql` - Seed data including `schema_migrations` table
|
|
70
|
+
- `db/quality_checks.sql` (optional) - Foreign keys and constraints
|
|
71
|
+
- `db/permissions.sql` (optional) - Database permissions for role-based access
|
|
30
72
|
|
|
31
73
|
### Installation
|
|
32
|
-
|
|
74
|
+
|
|
75
|
+
Add to your Gemfile:
|
|
33
76
|
|
|
34
77
|
```ruby
|
|
35
78
|
gem 'prodder', require: 'prodder/railtie'
|
|
36
79
|
```
|
|
37
80
|
|
|
38
|
-
|
|
39
|
-
to `:sql`:
|
|
81
|
+
Configure Rails to use SQL schema format:
|
|
40
82
|
|
|
41
83
|
```ruby
|
|
42
84
|
# config/application.rb
|
|
43
|
-
module
|
|
44
|
-
class Application
|
|
85
|
+
module YourApp
|
|
86
|
+
class Application < Rails::Application
|
|
45
87
|
config.active_record.schema_format = :sql
|
|
46
88
|
end
|
|
47
89
|
end
|
|
48
90
|
```
|
|
49
91
|
|
|
92
|
+
### Basic Usage
|
|
93
|
+
|
|
94
|
+
Once installed, use these commands:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Recreate database from structure and seed files
|
|
98
|
+
bundle exec rake db:reset
|
|
99
|
+
|
|
100
|
+
# Run only new migrations (those not in production's schema_migrations)
|
|
101
|
+
bundle exec rake db:migrate
|
|
102
|
+
|
|
103
|
+
# The typical development workflow
|
|
104
|
+
bundle exec rake db:reset db:migrate
|
|
105
|
+
```
|
|
106
|
+
|
|
50
107
|
If you want to work with permissions setup like production:
|
|
108
|
+
|
|
51
109
|
```ruby
|
|
52
110
|
# config/database.yml
|
|
53
111
|
|
|
@@ -74,6 +132,7 @@ bundle exec rake db:reset db:migrate
|
|
|
74
132
|
```
|
|
75
133
|
|
|
76
134
|
### Usage
|
|
135
|
+
|
|
77
136
|
Things that really matter:
|
|
78
137
|
|
|
79
138
|
1. `rake db:reset` recreates your database, loading `db/structure.sql`, `db/seeds.sql`,
|
|
@@ -92,49 +151,48 @@ Things that really matter:
|
|
|
92
151
|
does not make sense to restore permissions in your environment if you're just going to run everything as a single,
|
|
93
152
|
most likely superuser.
|
|
94
153
|
|
|
95
|
-
|
|
96
154
|
### Details
|
|
97
155
|
|
|
98
156
|
This will remove the `db:*` tasks:
|
|
99
157
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
158
|
+
- `db:_dump`: an internal task used by rails to dump the schema after migrations. Obsolete.
|
|
159
|
+
- `db:drop:*`
|
|
160
|
+
- `db:create:*`
|
|
161
|
+
- `db:migrate`
|
|
162
|
+
- `db:migrate:reset`
|
|
163
|
+
- `db:migrate:up`
|
|
164
|
+
- `db:migrate:down`
|
|
165
|
+
- `db:fixtures:.*`
|
|
166
|
+
- `db:abort_if_pending_migrations`
|
|
167
|
+
- `db:purge:*`
|
|
168
|
+
- `db:charset`
|
|
169
|
+
- `db:collation`
|
|
170
|
+
- `db:rollback`
|
|
171
|
+
- `db:version`
|
|
172
|
+
- `db:forward`
|
|
173
|
+
- `db:reset`
|
|
174
|
+
- `db:schema:*`
|
|
175
|
+
- `db:seed`
|
|
176
|
+
- `db:setup`
|
|
177
|
+
- `db:structure:*`
|
|
178
|
+
- `db:test:*`
|
|
179
|
+
- `test:prepare`: Rails 4.1 added this task to auto-maintain the test DB schema.
|
|
122
180
|
|
|
123
181
|
And reimplement only the following:
|
|
124
182
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
183
|
+
- `db:structure:load`: Load the contents of `db/structure.sql` into the database of your current environment.
|
|
184
|
+
- `db:seed`: Load `db/seeds.sql` into the database of your current environment.
|
|
185
|
+
- `db:quality_check`: Load `db/quality_checks.sql` into the database of your current environment, if present.
|
|
186
|
+
- `db:reset`: db:drop db:setup
|
|
187
|
+
- `db:settings`: Load the contents of `db/settings.sql` into the database of your current environment.
|
|
188
|
+
- `db:setup`: db:create db:structure:load db:seed db:quality_check db:settings
|
|
189
|
+
- `db:test:prepare`: RAILS_ENV=test db:reset db:migrate
|
|
190
|
+
- `db:test:clone_structure`: RAILS_ENV=test db:reset db:migrate
|
|
191
|
+
- `test:prepare`: db:test:prepare
|
|
192
|
+
- `db:drop`: Drop database as superuser
|
|
193
|
+
- `db:create`: Create database as `superuser` and transfer ownership to `migration_user`
|
|
194
|
+
- `db:migrate:*`, `db:rollback` Run migrations up/down as `migration_user`
|
|
195
|
+
- `db:purge:*, db:charset, db:collation, db:version, db:forward, db:rollback, db:abort_if_pending_migrations` as
|
|
138
196
|
appropriate users.
|
|
139
197
|
|
|
140
198
|
See [lib/prodder/prodder.rake](lib/prodder/prodder.rake)
|
|
@@ -143,10 +201,40 @@ for more info.
|
|
|
143
201
|
This is likely to cause issues across Rails versions. No other choice really. It
|
|
144
202
|
has been used in anger on Rails 3.2.x and Rails 4.1.x.
|
|
145
203
|
|
|
146
|
-
|
|
204
|
+
## Development and Testing
|
|
205
|
+
|
|
206
|
+
### Ruby Version
|
|
207
|
+
|
|
208
|
+
This project requires Ruby 2.7+ for gem usage, though development is done on Ruby 3.3+. The development Ruby version is specified in `.ruby-version` and minimum required version in the gemspec file.
|
|
209
|
+
|
|
210
|
+
### Testing Frameworks
|
|
211
|
+
|
|
212
|
+
This project uses the following testing frameworks:
|
|
147
213
|
|
|
148
|
-
|
|
149
|
-
|
|
214
|
+
- **RSpec 3.13+** for unit tests
|
|
215
|
+
- **Cucumber 10.x** for feature tests (upgraded from 2.x)
|
|
216
|
+
- **Aruba 2.x** for CLI testing (upgraded from 0.5.x)
|
|
217
|
+
|
|
218
|
+
### Running Tests
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# Run RSpec tests
|
|
222
|
+
bundle exec rspec
|
|
223
|
+
|
|
224
|
+
# Run Cucumber features
|
|
225
|
+
bundle exec cucumber
|
|
226
|
+
|
|
227
|
+
# Run all tests
|
|
228
|
+
bundle exec rspec && bundle exec cucumber
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Supported PostgreSQL Versions
|
|
232
|
+
|
|
233
|
+
This gem requires PostgreSQL 15.0 or later. Tested and confirmed working on:
|
|
234
|
+
|
|
235
|
+
- PostgreSQL 15.x
|
|
236
|
+
- PostgreSQL 16.x
|
|
237
|
+
- PostgreSQL 17.x
|
|
150
238
|
|
|
151
239
|
## Using prodder to maintain `db/*` files
|
|
152
240
|
|
|
@@ -205,13 +293,15 @@ store:
|
|
|
205
293
|
```
|
|
206
294
|
|
|
207
295
|
### Quality Checks
|
|
296
|
+
|
|
208
297
|
In some cases, such as foreign key dependencies and triggers, you may wish to defer
|
|
209
|
-
loading constraints on your tables until
|
|
298
|
+
loading constraints on your tables until *after* your seed data has been loaded.
|
|
210
299
|
`prodder` treats the presence of a `quality_check_file` key in the configuration
|
|
211
300
|
as an indication that it should split `structure_file` into those statements which
|
|
212
301
|
create the base structure, and put the constraints into the `quality_check_file`.
|
|
213
302
|
|
|
214
303
|
### Permissions
|
|
304
|
+
|
|
215
305
|
We have had multiple cases in the past with deployments failing because some role
|
|
216
306
|
cannot access something on prod. To fail early and catch these in development, it
|
|
217
307
|
would be easier to just have these permissions loaded in development environments.
|
|
@@ -221,10 +311,9 @@ must configure the 3 users as mentioned before in `#config/database.yml`.
|
|
|
221
311
|
```yaml
|
|
222
312
|
store:
|
|
223
313
|
structure_file: db/structure.sql # CREATE TABLE ...
|
|
224
|
-
quality_check_file: db/
|
|
314
|
+
quality_check_file: db/quality_checks.sql # ALTER TABLE ... ADD FOREIGN KEY ...
|
|
225
315
|
```
|
|
226
316
|
|
|
227
|
-
|
|
228
317
|
### Example usage
|
|
229
318
|
|
|
230
319
|
The `-c` option to specify the configuration file is always required. All
|
|
@@ -254,19 +343,22 @@ $ prodder push -c prodder.yml
|
|
|
254
343
|
```
|
|
255
344
|
|
|
256
345
|
## TODO
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
346
|
+
|
|
347
|
+
- Log activity as it is performed.
|
|
348
|
+
- Support tracking a particular branch instead of master.
|
|
349
|
+
- Support specifying the options to pass to each pg_dump form.
|
|
350
|
+
- Select dumping only a subset of a seed table. (pg_dump won't do this ...)
|
|
261
351
|
|
|
262
352
|
## Previous Contributors
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
353
|
+
|
|
354
|
+
- [Kyle Hargraves](https://github.com/pd)
|
|
355
|
+
- [Sri Rangarajan](https://github.com/Slania)
|
|
356
|
+
- [Emmanuel Sambo](https://github.com/esambo)
|
|
357
|
+
- [Cindy Wise](https://github.com/cyyyz)
|
|
358
|
+
- [Robert Nubel](https://github.com/rnubel)
|
|
359
|
+
- [Josh Cheek](https://github.com/JoshCheek)
|
|
360
|
+
- [Alexandre Castro](https://github.com/acastro2)
|
|
269
361
|
|
|
270
362
|
## License
|
|
271
363
|
|
|
272
|
-
The gem is available as open source under the terms of the [MIT License](
|
|
364
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
data/compose.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
services:
|
|
2
2
|
postgres:
|
|
3
|
-
image: postgres:
|
|
3
|
+
image: postgres:17-alpine
|
|
4
4
|
volumes:
|
|
5
5
|
- postgres_data:/var/lib/postgresql/data
|
|
6
6
|
ports:
|
|
@@ -22,7 +22,7 @@ services:
|
|
|
22
22
|
context: .
|
|
23
23
|
dockerfile: Dockerfile
|
|
24
24
|
args:
|
|
25
|
-
RUBY_VERSION: 3.
|
|
25
|
+
RUBY_VERSION: 3.3
|
|
26
26
|
volumes:
|
|
27
27
|
- .:/app
|
|
28
28
|
- /app/config
|
data/cucumber.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
default: --publish-quiet
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
Given 'a
|
|
1
|
+
Given 'a {string} git repository' do |project|
|
|
2
2
|
fixture_repo = File.join(@prodder_root, 'features', 'support', "#{project}.git")
|
|
3
3
|
unless File.directory? fixture_repo
|
|
4
4
|
raise "Cannot initialize repo for project #{project}; expected fixture at: #{fixture_repo}"
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
if File.exist? File.join(
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
run_command_and_stop "mkdir -p repos"
|
|
8
|
+
if File.exist? File.join(expand_path('.'), "repos", "#{project}.git")
|
|
9
|
+
run_command_and_stop "chmod -R a+w repos/#{project}.git"
|
|
10
|
+
run_command_and_stop "rm -rf repos/#{project}.git"
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
run_command_and_stop "cp -pR #{fixture_repo} repos/#{project}.git"
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
Given 'I deleted the
|
|
16
|
-
|
|
15
|
+
Given 'I deleted the {string} git repository' do |project|
|
|
16
|
+
run_command_and_stop "rm -rf repos/#{project}.git"
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
Given 'the
|
|
20
|
-
|
|
19
|
+
Given 'the {string} git repository does not allow pushing to it' do |project|
|
|
20
|
+
run_command_and_stop "chmod -R a-w repos/#{project}.git"
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
Given 'a new commit is already in the
|
|
23
|
+
Given 'a new commit is already in the {string} git repository' do |project|
|
|
24
24
|
commit_to_remote project
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
Then 'the new commit should be in the workspace copy of the
|
|
28
|
-
|
|
27
|
+
Then 'the new commit should be in the workspace copy of the {string} repository' do |project|
|
|
28
|
+
expect("prodder-workspace/#{project}/README").to have_file_content(/Also read this!/)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
Then(/^(\d+) commits? by "([^"]+)" should be in the "([^"]+)" repository$/) do |n, author, project|
|
|
@@ -35,14 +35,14 @@ Then(/^(\d+) commits? by "([^"]+)" should be in the "([^"]+)" repository$/) do |
|
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
Then 'the file
|
|
39
|
-
|
|
38
|
+
Then 'the file {string} should now be tracked' do |filename|
|
|
39
|
+
in_current_directory do
|
|
40
40
|
git = Prodder::Git.new(File.expand_path("prodder-workspace/blog"), nil)
|
|
41
41
|
expect(git).to be_tracked(filename)
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
Then 'the latest commit should have changed
|
|
45
|
+
Then 'the latest commit should have changed {string} to contain {string}' do |filename, content|
|
|
46
46
|
in_workspace('blog') do
|
|
47
47
|
changed = `git show --name-only HEAD | grep #{filename}`.split("\n")
|
|
48
48
|
expect(changed).to_not be_empty
|
|
@@ -52,7 +52,7 @@ Then 'the latest commit should have changed "$file" to contain "$content"' do |f
|
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
Then 'the latest commit should not have changed
|
|
55
|
+
Then 'the latest commit should not have changed {string}' do |filename|
|
|
56
56
|
in_workspace('blog') do
|
|
57
57
|
changed = `git show --name-only HEAD | grep #{filename}`.split("\n")
|
|
58
58
|
expect(changed).to be_empty
|
|
@@ -60,7 +60,7 @@ Then 'the latest commit should not have changed "$filename"' do |filename|
|
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
Then 'the new commit should be in the remote repository' do
|
|
63
|
-
|
|
63
|
+
in_current_directory do
|
|
64
64
|
latest = `git --git-dir="./repos/blog.git" log | grep prodder`.split("\n")
|
|
65
65
|
expect(latest).to_not be_empty
|
|
66
66
|
end
|