-
-
Notifications
You must be signed in to change notification settings - Fork 270
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
What should version in Project.toml be between releases? #351
Comments
I'm not so keen on the |
Seems to work for cargo and npm and IIRC most python package managers. What is different about julia? Also seems better than just guessing that everything that is checked out is a higher version than the latest registered version and guessing 0.0 for unregistered packages. Please elaborate on the "significanct issues" |
The main issue is that it's inherently never correct. Most things you commit aren't actually the version labeled and there's no mechanism for making sure that it's even remotely accurate. When do you change the version? Before you tag it? What if that turns out not to actually be the version? |
The reason why I suggested
where "Release 1.2.3" and "Start developing 1.2.4" are automatically generated by a single command like Of course, you can go back to Pkg2 way and generate the developing version on-the-fly. But I think there are some drawbacks:
|
Right. Another approach is to only save the major and minor versions in the project file. I.e. |
So then the full version number would be stored in the git tag? I guess it is a valid solution but personally it sounds nicer if you have single data source for versions, like only in Another argument for preferring version bump to
Yeah, so why don't you guys decide the meaning of For example, (although it's probably already apparent but) my suggestion is:
Of course, to maintain the uniqueness in item 1 without careful manual maintenance, it is ideal to have Pkg command that imposes the constraint. |
I think it's somewhat unrealistic to think that people developing packages are actually conscious of when they make incompatible API changes and will remember to bump the version number at the time. And once it's in a commit, it's permanent. So then you have what is effectively misinformation permanently committed in your repository. External tagging can at least be fixed in retrospect. |
Hmm... I thought that developers are more conscious about the consequence of change in code when they are writing it. For example, I've seen PR comments from PR writer something like "Don't forget to bump minor version since this PR adds some features!" But I know I'm biased toward remembering semver-compatible examples :)
Since Git allows branching, you can branch off from the commit introducing changes requiring major or minor version up and release it. You can then merge the branch back to the master if you want (which is likely the case if you do the major bump). |
NPM:
Cargo:
Setup.py
Gradle (java)
Can we discuss what is fundamentally different with Julia so that we can't store the version in the source code like every single other major package manager? Right now, with old packages, we cannot do proper version resolution with checked out packages because we have no idea what version they have. Guessing on them being the last registered version is just incredibly wrong (the version of a git-commit changes with unrelated tags to a registry, wat). For the concrete answer to this issue see e.g. https://internals.rust-lang.org/t/confused-about-cargo-version-property/537/2. You bump the version just before you tag. |
Ok, ok. We should make sure that the tooling enforces that the version field in a tagged version matches. Having a mismatch there would truly be a disaster. What should the version string be pre/post tagged versions? I.e. when do you change it? How do you know of you are before or after? |
I'd say the commit setting the version should be tagged as that version. In the future, attobot could listen for such a commit instead of the tag/GitHub release. |
Yes, this is the Attobot workflow I imagined. |
What if that version then doesn’t pass its tests or CI verifications? |
Then that becomes an unregistered version? Even now (i.e. pre-Pkg3), one can tag versions that never make into METADATA, but can still keep the tag. |
@KristofferC My guess is that they are not serious about version number of in-development code although I'm reasonably sure only for setup.py. But I don't strongly argue that Pkg3 should solve this problem. I can see that most people don't find it necessary and solving it perfectly probably complicates the development workflow.
@StefanKarpinski One idea to make the whole release process (automated testing, code review and then registration) atomic is to create a release branch and let Attobot handle that branch. Once the "transaction" succeeds, the release branch can be merged into the master; otherwise, revert the release branch, force-push, and then try releasing again.
@martinholters Doesn't it mean that the version string before the release is ill-defined? But making it well-defined probably requires a complicated workflow to make the release process atomic as mentioned above. I'm not sure many developers like it :) |
It is not very important exactly when the version bump is made. The point is so that you can see that when you instantiate a manifest that tracks some old repo branch that the code you are using is at e.g. v0.5.1 when the latest release is 1.2.0. Instead of showing very old code as 1.2.0+ as Pkg2 does (and resolution of other packages should be better as well). |
It's fine that Pkg3 don't care in-development version numbers (although it's nice if that's documented). Though you will loose a chance to handle it in a standardized way: for example, Pkg3 can generate something like |
But just looking at the version tag is insufficient since the fact that it’s at |
The fact that the current system leads to registered version sequences with holes like Swiss cheese is not exactly great. In the future, it would be preferable to avoid that. I like @tkf’s branch idea. If the version update process was automated I could see the version right before tagging being |
Could you elaborate on this? What are the holes? How is it different from what we had in 0.6? If your points is that the same version applies to multiple commits then I think this has already been discussed above.
That's all resolution care about and it is better than having a version for a given commit continuously changing based on external state. |
The holes come from people tagging a version locally and then trying to register it, which fails and then they keep trying with new tags and skip registering the old, broken tags. It's not new in 0.7, it's a mess in 0.6 and earlier as well. But we can fix it now by improving the process. All you have to do is look at a few PRs on METADATA to see that it's really common to register multiple, consecutive patch versions at the same time, which doesn't make any sense. Not to pick on any particular package or PR but I found e.g. https://github.com/JuliaLang/METADATA.jl/pull/15087/files after poking around for five seconds. This is entirely the fault of the tooling and the workflow. A version number should not be assigned to a source tree until after it is actually clear that the tree is worthy of the version number:
The only way to make sure this works is to arrange that tagged versions are not permanent until after all that stuff is checked. So I think the workflow needs to be something like this:
It's possible that we can skip the actual branching since we don't need versions to be actual commits anymore, they are associated with source tree states and if you want to register |
I've started thinking about the new attobot. For the above process to work, we would need:
In the first iteration of attobot I intentionally tried to avoid these, because I wanted to keep it simple, but also because I don't trust myself enough to code up a system that is sufficiently robust against injection attacks and whatnot. Technically, those problems aren't insurmountable, but they will require careful planning and thought. On the other hand, if I was new to Julia and registering my package required giving some random app write access to my repo for what is a rather trivial reason, I might have second thoughts about doing it. |
Why can't we still use tags? |
Do you mean trigger the process from a GitHub Release like we do now? Because that would create a tag that points to a commit with a Project.toml file set to version 1.2.3-DEV. |
Project files only have |
My interpretation of @StefanKarpinski's comment above is that only the actual tagged version should have version 1.2.3 in the Project.toml, all others should be -DEV or whatnot. |
I mean, we could just abandon git tags altogether (which seems to be what rust does: rust-lang/cargo#841), but having them match is kind of nice from a developer perspective. |
Cargo also hosts the published packages, right? I want to point out that the version in the Project file is only used when you are checking out that package and then it is used to guide the resolver. It is the registry that says what tree is associated with what version. Anyway, I don't feel like getting into a long discussion about this. Npm:
Cargo:
My thought for Julia was:
|
Agreed. It is perhaps worth pointing out that for the other package managers mentioned (npm, cargo, pypi via twine) publishing is done via command line utilities, so their workflows are built around that. Using github releases has made things very simple, and also allowed us to avoid issues like authentication, but it is restrictive. |
When I suggested the branch-based workflow to @StefanKarpinski, what I was thinking was to setup attobot such that it watches branches |
It is now checked, which can lead to rejections upon tagging new releases. Cf. https://discourse.julialang.org/t/version-of-package-version-of-documentation-version-of-project-toml/20582/3 JuliaLang/Pkg.jl#849 JuliaLang/Pkg.jl#351
I think the way things work now is ok. |
If I checkout (say) Compat.jl with
] develop
, the version number returned byPkg.API.installed()["Compat"]
is whateverversion
field is inCompat.jl/Project.toml
. In Pkg2, it had "+" after the version number. Here is a concrete example:Of course, each package developer can set
version = "$X.$Y.$(Z+1)-dev"
(say) right after releasingversion = "$X.$Y.$Z"
. If you are going to implement something likePkgDev.tag
(#249), it would be nice to automate this.The text was updated successfully, but these errors were encountered: