|
| 1 | + |
| 2 | +# RFC: RSpec Rails new versioning strategy |
| 3 | + |
| 4 | +Hi Folks, |
| 5 | + |
| 6 | +This RFC captures a proposal for RSpec Rails' new versioning strategy. Specifically, this represents two things: |
| 7 | +* A change in representation of what we use SemVer for, in RSpec Rails |
| 8 | +* A departure from RSpec Rails having the same versioning as RSpec's other gems (-core, -mocks, -expectations, and, internally, -support). |
| 9 | + |
| 10 | +## Need |
| 11 | + |
| 12 | +Currently, the RSpec Rails [build matrix](https://travis-ci.org/rspec/rspec-rails) |
| 13 | +has 63 entries. This permutes rubies since 1.8.7 and Rails versions since 3.0. |
| 14 | +As of right now the full build takes over an hour to run, and this makes cycling |
| 15 | +for PRs and quick iterative development very difficult. |
| 16 | + |
| 17 | +RSpec Rails's code itself also is damaged by this. Everything from the Gemfile |
| 18 | +setup[1](https://github.com/rspec/rspec-rails/blob/1d2935861c89246236b46f77de753cda5ea67d61/Gemfile) |
| 19 | +[2](https://github.com/rspec/rspec-rails/blob/1d2935861c89246236b46f77de753cda5ea67d61/Gemfile-rails-dependencies) |
| 20 | +[3](https://github.com/rspec/rspec-rails/blob/1d2935861c89246236b46f77de753cda5ea67d61/Gemfile-rspec-dependencies), |
| 21 | +to the [library code](https://github.com/rspec/rspec-rails/blob/1d2935861c89246236b46f77de753cda5ea67d61/lib/rspec/rails/configuration.rb#L128-L143), |
| 22 | +to the [test setup](https://github.com/rspec/rspec-rails/blob/1d2935861c89246236b46f77de753cda5ea67d61/Rakefile#L29-L53), |
| 23 | +to the [tests themselves](https://github.com/rspec/rspec-rails/blob/1d2935861c89246236b46f77de753cda5ea67d61/spec/rspec/rails/example/job_example_group_spec.rb) |
| 24 | +contain conditional execution based on which Rails version is currently loaded. |
| 25 | +This makes ongoing maintenance difficult, as it requires that RSpec Rails' |
| 26 | +maintainers be conscious of every Rails version that might be loaded. |
| 27 | +Acknowledging that, patches still sometimes break people's suites, due to the |
| 28 | +number of permutations of gems that can be loaded. |
| 29 | + |
| 30 | +Our need is therefore best characterised by cost of maintenance. Having to |
| 31 | +maintain several versions of Rails and Ruby costs us a lot. It makes our |
| 32 | +development slower, and forces us to write against Rails versions that most |
| 33 | +people no longer use. I want RSpec Rails development to be fast, and |
| 34 | +lightweight, much like it was when I joined the RSpec project. |
| 35 | + |
| 36 | +## Approach |
| 37 | + |
| 38 | +The approach to fix this is an adjustment of versioning strategy. RSpec Rails |
| 39 | +will still continue to maintain a SemVer strategy, that is: |
| 40 | + |
| 41 | +* Breaking changes in Majors |
| 42 | +* New features in Minors |
| 43 | +* Bug Fixes in Patchlevels |
| 44 | + |
| 45 | +For the purposes of this versioning strategy, we consider removing a Rails or |
| 46 | +Ruby version to be a breaking change. We consider adding a Ruby or Rails version |
| 47 | +to be a Minor, along with normal feature releases. |
| 48 | + |
| 49 | +The intent, however, is to change the cycle of these releases to align with |
| 50 | +Rails. Specifically, a Rails release cycle typically looks like: |
| 51 | + |
| 52 | +* Release a Major X.0, (X-2).0 is no longer supported, all but the most recent |
| 53 | + (X--1) series are unsupported, introduces deprecation warnings for many |
| 54 | + features |
| 55 | +* Release a Minor X.1, deprecation warnings from X.0 are now errors |
| 56 | +* Release a Minor X.2, new features are added, some further deprecation warnings |
| 57 | + from X.1 may now be broken. |
| 58 | + |
| 59 | +As such, RSpec Rails's new versioning strategy will be: |
| 60 | + |
| 61 | +* Release a major with any Rails Major, removing support for any newly |
| 62 | + unsupported versions of Rails, and adding support for the new major. |
| 63 | +* Release a minor with any Rails Minor, adding support for the new features |
| 64 | + * Additionally, release minors for any new RSpec features |
| 65 | +* Release patchlevels frequently, as bugfixes occur. |
| 66 | + |
| 67 | +As to the transition to this strategy: it is my intent to move to this strategy |
| 68 | +along with releasing support for Rails 5.2 for RSpec Rails, so relatively soon, |
| 69 | +dropping support for anything below Rails 4.2, and any Rubies below 2.2. This |
| 70 | +means that RSpec Rails 4.0.0 will be released within a handful of months from |
| 71 | +this RFC being accepted. |
| 72 | + |
| 73 | +I do expect this to mean that the major version of RSpec Rails will increment |
| 74 | +relatively quickly with comparison to the rest of RSpec. I do not think that is |
| 75 | +necessarily a bad thing, it does not mean that the library is unstable as such, |
| 76 | +but rather that we are tracking our dependencies accurately. |
| 77 | + |
| 78 | +Traditionally, RSpec Rails has been versioned at the same version number as |
| 79 | +RSpec. This will represent a departure from that. In order to maintain |
| 80 | +compatibility, RSpec Rails will continue to support the RSpec 3 series, and will |
| 81 | +probably add support for RSpec 4 without breaking changes. To do this, I intend |
| 82 | +to move off RSpec Rails using any private APIs from RSpec. |
| 83 | + |
| 84 | +## Benefits |
| 85 | + |
| 86 | +Execution of this strategy will greatly increase our ability to maintain RSpec, |
| 87 | +and release against modern Rails versions. While RSpec has been very stable and |
| 88 | +essentially continuously expanded Rails version support for the last few years, |
| 89 | +this has now become unsustainable and we want to take this tradeoff to best |
| 90 | +serve the needs of the community. |
| 91 | + |
| 92 | +## Competition |
| 93 | + |
| 94 | +### Do nothing |
| 95 | + |
| 96 | +If we do this, it will become deeply unsustainable for us to maintain RSpec |
| 97 | +Rails in the future. We have too many Rails versions today, and we expect the |
| 98 | +rate of Rails releases to increase as time goes on. As such, it is our intent to |
| 99 | +start dropping Rails versions inline with Rails, in order to continue to improve |
| 100 | +the RSpec Rails gem. |
| 101 | + |
| 102 | +### Keep inline versioning with RSpec |
| 103 | + |
| 104 | +RSpec has a materially different versioning need to Rails. Specifically, RSpec |
| 105 | +as of today is a mostly entirely stable library. It's development needs are |
| 106 | +largely as feature proposals occur, or as bugs are found. RSpec has no external |
| 107 | +forces pushing versioning pressure on it (other than say, ruby and bundler, |
| 108 | +which are themselves, relatively stable). This is not true of RSpec Rails, which |
| 109 | +is popular, and there is a general expectation that RSpec will work with Rails |
| 110 | +applications, as of right now, we typically lag behind a Rails release by weeks |
| 111 | +when a Rails version gets released. |
| 112 | + |
| 113 | +## Conclusions |
| 114 | + |
| 115 | +It is my intent to ship this change relatively soon, inline with Rails 5.2 |
| 116 | +support in the next few months. I really do think this represents the best |
| 117 | +future tradeoff for RSpec. If you strongly believe that dropping support for |
| 118 | +Rails versions lower than 4.2 will affect your needs, please do let us know so |
| 119 | +that we can consider the full weight of your use case. |
0 commit comments