Browse Source

README: drop docs, point to

Michael Prokop 10 years ago
  1. 420


@ -1,419 +1 @@
* Project Idea
jenkins-debian-glue provides scripts for building Debian packages via Jenkins
(a Continuous integration / delivery system). It tries to minimize the
required steps to get it up and running and keep it as manageable and
homogeneous as possible.
* System requirements
+ [[][Jenkins]]
+ [[][Debian]] / [[][Ubuntu]]
+ [[][cowbuilder]], [[][reprepro]] and [[][sudo]] (all available via apt-get/aptitude)
Debian packages of jenkins-debian-glue are available at for your service.
* Setup instructions
jenkins-debian-glue assumes two (or optionally more) Jenkins jobs for each software package. One job builds the Debian source package, this is the source job. Assuming the software package is named /foobar/ then its source job is assumed to be /foobar-source/. The other job builds the Debian binary package(s), this is the binaries job. Once again assuming we're talking about the /foobar/ software package then the binaries job is assumed to be /foobar-binaries/.
Setting up those jobs is really quite simple. Just follow the following steps and you should have a working system in less than 10 minutes.
** Install "Copy Artifact Plugin"
The [[][Copy Artifact Plugin]] (install it via http://$JENKINS_SERVER/pluginManager/available or through the [[][jenkins-cli.jar]]'s install-plugin option on the command line) provides the option to deploy artifacts from the source job to the binaries job. Make sure it's installed so you get the "Copy artifacts from another project" option as "Build" step, used in the following steps.
** Install "Jenkins Workspace Cleanup Plugin"
The [[][Jenkins Workspace Cleanup Plugin]] provides the "Delete
workspace before build starts" option which is useful for getting rid of files from previous runs.
** Source job configuration (foobar-source)
jenkins-debian-glue provides scripts to handle Debian packages managed in Git (via /generate-git-snapshot/) and Subversion (via /generate-svn-snapshot/). Before you're creating a new Jenkins job please make sure you've the dependencies installed, follow "Debian packages managed in Git" and/or "Debian packages managed in Subversion" accordingly.
*** Debian packages managed in Git
Make sure the "Git Plugin" is installed in Jenkins. On the build system you need git-buildpackage and a basic Git configuration for the user under which Jenkins is running (usually being 'jenkins'):
# apt-get install git-buildpackage
Then either adjust the "Git plugin" settings at http://$JENKINS_SERVER/configure or manually execute:
# su - jenkins
% git config --global ""
% git config --global "Jenkins User"
*** Debian packages managed in Subversion
The "Subversion Plugin" is shipped by Jenkins out of the box nowadays, but to use it with Debian packages please make sure you've subversion-tools available on the build system:
: # apt-get install subversion-tools
*** Create a Jenkins source job
Create a new job using the 'Build a free-style software project' option in Jenkins. If your software is named /foobar/ then use /foobar-source/ for the job name. Then enable and configure 'URL of repository' of the according version control system under 'Source Code Management' to automatically check out sources.
*Important*: For git, set the "/Local subdirectory for repo (optional)/" option under /Advanced/ settings to "/source/". For svn, set "/Local module directory (optional)/" to "/source/".
In the "/Build/" section add a build step "/Execute shell/" as follows to get rid of files from previous runs without removing the VCS checkout:
rm -f ./* || true
NOTE: the "Delete workspace before build starts" option provided by the [[][Jenkins Workspace Cleanup Plugin]] works as well, though it also removes the repository checkout so build time might increase.
Then add another build step of "/Execute shell/" as follows:
# when using git:
# when using subversion:
# /usr/bin/generate-svn-snapshot
Under "/Post-build Actions/" select "/Archive the artifacts/" using:
: *.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes
Enable "/Record fingerprints of files to track usage/" and its "/Fingerprint all archived artifacts/" setting.
** Binaries job configuration (foobar-binaries)
Add a new "/Build multi-configuration project/" Jenkins job named /foobar-binaries/ (assuming your project is named /foobar/).
Enable "/Build after other projects are built/" under /Build Triggers/ and choose the name of the source job, being /foobar-source/ in this example.
Under /Configuration Matrix/ create a user-defined Axis titled "/architecture/" specifying the architectures your Debian packages should be built for. If you're running an amd64 system (recommended nowadays) then /amd64/ should be your default choice no matter what. If you also want to build Debian packages for i386 then add /i386/.
Choose "/Run each configuration sequentially/".
In the /Build Environment/ section enable the "Delete workspace before build starts" option (provided by the Workspace Cleanup Plugin).
In the "/Build/" section add a build step "/Copy artifacts from another project/" using:
: Project name: $JOBNAME-source
: Which build: "/Upstream build that triggered this job/"
: [x] "Last successful build"
: Artifacts to copy: *
: Target directory:
Screenshot for this /Copy artifacts/ configuration:
In the "/Build/" section add a build step "/Execute shell/" using:
Under "/Post-build Actions/" select "/Archive the artifacts/" using:
: *.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes
** Configure sudo
To be able to execute cowbuilder as user /jenkins/ adjust /etc/sudoers using visudo(8):
: jenkins ALL=NOPASSWD: /usr/sbin/cowbuilder, /usr/sbin/chroot
Create //srv/repository/ and provide write permissions to jenkins user:
: # mkdir /srv/repository
: # chown jenkins /srv/repository
*Alright - you're done!* Now Jenkins can build Debian packages for you.
** Build Debian packages
Visit the source Job and choose "/Build Now/". This will start building the Debian source package and if that works as expected it will automatically trigger building the Debian binary package(s). The first run might take some time because you're checking out the source from your VCS for the first time and setting up the cowbuilder environment also takes some time. Once you're past this stage rebuilding should be damn fast, just depending on your network and system speed.
To use the local Debian repository just add an entry to your //etc/apt/sources.list.d/foobar.list/, like:
: deb file:/srv/repository/ foobar main
To use the Debian repository from remote systems you can install a web server, symlink the repository to the webserver share via e.g.:
: ln -s /srv/repository/ /var/www/debian
and point //etc/apt/sources.list/foobar.list/ to it:
: deb http://$JENKINS_SERVER/debian/ foobar main
** Enable Lintian reports
[[][Lintian]] dissects Debian packages and tries to find bugs and policy violations. It contains automated checks for many aspects of Debian policy as well as some checks for common errors which turns out to be very useful for inclusion in Continuous Integration/Delivery infrastructures.
To enable Lintian reports for your jenkins-debian-glue jobs add the following "/Execute shell/" build step at the end of the build steps in your *-source and *-binaries Jenkins jobs:
mkdir -p report
/usr/bin/lintian-junit-report *.dsc > report/lintian.xml
and add "**/lintian.txt" to the list of artifacts to archive.
Enable the "/Publish JUnit test result report/" Post-build action and select "**/lintian.xml" for the files to report.
Then you should get test reports for your Debian packages based on lintian's output.
* Configuration options
** System wide via /etc/jenkins/debian_glue
+ /KEY_ID/: setting this variable automatically signs repository with the specified GnuPG key ID. Please notice that already existing repositories won't be touched. If you set up a GnuPG key and the /KEY_ID/ configuration after a repository was created (will be done on first execution of /build-and-provide-package/ for a given binary job) make sure to manually add /SignWith: ${KEY_ID}/ to your repository configuration ("//srv/repository/conf/distributions//" by default).
+ /MAIN_ARCHITECTURE/: if you are building Debian packages for more than one architecture you can control which architecture should be used as main one. The main architecture setting controls which architecture should be used as the one providing the architecture independent Debian packages (like /foobar_0.42-1_all.deb/). If unset it defaults to the architecture your build system is running.
+ /REPOSITORY/: the directory where your Debian repository will be placed at. Defaults to "//srv/repository//".
+ /TRUNK_RELEASE/: if you want to get a copy of all generated Debian packages in one single distribution you can set /TRUNK_RELEASE/ to something like "/release-trunk/". The repository will be automatically set up if it doesn't exist yet.
** Supported in build-and-provide-package
+ /architecture/: controls for which architectures Debian packages should be built.
+ /distribution/: controls Debian version that should be used for the cowbuilder environment (defaults to the host's distribution if unset).
+ /release/: install Debian package in repository name as specified via "$release" instead of the default (being $REPOS), see "/Can I collect multiple Debian packages in one single repository?/" in the FAQ section for further details.
+ /BASE_PATH/: use specified directory as base directory for further actions. Defaults to "${WORKSPACE}" if unset. Adjust it if you e.g. have a customized "Target directory" in the "Copy artifacts from another project" configuration.
+ /BUILD_ONLY/: execute the steps building Debian binary package(s) but skip the repository setup/inclusion steps (useful for building the package(s) on slave nodes and including the result on a different node later then)
+ /COMPONENTS/: the specified repository components will be enabled when creating a new cowbuilder base.cow. If unset defaults to pbuilder's defaults (the underlying system of cowbuilder). Notice that on Ubuntu systems /COMPONENTS/ will be automatically set to "main universe" (if /COMPONENTS/ isn't set yet) to work around a cowdancer issue.
+ /COWBUILDER_BASE/: set path for cowbuilder's base.cow, defaults to //var/cache/pbuilder/base-${COWBUILDER_DIST}-${arch}.cow/ whereas /COWBUILDER_DIST/ depends on its according variable and /arch/ depends on /architecture/ (though doesn't match it if it's set to "all").
+ /COWBUILDER_DIST/: distribution that should be used for creating the cowbuilder base.cow. If /distribution/ is set COWBUILDER_DIST defaults to that, otherwise defaults to the currently running distribution and if that can't be determined then falls back to "sid" (being Debian/unstable).
+ /PROVIDE_ONLY/: skip the steps building Debian binary package(s) and just run the repository setup/inclusion steps (useful if building the package(s) takes place on slave nodes and the result should by included in repository/repositories on a specific node then)
+ /REPOS/: controls the repository name used for the binary job. Defaults to the Jenkins job name without trailing "/-binaries/" and without trailing "/-repos/".
+ /SUDO_CMD/: if this variable is set then reprepro and related actions will be executed under $SUDO_CMD. If the jenkins user doesn't have write permissions to the repository and related settings then you might consider setting "export SUDO_CMD=sudo" in your Build step.
** Supported in generate-git-snapshot
+ /DEBEMAIL/: user configuration to be used for generating new entries in debian/changelog (defaults to "jenkins-debian-glue Autobuilder <>")
+ /DCH_OPTS/: use custom git-dch options instead of the defaults.
+ /DCH_EXTRA_OPTS/: use additional custom git-dch options.
** Supported in generate-reprepro-codename
+ /SUDO_CMD/: if this variable is set then reprepro and related actions will be executed under $SUDO_CMD. If the jenkins user doesn't have write permissions to the repository and related settings then you might consider setting "export SUDO_CMD=sudo" in your Build step.
* Tips and Tricks / Advanced configuration
+ Reduce disk usage: enable "/Discard Old Builds/" and set "/Max # of builds to keep/" to something like 15 to keep disk usage at a sane level.
+ For building the Debian package using different branches enable the "This build is parameterized" option in the source job. Add String Parameter settings as follows (replace Git's /master/ with /trunk/ when using Subversion):
: Name: branch
: Default value: master
: Description: branch to build (trunk, tags/...)
This allows you to choose the branch name that should be used for building the Debian source package.
+ Install and use the [[][Configuration Slicing Plugin]] to perform mass configuration of your source and binaries jobs.
+ Enable "/Trigger builds remotely (e.g., from scripts)/" under Build Triggers and set an user-defined authentication token. The /svn/ and /git/ directory of the jenkins-debian-glue source provide examples for VCS hooks to trigger remote builds on each commit.
+ To avoid polling for updates in VCS either trigger the builds remotely (see previous bullet) or if you're using Github for your Git repository use the [[][Github Plugin]] with its "/Build when a change is pushed to GitHub/" option.
* Scripts description
+ *build-and-provide-package*: uses the dsc file for building a binary package for the specified /$architecture/ of the matrix build using cowbuilder. The resulting binary package will be installed in reprepro to provide it for usage via APT.
+ *generate-git-snapshot*: generates a snapshot version of a Debian package using git-dch. Use 'auto' as command line option to use git-dch's magic to build changelog, without the 'auto' option the version string will be build based on last tag/merge.
+ *generate-reprepro-codename*: takes a repository/codename as command line option and adds an according repository/codename definition to //srv/repository/conf/distributions/ (iff the codename is not present yet).
+ *generate-svn-snapshot*: generates snapshot version of a Debian package using svn log, svn2cl and some dirty shell magic.
+ *increase-version-number*: takes a version number as command line argument and raises the version number for usage inside as a new snapshot version. Nowadays the script just adds "+0" to the version number, so when running the script with "0.42" the output will be "0.42+0". (Disclaimer: This script used to be more sophisticated but turned out to fail in some situations, the +0 approach usually just works and the script is there to provide a central place to handle version number management.)
+ *lintian-junit-report*: run Debian package checks using lintian and report in JUnit format (and provide a plaintext copy of the output inside file /lintian.txt/).
+ *repository_checker*: provides simple access to codename/repository and package listings (without the need to know how to handle reprepro) as well as an option to verify whether Debian source packages match with binary package versions.
** Where do I find the console output?
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":
On the left side on the bottom you'll find a link named "Console Output" then, choose this one:
** Where do I find the console output of my *-binaries Job / Matrix build?
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":
Or if you have multiple axes assigned then you'll find them listed below "Configurations" as well, like:
Inside the Matrix configurations you'll find the usual "Permalinks" as documented in the previous section of this FAQ.
** How can I build binary packages on some slave nodes and use the repository on a different system?
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
** How can I add multiple Jenkins jobs for the same software package?
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}"
** I've problems building Debian packages against Debian/unstable
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.
** Building the initial cowbuilder environment fails
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.
** Can I collect multiple Debian packages in one single repository?
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 from a central place (like your own dashboard) to get a full release build.
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:
: release=${release}
That's it. Now you can replace the "none" with your specific release build name when triggering a new source job.
** How do I build Debian packages for specific architectures/distributions which require specific features on a build host?
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:
This should give you a Matrix job execution like:
* Contributors
+ Thomas Clavier <>
+ Alexander Wirt <>
+ Christoph Berg <>
+ Christian Hofstaedtler <>
+ Axel Beckert <>
* Known installations driven by jenkins-debian-glue
+ [[][]]
+ [[][]]
+ [[][]]
+ [[][]]
+ Internal system at [[][Sipwise]]
* License
Copyright (c) 2011,2012 Michael Prokop <>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
Please head over to [[][]] for setup instructions and documentation.