-
-
Notifications
You must be signed in to change notification settings - Fork 751
RFC: Combine multiple RSpec repositories into a single one. #2509
Description
Summary
Combine rspec-core
, rspec-mocks
, rspec-expectations
, rspec-support
, rspec-dev
(which would be mostly deprecated with this proposal), the rspec
meta-gem, and possible rspec-rails
into a single repository.
Motivation
Making cross-cutting changes to RSpec involves a complicated dance of PRs. Selected examples:
- Upgrading rubocop involved multiple PRs, that all needed to be somewhat kept in sync as a result of changes/feedback, and are still pending a final
rspec-dev
sync. As well as been a pain at the time, this has caused confusion for a subsequent contribution. - Adding to
rspec-support
to fix a bug in (say)rspec-mocks
requires a PR to support, a PR to mocks pointing at that branch to demonstrate that the support change works, merging the support PR, then redoing the mocks PR to point back at master. (e.g. Add specs demonstrating problem with verified doubles and keyword args. rspec-mocks#726) - Any of the
rspec-dev
tasks to "sync" configuration to all repos requires a PR for each repo. - complex and partially overlapping CI builds
It's also not always clear to issue reporters which project is appropriate for an issue. We shouldn't expect newcomers to know which sub-project an issue could be related to!
Approach
Issues
Given a motivation is to simplify issue reporting, we should migrate them all to the main rspec
project (which current has issues disabled) using something like github-issues-import
. We can use tags (mocks
, etc...) to track what came from where, but for new issues they would be optional.
Inflight PRs
We should explicitly close or merge every open PR. This will include closing many stale PRs, that will need to be re-opened against the new monorepo. We can mitigate this with a notice period (i.e. "one month from now we're merging repos").
CI
I see two ways to set up CI:
- Run all the specs for each project on every CI. Conceptually the simplest, potential downside is runtime. Given a lot of build time is build setup (installing ruby, gems, etc...) I suspect this will work out fine.
- Add conditional build logic to identify which projects are likely affected based on file paths changed, and only run those. Speeds things up, but more complicated and not technically as thorough (though probably good enough).
This is where rspec-rails
would be an interesting addition, because it has a test matrix with rails versions that isn't applicable to the other projects and would probably force us to option 2. I'm leaning towards keeping it out, at least to begin with. We can always incorporate it later!
For now we should benchmark option 1.
rspec-dev
We need to audit rspec-dev
to see what things it does are still appropriate and how to best incorporate them into the monorepo. Given it's primarily used to "manage" multiple repos, my hope is it can be mostly deprecated. This will be investigated in the prototype suggested below.
Drawbacks and mitigations
- Git history is harder to work with. We should keep around the old git projects for spelunking purposes.
- Intermingled git logs. I'm not worried about this. Possibly consider it an upside, being able to see what was happening across the entire project.
- Easy to accidentally add unwanted dependencies. Since the code is "there" this potentially makes it easier to accidentally introduce coupling between the various components. I figure we have enough history and discipline keeping them separate that this shouldn't be an issue in practice.
- wrap up or manually transfer all hanging pull requests in Expectations/Mocks/Support/Core
- align git version tags - they overlap, and we need to keep them in sync
CI limit of simultaneous jobs constraints our a bit tighter
Next steps
- Feedback from other members of core team.
- Create a new project to test this idea (
rspec-monorepo
), including setting up CI and incorporatingrspec-dev
.