3 ms·
> If you're versioning, a version.txt file at the root of the versioned content is your friend. Have a {subproject_name}-v1.6 branch, you tag commits on that br
by WorldMaker 3y ago
> If you're versioning, a version.txt file at the root of the versioned content is your friend. Have a {subproject_name}-v1.6 branch, you tag commits on that branch v1.6.3-rc1, rc2, ... automatically with CI/CD, until you tag one RC as a release when you release it.
You can save a bunch of text editing and merge conflicts with `git describe` [0]. git describe at any commit will give you a CI/CD version number in the general format of `{most-recent-tag}-{commit count since}-g{hash abbreviation of current commit}`. If the current commit corresponds with the most recent tag, git describe doesn't show the other parts. The `--dirty` flag to git describe will optionally also add a `-dirty` to the end of the version output if the repo has uncommitted changes.
You can pipe `git describe` into a (non-source-controlled) VERSION.TXT file (or a VERSION.JSON makes a simple API for web services) as a build artifact in your CI system. Just about any git command that takes a "commitish" will accept the git describe version format and you can generally just copy and paste the contents of your VERSION.TXT artifact, such as: git switch v1.6.2-11-g1abcde
If you've got multiple subprojects independently versioned in the same repo it gets a bit trickier but if your naming scheme is consistent you can use the `--match` flag to git describe to give a tag pattern. `git describe --match v*` for main tags that start with v versus `git describe --match subproject-name/v*` for a subproject. (Aside: using a forward slash in your subproject tags creates a nice folder structure in many UIs, as with slashes in branch names.)
In early development before you cut a first tag you might want the `--always` flag which will fallback to just the `g{current commit hash}` (and optional dirty with that flag).
The only other twist to git describe is that it defaults to only using annotated tags and doesn't include "lightweight" tags and not everyone or every UI is in the habit of `git tag -a` to create the annotated commit. It can be sometimes useful to have that distinction between annotated and lightweight so you just need to learn to annotate the tags that you care to show up in your git describe versions. Or you can use the `--all` flag to git describe and include lightweight tags for consideration in version numbers as well.
I've used git describe consistently in a number of CI builds for years and it is great. The one small criticism I have of it is that many times for proper semver compliance you really want the first `-` to be a plus (`v1.6.2+11-g1abcde`) as these are generally post-version indicators not pre-version indicators, but that's easy enough to swap with a possibly simple find/replace in the shell script or scripting language of your choice (simplicity depending in part on whether or not you use pre-versions in your tags like v1.6.2-rc.1 which would yield from git describe something like v1.6.2-rc.1-11-g1abcde). There are some off the shelf libraries [1] for that, too.
[0] https://git-scm.com/docs/git-describe https://git-scm.com/docs/git-describe
[1] https://www.npmjs.com/package/git-describe https://www.npmjs.com/package/git-describe (namely the "semverString" output)