Table of Contents

No. jenkins-debian-glue is not a replacement for providing a debian/ directory inside the project you want to build.

There are four main approaches how to build a Debian package:

  1. build a binary package locally, no chroot/cowbuilder-like environment
  2. build a binary package locally, chroot/cowbuilder-like environment
  3. build a source package locally, upload result to build environment
  4. no local builds at all, changes are committed to a version control system and handled centrally then

Approaches #1-3 are broken by design. The results might differ depending on what's available on your local system (uncommitted files laying around), what packages are available on your system (different build-dependencies), how recent your build environment is (forgot to update it), etc.

Approach #4 is the most sane one (only what's available under version control matters, centrally maintained build environments, policy and Q/A tests,...) and it's the one jenkins-debian-glue is to solve.

Last but not least - why should you build stuff manually at all? Computers are there to do that for you, so why not just commit your changes to the version control system and let them figure out the rest for you?

Currently Git and Subversion are supported. The author of jenkins-debian-glue is aware of people working on Bazaar support. Support for further version control systems is welcome, check out the the existing generate-*-snapshot scripts if you're interested in how they work.

Background story: Git is the version control system we're using for the Grml project where we heavily rely on Jenkins in our development and release pipeline. Development on subversion support was sponsored by Sipwise. By supporting Git and Subversion we are targeting for more than 9000 packages available in Debian. representing more than 90% of the VCS managed packages. See 'Use of VCS in Debian packages' for more information regarding those stats.

cowbuilder is a wrapper for pbuilder, which itself is a tool for building Debian packages inside a clean chroot. Building Debian packages inside clean and reproducable environments is an important step in the philosophy of Debian packaging as well as Continuous Integration and Continuous Delivery.

No worries though, jenkins-debian-glue abstracts all the cowbuilder magic away for you.

No. jenkins-debian-glue works on top of cowbuilder (which itself uses pbuilder/cowdancer). It neither replaces cowbuilder nor tries to do so. jenkins-debian-glue provides the layer between your version controlled Debian packages, building them with cowbuilder and integrating that in Jenkins.

Jenkins is one of the leading continuous integration servers, being available under an open source license and a vibrant community around it. It provides an easy to use web interface as well as enterpriseā„¢-ready integration. This provides a perfect continous integration system for jenkins-debian-glue to address individual developers as well as big developer teams.

Yes. It's about building .deb files, not about being restricted to the Debian system. You can build packages for Debian on your Ubuntu system and also build packages for Ubuntu on your Debian system. Actually every distribution should work where cowbuilder & related tools are available.

No. jenkins-debian-glue is limited to Debian packages currently. If you want to get something like jenkins-debian-glue for RPMs please talk to the author.

jenkins-debian-glue makes use of environment variables wherever feasible. Environment variables are an important concept within Jenkins jobs, especially when dealing with Matrix Jobs and Copy artifacts (where you can copy stuff e.g. with foobar-source/distribution=$distribution) as well as when you're considering usage of plugins like EnvInject.

The easiest way to access the console output is choosing the "Last build" URL under the "Permalinks" section at the bottom of you Jenkins job, which usually corresponds to http://$JENKINS_SERVER/job/$JOBNAME/lastBuild/console. This URL contains the "lastBuild" keyword instead of hardcoding a specific build number so you just need to choose reload in your browser to get the most current version.

To locate this URL from the Jenkins web interface choose 'Last build':

Screenshot of permalinks in Jenkins

On the left side on the bottom you'll find a link named "Console Output" then, choose this one:

Screenshot of console output in Jenkins

Locating the console output of Matrix builds sadly is not obvious. You have to visit the according Matrix axe configurations which are listed under the "Configurations" section of your Jenkins job. If you have just one axis inside your Jenkins job configuration it wil be named "default":

Axis configuration in Jenkins

Or if you have multiple axes assigned then you'll find them listed below "Configurations" as well, like:

Screenshot of multiarch configuration

Inside the Matrix configurations you'll find the usual "Permalinks" as documented in the previous section of this FAQ.

Once you start up scaling with Debian package builds with several nodes you don't want to include the Debian package(s) on the same node as you're building (for obvious reasons).

The build-and-provide-package script does support such distributed builds by using the BUILD_ONLY and PROVIDE_ONLY variables. Usage example for the *-binaries job:

export BUILD_ONLY=true
export SUDO_CMD=sudo

Create a *-repos job which gets triggered from the *-binaries job. Don't forget to use "Copy artifacts from another project" (copying the files from the *-binaries job) there. Assign the *-repos job to the node which provides the Debian repository so it gets executed only on the system it should be executed on.

