Snapcraft version scripts

We currently only create meta for prime (the step and directory) and have some technical debt to do it for stage to be able to snap try stage.

That aside, I can rephrase saying that we probably want to run the version-script right after everything has built given that the script can reference anything that was built in any part. That or we extend the language or version-script even more to tell it after which part to run, but I honestly think that will just not be as straightforward.

Ah, after stage sounds good then.

After everything has settled I had one more idea I want to share and see if there is agreement on.

If we have this

version: git-tag

Then we get automatic versioning from the source where snapcraft.yaml lives. Let me illustrate further:

  • When snapcraft starts, before doing anything, verifies that it is under git source control
  • It gets the latest tag git describe --abbrev=0 --tags
  • It gets the latest commit git rev-parse HEAD

Two things can happen:

  • if the tag == latest_commit, then the version is set to the tag
  • if the tag != latest_commit, the the version is set to tag+$(git rev-parse HEAD | cut -c -10)

The 10 can be agreed upon. Tags on github essentially create releases, which makes this interesting to do IMO.

1 Like

This of course is a subset of the functionality already proposed, but I could see it being helpful if a lot of people are looking for that functionality (which it seems they are). Would we support this for other version control systems, as well?

@sergiusens Nice, that’s a great shortcut! I’d suggest simply version: git, though, as it’s both nicer to look at and more realistic since this using heuristics and a string which is not just a tag. For the behavior, have a look at mkversion.sh inside the snapd repository. We’ve put some good thinking on that in terms of what information would be relevant when the tag isn’t matching exactly, so we might reuse the same logic.

@kyrofa Yes, it’d be fine to introduce equivalent logic for others. The git one is likely easier because it does part of the job internally, and it’s of course pretty popular, but having “svn”, “bzr”, etc, seems good.

1 Like

I will take a look at mkversions.sh before getting any code in, thanks. I am ok with version: git too, I was just being paranoid at someone setting their version to that to be that, in retrospect, it with proper messaging this isn’t a problem.

@kyrofa WRT other VCS, if people claim for it or a PR is created they will be prioritized for implementation or reviewed/merged but I think focusing on git now gives us a lot of bonus points.

I looked at using git describe, this is what I get

$ git describe --tags --always --long
2.28-28-g3f5c735f

Where 2.28 is the tag, the 28 that follows is the number of commits on top of that tag and last is the first part of the hash of the latest commit.

I would think that something like this looks nicer though 2.28+gitg3f5c735f. Any thoughts on this? Should I just use what git describe returns, am I biased towards a debian/changelog style of version formatting (although some use +git with a date instead)?

Did you look at what mkversion.sh does? I mean the whole thing, not just the git command it runs. What was your impression?

We went through the thinking process of making it both look good and be useful, so it’s a good starting point as mentioned above.

Yes I have, went into https://github.com/snapcore/snapd/blob/master/mkversion.sh saw the fallback logic and on the same branch above produces something like 3f5c735f+gitdirty. It omits the tags though which I find rather important to keep.

@sergiusens Sorry, I’m still having a hard time parsing your feedback or intention. Let me turn this around and tell you what we have and why. This is what I get when running mkversion.sh in the snapd repository:

% ./mkversion.sh 
*** Setting version to '2.23.1+git134.g27f30d5' from git.

So, in order:

  • 2.23.1 is the most recent tag in this tree
  • +git means we’re taking source from a repository rather than a release
  • 134 means how far we are from the tagged version… much better for humans than the next
  • g27f30d5 is the exact revision used, and can probably be omitted in this context as it’s long and ugly
  • dirty is also omitted because it’s ugly and helps little (snap may have changes later anyway)

Ok, I think we are on the same page it’s just that if I run that on the snapcraft tree on a clean master I get something like this:

./mkversion.sh 
*** Setting version to '3f5c735f' from git.

And it seems to be due to git describe missing --tags to match the way we are tagging. That said, I will start using annotated tags from now on.

So I agree with the objective :wink: Thanks for approaching this the other way around.

1 Like

Here’s the PR that implements version: git support:

https://github.com/snapcore/snapcraft/pull/1260

The tests should be rather informative on how the mechanics work.

This only covers the case where the snapcraft.yaml is in the git repo whose version you care about, right?

Right, more PRs will follow with the other stuff; please see if my edit of the original post (converted to wiki) still satisfies your needs.

Ah yes, that looks great (I follow the forum in mailing list mode, so I wasn’t aware of the edits). Thanks!

Version override support through version-script is here.
https://github.com/snapcore/snapcraft/pull/1267

Did this feature get documented? It seems to be released in snapcraft 2.29 but I can’t find anything in the snapcraft.io documentation.

The current implementation is a little problematic and confusing. In my understanding version-script supersedes the existing and mandatory version field but when I use the environment variable SNAPCRAFT_PROJECT_VERSION in a plugin, its value refers to the previously superseded field, version.

Think of a case where dump plugin downloads a zip file from a dynamic URL based on the version number. Currently this results in a practically static URL because SNAPCRAFT_PROJECT_VERSION always refers to the hard-coded value of version field.

I have a packaging example here that elaborates the issue I am talking above.

A simple solution in my opinion would be to to call version-script block at the very start and export its returned value as SNAPCRAFT_PROJECT_VERSION.

The reason is, version-script was created to set a version in the metadata from information set from built sources, you are trying to use it the other way around, this won’t be possible with this implementation, ever.

It may find its way when the pre and post work taking into account the setting of metadata through setters takes place (Scripting and setting metadata in snapcraft), that work should start to be surfaced around January.

Hi @sergiusens. I don’t think this behaviour has been documented on the main site yet, and does seem to be slightly broken as per https://bugs.launchpad.net/snapcraft/+bug/1769519 . Would it be possible to patch the behaviour to deal with invalid characters such as underscores in git tags?

1 Like