In RubyGems, what makes a version such as 1.0.0.rc1 a prerelease, and how do users install one before the final 1.0.0?
answer
- any letter in the version
- sorts below the release
- hyphen becomes .pre.
- --prerelease or an explicit -v
- requirement must name a prerelease
basics
~10 sA RubyGems version containing a letter, such as 1.0.0.rc1 or 1.0.0.beta.2, is a prerelease and sorts below 1.0.0. gem install ignores prereleases unless given --prerelease or a -v requirement naming one.
solid answer
~30 s`Gem::Version#prerelease?` is true when the version string contains a **letter**: `1.0.0.rc1`, `1.0.0.beta.2` and `1.0.0.pre` all qualify, and a hyphen is rewritten, so `1.0.0-rc1` becomes `1.0.0.pre.rc1`. Prereleases sort **below** the release they precede: `1.0.0.a.2 < 1.0.0.b1 < 1.0.0`. You publish one exactly like a release, bumping the version to `1.0.0.rc1` and running `gem build` and `gem push`. Users do not get it by accident: `gem install hue_palette` skips prereleases, while `gem install hue_palette --prerelease` or `-v 1.0.0.rc1` selects one. Dependency requirements behave the same way: a requirement matches a prerelease only when it names one itself, as in `">= 1.0.0.a", "< 2"`.
code
bash · 7 lines# lib/hue_palette/version.rb has VERSION = "1.0.0.rc1"
gem build hue_palette.gemspec # -> hue_palette-1.0.0.rc1.gem
gem push hue_palette-1.0.0.rc1.gem
gem install hue_palette # still installs the newest release
gem install hue_palette --prerelease # installs 1.0.0.rc1
gem install hue_palette -v 1.0.0.rc1 # same, by exact versiongo deeper
Recall that a letter in the version makes it a prerelease and that users must opt in with --prerelease or an exact -v.
Explain how prereleases sort, the hyphen rewrite, and why ordinary requirements skip them unless they name a prerelease.
Plan a 1.0 with release candidates, tell testers exactly how to install them, and write requirements that accept candidates only on purpose.
Choose a pre-release policy for a family of gems: how many candidates, how long they soak and who is expected to test them.
## What RubyGems calls a prerelease RubyGems versions are dot-separated segments. The rule for prereleases is purely syntactic: **if any segment contains a letter, the version is a prerelease** (`Gem::Version#prerelease?` checks for `a-z` or `A-Z`). - `1.0.0.rc1`, `1.0.0.beta.2`, `1.0.0.alpha`, `1.0.0.pre` are prereleases. - `1.0.0` and `1.0.10` are releases. - A hyphen is not a separator RubyGems keeps: `1.0.0-rc1` is rewritten to `1.0.0.pre.rc1`, which is still a prerelease. - Mixed segments are split for sorting, so `1.0.a10` is treated as `1.0.a.10` and sorts after `1.0.a9`. ## How prereleases sort A prerelease sorts **below** the release it leads up to, and letter segments sort alphabetically. The RubyGems documentation's own ordering, newest first: 1. `1.0` 2. `1.0.b1` 3. `1.0.a.2` 4. `0.9` So `1.0.0.rc1` is newer than `0.9.5` but older than `1.0.0`, and `rc` sorts after `beta`, which sorts after `alpha`, purely alphabetically. ## Publishing one For the 1.0 of a colour-palette gem, a common path is one or more release candidates first: 1. Set `HuePalette::VERSION = "1.0.0.rc1"`. 2. `gem build hue_palette.gemspec` writes `hue_palette-1.0.0.rc1.gem`. 3. `gem push hue_palette-1.0.0.rc1.gem` publishes it like any release. 4. Early adopters try it; fixes go out as `1.0.0.rc2`. 5. When it is ready, set the version to `1.0.0`, build and push again. Nothing in the gemspec marks the release as a prerelease except the version string. ## Who receives it RubyGems keeps prereleases away from people who did not ask: | Command | Picks up 1.0.0.rc1? | |---|---| | `gem install hue_palette` | no, installs the newest release | | `gem install hue_palette --prerelease` | yes, if it is the newest version | | `gem install hue_palette -v 1.0.0.rc1` | yes, a prerelease requirement implies `--prerelease` | | `gem update hue_palette` | no, unless `--prerelease` is given | | `gem list hue_palette --remote --prerelease` | lists it | ## Naming candidates so they sort as intended Because letter segments sort alphabetically and mixed segments are split into letters and numbers, a few habits keep the order predictable: - `alpha` < `beta` < `pre` < `rc`, so `1.0.0.beta.1` comes before `1.0.0.rc1`. - `1.0.0.rc10` is split into `rc` and `10`, so it sorts after `1.0.0.rc9`, not between `rc1` and `rc2`. - RubyGems documents only lowercase `a-z` letters as supported in versions, so stick to lowercase. - Stay with one scheme for the whole release; mixing `1.0.0.pre1` and `1.0.0.rc1` works, but only because `pre` happens to sort before `rc`. ## Prereleases in dependency requirements A gem that depends on hue_palette sees the same rule. A requirement like `"~> 1.0"` or `">= 0.9"` does **not** match `1.0.0.rc1`, because RubyGems matches prereleases only when the requirement itself contains one. The RubyGems documentation's recommended way to accept both the 1.x prereleases and releases is: ```ruby spec.add_dependency "hue_palette", ">= 1.0.0.a", "< 2.0.0" ``` ## Common mistakes - Publishing `1.0.0` "to test it" and then needing a `1.0.1` for the fix, instead of starting with `1.0.0.rc1`. - Using an all-numeric scheme such as `1.0.0.1` for a candidate, which RubyGems treats as a full release newer than `1.0.0`. - Expecting `gem install hue_palette` to pick up the release candidate for testers; they need `--prerelease` or an explicit `-v`.
- Why does a dependency on "~> 1.0" not pick up 1.0.0.rc1?Two reasons. `1.0.0.rc1` sorts below `1.0`, so it is outside `>= 1.0` anyway. More generally, RubyGems only matches a prerelease when the requirement itself names a prerelease, so even `">= 0.9"` skips it. To accept prereleases, write a requirement such as `">= 1.0.0.a", "< 2.0.0"`.
- Is 1.0.0.1 a good version for a release candidate?No. It contains no letter, so RubyGems treats it as a full release, and it sorts above `1.0.0`. Every user running `gem install` or `gem update` would get it. A candidate needs a letter, as in `1.0.0.rc1`, so that it sorts below `1.0.0` and stays opt-in.
saying these in an interview costs you the question
- Thinks gem install hue_palette installs the newest rc automatically
- Believes a prerelease needs a special gemspec flag
- Thinks 1.0.0.rc1 sorts above 1.0.0
- Uses 1.0.0.1 as a release candidate number
- Expects "~> 1.0" to match 1.0.0.rc1