Closed grembo closed 2 years ago
Thanks for reporting, and for pointing to the same problem in the python-versioneer repo! I can see how this is an issue for the packagers. We definitely want to make life easier for you guys!
We want scli --version
to print a meaningful output whether scli has been obtained with git clone
or downloaded from GitHub as a zip / tar.gz archive. But I don't want to have to update the version string somewhere in the source code, and then make a 'bump version' commit before every release.
Instead, getting the version number is taken care of by get_version()
coupled with the VERSION
file. If scli finds a .git
dir, then scli --version
runs git describe
. If, on the other hand, scli has been downloaded as an archive from GitHub, then GitHub runs git archive
to create that file; thanks to a hook in .gitattributes
, during this process the contents of VERSION
file are replaced with the actual version info, similar to that printed by git describe
(see comments in the VERSION
file).
Unfortunately, it's not exactly the same as git describe
: we are limited to what git log
's --pretty=format:'...'
provides. The closest thing to what we want - the latest tag name - is the %d
placeholder, which comes burdened with this extranous information about git branches pointing to the current commit. And those can change, of course, e.g. when a new commit is added to a branch that initally pointed to the tag.
python-versioneer
apparently uses the same technique. Our version is a minimal implementation of the same idea.
Now, the problem arises because the archive files that GitHub provides for downloading, like the 'source code' files on the releases page, are generated dynamically at download time. This implies that there is no guarantee that the hashes of zip / tar.gz files downloaded at different times will stay the same. It's the same thing that causes #143.
master
at the time)pre-tag
git hook, as far as I can see, but a custom script could be written as a replacement. git clone && git checkout
instead of downloading a tarball. I am leaning towards the first option as the "least worst". It will also solve #143 and the potential future issues arising from relying on dynamically generated archive files. But none of the above seem ideal. Suggestions welcome!
@0mp has this come up in the past? Is this commit relevant? (The message "Fix scli --version")
@alexeyre can this be a problem for nixpkgs too?
@exquo What about using the %(describe) placeholder instead? It's available since git 2.32.
Example:
$Format:%h %(describe:match=v*)$
The above matches all annotated tags which start with a "v". So the one caveat is that tagging has to happen using git tag -a <tagname>
(which seems like good practice for releases anyway).
The results look like this:
0bb2874 v0.0.1
aa12f3e v0.0.1-1-gaa12f3e
c41b211 v0.0.3
Which relate to:
I created a test repo to verify that this is actually supported by github: grembo/gitformattest
Testing shows that version strings stay stable this way.
The next release of git should contain this change, which will allow to do:
$Format:%h %(describe:match=v*:tags=true)$
to get rid of the annotation requirement on tags (even though, I kind of like using them anyway).
What about using the %(describe) placeholder instead? It's available since git 2.32.
That's exactly what we need here, thanks so much!
I'm on an older git version, so was not aware of this addition. Ironically, it's right there next to %d
in the git formatter documentation linked to above 🤦.
one caveat is that tagging has to happen using
git tag -a <tagname>
Yes, we're using git's annotated tags. I agree it's a good practice regardless.
If you want to make a PR with this change to the VERSION
file, I'd be happy to merge.
That should take care of this particular problem, but other issues caused by changing hashes of dynamically generated files might come up in the future. So, (note-to-self), we might still want to start uploading our own archive files to the releases.
(tagging @0mp, who is maintaining the FreeBSD port)
VERSION contains a version string that changes based on the state of the archive.
https://github.com/isamert/scli/blob/d9b38cf874aa6466f503a0b1df447d47ffad8326/VERSION#L1
This means, right after v0.6.5 was released, the file contained:
d2f437a (HEAD -> master, tag: v0.6.5, develop)
later this changed to
d2f437a (tag: v0.6.5).
This results in hashes of artifacts changing, which means package builders relying on those being correct end up not being able to fetch the package - one would think that official artifacts stay the same, but it appears that this might actually not be the case (comparing contents of v0.6.6 and v0.6.5 sources on the release page lead to this assumption).
There a discussion about this here: https://github.com/python-versioneer/python-versioneer/issues/217