Jenkins configuration¶
Job configuration¶
Configuration for Jenkins projects that use the releng scripts are described here.
General configuration¶
SCM checkout configuration:
- Jenkins SCM configuration should be used to check out the repository from where the build is triggered as a subdirectory of the workspace, with the same name as the repository. This is necessary for the Git Plugin to show reasonable change lists for the builds etc., although the build in reality always starts from the releng repository. In a workflow build, this checkout can be done in the workflow script.
- The build script always needs to check out the
releng
repository if it did not trigger the build, and start the build from there. - The releng script will check out remaining repositories if necessary.
- Various
*_REFSPEC
environment variables (see Input environment variables) need to be set in one way or another (see below for the suggested approach with build parameters).
In SCM poll jobs it is possible to simply set the various environment variables
to static values using a properties file in “Prepare environment for the run”
(CHECKOUT_PROJECT
and the various *_REFSPEC
variables). Note that the
SCM checkout behavior cannot use CHECKOUT_PROJECT
in the git address,
because the injected variables are not available for SCM polling.
Build parameters¶
To create a build that allows both intuitive parameterized builds with given refspecs and Gerrit Trigger builds, the following configuration is recommended:
Use
GROMACS_REFSPEC
,RELENG_REFSPEC
, andREGRESSIONTESTS_REFSPEC
as build parameters, withrefs/heads/master
(or another branch ref) as the default.Use “Prepare environment for the run” and the following Groovy script:
if (!binding.variables.containsKey('GERRIT_PROJECT')) { return [CHECKOUT_PROJECT: 'gromacs', CHECKOUT_REFSPEC: GROMACS_REFSPEC] } else { return [CHECKOUT_PROJECT: GERRIT_PROJECT, CHECKOUT_REFSPEC: GERRIT_REFSPEC] }
Configure all SCM checkout behaviors to use
CHECKOUT_PROJECT
andCHECKOUT_REFSPEC
.
To create a build that works as expected in all corner cases when triggered from a workflow job, the following configuration is recommended:
Create additional string parameters
GROMACS_HASH
,RELENG_HASH
, andREGRESSIONTESTS_HASH
with empty default values.Create a string parameter
CHECKOUT_PROJECT
, with the default valuegromacs
(or another repository that you want to see in Changes section for manually triggered builds).Use the following Groovy script for injecting environment variables:
return [CHECKOUT_REFSPEC: binding.variables."${CHECKOUT_PROJECT.toUpperCase()}_REFSPEC"]
If you also need to support directly triggering the build with Gerrit Trigger, you need a slightly more complicated script, but in most cases, it should be the workflow job that is triggered with Gerrit Trigger.
Normal/matrix builds¶
Builds that call run_build() should use the following post-build steps:
- The job should check the console output for the string “FAILED” and mark the build unstable if this is found.
- The job should use
logs/unsuccessful-reason.log
as the “Unsuccessful Message File” for the Gerrit Trigger plugin. TODO: How to best handle this for matrix builds (or other types of multi-configuration builds) - The job should archive all
.log
files fromlogs/
. Note that the build should be configured not to fail if there is nothing to archive if all the logs are conditionally produced. - The job can check various log files under
logs/category/
for warnings; the general design is that all logs from a certain category are checked using the same warning parser.
The build script in Jenkins will look something like this:
import os
import shlex
import subprocess
import sys
# For builds not triggered by Gerrit Trigger, the conditional is not
# necessary.
if os.environ['CHECKOUT_PROJECT'] != 'releng':
if not os.path.isdir('releng'):
os.makedirs('releng')
os.chdir('releng')
subprocess.check_call(['git', 'init'])
subprocess.check_call(['git', 'fetch', 'ssh://jenkins@gerrit.gromacs.org/releng.git', os.environ['RELENG_REFSPEC']])
subprocess.check_call(['git', 'checkout', '-qf', 'FETCH_HEAD'])
subprocess.check_call(['git', 'clean', '-ffdxq'])
subprocess.check_call(['git', 'gc'])
os.chdir('..')
sys.path.append(os.path.abspath('releng'))
import releng
# For non-matrix builds, opts can be a hard-coded list (or possibly None).
opts = shlex.split(os.environ['OPTIONS'])
releng.run_build('gromacs', releng.JobType.GERRIT, opts)
The script checks out the releng
repository to a releng/
subdirectory of the workspace if not already checked out, imports the
releng
package and runs run_build() with arguments identifying which
build script to run, and options that affect how the build is done.
shlex.split()
is necessary to be able to pass quoted arguments with spaces
to options such as gmxtest+
.
For matrix builds not triggered with a dynamic matrix (see below), the build
host can be selected with a host=
or a label=
option that is
automatically ignored by run_build().
run_build() will first check out the gromacs
repository to a
gromacs/
subdirectory of the workspace, and then execute a script from
gromacs/admin/builds/
, selected based on the first argument.
If necessary, it will also check out the regression tests.
If the script exits with a non-zero exit code, the build fails.
The folder structure in the build workspace looks like this:
$WORKSPACE/
releng/
gromacs/
[regressiontests/]
logs/
[unsuccessful-reason.log]
[<category>/]*
Workflow builds¶
Workflow builds should use a bootstrapping script like this:
def script
node('pipeline-general') {
def checkout_refspec = params.RELENG_REFSPEC
if (params.GERRIT_PROJECT == 'releng') {
checkout_refspec = params.GERRIT_REFSPEC
}
sh """\
set -e
mkdir -p releng
cd releng
git init
git fetch ssh://jenkins@gerrit.gromacs.org/releng.git ${checkout_refspec}
git checkout -qf FETCH_HEAD
git clean -ffdxq
git gc
""".stripIndent()
script = load 'releng/workflow/<workflow-name>.groovy'
<possible additional calls as needed by the workflow>
}
script.doBuild(<possible additional parameters>)
where expressions in angle brackets depend on the workflow.
For workflows that are never triggered by Gerrit Trigger from releng, the part
referencing GERRIT_PROJECT
and GERRIT_REFSPEC
can be omitted.
The workflow script will take care of most other tasks; the Jenkins
configuration may only need to specify some build parameters (typically,
GROMACS_REFSPEC
etc., as for normal builds) and the possible build triggers.
Build agent labels¶
The following labels on the Jenkins build agents are currently used to allocate builds to agents:
- pipeline-master
- Used to run general steps in workflow jobs that do not do any lengthy processing (except for source code checkouts). These could in principle run anywhere, but limiting them to a subset of the nodes reduces the number of workspaces used. This reduces disk space use, and each time a new workspace is created, the initial checkout takes quite a bit of time.
- clang-static-analyzer-X.Y
- Used to run clang static analysis builds. The build is dynamically allocated
using a version-specific label, based on what is specified in the
clang-analyzer.py
build script in the source repository. - cppcheck
- Used to run cppcheck builds for release-2018 and earlier. For now, there is no version specification: all used versions of cppcheck must be installed on each node.
- doxygen
- Used to run documentation builds. In addition to Doxygen, also other tools needed by the documentation build (Sphinx, Latex) need to be installed here. Also the source packaging builds use this label, since they need Sphinx.
- linux
- Used for regression test packaging builds to get a uniform enough environment.
- windows
- Should not be currently used, but has been used to restrict Unix-specific things in workflows to not run on Windows agents.
In other cases, agents are explicitly assigned to a node. Multi-configuration
builds are currently assigned to nodes based on information in
agents.py
, not on labels configured in Jenkins.