Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for snapshot versioning and publish under custom tag #359

Merged
merged 14 commits into from
May 21, 2020

Conversation

ajaymathur
Copy link
Contributor

@ajaymathur ajaymathur commented May 10, 2020

Resolves issue: #327

Changes:

1. version command now supports snapshot flag.

Rule:

  • It will not commit the version change.

Usage:

$ # Creates a version as 0.0.0-[tag]-<hash>
$ # hash -> date-time combination -> YYYYMMDDHHMMSS
$ changeset version --snapshot [tag]

2. publish command now supports tag flag

Rules:

  • Throws error if project is in pre mode.

Usage:

$ # Publishes the packages as per changeset(s) to the provided tag.
$ changeset publish --tag <tag>

@changeset-bot
Copy link

changeset-bot bot commented May 10, 2020

🦋 Changeset is good to go

Latest commit: c84899f

We got this.

This PR includes changesets to release 3 packages
Name Type
@changesets/apply-release-plan Minor
@changesets/assemble-release-plan Minor
@changesets/cli Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov
Copy link

codecov bot commented May 10, 2020

Codecov Report

❗ No coverage uploaded for pull request base (master@9f9c61f). Click here to learn what that means.
The diff coverage is 75.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master     #359   +/-   ##
=========================================
  Coverage          ?   80.32%           
=========================================
  Files             ?       41           
  Lines             ?     1103           
  Branches          ?      258           
=========================================
  Hits              ?      886           
  Misses            ?      209           
  Partials          ?        8           
Impacted Files Coverage Δ
packages/cli/src/commands/pre/index.ts 89.47% <ø> (ø)
packages/apply-release-plan/src/index.ts 92.47% <50.00%> (ø)
packages/cli/src/commands/publish/index.ts 74.19% <54.54%> (ø)
...ckages/cli/src/commands/publish/publishPackages.ts 76.00% <75.00%> (ø)
packages/assemble-release-plan/src/index.ts 94.82% <100.00%> (ø)
packages/cli/src/commands/version/index.ts 90.90% <100.00%> (ø)
packages/cli/src/utils/v1-legacy/removeFolders.ts 66.66% <0.00%> (ø)
packages/get-version-range-type/src/index.ts 100.00% <0.00%> (ø)
packages/cli/src/commands/add/createChangeset.ts 50.61% <0.00%> (ø)
... and 37 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9f9c61f...c84899f. Read the comment docs.

newVersion:
snapshotConfig === undefined
? incrementVersion(incompleteRelease, preInfo)!
: `0.0.0-${snapshotConfig.tag}-${snapshotConfig.commitHash}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why 0.0.0 should be used instead of the current version?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the current version or the future version(as in the current version but with bumps applied) can cause unexpected behavior when combined with other pre-releases(e.g. you have a regular pre-release at 1.0.0-beta.0 and then you had a snapshot pre-release at 1.0.0-canary-git-hash and a consumer is using the range ^1.0.0-beta, most people would expect that range to resolve to 1.0.0-beta.0 but it'll actually resolve to 1.0.0-canary-hash). Using 0.0.0 solves this problem because it won't conflict with other versions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the detailed explanation! I always forget that this is how canary versions are resolved. Might be good to add this as a comment in the code or/and an explanation in the docs about snapshot publish.


logger.log("All the files have been updated with snapshot release.");

await publish(cwd, { otp: options.otp, tag: options.tag }, updatedConfig);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to be able to use a custom publisher. I use pnpm publish -r instead of changeset publish because it works better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be a separate improvement maybe

packages/cli/src/commands/publish/publishPackages.ts Outdated Show resolved Hide resolved
packages/cli/src/commands/version/index.ts Show resolved Hide resolved
(command === "snapshot" || command === "enter") &&
typeof tag !== "string"
) {
error(`A tag must be passed when using prerelese ${command}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the tag required when making a snapshot publish?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a tag to know what npm dist-tag to publish to

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, indeed. There is no way to publish without a tag because that way it would be "latest".

In that case, makes sense. Maybe some default tag could be used. Like the branch name, or "snapshot", or "dev". But that's just a good to have.

@zkochan
Copy link
Contributor

zkochan commented May 11, 2020

I don't understand what pre means. Why cannot it be called changeset snapshot --tag <tag>? I guess it would make sense to even include publish in there, to make it clear that a publish will happen: changeset publish-snapshot --tag <tag>

@emmatown
Copy link
Member

pre means pre-release. The reason it's called changeset pre snapshot is that it's a snapshot pre-release.

@Andarist
Copy link
Member

It seems to me as well that including "publish" somewhere in the command would make it easier to understand for newcomers, even at the cost of some added verbosity.

@emmatown
Copy link
Member

Okay, let's make it changeset publish-snapshot <tag>

@ajaymathur
Copy link
Contributor Author

ajaymathur commented May 12, 2020

Thanks for the feedback everyone. :)

Tasks that I am completing now:

I am going ahead with working on change but please feel free to discuss if you think something should be added or updated.

Please see the comments below now. #359 (comment)

@Andarist
Copy link
Member

Currently, regular versioning and publishing scripts are separate - IMHO it would make sense to stick to that here as well without introducing no-publish flag or similar because it deviates from the standard usage.

My alternative proposal would be to add --snapshot flag to both version and publish commands. You need to rethink if it makes sense to call publish --snapshot tag without previously calling version at all, but seems to me that it shouldn't create much of a problem and maybe would be useful on its own for somebody.

Q: why this has been bound to pre mode? Wouldn't it make sense to allow this outside of it? One could setup snapshot releases on each pr/commit without ever entering the pre mode - this use case seems useful.

@ajaymathur
Copy link
Contributor Author

A: Snapshot release does not have to bound to pre release, it is just the significance that pre defines a pre-release. User does not have to be in pre mode snapshot release.


Yes, I like the idea of changeset publish --snapshot tag, it read clear to me of what it does but then users will not able to use their own publish script. like mentioned in #359 (comment), any opinions on this?


Continuing on suggestion of keeping the version and publish separate I see this as:

$ # Gives a version as 0.0.0-<hash>, but does not commit the files no matter the config
$ changeset version --snapshot
$ # Publish command supports the tag option, this overrides config for publish - default as latest
$ changeset publish --tag <tag>

Opinions?

@emmenko
Copy link
Contributor

emmenko commented May 12, 2020

It makes sense to me, thanks.

To summarize, let me try to apply this to some examples:

Publishing to latest (default)

changeset version
changeset publish

Publishing to next dist-tag instead of latest

changeset version
changeset publish --tag next

Publishing canary releases

changeset version --snapshot
changeset publish --tag canary

Publishing in "pre" mode

changeset pre enter next
changeset version
changeset publish

Did I get this right?

@Andarist
Copy link
Member

Yes, I like the idea of changeset publish --snapshot tag, it read clear to me of what it does but then users will not able to use their own publish script. like mentioned in #359 (comment), any opinions on this?

Isn't this problem solved by splitting this into 2 commands? @zkochan could use versioning command to adjust files and just use a custom publish command, or have I missed something?

@ajaymathur
Copy link
Contributor Author

Hey @Andarist, yes you are right. I misunderstood the second line. Sorry.

I see using snapshot flag with version and using tag option with publish looks clean. As in #359 (comment)

How can we decide on it?

@Andarist
Copy link
Member

Probably a good idea to wait for @mitchellhamilton’s or @Noviny’s green light

@emmatown
Copy link
Member

$ # Gives a version as 0.0.0-<hash>, but does not commit the files no matter the config
$ changeset version --snapshot
$ # Publish command supports the tag option, this overrides config for publish - default as latest
$ changeset publish --tag <tag>

This sounds good to me. One little thing: changeset publish should throw if --tag is passed when in pre mode (because the tag changes in a nuanced way when in pre mode). Also changeset version --snapshot some-tag should make the version 0.0.0-some-tag-hash


Unrelated to the above - instead of using the git hash, let's use a random hash so that it's not tied to git + you should be able to do multiple releases without the last commit hash changing

