Releasing multiple gems from one repository
When I released qu, I wanted to split the various backends and exception handlers into multiple gems so each gem had the proper dependencies without enforcing all of the dependencies on everyone all the time.
I had to decide between maintaining multiple repositories for each plugin, or releasing them all from the same repository. There are advantages and disadvantages to both, but I decided I would rather start with them in one repository and split them out later if it became a problem.
Several people have asked how I did it. Here’s my secret formula.
For each gem we want to release, we need a gemspec. For example, check out
qu-redis.gemspec. Most of the gemspec is standard, but there are a few things I want to draw to your attention.
Since we’ll be releasing multiple gems out of this directory, we need to make sure we get the right files for this gem. You can use whatever criteria makes sense for your project, but for
qu-redis it worked out to just grab any file that has “redis” in the name.
We need to make sure that this plugin then depends on a compatible version of the main library. For Qu, I lock each plugin to the exact version. When I release a bugfix, I release a new version of each gem, whether it is changed or not.
Each plugin can and should declare any other dependencies.
Now we have a gem for our plugin, with its own files and dependencies.
The gemspec for our “core” library will look a little different. Check out
qu.gemspec for the full version. We want to avoid including files from other gems in our project, so first we get a list of those files.
We get a list of the files for the gem, and then exclude files from our other gems.
If you’re using bundler for your development dependencies (which you should be), then you probably want to lock the dependencies from your gemspecs without having to redeclare them. We can easily tell bundler about all of our gemspecs.
Lastly, we want to automate the build process by adding
release rake tasks.
This has worked out really well so far. All the activity for the project is in one repo, and pushing out a new release is really easy. Win, win!