<p>When using git, it's very convenient to create a tag (e.g. v1.2.3) on a certain commit which also looks great on GitHub as a release.</p>
<p>Go makes deployments trivial with the use of static binaries but sometimes when I go back to binaries that I have deployed maybe months ago, I find myself wondering "Is this really the latest version?". It's probably something I should have done from the start but after encountering that problem I started using a -v flag which prints the program version. That made me wonder if there is a "standard" way of "storing" the version number of a Go program.</p>
<p>Obviously the simplest solution is to use something like <code>const version = "1.2.3"</code> and always remember to update it when a new git version tag is created.</p>
<p>Another approach (used by the go tooling if I remember correctly) is to keep a <code>VERSION</code> file at the top of your repository and use a combination of go generate and file reading to make the version number available where needed. This approach can help with more complex projects.</p>
<p>There are probably more approaches. Maybe something less static that includes reading git tags? Which approach do gophers prefer to use? Is there a "standard" way?</p>
<hr/>**评论:**<br/><br/>THEHIPP0: <pre><p>I usually use Makefiles for building my go projects, but this should work on the command line too:</p>
<p><code>go build -i -v -ldflags="-X main.version=$(git describe --always --long --dirty)" github.com/MyUserName/MyProject</code></p>
<p>and in my go file:</p>
<p><code>var version = "undefined"</code></p>
<p>During compilation the <code>"undefined"</code> will be replaced with the current version from git.</p>
<p>As requested an example <a href="https://gist.github.com/TheHippo/7e4d9ec4b7ed4c0d7a39839e6800cc16">Makefile</a>.</p></pre>intortus: <pre><p>Same here, this is exactly what the -X linker flag was made for.</p></pre>lovetocode: <pre><p>I am interested in how you are using Make files to build your go projects, do you have any opens source examples? I am new to writing Make files so I am not sure how much it differs really.</p></pre>Bake_Jailey: <pre><p>Glide does this for their builds, if you need an example.</p>
<p><a href="https://github.com/Masterminds/glide/blob/master/Makefile" rel="nofollow">https://github.com/Masterminds/glide/blob/master/Makefile</a></p></pre>THEHIPP0: <pre><p>Added a link to an example Makefile to my comment.</p></pre>sdboyer: <pre><p>This is probably the best way, because no, there is no standard way.</p>
<p>I'd avoid that <code>VERSION</code> file idea, as not only are you prone to forget it, but it'd start straying into the domain of what a package manager does...and we already have too many things competing in that space :)</p></pre>jonbonazza: <pre><p>We do this exact same thing on our build servers. </p></pre>elithrar_: <pre><p>You can also do this with most CI services—e.g. TravisCI with <a href="https://docs.travis-ci.com/user/uploading-artifacts/" rel="nofollow">build artifacts</a> and your .travis.yml (which is just a take on a Makefile, technically).</p></pre>yxlx: <pre><p>That set of options to <code>git describe</code> is better than the one I've been using because the one I was using required a tag to exist, which would lead to "fatal: No names found, cannot describe anything." Thanks for sharing.</p></pre>gergo254: <pre><p>"always remember to update it when a new git version tag is created"</p>
<p>Or create a build script which would update it for you.
Something like this: <a href="http://stackoverflow.com/questions/11354518/golang-application-auto-build-versioning" rel="nofollow">http://stackoverflow.com/questions/11354518/golang-application-auto-build-versioning</a></p></pre>mwholt: <pre><p>I use this build script; it produces a slightly elaborate version string that is really useful for knowing what commit/tag the build is based on and which files have changed: <a href="https://github.com/mholt/caddy/blob/master/build.bash" rel="nofollow">https://github.com/mholt/caddy/blob/master/build.bash</a></p></pre>warmans: <pre><p>The way I do it for bigger collaborative projects is to store the version in a constant which is updated as part of a release process. So the workflow is something like: </p>
<ol>
<li>merge changes into develop over time.</li>
<li>decide a new release is required. </li>
<li>create a release branch with an incremented version number (as per semver) e.g. <code>release/0.1.2</code>.</li>
<li>in the release branch increment the version constant and commit it.</li>
<li>build the project (if required) any release artifacts (e.g. a deb or rpm) and commit the artifacts (again, maybe you don't want to do this) to the release branch (these tend to just take the version from the binary).</li>
<li>merge release branch into master and tag it with the version number.</li>
<li>merge master into develop.</li>
</ol>
<p>At the end of the process there is some kind of distributable package with the right version numbers in both the binary and package metadata (important for the package manager) so it can be released.
It sounds like a lot of trouble but most of it can be scripted in a makefile.</p>
<p>If it's just a personal project I do a similar thing but without all the branching and merging. Just merge into develop and at some point increment the version number, build, create artifacts, commit, and possibly tag at that point.</p></pre>therealdrowranger: <pre><p>you can also use "go generate" to trigger a script that fills in a "version.go" file</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传