@zkochan
Copy link
Contributor

zkochan commented May 12, 2020

Another good alternative to using hash would be to use date/time. I have noticed this in the typescript canary versions but they use only date.

They have versions like this: 4.0.0-dev.20200512

@ajaymathur ajaymathur changed the title Snapshot release [WIP] Snapshot release May 13, 2020
@emmenko
Copy link
Contributor

emmenko commented May 15, 2020

@ajaymathur ajaymathur changed the title [WIP] Snapshot release Support for snapshot versioning and publish under custom tag May 17, 2020
@ajaymathur
Copy link
Contributor Author

Hey 👋, PR is ready for review. 🙂

@emmatown emmatown self-requested a review May 18, 2020 00:17
Copy link
Member

@emmatown emmatown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so great @ajaymathur, thanks!!

Just some little comments

* but it'll actually resolve to 1.0.0-canary-hash. Using 0.0.0 solves this problem because it won't conflict with other versions.
*/
// Creating cache of hash since this function is called for every release the value of second may change
let uniqueHash: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we cache this per assembleReleasePlan call rather than globally?

now.getHours(),
now.getMinutes(),
now.getSeconds()
].join("");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the UTC methods instead of the timezone-relative methods here? I don't think that the user's timezone should affect the release name. (e.g. two people in different time zones do releases(or you move from manual releases to doing releases on CI or etc.), you wouldn't want a newer release to have an older time)

options.snapshot === undefined &&
preState !== undefined &&
preState.mode === "pre"
) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we throw here if snapshot is passed and we're in pre mode?(to give the user feedback before they're at the publish stage)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why pre mode should clash with snapshot releases? seems like both could be used at the same time with success

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pre mode changes the npm dist tag that's used and so does the --tag option. Given you shouldn't commit the result of a snapshot release, it's easy to exit pre mode and then do the snapshot and you won't get any unexpected behavior. We can always change this behavior in the future if we want to in the direction of not erroring but going in the opposite direction is harder.

"@changesets/cli": minor
---

- Add support for snapshot flag to version command. Usage: `changeset version --snapshot [tag]`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you describe the motivation and the use case for this?

The second thing (publish --tag) is not tightly coupled to the --snapshot so it could be moved to a separate changeset.

@@ -39,7 +39,8 @@ async function getCommitThatAddsChangeset(changesetId: string, cwd: string) {
export default async function applyReleasePlan(
releasePlan: ReleasePlan,
packages: Packages,
config: Config = defaultConfig
config: Config = defaultConfig,
snapshot?: string | boolean
Copy link
Contributor

@zkochan zkochan May 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why snapshot is not part of config or releasePlan?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re config: the config refers to the written config, this doesn't want to be part of that.

It could be part of the release plan, but would like to see it land and stabilise, as the release plan being relatively clean is nice.

…-release-plan's main function

2: [Version command] Add condition to throw error if snapshot version is made while changeset is in pre-state
3: [Publish command] Update the condision to capture preState.mode and updated the error message when tag is passed in pre state
@emmatown emmatown self-requested a review May 21, 2020 03:28
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
@atlassian-cla-bot
Copy link

atlassian-cla-bot bot commented May 21, 2020

Thank you for your submission! Like many open source projects, we ask that you sign our CLA (Contributor License Agreement) before we can accept your contribution.

The following users still need to sign our CLA:
❌mitchellhamilton

Already signed the CLA? To re-check, try refreshing the page.

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Copy link
Member

@emmatown emmatown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for this @ajaymathur!!!

@emmatown emmatown merged commit 6d0790a into master May 21, 2020
@emmatown emmatown deleted the issue/137-snapshot-release branch May 21, 2020 10:28
@github-actions github-actions bot mentioned this pull request May 21, 2020
@ajaymathur
Copy link
Contributor Author

Hey @mitchellhamilton , thanks for a lot for accepting suggestion and merging the PR. Due to my travel arrangement this week I will not able to respond. Appreciate it. 🙂

@MichaelKapustey
Copy link
Contributor

Hey guys, when do you expect to publish this change? I can't wait to use it already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants