planetscale_rails 0.1.4 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1fac50d24f5d87d2be01f128dd42f63b75023d7761d5516c92ac8ad92f776fae
4
- data.tar.gz: 29a0fc6de3302ccd5b228c458facf7516147c2ca78b5f1717979bfbd6d8534d8
3
+ metadata.gz: e1c96f1384c6bcee4a33e81124384b80ce8cff99823b1d5fc77ad926967087a4
4
+ data.tar.gz: '0880e54628a3c0b22a98f1883dce8fd6ac4aee57315fffab014d07c9da66e014'
5
5
  SHA512:
6
- metadata.gz: 3993c4de9fb27abda2d3f9506f28a8f8c8b12312540fdee58d7838d37fb8af25fba31b2b7c291915e9f1488fc8586708f516e6149dede3fe26a4c22ce5e44cb9
7
- data.tar.gz: 93bcfb6f5d2f2bc0096de75029a2c12de9db97ab1fa591aa50e37d8d1548c23142a2dbda0079d51b8078d160f3535ba8bed3965042331e7b447136d69abdd997
6
+ metadata.gz: c4fabd32053c4456bdd002729f21fd9548905a7fc8472a97dd23fb0f1aed9df5798381cae839fd4495b0acacdc97170c47b92312cc38c78a0a31df3911097765
7
+ data.tar.gz: 2f50ab3be8305f60c81c11d625f470775678bf311d103c1301d982fb1aa5f6c39ac8b176f21bd8eb4ea511098f22e8a77a3b09cdb459130ea60bdddcee37ae57
data/.rubocop.yml CHANGED
@@ -1,6 +1,12 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 3
3
3
 
4
+ Metrics/CyclomaticComplexity:
5
+ Enabled: false
6
+
7
+ Metrics/PerceivedComplexity:
8
+ Enabled: false
9
+
4
10
  Style/StringLiterals:
5
11
  Enabled: true
6
12
  EnforcedStyle: double_quotes
@@ -10,7 +16,13 @@ Style/StringLiteralsInInterpolation:
10
16
  EnforcedStyle: double_quotes
11
17
 
12
18
  Layout/LineLength:
13
- Max: 180
19
+ Enabled: false
20
+
21
+ Metrics/MethodLength:
22
+ Enabled: false
23
+
24
+ Metrics/AbcSize:
25
+ Enabled: false
14
26
 
15
27
  Metrics/BlockLength:
16
28
  Enabled: false
data/Gemfile.lock CHANGED
@@ -1,74 +1,74 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- planetscale_rails (0.1.1)
4
+ planetscale_rails (0.2.0)
5
5
  colorize (~> 0.8.1)
6
- rails (~> 7.0)
6
+ rails (>= 6.0, < 8)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- actioncable (7.0.4.2)
12
- actionpack (= 7.0.4.2)
13
- activesupport (= 7.0.4.2)
11
+ actioncable (7.0.6)
12
+ actionpack (= 7.0.6)
13
+ activesupport (= 7.0.6)
14
14
  nio4r (~> 2.0)
15
15
  websocket-driver (>= 0.6.1)
16
- actionmailbox (7.0.4.2)
17
- actionpack (= 7.0.4.2)
18
- activejob (= 7.0.4.2)
19
- activerecord (= 7.0.4.2)
20
- activestorage (= 7.0.4.2)
21
- activesupport (= 7.0.4.2)
16
+ actionmailbox (7.0.6)
17
+ actionpack (= 7.0.6)
18
+ activejob (= 7.0.6)
19
+ activerecord (= 7.0.6)
20
+ activestorage (= 7.0.6)
21
+ activesupport (= 7.0.6)
22
22
  mail (>= 2.7.1)
23
23
  net-imap
24
24
  net-pop
25
25
  net-smtp
26
- actionmailer (7.0.4.2)
27
- actionpack (= 7.0.4.2)
28
- actionview (= 7.0.4.2)
29
- activejob (= 7.0.4.2)
30
- activesupport (= 7.0.4.2)
26
+ actionmailer (7.0.6)
27
+ actionpack (= 7.0.6)
28
+ actionview (= 7.0.6)
29
+ activejob (= 7.0.6)
30
+ activesupport (= 7.0.6)
31
31
  mail (~> 2.5, >= 2.5.4)
32
32
  net-imap
33
33
  net-pop
34
34
  net-smtp
35
35
  rails-dom-testing (~> 2.0)
36
- actionpack (7.0.4.2)
37
- actionview (= 7.0.4.2)
38
- activesupport (= 7.0.4.2)
39
- rack (~> 2.0, >= 2.2.0)
36
+ actionpack (7.0.6)
37
+ actionview (= 7.0.6)
38
+ activesupport (= 7.0.6)
39
+ rack (~> 2.0, >= 2.2.4)
40
40
  rack-test (>= 0.6.3)
41
41
  rails-dom-testing (~> 2.0)
42
42
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
43
- actiontext (7.0.4.2)
44
- actionpack (= 7.0.4.2)
45
- activerecord (= 7.0.4.2)
46
- activestorage (= 7.0.4.2)
47
- activesupport (= 7.0.4.2)
43
+ actiontext (7.0.6)
44
+ actionpack (= 7.0.6)
45
+ activerecord (= 7.0.6)
46
+ activestorage (= 7.0.6)
47
+ activesupport (= 7.0.6)
48
48
  globalid (>= 0.6.0)
49
49
  nokogiri (>= 1.8.5)
50
- actionview (7.0.4.2)
51
- activesupport (= 7.0.4.2)
50
+ actionview (7.0.6)
51
+ activesupport (= 7.0.6)
52
52
  builder (~> 3.1)
53
53
  erubi (~> 1.4)
54
54
  rails-dom-testing (~> 2.0)
55
55
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
56
- activejob (7.0.4.2)
57
- activesupport (= 7.0.4.2)
56
+ activejob (7.0.6)
57
+ activesupport (= 7.0.6)
58
58
  globalid (>= 0.3.6)
59
- activemodel (7.0.4.2)
60
- activesupport (= 7.0.4.2)
61
- activerecord (7.0.4.2)
62
- activemodel (= 7.0.4.2)
63
- activesupport (= 7.0.4.2)
64
- activestorage (7.0.4.2)
65
- actionpack (= 7.0.4.2)
66
- activejob (= 7.0.4.2)
67
- activerecord (= 7.0.4.2)
68
- activesupport (= 7.0.4.2)
59
+ activemodel (7.0.6)
60
+ activesupport (= 7.0.6)
61
+ activerecord (7.0.6)
62
+ activemodel (= 7.0.6)
63
+ activesupport (= 7.0.6)
64
+ activestorage (7.0.6)
65
+ actionpack (= 7.0.6)
66
+ activejob (= 7.0.6)
67
+ activerecord (= 7.0.6)
68
+ activesupport (= 7.0.6)
69
69
  marcel (~> 1.0)
70
70
  mini_mime (>= 1.1.0)
71
- activesupport (7.0.4.2)
71
+ activesupport (7.0.6)
72
72
  concurrent-ruby (~> 1.0, >= 1.0.2)
73
73
  i18n (>= 1.6, < 2)
74
74
  minitest (>= 5.1)
@@ -83,12 +83,12 @@ GEM
83
83
  erubi (1.12.0)
84
84
  globalid (1.1.0)
85
85
  activesupport (>= 5.0)
86
- i18n (1.12.0)
86
+ i18n (1.14.1)
87
87
  concurrent-ruby (~> 1.0)
88
88
  json (2.6.3)
89
- loofah (2.19.1)
89
+ loofah (2.21.3)
90
90
  crass (~> 1.0.2)
91
- nokogiri (>= 1.5.9)
91
+ nokogiri (>= 1.12.0)
92
92
  mail (2.8.1)
93
93
  mini_mime (>= 0.1.1)
94
94
  net-imap
@@ -97,8 +97,8 @@ GEM
97
97
  marcel (1.0.2)
98
98
  method_source (1.0.0)
99
99
  mini_mime (1.1.2)
100
- minitest (5.18.0)
101
- net-imap (0.3.4)
100
+ minitest (5.19.0)
101
+ net-imap (0.3.7)
102
102
  date
103
103
  net-protocol
104
104
  net-pop (0.1.2)
@@ -107,40 +107,42 @@ GEM
107
107
  timeout
108
108
  net-smtp (0.3.3)
109
109
  net-protocol
110
- nio4r (2.5.8)
111
- nokogiri (1.14.2-x86_64-darwin)
110
+ nio4r (2.5.9)
111
+ nokogiri (1.15.4-x86_64-darwin)
112
112
  racc (~> 1.4)
113
- nokogiri (1.14.2-x86_64-linux)
113
+ nokogiri (1.15.4-x86_64-linux)
114
114
  racc (~> 1.4)
115
115
  parallel (1.22.1)
116
116
  parser (3.2.1.0)
117
117
  ast (~> 2.4.1)
118
- racc (1.6.2)
119
- rack (2.2.6.3)
120
- rack-test (2.0.2)
118
+ racc (1.7.3)
119
+ rack (2.2.7)
120
+ rack-test (2.1.0)
121
121
  rack (>= 1.3)
122
- rails (7.0.4.2)
123
- actioncable (= 7.0.4.2)
124
- actionmailbox (= 7.0.4.2)
125
- actionmailer (= 7.0.4.2)
126
- actionpack (= 7.0.4.2)
127
- actiontext (= 7.0.4.2)
128
- actionview (= 7.0.4.2)
129
- activejob (= 7.0.4.2)
130
- activemodel (= 7.0.4.2)
131
- activerecord (= 7.0.4.2)
132
- activestorage (= 7.0.4.2)
133
- activesupport (= 7.0.4.2)
122
+ rails (7.0.6)
123
+ actioncable (= 7.0.6)
124
+ actionmailbox (= 7.0.6)
125
+ actionmailer (= 7.0.6)
126
+ actionpack (= 7.0.6)
127
+ actiontext (= 7.0.6)
128
+ actionview (= 7.0.6)
129
+ activejob (= 7.0.6)
130
+ activemodel (= 7.0.6)
131
+ activerecord (= 7.0.6)
132
+ activestorage (= 7.0.6)
133
+ activesupport (= 7.0.6)
134
134
  bundler (>= 1.15.0)
135
- railties (= 7.0.4.2)
136
- rails-dom-testing (2.0.3)
137
- activesupport (>= 4.2.0)
135
+ railties (= 7.0.6)
136
+ rails-dom-testing (2.1.1)
137
+ activesupport (>= 5.0.0)
138
+ minitest
138
139
  nokogiri (>= 1.6)
139
- rails-html-sanitizer (1.5.0)
140
- loofah (~> 2.19, >= 2.19.1)
141
- railties (7.0.4.2)
142
- actionpack (= 7.0.4.2)
143
- activesupport (= 7.0.4.2)
140
+ rails-html-sanitizer (1.6.0)
141
+ loofah (~> 2.21)
142
+ nokogiri (~> 1.14)
143
+ railties (7.0.6)
144
+ actionpack (= 7.0.6)
145
+ activesupport (= 7.0.6)
144
146
  method_source
145
147
  rake (>= 12.2)
146
148
  thor (~> 1.0)
@@ -175,15 +177,15 @@ GEM
175
177
  rubocop-ast (1.27.0)
176
178
  parser (>= 3.2.1.0)
177
179
  ruby-progressbar (1.12.0)
178
- thor (1.2.1)
179
- timeout (0.3.2)
180
+ thor (1.2.2)
181
+ timeout (0.4.0)
180
182
  tzinfo (2.0.6)
181
183
  concurrent-ruby (~> 1.0)
182
184
  unicode-display_width (2.4.2)
183
- websocket-driver (0.7.5)
185
+ websocket-driver (0.7.6)
184
186
  websocket-extensions (>= 0.1.0)
185
187
  websocket-extensions (0.1.5)
186
- zeitwerk (2.6.7)
188
+ zeitwerk (2.6.9)
187
189
 
188
190
  PLATFORMS
189
191
  x86_64-darwin-20
