Pros and Cons of GitHub vs RubyForge as Gem Source
GitHub recently started its own RubyGems server, which makes publishing gems a breeze. All you need to do is to provide a gemspec in your repository's root and check a box in the GitHub configuration. The gem will be built and is available for others to install. To avoid collisions with other users' gems, it is prefixed with your username, in the form username-project.
But now, RubyGems users don't have a single source for gems—RubyForge—anymore, but need to configure the additional GitHub source. This doesn't seem like a big hurdle, but there are some problematic aspects, as Magnus Holm points out in his blog. The biggest problem seems to be the automatic dependency management, which doesn't work so well because RubyGems expects the dependecies to be on the same server. Additionally, you need to know the name of the user who provides the specific gem on GitHub.
To get some more insight, InfoQ talked to RubyGems maintainer Eric Hodel, PJ Hyett from GitHub, and Tom Copeland from RubyForge.
Eric Hodel explains the details of the problem:
The biggest potential problem is gems with dashes in them. A malicious user could go to GitHub and create a net account and release a package ssh with a higher version than the net-ssh on RubyForge. RubyGems would install the GitHub one which would be wrong.
Unfortunately this is more commonly used as a feature. gems.rubyonrails.org (and other developers) contains development versions of gems with the same names as gems.rubyforge.org. People expect the names to match so RubyGems will pick the development version.
Adding sources is an at-your-own-risk as is installing any software over the internet.
Currently the best solution to problems like this is for gem authors to sign gems they release. This way gem users can trace back a gem to a trusted source. I'm not sure how easy it will be to build up the web of trust, but I've added code to hoe that will automatically sign released gems after you run `rake generate_key` (see `ri Hoe` for details). There is extensive documentation on signing and verifying gems in `ri Gem::Security`.
Since gems are now being released on RubyForge and GitHub, there's been talk about alternate dependencies. This would allow a gem author to say "I depend on brixen-mspec or rubyspec-mspec or mspec". John Barnette and Yehuda Katz [expressed] some interest in implementing this, but there hasn't been any progress on it to my knowledge.
Right now, it is still necessary for users to manually add gems.github.com to the RubyGems sources to get GitHub gems. Eric says that he's "not completely opposed to [adding GitHub to the default sources], but I don't know how useful it will be without alternative dependencies".
Pj Hyett from GitHub confirmed Eric's comment:
The concerns Eric brought up regarding naming collision are definitely a worry for us, considering the scenario where a user named net built a gem named ssh has already happened. Fortunately, it was someone showing us the vulnerability so that we were aware of it. Of course, not all of our users will be as kind, so we need to come up with a solution. The last thing we want is for our service to break a system we use every day.
Originally, we wanted to build gems on GitHub with the convention username/repo-name so conflicts like this wouldn't have been an issue. It also has the added benefit of mimicking our URL structure. Unfortunately, slashes don't work out of the box with RubyGems and we wanted to allow people to use GitHub gems without patching the code.
Tom Copeland from RubyForge thinks about auto-publishing gems for RubyForge projects:
Perhaps we'd add some stuff the to admin tab of a project so that a person could either point to a gemspec in their svn/git repo and we could build it, or they could point to the root of their repo and we could look for a lib directory and use the project name as the gem name and the svn repo revision as the gem number. [..] would that feature be in demand?
Another possibility would be to add the "create RubyForge project" and "publish to RubyForge" features to GitHub. But as Tom points out, "there's currently a manual project approval step on RubyForge. We'd need to sort out how to autoaccept and provision project creation requests coming from GitHub."
Pj Hyett's comment on this idea:
I'm not completely against the idea of a 'Publish to RubyForge' button, but if I'm being perfectly honest, I'd prefer just making our system work in tandem with their site. Building a gem on GitHub is as simple as pushing code to their repository, something our users are doing anyway, so you don't even have to think about it anymore.
That said, there are always going to be people that have custom requirements for building gems, requirements we may never support support due to security concerns or various other reasons, so we still recommend people use RubyForge if they're doing something that's outside of what we currently offer.
To sum up, we can see that the people involved are interested in finding a solution, even though it might take some time to implement and agree on one.
While publishing Gems to GitHub can be automatic, publishing Gems to RubyForge can be automated too with Ryan Davis' Hoe, a helper for Rake and RubyGems that, among other things, includes a task that allows to release Gems on RubyForge. Once Hoe it is set up correctly, a simple rake release VERSION=x.y.z takes care of your release. For more information on Hoe, take a look at this tutorial about Hoe on Nuby on Rails.
Do you host projects on GitHub? If yes—do you push to RubyForge too—and how do you use it (tools, scripts, tasks)?
Todd Montgomery Dec 19, 2014