<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://brokenco.de//feed/by_tag/maven.xml" rel="self" type="application/atom+xml" /><link href="https://brokenco.de//" rel="alternate" type="text/html" /><updated>2026-05-03T00:12:50+00:00</updated><id>https://brokenco.de//feed/by_tag/maven.xml</id><title type="html">rtyler</title><subtitle>a moderately technical blog</subtitle><author><name>R. Tyler Croy</name></author><entry><title type="html">Crawling towards continuous delivery for Jenkins</title><link href="https://brokenco.de//2018/08/30/cd-for-the-jenkins-project.html" rel="alternate" type="text/html" title="Crawling towards continuous delivery for Jenkins" /><published>2018-08-30T00:00:00+00:00</published><updated>2018-08-30T00:00:00+00:00</updated><id>https://brokenco.de//2018/08/30/cd-for-the-jenkins-project</id><content type="html" xml:base="https://brokenco.de//2018/08/30/cd-for-the-jenkins-project.html"><![CDATA[<p>This year I’ve been working on an ambitious new project referred to as Jenkins
Evergreen. It is ambitious in that we’re aiming to significantly alter the way
in which <a href="https://jenkins.io/">Jenkins</a> is downloaded, updated, and used.
In most visible ways Evergreen is the same as a traditional Jenkins
installation, but the way it is assembled into a package and delivered is
radically different. Among the many challenges which the Evergreen project must tackle,
there is one problem in common with most other organizations:
<strong>how do you take a big, complex system, and make it continuously deliverable</strong>.</p>

<p>Long story short: very carefully.</p>

<h2 id="the-old-way">The Old Way</h2>

<p>Jenkins follows a pretty typical development and release process,
we chat on mailing lists, open up loads of
pull requests, merge some of them, and then release binary packages at
prescribed intervals.
Users are then expected to know an update has occurred, run some program to check for
updates (<code class="language-plaintext highlighter-rouge">apt-get update</code>) and install the updates. From the user’s
perspective, each release might contain a lot of relevant or important changes,
or it might contain completely trivial ones. Depending on the release line, a
bug identified and fixed may take anywhere from one to a few weeks before
it’s made available. Then of course, the user must go through the update song
and dance once more. This common <strong>release train model</strong> sucks for users and, I
would argue, for developers too..</p>

<p>Jenkins has an additional complication: it is plugin-based, and all those
plugins are developed and released largely independently from one another.
Jenkins “core” by itself isn’t very useful at all. It is those <em>plugins</em> which
make Jenkins a joy (and sometimes a pain) to use. For all intents and purposes,
plugins <em>also</em> follow the <strong>release train model</strong> (which sucks for users), but
with the bonus feature of requiring users to check for updates through the
built-in Update Center rather than through the same distribution mechanism as
Jenkins core.</p>

<p>Altogether, this leads to large numbers of Jenkins users never updating their
systems.</p>

<p>Nonetheless, the release train model has helped Jenkins grow to where it is
today. The times however, have changed.</p>

<p>Expectations around how we consume and operate our software have changed
radically in the past decade. It is my steadfast opinion that the <strong>release
train model</strong> is now a legacy which we should all be leaving behind.</p>

<h2 id="the-new-way">The New Way</h2>

<p>The model for Jenkins Evergreen is completely different. Rather than a
time-based pull model (also known as the release train model), it provides an on-demand <em>push</em> model. As I described in the
design overview document,
<a href="https://github.com/jenkinsci/jep/tree/master/jep/300">JEP-300</a>:</p>

<blockquote>
  <p>Jenkins Evergreen will be distributed as an automatically
self-updating distribution, containing Jenkins core and a version-locked set
of plugins considered “essential.” Rather than attempting to mirror the
existing Weekly and LTS release lines for core, plus some plugin version
matrix, Jenkins Evergreen will update in a manner similar to Google Chrome.</p>

  <p>For Jenkins end users, this automatically updating distribution will mean
that Jenkins Evergreen will require significantly less overhead to manage,
receiving improvements and bug fixes without any user involvement.</p>
</blockquote>

<p>Fundamentally, Jenkins Evergreen is about building the machinery to practice
Continuous Delivery with Jenkins itself. The argument for
Continuous Delivery is that smaller releases are <strong>safer</strong> than
big-bang releases. Risk is amortized, and the tooling and habits of
releasing often result in higher-quality software.</p>

<p><strong>Jenkins needs Continuous Delivery</strong>.</p>

<hr />

<p>How on earth do we get from the release train model (which sucks for
users), to something more continuously delivered?</p>

<p>Very carefully!</p>

<p>Like most transitions to continuous delivery, Jenkins Evergreen requires a
significant amount of ground work in our existing code bases before new code
adopts the Evergreen distribution model.</p>

<h3 id="incremental-releases">Incremental Releases</h3>

<p>My colleague Jesse wrote a pretty in-depth article on a new pattern we’ve
introduced into the Jenkins project, generally referred to as <a href="https://jenkins.io/blog/2018/05/15/incremental-deployment/">incremental
releases</a>.
Jenkins core and plugins are all Java projects which have rich
<a href="https://maven.apache.org">Maven</a> metadata describing their interdependencies.</p>

