New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix bin/rails db:migrate
with specified VERSION
#30714
Fix bin/rails db:migrate
with specified VERSION
#30714
Conversation
r? @eileencodes (@rails-bot has picked a reviewer for you, use r? to override) |
result = execute_migration_in_transaction(migration, @direction) | ||
if invalid_target? | ||
raise UnknownMigrationVersionError.new(@target_version) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does the error message say for the UnknownMigrationVersionError? I'm wondering if it's user friendly enough like "0.1.1" is an unknown migration number please run with VERSION=123
. I'm concerned about inexperienced users not realizing their VERSION env var is set elsewhere and how to set it for the Rails migrations.
I think this is fine as a bandaid fix, but I'm not sure whether this is a good long term solution. Think about this usecase:
I worry that this PR instead will completely block migrations without a clear path forward causing a lot of friction in the migration process. |
26ff22f
to
36db0ee
Compare
Thanks, @eileencodes. This PR doesn't fix the issue #30707 (but related to this issue), it just fix our current implementation that we have. Currently, if run Example: $ rails db:migrate:status
Status Migration ID Migration Name
--------------------------------------------------
up 20171005143525 One
up 20171005143538 Two
up 20171005143556 Three
$ rails db:migrate VERSION=1
rails aborted!
ActiveRecord::UnknownMigrationVersionError:
No migration with version number 1.
# There is bug
$ rails db:migrate VERSION=-1
ubuntu@ubuntu-xenial:/active_projects/zz$ rails db:migrate VERSION=-1
== 20171005143556 Three: reverting ============================================
== 20171005143556 Three: reverted (0.4047s) ===================================
== 20171005143538 Two: reverting ==============================================
== 20171005143538 Two: reverted (0.0000s) =====================================
== 20171005143525 One: reverting ==============================================
== 20171005143525 One: reverted (0.0000s) ===================================== After: $ rails db:migrate:status
Status Migration ID Migration Name
--------------------------------------------------
up 20171005143525 One
up 20171005143538 Two
up 20171005143556 Three
$ rails db:migrate VERSION=1
rails aborted!
ActiveRecord::UnknownMigrationVersionError:
No migration with version number 1.
# Fixed
$ rails db:migrate VERSION=-1
rails aborted! About the case:
I think the main reason of the problem in common name of environment variable that we use What do you think about deprecation of using |
849b6cc
to
8ab4dd8
Compare
Can we validate the supplied version before we call Renaming the variable is not appropriate: unlike the others you mentioned, it's intended to be set on the rake command line; the others are intended to suitable for setting more globally across a session. (And I believe that's the stronger convention in general: the more broadly a variable is visible, the more specifically it should be named.) Naming such a redundant variable on a It would also be an unnecessary stopgap: the ability to pass proper arguments to commands, instead of using ugly env vars, is a large motivation for our ongoing effort to convert rake-based commands to thor. Once we've done We've been using |
If someone does have I haven't checked, but I assume they can run the command with |
dd8c82a
to
e3563da
Compare
@matthewd I think I got your point. I just added the changes that check VERSION. This PR shouldn't break our current implementation that we have and AIUI we can apply new strict behavior(See #30714 (comment)). Could you please review and provide feedback about behavior that this PR provides? If this behavior doesn't fit, I'll try to find another implementation 😄 but I guess we are moving in the right direction. Thank you for the response! ❤️ |
scope.blank? || scope == migration.scope | ||
end | ||
ActiveRecord::Base.clear_cache! | ||
ensure | ||
Migration.verbose = verbose_was | ||
end | ||
|
||
def check_target_version | ||
if ENV["VERSION"] && ENV["VERSION"].empty? | ||
raise "Empty VERSION provided" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned, I think an empty VERSION should be treated just the same as when it's not set at all, so people can easily override a more widely-set variable. Before we kill it though, can you see any history on why we added the existing emptiness check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking for empties of VERSION
is added by #28485 because db:migrate:redo
, db:migrate:up
, db:migrate:down
require VERSION
,
but db:migrate
doesn't require VERSION
, so I think it db:migrate
with empty VERSION
should behave as without VERSION
.
raise "Empty VERSION provided" | ||
end | ||
|
||
if target_version == 0 && ENV["VERSION"].strip.length != 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds like an overly-special case. 1.2.3
should raise too, even if there's a migration number 1.
|
||
if target_version == 0 && ENV["VERSION"].strip.length != 1 | ||
raise( | ||
"Invalid format of target version: \n\n `VERSION=#{ENV['VERSION']}`" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need the fancy spacing here
@@ -206,6 +278,46 @@ class AMigration < ActiveRecord::Migration::Current | |||
end | |||
end | |||
|
|||
test "raise error on any move when target migration does not exist" do | |||
app_file "db/migrate/01_one_migration.rb", <<-MIGRATION |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see a test somewhere (assuming we don't already have one, though I haven't checked) to ensure that VERSION=01_one_migration.rb
will work, even after we make VERSION=1.2
fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see a test somewhere (assuming we don't already have one, though I haven't checked) to ensure that VERSION=01_one_migration.rb will work, even after we make VERSION=1.2 fail.
I just implemented this behavior and added test cases.
d66e70a
to
8b2f5e2
Compare
@matthewd What do you think about current behavior that is implemented by this PR? |
352278a
to
7822c6b
Compare
scope.blank? || scope == migration.scope | ||
end | ||
ActiveRecord::Base.clear_cache! | ||
ensure | ||
Migration.verbose = verbose_was | ||
end | ||
|
||
def check_target_version | ||
if target_version && !(Migration::MigrationFilenameRegexp.match?(ENV["VERSION"]) || /\A\d+\z/.match?(ENV["VERSION"])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matthewd What do you think about this condition?
ce8398c
to
5b8b225
Compare
let me know if there is something i should to do. |
Could you please provide any feedback about this PR? |
end | ||
|
||
def target_version | ||
return ENV["VERSION"].to_i if ENV["VERSION"] && !ENV["VERSION"].empty? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✂️ the return
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
Ensure that `bin/rails db:migrate` with specified `VERSION` reverts all migrations only if `VERSION` is `0`. Raise error if target migration doesn't exist.
5b8b225
to
90fe2a4
Compare
Fix
bin/rails db:migrate
with specifiedVERSION
.bin/rails db:migrate
with empty VERSION behaves as withoutVERSION
.Check a format of
VERSION
: Allow a migration version numberor name of a migration file. Raise error if format of
VERSION
is invalid.Raise error if target migration doesn't exist.
Related to #30707
/cc @matthewd