Inside the *-repos job you can use something like:

mkdir -p binaries

for suffix in gz bz2 xz deb dsc changes ; do
  mv */*.${suffix} binaries/ || true

# if building a tagged version then do not include that one in the release-trunk repository
case "$branch" in tags/*|branches/*) export IGNORE_RELEASE_TRUNK=true;; esac

export SUDO_CMD=sudo
export BASE_PATH="binaries/"
export PROVIDE_ONLY=true

If you need further Jenkins jobs for the same package you can achieve that by setting the REPOS environment variable. Let's assume you already have the Jenkins jobs foobar-source and foobar-binaries for a software package called foobar. To use foobar with different settings as project foobar-testing all you've to do is setting the REPOS environment variable inside the build steps of the Jenkins job. Usage example for foobar-testing-binaries:

export REPOS="${JOB_NAME%-testing-binaries*}"
sudo /usr/bin/generate-reprepro-codename "${REPOS}"

Make sure you're using recent versions of cowbuilder and its underlying pbuilder. Some features like '[linux-any]' in Build-Depends might not be available in the cowbuilder/pbuilder version used in Debian/squeeze yet, so make sure you install cowbuilder/pbuilder from Debian/testing and/or Debian/unstable.

If you notice 'pbuilder create failed' in the build log then you might be building a Debian unstable cowbuilder environment at a time where some dependencies cause bootstrap errors. To avoid this manually install the cowbuilder base.cow using the command line present in your build log but replace sid with squeeze and manually upgrade the cowbuilder environment to Debian unstable/sid then.

Yes. This feature is provided through so called release builds. In release builds you add a release repository name through the "$release" variable to the source job which is then handed over to the binaries job. The binaries job then takes care of installing the Debian packages to the repository as specified by the "$release" variable instead of installing them into their own repository. This feature is especially handy if you trigger several Jenkins jobs for different (Debian) packages - e.g. from a central place (like your own dashboard) - and want to collect all of them in one single place (e.g. to get a full release build).

NOTE: Starting with version 0.5.0 of jenkins-debian-glue it's possible to set the path for the release repository using $RELEASE_REPOSITORY (if unset defaults to ${REPOSITORY}/release/${release}).

First of all make sure you have the Parameterized Trigger plugin installed. Then add "This build is parameterized" in the source job with String parameters as follows:

Name: release
Default value: none
release version if the results should be part of a release (otherwise leave it at 'none')

Enable "Trigger parameterized build on other projects" with settings as follows (replace $JOBNAME-binaries accordingly):

Projects to build: $JOBNAME-binaries
Trigger when build is: Stable or unstable but not failed
Trigger build without parameters [ ]

and set "Predefined parameters" to:


That's it. Now you can replace the "none" with your specific release build name when triggering a new source job.

While building amd64 and i386 can be done on one single 64bit build system you can't build e.g. packages for the sparc architecture on the same host any longer. To get such a setup up and running you need to extend the Matrix job configuration of your binaries Jenkins job to include all the architectures that should be supported. Then make sure your Jenkins slave nodes have according label names, like "amd64", "i386" and "sparc" so you can assign specific builds to specific slaves.

Then enable the "Combination Filter" to execute the according architecture builds only on the according hosts, like:

(label=="sparc").implies(architecture=="sparc") && (label=="amd64").implies(architecture=="amd64") && (label=="i386").implies(architecture=="i386")

Screenshot of such a configuration:

Screenshot of advanced multiarch configuration in Jenkins

This should give you a Matrix job execution like:

Screenshot of matrix build result

The *-source job using generate-git-snapshot might fail with:

+ git-buildpackage -nc --git-force-create --git-ignore-new --git-ignore-branch -S -us -uc --git-verbose [...]
gbp:debug: ['git', 'rev-parse', '--show-cdup']
gbp:debug: ['git', 'rev-parse', '--is-bare-repository']
gbp:debug: /bin/true [] []
gbp:debug: ['git', 'symbolic-ref', 'HEAD']
gbp:debug: ['git', 'show-ref', 'refs/heads/jenkins-debian-glue-buildbranch18981']
gbp:debug: ['git', 'show-ref', 'refs/heads/pristine-tar']
gbp:debug: ['git', 'ls-tree', 'upstream/0.42']
fatal: Not a valid object name upstream/0.42
Build step 'Execute shell' marked build as failure

This means you're lacking the according tag in your Git repository ('upstream/0.42' in the above example), make sure to push the tags (e.g. via 'git push --tags'). generate-git-snapshot assumes you're using the default git-buildpackage workflow.

Fork me on GitHub