Beachball canary isn't documented and doesn't work as would be expected
DanProudfoot opened this issue · comments
This is going to be a relatively wide ranging issue on the topic of the canary
command.
- There isn't any documentation on the
Canary
command. I had to figure it out for myself after noticing it mentioned once in the docs. - The bump algorithm on canary works a bit weirdly? My packages were on version
0.1.5
and I created a minor change. Runningbump
locally increased the version to0.2.0
as expected. However, if I undo those changes and instead runcanary
I get0.2.1-pr30.0
(where I'm using the PR number from bitbucket). This doesn't seem right, why am I bumping an extra patch version above where I should be? - It might be slightly related to the undocumented nature of the command, but as the bump is not committed back to git, how does
canary
know to go from.0
to.1
the next time a version is pushed?
I'm might be willing to look into this and submit a PR, but before I do I'd like my assumptions cleared up, just in case I'm barking up the wrong tree.
I am also confused about the prerelease workflow, and have noted the various options (prerelease-prefix
via Bumping and publishing options, prereleasePrefix
via Options and as mentioned in this issue the one reference to canary
also via Bumping and publishing options).
I, too, would be very interested in contributing, but do not want to rush in with invalid assumptions. I will try to address one of your questions, add what I understand and then expand on how I think a workflow could work in theory to (hopefully?) move this discussion along.
To try and address your second question first:
Running bump locally increased the version to 0.2.0 as expected. However, if I undo those changes and instead run canary I get 0.2.1-pr30.0 (where I'm using the PR number from bitbucket). This doesn't seem right, why am I bumping an extra patch version above where I should be?
I believe this is explained by the documented behaviour of semver prerelease
, which is the only option used by the Canary command:
If called from a non-prerelease version, the prerelease will work the same as prepatch. It increments the patch version, then makes a prerelease.
To summarise:
input (after bump) | action | output |
---|---|---|
0.2.0 |
prerelease preid=pr30 |
0.2.1-pr30.0 |
0.2.0 |
prepatch preid=pr30 |
0.2.1-pr30.0 |
0.2.0 |
preminor preid=pr30 |
0.3.0-pr30.0 |
0.2.0 |
premajor preid=pr30 |
1.0.0-pr30.0 |
Understanding so far:
- Currently
prerelease
is a change type:
beachball/src/types/ChangeInfo.ts
Line 1 in c14489d
- semver describes a prerelease as a “label” or “extension“ to a version (i.e. to be used in conjunction with a version)
- Canary only ever uses
prerelease
, it never usespreminor
orpremajor
, even if the change type is minor or major):
beachball/src/commands/canary.ts
Line 30 in c14489d
- A PR was raised previously to always offer prerelease as a change option, but was closed due to understandable concerns: #571
- There is no documented workflow for how to manage prerelease versions
- Currently
publish
has no understanding of how to handleprerelease
versions.- Publishing
2.0.0-canary.0
with typemajor
will result in3.0.0
instead of releasing2.0.0
- Publishing
How I think a workflow could work:
I think prerelease should be treated as a modifier to a change, rather than a change itself.
In other words, I don’t think it should ever be a valid change type in a change file, it should instead work in conjunction with the change type defined (i.e. patch/minor/major).
To expand:
- Running
canary
creates the appropriate prerelease version based on thetype
specified on the change file - Running
publish
converts the prerelease version into the desired release version
So a workflow might be:
beachball change
creates a change file forpatch
/minor
/major
beachball canary
(or aliased asprerelease
) can be run any number of times to publish prerelease versionsbeachball publish
will convert the pre-release version to the target release version
And then to illustrate:
original | change |
canary x1 |
canary x2 |
canary x3 |
publish |
---|---|---|---|---|---|
1.0.0 | patch | 1.0.1-canary.0 | 1.0.1-canary.1 | 1.0.1-canary.2 | 1.0.1 |
1.0.0 | minor | 1.1.0-canary.0 | 1.1.0-canary.1 | 1.1.0-canary.2 | 1.1.0 |
1.0.0 | major | 2.0.0-canary.0 | 2.0.0-canary.1 | 2.0.0-canary.2 | 2.0.0 |
Obviously implied in that is that I do not believe publish
should also be used as the command to publish prerelease versions, because they require slightly specialist handling (and I would infer this is why canary exists in the first place). Of course there is nothing stopping most of the publish logic from being reused, but I think it is conceptually clearer if publish itself is only used for final release versions.
Without this pivot though I feel you are going to be stuck with manual tasks each time to convert back and forth between versions and prerelease versions (which is liable to mistakes).
For me, when publishing prereleases, I have access to a CI build number I could use. However that would result in an awkward version of 1.0.0-canary.1.0
since the .0
will always be appended at the end still.
I could switch from canary
back to publish
but I believe that would then muck with the change files that may have been generated. Hope I am not mistaken, is there a workaround to set the versions more directly?