<p>In the release train model the velocity of of changes, and version bumps,
required for any given plugin will be fairly minimal. In the release train
model, it is <em>okay</em> to create a pull request to Plugin B, wait for that to be
released, then update Plugin A, to depend on that change, and then wait for
that to be released. In the release train model it is <em>okay</em> to wait for weeks
on end before users see the effects of changes.</p>

<p>In 2018 however, that long cycle time is <strong>not okay</strong>.</p>

<p>Incremental releases allow for plugins to produces artifacts built from pull
requests, or branches, and for those artifacts to be published to a special
<code class="language-plaintext highlighter-rouge">incrementals</code> Maven repository. From that repository, incremental releases of
artifacts can be subsequently consumed by other tooling.</p>

<p>In the case of Jenkins Evergreen, this allows us to craft a distribution with
changes that are hot off the presses, using another foundational component: the
Bill of Materials.</p>

<p>If you’re curious about the design of incremental releases, consult
<a href="https://github.com/jenkinsci/jep/tree/master/jep/305">JEP-305</a> which outlines
their design.</p>

<h3 id="the-bill-of-materials">The Bill of Materials</h3>

<p>Curation is a key component of any continuous delivery system. We do not
necessarily want any old commit to be released all the way through to
“production.” Instead we want a means to describe what versions of which
components are safe to proceed through the pipeline.</p>

<p>As described in
<a href="https://github.com/jenkinsci/jep/blob/master/jep/309">JEP-309</a>, the Bill of
Materials gives us a means of describing a combination of Jenkins core and plugins, which should
be delivered together. This specification is currently being used by multiple
parts of the Jenkins project where we have a similar need to test across
multiple components and repositories. In Evergreen it is taken much further.</p>

<p>The Bill of Materials describes what code will be delivered to a Jenkins
Evergreen instance, and the Evergreen distribution system will attempt to
ensure that <em>all</em> instances are at the same exact version of that Bill of
Materials.  The Evergreen distribution system treats all instances as if they
were part of as single fleet, similar to how SaaS applications are deployed.</p>

<p>This homogeneity addresses a fundamental problem with plugin-based ecosystems
like Jenkins’s: an explosion of possible installed combinations of software
across all user installations. The large variety of plugin combinations
possible “in the wild” makes bug reporting and reproduction difficult, and
serious pre-release acceptance testing <em>practically impossible</em>. In many cases,
the first time certain combinations will ever be executed together will be on
the user’s installation</p>

<h3 id="feedback">Feedback</h3>

<p>The final logical piece of the puzzle which any continuous delivery pipeline
requires is <em>feedback</em>. Much as it pains me to say this, current releases of
Jenkins provide no automated feedback to the Jenkins project on whether they
are operating successfully. No automated crash reports. No error logs. No
analytics. Nothing. The <em>only</em> two ways that a Jenkins contributor will ever
learn about a bug in their plugin or core is if:</p>

<ol>
  <li>They see it themselves.</li>
  <li>A user actually takes the time to manually report it.</li>
</ol>

<p>Regrettably, this is also the case for tons of free and open source software,
and it’s an absolute shame.</p>

<p>With Jenkins Evergreen, basic error reporting is built in by default. We have
integrated with <a href="https://sentry.io">Sentry</a> for collecting errors automatically
from Jenkins Evergreen installations without any required user involvement. In
the future I’m sure we’ll add more advanced feedback mechanisms, but at the
moment a blurry picture of how Jenkins is running “in the real world” is tons
better than flying blind.</p>

<hr />

<p>Jenkins, like any large piece of software which has grown over a long period of
time, has its flaws. After a couple beers, I could tell you about some of the
skeletons in its closet, but on the whole I don’t believe Jenkins is inherently
broken, or a lost cause. In fact, I believe that Jenkins is likely now more
important than ever. With the practices of continuous integration and
continuous delivery becoming a core part of every software project, a flexible
and customizable open source tool like Jenkins is increasingly important.</p>

<p><a href="https://github.com/jenkins-infra/evergreen">Jenkins Evergreen</a> is my vision of
how we get to a better future with Jenkins. By continuously delivering Jenkins,
I believe we will be able to improve the user experience, alleviate troublesome
bugs, and make Jenkins even more accessible to new developers.</p>]]></content><author><name>R. Tyler Croy</name></author><category term="jenkins" /><category term="maven" /><category term="continuousdelivery" /><category term="cicd" /><summary type="html"><![CDATA[This year I’ve been working on an ambitious new project referred to as Jenkins Evergreen. It is ambitious in that we’re aiming to significantly alter the way in which Jenkins is downloaded, updated, and used. In most visible ways Evergreen is the same as a traditional Jenkins installation, but the way it is assembled into a package and delivered is radically different. Among the many challenges which the Evergreen project must tackle, there is one problem in common with most other organizations: how do you take a big, complex system, and make it continuously deliverable.]]></summary></entry></feed>