Snapcraft version scripts

the problem here is that this will not help when your variable content gets only available later in the process, after the scriptlet runs.

as an example, we want to set the snapd deb version included in the core snap as an attribute of the version string of the snap (i.e. 16-2.45.3-git16513). the information for that version string is only available at the very end of the process where we currently can not run any scripts anymore.

so here we either need a scriptlet that runs later or (as suggested above) a variable that simply overrides any existing version string when set.

Environment variables mean that each CI system would need to understand this, so the logic gets split in two. That would be my only objection.

Yes, I don’t think variables would solve the problem. The main goal is to to allow some small tuning along the way. Setting variables early on would mean the tuning is done early on, not when the content is actually available (think changing a file, or creating a directory, or calling a specific executable, etc).

Two questions:

  1. What examples are there where the snap’s version information wouldn’t be available after the pull step?

  2. What examples are there where we would need the snap’s version information before the pull step?

In all of the upstreams snaps I’ve worked on, I believe that having a script run between the pull and build steps would accomplish the goals expressed here.

depends if you want it to affect the $SNAPCRAFT_PROJECT_VERSION exported variable or not, and here is an example:

name: asciinema
version: 1.3.0

...
parts:
    asciinema:
        plugin: python
        python-packages:
            - $SNAPCRAFT_PROJECT_NAME==$SNAPCRAFT_PROJECT_VERSION

If we change the version after pull, all deals about the consistency of this variable are gone. I am not so keen about updating beween steps and would prefer it be very explicit (such as the -override suggestion).

In this example you’re using the variable to avoid duplication of the already-known version number in multiple places, which seems like a different problem than needing to discover a version number you don’t know when you create the snapcraft.yaml

right, but imagine changing the meaning of that variable. If the requirement is after pull, then I guess it will only be applied to the version field in snap.yaml and not exposed in other places to avoid confusion.

@mhall119 Ironically, here is an example of a case after pull:

That could be run as soon as you have the code through right? Meaning, immediately after the pull step, and before the build step?

The point is that the code ships with a VERSION file in the local directory that is dynamically created during the build procedure. It’s much easier to build and cat VERSION than to find out what else to do and then ensure it’s actually safe to do so.

So essentially, version-script should be evaluated after build, to which point I’d say we do it after stage.

1 Like
  • any build that generates a version during build using some mkversion.sh script.
  • anything that pulls an external sub-tree via the build scripts and uses a version string extension from that (imagine: kodi-1.2.3-ffmpeg-0.0+git87235).
  • our core snap (for which we want the snapd version in the version string in the future). which uses several stacked chroots for getting a clean build environment, the info is only available in the innermost chroot at the end of the build step.
1 Like

Not sure if after stage, but within its step perhaps. Otherwise we’d be staging the wrong meta/snap.yaml file.

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)?