-
-
Notifications
You must be signed in to change notification settings - Fork 266
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
Fixed version info be set when go install #991
Fixed version info be set when go install #991
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd looked into how to best accomplish this a couple weeks ago and agree that the new debug.BuildInfo
type is the way to go (pun intended) since the project is now >= Go v1.18. I'm not sure that we shouldn't still rely on the Make file for LAST_TAG
and EXACT_TAG
... if there's no tag on HEAD
, one common alternative would be to use the commit. I also like think we should be outputting a version that includes the dirty
flag. Perhaps this library can be some inspiration - https://pkg.go.dev/github.com/carlmjohnson/versioninfo.
The Makefile
also has a problem that we don't currently manage well (though it hasn't broken a release build yet) ... both git
commands that used to be in the Makefile
only use the last tag found on the commit. If there's more than one tag we're going to get whatever it contains (hopefully some sort of semantic version!)
commands/root.go
Outdated
} | ||
} | ||
|
||
cmd := exec.Command("git", "describe", "--tags", "--abbrev=0") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we want to run this every time a git-bug
command is executed and, since we're already using go-git
using exec
might be a bit dangerous. Theoretically, git-bug
is run inside a git
repository and the executable should be available but perhaps not?
The bigger issue is that this would return tag information for the git
repository where git-bug
is run rather than tag information for the git-bug
repository. I think I'd continue to ask the Makefile
for this information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smoyer64 is correct, we want to bake into the binary which code was compiled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smoyer64 @MichaelMure thank you for the detailed response, I see what you say.
I think I was too fast, opening this PR.
Here are my suggestions for now, would like to validate that with you, before I move forward:
- Use
Makefile
in the first place (revert all the changes I did) - If
GitLastTag
,GitCommit
andGitExactTag
are not defined - try to extract info fromReadBuildInfo
(if that's possible and Go is 1.18+) - If by the end we do not have required info - return some sort of better defined version, as now it's
-dev-
There is one more thing wort mentioning: ReadBuildInfo
does return only vcs.revision
, that is commit, and we cannot get tag from there.
Does that sound okay for you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that:
vcs.revision
is the equivalent ofGIT_COMMIT
vcs.modified
tells if the original repo was dirty, which could be used to add a-dirty
suffix on the version name
We are indeed missing the tag, which is quite annoying.
So ... what to do ... We could use those two variables when they are available, which I assume would at least partially fix #928. Ideally golang would also expose the tag, but I don't even see an issue in their tracker for that so it's not going to happen anytime soon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But yeah, the tag extraction in the makefile need to stay for now.
So we would have different version schema:
v0.8.0
<-- releasev0.8.0-dev-xyxyxy
<-- non release, at commit xyxyxyv0.8.0-dev-xyxyxy-dirty
<-- same but also dirtydev-xyxyxy
<-- we don't know the tagdev-xyxyxy-dirty
<-- same but also dirty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also vcs.time
... after I wrote the above I was also coming to the conclusion that we might want a different format. Fortunately, debug.BuildInfo.Main.Version
will either contain the tag or the word "devel". The real problem (for me) is that I'll never install a release package, and I'd love to know the "base" release for what I'm working on!
In the examples above, the first three would have to be tagged AND would be produced by the Makefile
right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related (with links to a lot more):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that you can still use linker flags with go install
- would users do that if so instructed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good reading about the build info and it's caveats.
Basically, the case when we can retrieve a tag from debug.BuildInfo.Main.Version
will work only when we have a release, right?
There's also vcs.time
We can use time from the build info as well, but will this more useful info for the use?
In this case, it sounds better to use linker flags as you suggest - it will be more useful for those who really need full release. But I should admit that will have to research that, since have never used linker flags
In the examples above, the first three would have to be tagged AND would be produced by the Makefile right?
Yes, exactly. Updating PR description with that info again
For now, updated PR: reverted back changes in Makefile. The only change there, is --dirty
flag. And added changes to return version per new schema described above
Makefile
Outdated
@@ -1,7 +1,7 @@ | |||
all: build | |||
|
|||
GIT_COMMIT:=$(shell git rev-list -1 HEAD) | |||
GIT_LAST_TAG:=$(shell git describe --abbrev=0 --tags) | |||
GIT_COMMIT:=$(shell git rev-parse --short HEAD) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you explain those changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that change was unnecessary. I was thinking of returning a short commit hash to not to format it in the root
|
||
info, ok := debug.ReadBuildInfo() | ||
|
||
if !ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you can't read the build infos:
- you should not continue reading the returned value, that could crash. Instead, return an error or a valid value.
- you should not print anything
commands/root.go
Outdated
@@ -90,3 +107,28 @@ func Execute() { | |||
os.Exit(1) | |||
} | |||
} | |||
|
|||
func getCommitAndDirty() (commit, dirty string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like dirty
should be a boolean
// modified status (that is the flag for repository dirty or not) | ||
for _, kv := range info.Settings { | ||
switch kv.Key { | ||
case "vcs.revision": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of going over all the values, you could simply try to read: if val, ok := info.Settings["vcs.revision"]; ok { ... }
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
info.Settings
returns an array of structs, so I can't access required values by key name
@vasser I made some changes, mostly style, but also fixed one or two edge cases I found. Thanks for the help :-) |
Great, happy to help 👍 |
Resolves #928
In Go 1.18+
debug.ReadBuildInfo
contains revision so we can read it from there when we are installing git-bug withgo install
.In this PR we are utilizing the following attributes of
debug.BuildInfo
:vcs.revision
- get commit hashvcs.modified
- identifies whether the state of project is cleanvcs.time
- in discussionThis change introduces new version schema:
v0.8.0
- releasev0.8.0-dev-xyxyxy
- non release, at commitxyxyxy
v0.8.0-dev-xyxyxy-dirty
- same as above, but also dirtydev-xyxyxy
- we don't know the tag, at commitxyxyxy
dev-xyxyxy-dirty
- same but also dirty