Skip to content

Commit

Permalink
Merge pull request #42263 from zzak/zzak/42012
Browse files Browse the repository at this point in the history
Use the current Rails->npm_version for package.json
  • Loading branch information
rafaelfranca committed Jun 10, 2021
2 parents 05fe94c + 96d50dc commit f10d814
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 11 deletions.
25 changes: 18 additions & 7 deletions guides/source/upgrading_ruby_on_rails.md
Expand Up @@ -16,6 +16,16 @@ Before attempting to upgrade an existing application, you should be sure you hav

The best way to be sure that your application still works after upgrading is to have good test coverage before you start the process. If you don't have automated tests that exercise the bulk of your application, you'll need to spend time manually exercising all the parts that have changed. In the case of a Rails upgrade, that will mean every single piece of functionality in the application. Do yourself a favor and make sure your test coverage is good _before_ you start an upgrade.

### Ruby Versions

Rails generally stays close to the latest released Ruby version when it's released:

* Rails 7 requires Ruby 2.7.0 or newer.
* Rails 6 requires Ruby 2.5.0 or newer.
* Rails 5 requires Ruby 2.2.2 or newer.

It's a good idea to upgrade Ruby and Rails separately. Upgrade to the latest Ruby you can first, and then upgrade Rails.

### The Upgrade Process

When changing Rails versions, it's best to move slowly, one minor version at a time, in order to make good use of the deprecation warnings. Rails version numbers are in the form Major.Minor.Patch. Major and Minor versions are allowed to make changes to the public API, so this may cause errors in your application. Patch versions only include bug fixes, and don't change any public API.
Expand All @@ -27,17 +37,18 @@ The process should go as follows:
3. Fix tests and deprecated features.
4. Move to the latest patch version of the next minor version.

Repeat this process until you reach your target Rails version. Each time you move versions, you will need to change the Rails version number in the `Gemfile` (and possibly other gem versions) and run `bundle update`. Then run the [Update task](#the-update-task) and finally, your tests.
Repeat this process until you reach your target Rails version.

You can find a list of all released Rails versions [here](https://rubygems.org/gems/rails/versions).
#### Moving between versions

### Ruby Versions
To move between versions:

Rails generally stays close to the latest released Ruby version when it's released:
1. Change the Rails version number in the `Gemfile` and run `bundle update`.
2. Change the versions for Rails JavaScript packages in `package.json` and run `yarn install`.
3. Run the [Update task](#the-update-task).
4. Run your tests.

* Rails 7 requires Ruby 2.7.0 or newer.
* Rails 6 requires Ruby 2.5.0 or newer.
* Rails 5 requires Ruby 2.2.2 or newer.
You can find a list of all released Rails gems [here](https://rubygems.org/gems/rails/versions).

### The Update Task

Expand Down
4 changes: 4 additions & 0 deletions railties/CHANGELOG.md
@@ -1,3 +1,7 @@
* `package.json` now uses a strict version constraint for Rails JavaScript packages on new Rails apps.

*Zachary Scott*, *Alex Ghiculescu*

* Modified scaffold generator template so that running
`rails g scaffold Author` no longer generates tests called "creating
a Author", "updating a Author", and "destroying a Author"
Expand Down
34 changes: 34 additions & 0 deletions railties/lib/rails/generators/app_base.rb
Expand Up @@ -298,6 +298,40 @@ def rails_version_specifier(gem_version = Rails.gem_version)
end
end

# This "npm-ifies" the current version number
# With npm, versions such as "5.0.0.rc1" or "5.0.0.beta1.1" are not compliant with its
# versioning system, so they must be transformed to "5.0.0-rc1" and "5.0.0-beta1-1" respectively.
#
# "5.0.1" --> "5.0.1"
# "5.0.1.1" --> "5.0.1-1" *
# "5.0.0.rc1" --> "5.0.0-rc1"
#
# * This makes it a prerelease. That's bad, but we haven't come up with
# a better solution at the moment.
def npm_version
# TODO: support `options.dev?`

if options.edge? || options.main?
# TODO: ideally this would read from Github
# https://github.com/rails/rails/blob/main/actioncable/app/assets/javascripts/action_cable.js
# https://github.com/rails/rails/blob/main/activestorage/app/assets/javascripts/activestorage.js
# https://github.com/rails/rails/tree/main/actionview/app/assets/javascripts -> not clear where the output file is
"latest"
else
Rails.version.gsub(/\./).with_index { |s, i| i >= 2 ? "-" : s }
end
end

def turbolinks_npm_version
# since Turbolinks is deprecated, let's just always point to main.
# expect this to be replaced with Hotwire at some point soon.
if options.main? || options.edge?
"git://github.com/turbolinks/turbolinks.git#main"
else
"^5.2.0"
end
end

def assets_gemfile_entry
return [] if options[:skip_sprockets]

Expand Down
Expand Up @@ -2,10 +2,10 @@
"name": "<%= app_name.underscore.dasherize %>",
"private": true,
"dependencies": {
"@rails/ujs": "^6.0.0"<% unless options[:skip_turbolinks] %>,
"turbolinks": "^5.2.0"<% end -%><% unless skip_active_storage? %>,
"@rails/activestorage": "^6.0.0"<% end -%><% unless options[:skip_action_cable] %>,
"@rails/actioncable": "^6.0.0"<% end %>
"@rails/ujs": "<%= npm_version %>"<% unless options[:skip_turbolinks] %>,
"turbolinks": "<%= turbolinks_npm_version %>"<% end -%><% unless skip_active_storage? %>,
"@rails/activestorage": "<%= npm_version %>"<% end -%><% unless options[:skip_action_cable] %>,
"@rails/actioncable": "<%= npm_version %>"<% end %>
},
"version": "0.1.0"
}
48 changes: 48 additions & 0 deletions railties/test/generators/app_generator_test.rb
Expand Up @@ -531,6 +531,54 @@ def test_gemfile_has_no_whitespace_errors
end
end

def test_package_json_uses_current_versions_and_set_version_of_turbolinks
run_generator
generator = Rails::Generators::AppBase.new ["rails"]
version = generator.send(:npm_version)

assert_file "package.json" do |content|
assert_match(/"@rails\/ujs": "#{version}"/, content)
assert_match(/"@rails\/activestorage": "#{version}"/, content)
assert_match(/"@rails\/actioncable": "#{version}"/, content)
assert_match(/"turbolinks": "\^5.2.0"/, content)
end
end

def test_package_json_uses_edge_versions
run_generator [destination_root, "--main"]

assert_file "package.json" do |content|
assert_match(/"@rails\/ujs": "latest"/, content)
assert_match(/"@rails\/activestorage": "latest"/, content)
assert_match(/"@rails\/actioncable": "latest"/, content)
assert_match(/"turbolinks": "git:\/\/github.com\/turbolinks\/turbolinks.git#main"/, content)
end
end

def test_package_json_excludes_activestorage_if_skipped
run_generator [destination_root, "--skip-active-storage"]

assert_file "package.json" do |content|
assert_not content.include?("activestorage")
end
end

def test_package_json_excludes_actioncable_if_skipped
run_generator [destination_root, "--skip-action-cable"]

assert_file "package.json" do |content|
assert_not content.include?("actioncable")
end
end

def test_package_json_excludes_turbolinks_if_skipped
run_generator [destination_root, "--skip-turbolinks"]

assert_file "package.json" do |content|
assert_not content.include?("turbolinks")
end
end

def test_config_database_is_added_by_default
run_generator
assert_file "config/database.yml", /sqlite3/
Expand Down

0 comments on commit f10d814

Please sign in to comment.