data/README.md CHANGED
@@ -15,7 +15,6 @@ against it. See [usage](#usage) for details.
15
15
  rake psdb:migrate # Migrate the database for current environment
16
16
  rake psdb:rollback # Rollback primary database for current environment
17
17
  rake psdb:schema:load # Load the current schema into the database
18
- rake psdb:setup_pscale # Setup a proxy to connect to PlanetScale
19
18
  ```
20
19
 
21
20
  ## Installation
@@ -34,36 +33,19 @@ And then execute in your terminal:
34
33
  bundle install
35
34
  ```
36
35
 
37
- ### Update database.yml
38
-
39
- In your application's `database.yml`, you'll need to make two changes. This will allow the app to run migrations via a connection setup by the pscale CLI.
40
-
41
- 1. Swap to port 3305 if `ENV['ENABLE_PSDB']` is true.
42
- 2. Use production database name if `ENV['ENABLE_PSDB']` is true.
43
-
44
- Here is an example
45
-
46
- ```
47
- development:
48
- <<: *default
49
- database: <%= ENV['ENABLE_PSDB'] ? 'your_production_db_name' : 'your_development_db_name' %>
50
- port: <%= ENV['ENABLE_PSDB'] ? 3305 : ENV.fetch("DB_PORT", 3306) %>
51
- ```
36
+ Make sure you have the [`pscale` CLI installed](https://github.com/planetscale/cli#installation).
52
37
 
53
38
  ## Usage
54
39
 
55
- First, make sure you have the [`pscale` CLI installed](https://github.com/planetscale/cli#installation). You'll use `pscale` to create a new branch.
56
-
57
- 1. Run this locally, it will create a new branch off of `main`. The `switch` command will update a `.pscale.yml` file to track
58
- that this is the branch you want to migrate.
40
+ 1. Using pscale, create a new branch. This command will create a local `.pscale.yml` file. You should add it to your `.gitignore`.
59
41
 
60
42
  ```
61
- pscale branch switch my-new-branch-name --database my-db-name --create
43
+ pscale branch switch my-new-branch-name --database my-db-name --create --wait
62
44
  ```
63
45
 
64
46
  **Tip:** In your database settings. Enable "Automatically copy migration data." Select "Rails" as the migration framework. This will auto copy your `schema_migrations` table between branches.
65
47
 
66
- 2. Once your branch is ready, you can then use the `psdb` rake task to connect to your branch and run `db:migrate`.
48
+ 2. Run your schema migrations against the branch.
67
49
 
68
50
  ```
69
51
  bundle exec rails psdb:migrate
@@ -75,8 +57,6 @@ If you run multiple databases in your Rails app, you can specify the DB name.
75
57
  bundle exec rails psdb:migrate:primary
76
58
  ```
77
59
 
78
- This will connect to the branch that you created, and run migrations against the branch.
79
-
80
60
  If you make a mistake, you can use `bundle exec rails psdb:rollback` to rollback the changes on your PlanetScale branch.
81
61
 
82
62
  3. Next, you can either open the Deploy Request via the UI. Or the CLI.
@@ -88,6 +68,16 @@ pscale deploy-request create database-name my-new-branch-name
88
68
 
89
69
  4. To get your schema change to production, run the deploy request. Then, once it's complete, you can merge your code changes into your `main` branch in git and deploy your application code.
90
70
 
71
+ ## Using PlanetScale deploy requests vs `psdb:migrate` directly in production.
72
+
73
+ PlanetScale's deploy requests [solve the schema change problem](https://planetscale.com/docs/learn/how-online-schema-change-tools-work). They make a normally high risk operation, safe. This is done by running your schema change using [Vitess's online schema change](https://vitess.io/docs/18.0/user-guides/schema-changes/) tools. Once the change is made, a deploy request is [also revertible without data loss](https://planetscale.com/blog/revert-a-migration-without-losing-data). None of this is possible when running `rails db:migrate` directly against your production database.
74
+
75
+ We recommend using GitHub Actions to automate the creation of PlanetScale branches and deploy requests. Then when you are ready to merge, you can run the deploy request before merging in your code.
76
+
77
+ **When not to use deploy requests**
78
+
79
+ If your application has minimal data and schema changes are a low risk event, then running `psdb:migrate` directly against production is perfectly fine. As your datasize grows and your application becomes busier, the risk of schema changes increase and we highly recommend using the deploy request flow. It's the best way available to safely migrate your schema.
80
+
91
81
  ## Usage with GitHub Actions
92
82
 
93
83
  See the [GitHub Actions examples](actions-example.md) doc for ways to automate your schema migrations with PlanetScale + Actions.
data/actions-example.md CHANGED
@@ -18,7 +18,7 @@ Secrets needed to be set:
18
18
  - `PLANETSCALE_SERVICE_TOKEN_ID`
19
19
  - `PLANETSCALE_SERVICE_TOKEN`
20
20
 
21
- The PlanetScale service token must have permission on the database to create/read development branches, as well as create deploy requests.
21
+ The PlanetScale service token must have the `connect_branch`, `create_branch`, `delete_branch_password`, `read_branch`, `create_deploy_request`, and `read_deploy_request` permissions on the database.
22
22
 
23
23
  ```yaml
24
24
  name: Run database migrations
@@ -7,18 +7,13 @@ require "colorize"
7
7
 
8
8
  databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
9
9
 
10
- def shared_deps(name = nil)
11
- return [:environment, :check_ci, "setup_pscale:#{name}".to_sym] if name
12
- return %i[environment check_ci] if name.nil?
13
- end
14
-
15
10
  def puts_deploy_request_instructions
16
11
  ps_config = YAML.load_file(".pscale.yml")
17
12
  database = ps_config["database"]
18
13
  branch = ps_config["branch"]
19
14
  org = ps_config["org"]
20
15
 
21
- puts "Create a deploy request for '#{branch}' by running:\n"
16
+ puts "Create a deploy request for '#{branch.colorize(:blue)}' by running:\n"
22
17
  puts " pscale deploy-request create #{database} #{branch} --org #{org}\n\n"
23
18
  end
24
19
 
@@ -26,6 +21,28 @@ def kill_pscale_process
26
21
  Process.kill("TERM", ENV["PSCALE_PID"].to_i) if ENV["PSCALE_PID"]
27
22
  end
28
23
 
24
+ def delete_password
25
+ password_id = ENV["PSCALE_PASSWORD_ID"]
26
+ return unless password_id
27
+
28
+ ps_config = YAML.load_file(".pscale.yml")
29
+ database = ps_config["database"]
30
+ branch = ps_config["branch"]
31
+
32
+ command = "pscale password delete #{database} #{branch} #{password_id} #{ENV["SERVICE_TOKEN_CONFIG"]} --force"
33
+ output = `#{command}`
34
+
35
+ return if $CHILD_STATUS.success?
36
+
37
+ puts "Failed to cleanup credentials used for PlanetScale connection. Password ID: #{password_id}".colorize(:red)
38
+ puts "Command: #{command}"
39
+ puts "Output: #{output}"
40
+ end
41
+
42
+ def db_branch_colorized(database, branch)
43
+ "#{database.colorize(:blue)}/#{branch.colorize(:blue)}"
44
+ end
45
+
29
46
  namespace :psdb do
30
47
  task check_ci: :environment do
31
48
  use_service_token = ENV["PSCALE_SERVICE_TOKEN"] && ENV["PSCALE_SERVICE_TOKEN_ID"]
@@ -38,91 +55,63 @@ namespace :psdb do
38
55
  end
39
56
  end
40
57
 
41
- desc "Setup a proxy to connect to PlanetScale"
42
- task "setup_pscale" => shared_deps do
43
- ENV["ENABLE_PSDB"] = "1"
44
- ENV["DISABLE_PS_GEM"] = "1"
58
+ def create_connection_string
45
59
  ps_config = YAML.load_file(".pscale.yml")
46
60
  database = ps_config["database"]
47
61
  branch = ps_config["branch"]
48
62
 
49
63
  raise "You must have `pscale` installed on your computer".colorize(:red) unless command?("pscale")
50
64
  if branch.blank? || database.blank?
51
- raise "Your branch is not properly setup, please switch to a branch by using the CLI.".colorize(:red)
52
- end
53
-
54
- r, = PTY.open
55
-
56
- puts "Connecting to PlanetScale..."
57
-
58
- # Spawns the process in the background
59
- pid = Process.spawn("pscale connect #{database} #{branch} --port 3305 #{ENV["SERVICE_TOKEN_CONFIG"]}", out: r)
60
- ENV["PSCALE_PID"] = pid.to_s
61
-
62
- out = ""
63
- start_time = Time.current
64
- time_elapsed = Time.current - start_time
65
- sleep(1)
66
- while out.blank? && time_elapsed < 10.seconds
67
- PTY.check(pid, true)
68
- out = r.gets
69
- time_elapsed = Time.current - start_time
65
+ raise "Could not determine which PlanetScale branch to use from .pscale.yml. Please switch to a branch by using: `pscale branch switch branch-name --database db-name --create --wait`".colorize(:red)
70
66
  end
71
67
 
72
- raise "Timed out waiting for PlanetScale connection to be established".colorize(:red) if time_elapsed > 10.seconds
73
- ensure
74
- r&.close
75
- end
68
+ short_hash = SecureRandom.hex(2)[0, 4]
69
+ password_name = "planetscale-rails-#{short_hash}"
70
+ command = "pscale password create #{database} #{branch} #{password_name} -f json #{ENV["SERVICE_TOKEN_CONFIG"]}"
76
71
 
77
- namespace :setup_pscale do
78
- ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
79
- desc "Setup a proxy to connect to #{name} in PlanetScale"
80
- task name => shared_deps do
81
- ENV["ENABLE_PSDB"] = "1"
82
- ENV["DISABLE_PS_GEM"] = "1"
83
- ps_config = YAML.load_file(".pscale.yml")
84
- database = ps_config["database"]
85
- branch = ps_config["branch"]
86
-
87
- raise "You must have `pscale` installed on your computer" unless command?("pscale")
88
- if branch.blank? || database.blank?
89
- raise "Your branch is not properly setup, please switch to a branch by using the CLI."
90
- end
72
+ output = `#{command}`
91
73
 
92
- config = Rails.configuration.database_configuration[Rails.env][name]
74
+ if $CHILD_STATUS.success?
75
+ response = JSON.parse(output)
76
+ puts "Successfully created credentials for PlanetScale #{db_branch_colorized(database, branch)}"
77
+ host = response["access_host_url"]
78
+ username = response["username"]
79
+ password = response["plain_text"]
80
+ ENV["PSCALE_PASSWORD_ID"] = response["id"]
93
81
 
94
- raise "Database #{name} is not configured for the current environment" unless config
82
+ adapter = "mysql2"
95
83
 
96
- r, = PTY.open
97
-
98
- puts "Connecting to PlanetScale..."
99
-
100
- # Spawns the process in the background
101
- pid = Process.spawn("pscale connect #{database} #{branch} --port 3305 #{ENV["SERVICE_TOKEN_CONFIG"]}", out: r)
102
- ENV["PSCALE_PID"] = pid.to_s
84
+ if defined?(Trilogy)
85
+ adapter = "trilogy"
86
+ end
103
87
 
104
- out = ""
105
- start_time = Time.current
106
- time_elapsed = Time.current - start_time
107
- sleep(1)
108
- while out.blank? && time_elapsed < 10.seconds
109
- PTY.check(pid, true)
110
- out = r.gets
111
- time_elapsed = Time.current - start_time
112
- end
88
+ # Setting schema_dump to nil is intentional. It prevents Rails from creating a dump after running migrations.
89
+ url = "#{adapter}://#{username}:#{password}@#{host}:3306/#{database}?ssl_mode=VERIFY_IDENTITY&schema_dump="
113
90
 
114
- raise "Timed out waiting for PlanetScale connection to be established" if time_elapsed > 10.seconds
91
+ # Check common CA paths for certs.
92
+ ssl_ca_path = %w[/etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt /etc/ssl/ca-bundle.pem /etc/ssl/cert.pem].find { |f| File.exist?(f) }
115
93
 
116
- # Comment out for now, this messes up when running migrations.
117
- # Kernel.system("bundle exec rails db:environment:set RAILS_ENV=development")
118
- ensure
119
- r&.close
94
+ if ssl_ca_path
95
+ url += "&sslca=#{ssl_ca_path}"
120
96
  end
97
+
98
+ url
99
+ else
100
+ puts "Failed to create credentials for PlanetScale #{db_branch_colorized(database, branch)}"
101
+ puts "Command: #{command}"
102
+ puts "Output: #{output}"
103
+ puts "Please verify that you have the correct permissions to create a password for this branch."
104
+ exit 1
121
105
  end
122
106
  end
123
107
 
124
- desc "Migrate the database for current environment"
125
- task migrate: %i[environment check_ci setup_pscale] do
108
+ desc "Create credentials for PlanetScale and sets them to ENV['PSCALE_DATABASE_URL']"
109
+ task "create_creds" => %i[environment check_ci] do
110
+ ENV["PSCALE_DATABASE_URL"] = create_connection_string
111
+ end
112
+
113
+ desc "Connects to the current PlanetScale branch and runs rails db:migrate"
114
+ task migrate: %i[environment check_ci create_creds] do
126
115
  db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
127
116
 
128
117
  unless db_configs.size == 1
@@ -130,41 +119,45 @@ namespace :psdb do
130
119
  end
131
120
 
132
121
  puts "Running migrations..."
133
- Kernel.system("bundle exec rails db:migrate")
134
- puts "Finished running migrations\n".colorize(:green)
135
- puts_deploy_request_instructions
122
+
123
+ command = "DATABASE_URL=\"#{ENV["PSCALE_DATABASE_URL"]}\" bundle exec rails db:migrate"
124
+ IO.popen(command) do |io|
125
+ io.each_line do |line|
126
+ puts line
127
+ end
128
+ end
129
+
130
+ if $CHILD_STATUS.success?
131
+ puts_deploy_request_instructions
132
+ else
133
+ puts "Failed to run migrations".colorize(:red)
134
+ end
136
135
  ensure
137
- kill_pscale_process
136
+ delete_password
138
137
  end
139
138
 
140
139
  namespace :migrate do
141
140
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
142
- desc "Migrate #{name} database for current environment"
143
- task name => shared_deps(name) do
141
+ desc "Connects to the current PlanetScale branch and runs rails db:migrate:#{name}"
142
+ task name => %i[environment check_ci create_creds] do
144
143
  puts "Running migrations..."
145
- # We run it using the Kernel.system here because this properly handles
146
- # when exceptions occur whereas Rake::Task.invoke does not.
147
- Kernel.system("bundle exec rake db:migrate:#{name}")
148
144
 
149
- puts "Finished running migrations\n".colorize(:green)
150
- puts_deploy_request_instructions
151
- ensure
152
- kill_pscale_process
153
- end
154
- end
155
- end
145
+ name_env_key = "#{name.upcase}_DATABASE_URL"
146
+ command = "#{name_env_key}=\"#{ENV["PSCALE_DATABASE_URL"]}\" bundle exec rails db:migrate:#{name}"
156
147
 
157
- namespace :truncate_all do
158
- ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
159
- desc "Truncate all tables in #{name} database for current environment"
160
- task name => shared_deps(name) do
161
- puts "Truncating database..."
162
- # We run it using the Kernel.system here because this properly handles
163
- # when exceptions occur whereas Rake::Task.invoke does not.
164
- Kernel.system("bundle exec rake db:truncate_all")
165
- puts "Finished truncating database."
148
+ IO.popen(command) do |io|
149
+ io.each_line do |line|
150
+ puts line
151
+ end
152
+ end
153
+
154
+ if $CHILD_STATUS.success?
155
+ puts_deploy_request_instructions
156
+ else
157
+ puts "Failed to run migrations".colorize(:red)
158
+ end
166
159
  ensure
167
- kill_pscale_process
160
+ delete_password
168
161
  end
169
162
  end
170
163
  end
@@ -172,31 +165,79 @@ namespace :psdb do
172
165
  namespace :schema do
173
166
  namespace :load do
174
167
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
175
- desc "Load the current schema into the #{name} database"
176
- task name => shared_deps(name) do
168
+ desc "Connects to the current PlanetScale branch and runs rails db:schema:load:#{name}"
169
+ task name => %i[environment check_ci create_creds] do
177
170
  puts "Loading schema..."
178
- # We run it using the Kernel.system here because this properly handles
179
- # when exceptions occur whereas Rake::Task.invoke does not.
180
- Kernel.system("bundle exec rake db:schema:load:#{name}")
181
- puts "Finished loading schema."
171
+
172
+ name_env_key = "#{name.upcase}_DATABASE_URL"
173
+ command = "#{name_env_key}=\"#{ENV["PSCALE_DATABASE_URL"]}\" bundle exec rake db:schema:load:#{name}"
174
+
175
+ IO.popen(command) do |io|
176
+ io.each_line do |line|
177
+ puts line
178
+ end
179
+ end
180
+
181
+ unless $CHILD_STATUS.success?
182
+ puts "Failed to load schema".colorize(:red)
183
+ end
182
184
  ensure
183
- kill_pscale_process
185
+ delete_password
184
186
  end
185
187
  end
186
188
  end
187
189
  end
188
190
 
191
+ desc "Connects to the current PlanetScale branch and runs rails db:rollback"
192
+ task rollback: %i[environment check_ci create_creds] do
193
+ db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
194
+
195
+ unless db_configs.size == 1
196
+ raise "Found multiple database configurations, please specify which database you want to rollback using `psdb:rollback:<database_name>`".colorize(:red)
197
+ end
198
+
199
+ command = "DATABASE_URL=\"#{ENV["PSCALE_DATABASE_URL"]}\" bundle exec rails db:rollback"
200
+
201
+ IO.popen(command) do |io|
202
+ io.each_line do |line|
203
+ puts line
204
+ end
205
+ end
206
+
207
+ unless $CHILD_STATUS.success?
208
+ puts "Failed to rollback migrations".colorize(:red)
209
+ end
210
+ ensure
211
+ delete_password
212
+ end
213
+
189
214
  namespace :rollback do
190
215
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
191
- desc "Rollback #{name} database for current environment"
192
- task name => shared_deps(name) do
216
+ desc "Connects to the current PlanetScale branch and runs rails db:rollback:#{name}"
217
+ task name => %i[environment check_ci create_creds] do
218
+ required_version = Gem::Version.new("6.1.0.0")
219
+ rails_version = Gem::Version.new(Rails.version)
220
+
221
+ if rails_version < required_version
222
+ raise "This version of Rails does not support rollback commands for multi-database Rails apps. Please upgrade to at least Rails 6.1"
223
+ end
224
+
193
225
  puts "Rolling back migrations..."
194
- # We run it using the Kernel.system here because this properly handles
195
- # when exceptions occur whereas Rake::Task.invoke does not.
196
- Kernel.system("bundle exec rake db:rollback:#{name}")
197
- puts "Finished rolling back migrations.".colorize(:green)
226
+
227
+ name_env_key = "#{name.upcase}_DATABASE_URL"
228
+ command = "#{name_env_key}=\"#{ENV["PSCALE_DATABASE_URL"]}\" bundle exec rake db:rollback:#{name}"
229
+
230
+ IO.popen(command) do |io|
231
+ io.each_line do |line|
232
+ puts line
233
+ end
234
+ end
235
+
236
+ unless $CHILD_STATUS.success?
237
+ puts "Failed to rollback migrations".colorize(:red)
238
+ end
198
239
  ensure
199
- kill_pscale_process
240
+ delete_password
200
241
  end
201
242
  end
202
243
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PlanetscaleRails
4
- VERSION = "0.1.4"
4
+ VERSION = "0.2.1"
5
5
  end
@@ -29,5 +29,5 @@ Gem::Specification.new do |spec|
29
29
  spec.require_paths = ["lib"]
30
30
 
31
31
  spec.add_dependency "colorize", "~> 0.8.1"
32
- spec.add_dependency "rails", "~> 7.0"
32
+ spec.add_dependency "rails", ">= 6.0", "< 8"
33
33
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: planetscale_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Coutermarsh
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2023-07-28 00:00:00.000000000 Z
12
+ date: 2024-01-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: colorize
@@ -29,16 +29,22 @@ dependencies:
29
29
  name: rails
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '6.0'
35
+ - - "<"
33
36
  - !ruby/object:Gem::Version
34
- version: '7.0'
37
+ version: '8'
35
38
  type: :runtime
36
39
  prerelease: false
37
40
  version_requirements: !ruby/object:Gem::Requirement
38
41
  requirements:
39
- - - "~>"
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '6.0'
45
+ - - "<"
40
46
  - !ruby/object:Gem::Version
41
- version: '7.0'
47
+ version: '8'
42
48
  description: A collection of rake tasks to make managing schema migrations with PlanetScale
43
49
  easy
44
50
  email: