Using Jenkins BUILD NUMBER in RPM spec file
Asked Answered
S

4

8
Name:                   My Software
Version:                1.0.5
Release:                1
Summary:                This is my software

Not sure if anyone has tried this before or if it is easy, but:

A spec file has two unique indicators for its version:

  • Version (which specifies software version)
  • Release (which specifies the package's number - if you build an RPM, it's broken, and build another one, you up the 'Release' number.

I'm wondering if anyone has tried, or knows how, I could use the Jenkins $BUILD_NUMBER variable to dynamically change the Release number, thereby increasing the Release number every time a new successful build completes...?

Semipermeable answered 22/4, 2013 at 20:8 Comment(4)
sed -i "s/VERSION/$BUILD_NUMBER/" rpm.specDarcydarda
you do not want to sed teh .spec file... it (should) be under source control, so the build shouldn't change it.Trestle
try fpm, so much better than spec files 80% of the time!Afterthought
Hmm. Will have to look in to fpm. So far, the method mentioned by @Trestle has worked.Semipermeable
T
7

It's been a long time... and thankfully I have no rpm based systems so I can't test this.

You can pass parameters to rpmbuild on the commandline

rpmbuild --define="version ${env.BUILD_NUMBER}"

It would be helpful to post snippets of the spec and the script you're using to build the rpm. You don't want your build script editing the spec file, which I'm assuming it's pulling out down from some source control.

Trestle answered 22/4, 2013 at 21:36 Comment(4)
The spec file is in source control, yes. I understand the need for not changing anything in the spec file using the build script. On the other hand, everytime we have a build, I have to change the spec file manually and check it in, and make all the other associated changes. Having it change automatically would make it so much easier... :\Semipermeable
yes... that's why you have the build pass it in, and just leave some bogus value in the spec file, like 9.9.9-1 so it will be very apparent that the build didn't inject the proper versionTrestle
That didn't work. I tried both --define="Release = ${BUILD_NUMBER}" and --define="Release ${BUILD_NUMBER}" as mentioned in the rpmbuild help.Semipermeable
Got it. I had to change the value for "Release" to be a macro. Basically, change the line to "Release: %{release}" and then use your answer. Thanks!!Semipermeable
A
3

I've been using the Jenkins build number as the 'release' and packaging via fpm.

Couple fpm with some globals provided by Jenkins

# $BUILD_ID - The current build id, such as "2005-08-22_23-59-59" (YYYY-MM-DD_hh-mm-ss)
# $BUILD_NUMBER - The current build number, such as "153"
# $BUILD_TAG - String of jenkins-${JOB_NAME}-${BUILD_NUMBER}. Convenient to put into a resource file, a jar file, etc for easier identification.

There's some nebulous variables in the example command below, but $BUILD_NUMBER is what I'm using for the release here (fpm calls it iteration instead).

fpm_out=$(fpm -a all -n $real_pkg_name -v $version -t rpm -s dir --iteration $BUILD_NUMBER ./*)
Afterthought answered 9/12, 2013 at 14:27 Comment(0)
S
3

In my Jenkins setup, I've decided to bypass the build number with regards to the RPM version numbering completely. Instead, I use a home-made script that generates and keeps track of the various releases that are being generated.

In my spec file:

Version:    %{_iv_pkg_version}
Release:    %{_iv_pkg_release}%{?dist}

And in the Jenkins build script:

# Just initialising some variables, and retrieving the release number.
package="$JOB_NAME"
# We use setuptools, so we can query the package version like so.
# Use other means to suit your needs.
pkg_version="$(python setup.py --version)"
pkg_release="$(rpm-release-number.py "$package" "$pkg_version")"

# Creating the src.rpm (ignore the spec file variables)
rpmbuild --define "_iv_pkg_version $pkg_version" \
    --define "_iv_pkg_release $pkg_release" \
    -bs "path/to/my/file.spec"

# Use mock to build the package in a clean chroot
mock -r epel-6-x86_64 --define "_iv_pkg_version $pkg_version" \
    --define "_iv_pkg_release $pkg_release" \
    "path/to/my/file.src.rpm"

rpm-release-number.py is a simple script that maintains a file-based database (in JSON format, for easy maintenance). It can handle being run at the same time, so no worries there, but it won't work if you have build slaves (as far as I can tell, I don't use them so can't test). You can find the source code and documentation here.

The result is that I get the following package versioning scheme:

# Build the same version 3 times
foo-1.1-1
foo-1.1-2
foo-1.1-3
# Increment the version number, and build twice
foo-1.2-1
foo-1.2-2

PS: Note that the Jenkins build script is just an example, the logic behind creating the rpmbuild directory structure and retrieving the .src.rpm and .spec file names is a bit more complicated.

Segmentation answered 4/2, 2014 at 13:28 Comment(0)
F
-1

Taking into account that spec file could be 3rd-party I prefer to do pre-build sed-patching of Release field:

sed -i 's/^Release:\(\s*\)\(.*\)$/Release:\1%{?_build_num:%{_build_num}.}%{expand:\2}/g' ./path/to/spec
rpmbuild --define '_build_num $BUILD_NUM' -ba ./path/to/spec

Here %{expand:...} macro is used to handle macro defined release numbers like ones in Mageia specs:

Release: %mkrel 1

Resulting field will be:

Release: %{?_build_num:%{_build_num}.}%{expand:%mkrel 1}

Conditional expansion of _build_num macro makes spec still usable for local build. I.e. if SRPM is also prepared by build system. But it could be reduced to:

sed -i 's/^Release:\(\s*\)\(.*\)$/Release:\1'$BUILD_NUM'.%{expand:\2}/g' ./path/to/spec
rpmbuild -ba ./path/to/spec
Forsooth answered 13/11, 2019 at 19:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.