Skip to content

TOTHINK: In git snapshot rebuilds, suffix NUT version with number of commits since release #1949

@jimklimov

Description

@jimklimov

Autoconf tricks to allow embedding the git version are explored in autoconf's own build scripts:

A practical implementation example (not with git version, but still - with a command) can be seen at https://github.com/exfatprogs/exfatprogs/blob/master/configure.ac#L3-L11 or MidnightCommander/mc@eab8439 with a fully-fledged script.

The idea here might be to determine a release tag (annotated? by pattern?) as opposed to major milestones, release candidates etc. tagged during development), and count the number of commits since then.

A release might be tagged v2.8.0 (disregarding items like v2.8.0-Windows, Windows-v2.8.0-alpha4 or v2.8.1-rc1 which might have happened later, but maybe including patterns like v2.8.0-signed (which should refer to same commit as original v2.8.0 but with a signed tag object) and then the custom build would be configured as AC_INIT([nut], [2.8.0.123]...) for 123 commits after that release.

If this tweak to metadata works, it would be more idiomatic (and welcoming to rolling-release packaging form master branch by CI, for example) than calling all such custom builds formally 2.8.0.1 and detailing the git maturity level in plain comments or help messages which are not easily machine-parsable.

For bonus points, we may want to track the codebase maturity compared to both master and last release, perhaps 2.8.0.123.45 meaning that "master" branch had 123 commits since last release (2.8.0) and then the currently branched-off effort for a PR added 45 commits on top of that newest commit in the PR branch that is also in known master branch history (the branching or last-resync point), or alternately - just say 345 commits tracked in the PR branch overall when also counting since that release, which may be easier to tackle.

Then a build from newer master branch with 130 commits (or of a PR with foundations on that baseline) would win in terms of automated packaging version resolution, etc. despite the longer (and variable) amount of commits in development branches.

By either count, a release (tag, tarball) would then be pedantically (equivalent to) 2.8.1.0 or 2.8.1.0.0; for most packaging systems trailing zeroes may be ignored so 2.8.1 as usual.

UPDATE from Jul 2024: In current configure.ac we track AC_INIT with a fixed version string (e.g. 2.8.2 committed manually when making a release, and 2.8.2.1 persisting for development versions), and separately define NUT_SOURCE_GITREV via shell script parsing of tailored git describe output. This is further stripped into NUT_SOURCE_GITREV_NUMERIC substituted into e.g. PyPI packaging manifest:

:; grep NUT_SOU config.log
NUT_SOURCE_GITREV='2.8.2-3880-g118c427c7'
NUT_SOURCE_GITREV_NUMERIC='2.8.2.3880'

Elaborating on the idea of tracking two version increments on top of a formal release - of trunk (master) since last release and of current code since trunk, so that snapshot package versions are incremental and easy to upgrade:

  • As a trick seen from mc recipe linked above, --abbrev=0 can be used to strip the commit count and current hash, leaving just the nearest git tag name.
  • Note in configure.ac we add a lot of arguments to strip non-release tags from consideration.
  • Code snippet to experiment with:
getver() (TAG="`git describe --match 'v[0-9]*.[0-9]*.[0-9]' --exclude '*-signed' --exclude '*rc*' --exclude '*alpha*' --exclude '*beta*' --exclude '*Windows*' --exclude '*IPM*' --always --abbrev=0`";
echo "${TAG/v}.`git log --oneline "$TAG"..master | wc -l`.`git log --oneline master..HEAD | wc -l`" | sed -e 's/\.0$//' -e 's/\.0$//'; )
  • As an example, the FTY branch has so far thousands of DMF and other commits that are not part of master-branch history. Even though it is lately regularly merged-into from master, there are many commits seen as unique to it (thanks to backports per Upstreaming improvements from 42ity/nut fork #1316 many of these bring no diff's in content, just metadata). So the current state in one PR branch is NUT release v2.8.2 as baseline (the TAG), with current master adding 695 commits on top of that, and the branch having 3200 commits different from master:
nut-DMF$ getver
2.8.2.695.3200
  • Same expression for a release, with intentionally stripped one or two dot-zeroes in the end of line:
:; git checkout master
:; getver
2.8.2.695

:; git tag -a v2.8.3 -m test
:; getver
2.8.3

:; git tag -d v2.8.3

UPDATE2: Looking at "git merge-base" of current HEAD and known master trunk history, as the branch-off point (or just an older tag or other commit present in trunk) yields reasonable results:

getver() (TRUNK=master;
TAG="`git describe --match 'v[0-9]*.[0-9]*.[0-9]' --exclude '*-signed' --exclude '*rc*' --exclude '*alpha*' --exclude '*beta*' --exclude '*Windows*' --exclude '*IPM*' --always --abbrev=0`";
BASE="`git merge-base HEAD $TRUNK`" ;
echo "${TAG/v}.`git log --oneline $TAG..$BASE | wc -l`.`git log --oneline $TRUNK..HEAD | wc -l`" | sed -e 's/\.0$//' -e 's/\.0$//'; )

# PR branch recently synced from trunk
:; git checkout issue-2450 && getver
2.8.2.695.60

# Recent abandoned PR (current NUT release tag as predecessor, fewer trunk commits in between)
:; git checkout issue-1316-str_concat && getver
Switched to a new branch 'issue-1316-str_concat'
2.8.2.338.1

# Older abandoned PR, with one commit (and older NUT release tag as predecessor)
:; git checkout issue-1754-bcmxcp && getver
Switched to a new branch 'issue-1754-bcmxcp'
2.8.1.328.1

# Older commit ON trunk
git checkout master~30 && getver
HEAD is now at c91684f4b Merge pull request #2526 from jimklimov/issue-2523-cleanup
2.8.2.580

# Older tag
:; git checkout v2.8.1 && getver
HEAD is now at 4ba352d8f configure.ac: update AC_INIT for NUT v2.8.1 release
2.8.1

Primary question would rather be how to reconcile any such value derived from git with static offline-only files available in tarballs (return to some version.txt?); perhaps have a default-version file with e.g. 2.8.2.1 as used in AC_INIT now, tracked in SCM (and tarballs by extension) and updated from autogen.sh or configure.ac only if git is usable. Note that building or developing based on code from tarballs without git, and re-generating with autogen.sh along the way, is a valid scenario.

CC @clepple @aquette : WDYT?

Metadata

Metadata

Assignees

No one assigned

    Labels

    CIEntries related to continuous integration infrastructure (here CI = tools + scripts + recipes)enhancementpackaging

    Type

    No type

    Projects

    Status

    In Progress

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions