Skip to content

Analysis of tar_git

olf edited this page Sep 9, 2024 · 11 revisions

obs-service-tar-git

Jolla's OBS tar_git source service

Note that this README is not an exhaustive description or even a specification. It is merely a user contributed write-up providing some guidance how tar_git works. This write-up may have weaknesses or be erroneous at places; if you want to know something for sure, please read tar_git's interface definition and its shell script which provides all functionality.

Side note: This is not about the regular OBS (Open Build Service) services (plug-in modules) tar_scm or git_tar. The only publicly visible place where tar_git runs is the SailfishOS-OBS at build.sailfishos.org (= build.merproject.org), where it is the primary and mandatory service.

Parameters for OBS _service files

See tar_git's interface definition, its usage output for descriptions of the parameters and an exemplary _service file.

Git tag parsing

I went through its state as of 2020-12-14 to (at least) 2023-03-15 until I fully understood the parsing of tags:

  1. A valid Git tag for tar_git may be prefixed by either a small letter v or a "vendor string" ending in a slash (/), see first part of the function get_tagver_from_tag: Both are cut out, a v is discarded, but a "vendor string" is prepended (without the slash) to the release field in the spec file (but see 6.).
  2. A valid Git tag for tar_git may contain at most a single dash (-). If the sub-string starting with the dash conforms to the extended regular expression (ERE) \-[[:alnum:]]+$, tar_git puts it into the release field (without the dash and directly appended to a "vendor string") and the part up to the dash into the version field. Hence a valid tag can be used to fully rewrite the version and release fields in the spec file, before OBS builds this package (but see 6.), see second part of the function get_tagver_from_tag.
  3. The resulting, stripped tag must conform to the extended regular expression (ERE) ^[[:digit:]]+\.[[:alnum:].~+]*$ (but is actually written much more complicated) and originate from the branch provided by the branch parameter, otherwise it is discarded.
    But mind this issue, that the tar_git script does not obey the branch parameter, if there is no valid tag (according to tar_git's processing rules) or if a commit ID (short-hash) was provided, or if a branch parameter is set and either no revision is set or in this Git branch commits exist newer than the tag referenced by the revision parameter.
  4. If there is no valid tag or if a commit ID (short-hash) was provided, or if a branch parameter is set and either no revision is set or in this Git branch commits exist newer than the tag referenced by the revision parameter, then tar_git looks for the "closest" tag in the function set_versha which fulfils aforementioned rules (i.e. runs through steps 1 to 3 with it), but misses to filter for the branch provided by the branch parameter (i.e. it searches in all branches). Still, it uses the value of the branch parameter, or if none is provided, the branch name in which the "closest" tag was found to construct a new version string, which comprises: The processed name of the "closest" tag, a +, the branch name, a ., a date-time string (YYYYMMDDhhmmss), the number of commits since the "closest" tag in the branch it resides enclosed in dots .<n>., a g if newer commits exist in the branch referenced by branch than the tag referenced by revision, and the short-hash of the latest commit, resulting in, e.g. 0.5.2+main.20230129011931.6.g584263a with 0.5.2-3 as "closest" tag found.
    But mind this issue, that if the "closest" tag determined does not originate from the branch provided by the branch parameter, still this parameter is inserted in the constructed string, despite using a Git checkout from another branch.
  5. The result of this processing replaces the original Version: string in the RPM spec file, which can be viewed on a package's page in the SailfishOS-OBS.
  6. Note that, when a package is built by the SailfishOS-OBS, also a new release string is constructed, comprising a 1., the package revision at OBS, another . as separator, the number of builds for this revision of the package (i.e. the number of re-builds is one less), and .jolla. This is not visible in the processed RPM spec file of a package, because it is done while building a package.

Examples

Once understood how tar_git's parsing of Git tags works, one can play with it: For 1.2.3+git1, 1.2.3~git1 and 1.2.3.git1 the whole string will be used as the processed <version> string and become part of the RPM file-name; for 1.2.3-git4, git4/1.2.3 and git/1.2.3-4 only the 1.2.3 will, and the release field will be initially set to git4 for the latter three examples (which is later substituted by 1.I.1).

As an "real life" example, when using sfos4.2/0.3.0-5 as a tag name for the harbour-storeman app, this results in, e.g. harbour-storeman-0.3.0-1.13.1.jolla.armv7hl.rpm as a final package name.

Counter-examples

Because older release tags for harbour-storeman always contained two dashes, they were discarded and the alternate code path found v0.2.12-master as the newest "valid" tag (although referring to the master branch instead one of the release branches the branch parameter was set to) and used by tar_git.

The token parameter

When the token parameter contains a non-empty string (not a regular expression), this string is used as a sub-string an original (i.e. unprocessed) Git tag must match to, otherwise the tag is discarded. Note that such a Git tag is then subjected to the processing described in steps 1 to 4, above. Hence for the aforementioned example using the harbour-storeman app, sfos would be a suitable token. Or when marking release versions with the string release in Git tags (e.g. 1.2.3-release2), the string release is a suitable token to filter for.
But mind this issue, that tar_git's parameter token currently fails to filter for /.

Source archive name

tar_git always renames the source archive to <name>-<version>.<extension>, using the processed Git tag as <version>. While retaining the name and the extension, there is no way to achieve <name>-<version>-<release>.<extension> as its source archive, because the processing prevents any dashes (-) to be retained in the processed <version> string. If no valid {https|http|ftp} path to a source archive is provided, it performs a Git check-out using the tag determined as described above.

Hence the %prep section of a spec file must contain %autosetup or %setup [-q] [-n %{name}-%{version}], but no other parameter can be used for the option -n (which might as well be omitted, because this is the default format string) and -q is demanded by most spec file linters (e.g. rpmlint)!

Changelog extraction / processing

<ToDo>
This open <ToDo> WRT changelog extraction / processing is briefly, but not at all conclusively addressed in sailfishos-patches/patchmanager#327.

Notes