feature(gitinfo): Embed version info into binary.#18
feature(gitinfo): Embed version info into binary.#18OmniBlade wants to merge 1 commit intow3dhub:mainfrom
Conversation
|
At SDL, we're using |
| execute_process(COMMAND ${GIT_EXECUTABLE} show -s "--format=%H" HEAD | ||
| WORKING_DIRECTORY ${source} | ||
| OUTPUT_VARIABLE GIT_REVISION_HASH OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
| set(GIT_REVISION_HASH "${GIT_REVISION_HASH}" CACHE INTERNAL "git revision full hash") |
There was a problem hiding this comment.
Won't this caching cause the revision to be stuck on the value of the first CMake configuration?
There was a problem hiding this comment.
I tested rerunning the cmake configurations after changing things like the commit tag or creating a new commit and it updated the information as expected.
There was a problem hiding this comment.
When you reconfigure CMake, then it works indeed.
But it does not update the git parameters when you forget to configure, and only build the target.
The following sequence of commands do not trigger rebuilds, so the executables contain wrong hashes.
git commit -m hello --allow-empty
cmake --build . --target renegade
git commit -m hello --allow-empty
cmake --build . --target renegade
git commit -m hello --allow-empty
cmake --build . --target renegade
There was a problem hiding this comment.
I've done something similar to this before, as long as all the builds come from CI it's fine(since the buildserver would do a clean build every time). It does stay stuck at the previously cached value otherwise.
Looking at that, it still only sets a CMake variable that would ultimately have to be either passed as a define to the build system or used to configure a file that would be compiled into the target? |
I think the magic is it depends on |
That definitely sounds like the better way to do this, so you don't need to reconfigure in order to get updated variables. A thought on some of the string manipulation in cmake: if you want to be fancy, you could probably replace most of that with For the version that is shown to the user, what I generally do is to use |
My main issue with getting it from the CMake project version is that it involves pushing a commit specifically to bump the version rather than deciding a given commit is the next version, tagging it and making it so. Plus this doesn't rely on anything matching, any untagged commit will be built as a revision bump on the previous version tag. It will even work with other tagging if we started releasing nightlies or weeklies or something with a different tagging scheme treating them all as revisions on the last version patch until we do a full release. Just some of my thought process that went into the versioning anyhow. |
We did use a different CMake module for Vanilla Conquer that set up a custom target that forced a reconfigure, but it was a bit convoluted though this one seems to be also. I can't believe it takes so much complication to get something seemingly simple to work. |
I like to do more intentional releases, so that's where I'm coming from. Just as a point of comparison, Linux will do a single commit that bumps the version and then tag it like that(example). The other problem that just occurred to me is that without having the version number in the code, if you download the code you would have no idea what version it is - in other words, it's entirely driven by the git tag. So you wouldn't be able to download the code and build a binary that is exactly the same. |
290c59e to
4e7a611
Compare
The issue I have with that is that there is no single point of truth though and the tag and in code version could differ. If you just download the code without cloning the repo (which should pull the tags as well) then you are missing a bunch of other information like the commit hash, commit date and other information that would be needed to match the build so you still won't be able to match it exactly without recreating that data offline. The release can still be deliberate, you only create and puch a tag when you want a release and then the CI should build a new version of that commit with the updated tag and create the new release on github ready to download. All automated with the push of the tag only. The Linux process makes sense for Linux because it predates the git workflow so why mess with established convention for such a long lived project. |
|
I've refactored this PR to use a variation of the git watcher code that vanilla conquer uses, so it should address the issues with not picking up changes to the repo state. |
|
Almost all of the big open source projects that I'm aware of do embed the version into the source bundle. I would propose that we do something like the following:
Option A for releasing:
Option B for releasing(my preferred way):
Option B would be done locally with some sort of script in order to automate the process. We can follow a odd/even scheme for the releases that some other projects do, where even means "release version" and odd means "development version." The idea behind option B is that we also don't need any git information in the binary, although I would be open to keeping the git SHA. The commit author doesn't provide value IMHO. Thoughts? |
|
The SDL version is also embedded in various places. Because this version is present in multiple locations, we have scripts to check and update the version. What we do in SDL to get the git revision during the build process::
Our release checklist contains lots of points to make sure the versioning is handled correctly. I don't think this process is overly complicated, and can be automated. |
|
My preference is to follow something like semver, major version releases for when the API/ABI for scripts changes or the network protocol changes in an incompatible way with previous builds, minor for changes that add features or fixes in a backward compatible and patch for minor bug fixes that don't affect compatibility. I think that the more automated the process for release is, the less chance there is for mistakes to crawl in. I don't object with a generated gitinfo.cpp being embedded in a release source zip. I can remove the git author stuff and just leave the ability to pass in a build author so we can stamp it as an OpenW3D release on the CI. It is in there more to replicate the author info in the original build info stamped into the binary. |
ee432f6 to
59b001f
Compare
Embeds information from git into binary. Refactors printing version information for main menu and debug logs.
59b001f to
348076d
Compare
|
If we want to do this right, I think we should also do something with the version info in |
|
I can look into what TT is doing but it's not as robust as what's being discussed here I don't think. |
|
|
||
| # Do we want to embed git information into the binary? | ||
| option(W3D_EMBED_GIT_INFO "Embed information from git." OFF) | ||
| add_feature_info(W3DEmbedGit W3D_EMBED_GIT_INFO "Embed information from git") |
There was a problem hiding this comment.
I don't think we should make embedding git information optional.
When we ever do a source release, we should then make sure that it can build without git.
There is removed code for retrieving the version info from the embedded resources, not sure what the requirement for that was but it was removed before the source code was released. In Vanilla Conquer I generate the embedded resources from cmake to compile in on windows builds. |
I've added that code back in (temporarily) in my current active sdl3 PR #105 (please review). |
Resolves 4 merge conflicts: - buildnum.cpp/h: replaced old BuildNumber[char] post-build stamping with git-embedded info - dlgmainmenu.cpp: updated Update_Version_Number to use git info format - ConsoleMode.cpp: removed Get_Version_Number call (no longer needed) PR w3dhub#107 fixes applied on top: - rawfile.cpp: READ|WRITE data loss fix (r+b then w+b) - verchk.cpp: FAT date month decode (0xf → 0x1f) - rcfile: static init order fix (Meyers singleton)
Embeds information from git into binary.
Refactors printing version information for main menu and debug logs.