Quantcast
Channel: Jenkins Blog
Viewing all 1087 articles
Browse latest View live

Plugin Documentation-as-Code: Moving docs to GitHub

$
0
0

In September 2019 we announced support of GitHub as a source of documentation for the Jenkins Plugin Site. Thanks to Zbynek Konecny and Olivier Vernin and other contributors, now it is possible to store plugin documentation right inside plugin repositories instead of Jenkins Wiki which was historically difficult to maintain for plugin maintainers and for the Jenkins infrastructure team.

This blogpost may be interesting to plugin maintainers and to those who want to contribute to the Jenkins documentation. I will describe how to migrate plugin documentation to GitHub and to get pages like this one:

GitHub Documentation example

Why?

By using plugin GitHub repositories for documentation, plugin maintainers can follow the Documentation-as-code approach and make documentation changes a part of the pull requests so that documentation follow-ups do not get forgotten. It also gives an opportunity to review the documentation changes and to add documentation contributor recognition, especially if the story is combined with Release Drafter.

Unfortunately, before September 2019 usage of GitHub documentation was causing some issues. First of all, many plugin maintainers have already moved their documentation to GitHub, and it caused fragmentation of the documentation (Wiki, GitHub, jenkins.io). To address it, plugin maintainers still had to maintain stub Wiki pages with redirects, and users had to spend some time to find out where the real documentation is located. By supporting GitHub as a documentation source, we allow maintainers to phase out the plugin Wiki pages while improving the user experience.

And there are even more pressing reasons to do the migration now…​ If you are subscribed to the developer mailing list, you may have also seen an announcement by R. Tyler Croy about Jenkins Wiki stability issues and making it read-only as a temporary measure to stabilize the instance (mailing list thread). Although the functionality has been partially restored afterwards, there is a consensus in the Infrastructure team that we should gradually move to alternate solutions.

Examples

Since the announcement in September, more than 50 plugins were moved from Wiki to GitHub. Few examples:

Role Strategy example

How to enable GitHub documentation for your plugin?

  1. Convert documentation from Wiki to GitHub Asciidoc or Markdown format if you have not done it yet.

  2. Change the <url> field in pom.xml so that it points to GitHub (guide). Examples of valid links:

  3. Optional: Add badges to the page to improve look&feel and to provide quick links for users. There are standard badges for changelogs, chats, plugin site, and installation numbers.

  4. Release the new plugin version

  5. Wait a few hours till the change propagates. After that, the Jenkins Plugin Site will show the new documentation from GitHub.

What’s next?

The story is tracked as WEBSITE-406 which is a part of the wider subproject for using GitHub as a source of data for the Jenkins plugin site and update managers (WEBSITE-637). Later steps include support showing changelogs from GitHub releases, pulling plugin tags from GitHub, showing plugin logos, and using Repository Permission Updater as a source of the maintainer information.

How to contribute?

October is a great time to contribute! Plugin documentation is one of the featured projects for Hacktoberfest, and we will welcome all contributions to the documentation and to the codebase.

Contributing to Documentation

We are looking for contributors who are interested to improve plugin documentation and to help us with migration from Wiki to GitHub. For dozens of plugins the documentation is already in GitHub, and you are welcome to submit pull requests against any repository.

Migrating documentation:

If you have any questions about contributing to the documentation, please see this page or reach out to us in the Docs SIG Gitter chat.

Code contributions

Would you like to write some code in Java or JavaScript? Or would you like to work on CSS styles and improve Jenkins design? In such case you are welcome to contribute to the Jenkins Plugin Site. It is our own plugin marketplace implementation, and we invite contributions to this area. The plugin site is really easy to develop.


Thinking About Jenkins Security - DevOps World | Jenkins World 2019

$
0
0
This is a speaker blogpost for a DevOps World | Jenkins World 2019 talk in Lisbon, Portugal

Come join us at DevOps World | Jenkins World 2019 for "Thinking about Jenkins Security", a talk about securing your Jenkins server. We’ll review the layers that secure Jenkins and describe techniques that you can use to protect your Jenkins server.

Topics will include:

  • The secure by default configuration that Jenkins provides

  • Risks associated with reducing default security settings

  • Authentication and authorization alternatives

  • Using "least privilege" principles

  • Jenkins credentials and trusted access to resources

  • Software updates and Jenkins project security notices

do not run malicious code

We’ll intermix descriptions of good practices with some security horror stories. The horror stories remind us of our mistakes; we will discuss how to detect them and how to prevent them.

Come join us for the presentation in Lisbon!

Slides

Jenkins Performance: Avoiding Pitfalls, Diagnosing Issues, and Scaling for Growth - DevOps World | Jenkins World 2019

$
0
0
This is a speaker blogpost for a DevOps World | Jenkins World 2019 talk in Lisbon, Portugal

With Halloween upon us, there’s no better time to discuss Jenkinstein! Are you suffering from Jenkins performance issues? Are users complaining about a slow UI or even scarier, is Jenkins going down frequently?

Jenkinstein

Come join me at DevOps World | Jenkins World 2019 for "Jenkins Performance: Avoiding Pitfalls, Diagnosing Issues, and Scaling for Growth", a talk about JVM administration and best practices from the front lines of supporting thousands of Jenkins installations worldwide. During this talk we’ll cover how to prevent your Jenkins instance from becoming a Jenkinstein!

Topics we will be discussing:

  • JVM administration best practices

  • Horizontal scaling

  • Analyzing thread dumps, GC logs, and heap dumps

  • Real world data showing 3500% performance increases

  • Garbage collection

gc unhealthy

We’ll be discussing how you can forecast for growth, and baseline using key performance indicators like application throughput and latency, by analyzing spooky data like Garbage Collection logs!

Come join me for the presentation in Lisbon! There will be candy!

Slides

DevOps World | Jenkins World San Francisco in Living Colors

$
0
0

DevOps World | Jenkins World San Francisco was August 12 - 15, 2019. The event was delivered in vivid colors starting with flowing banners hung from street lamp posts to the big screens in breakout rooms, to the expo hall. The energy and enthusiasm in the Moscone convention center made the colors even more vibrant, thanks to the people attending the conference.

Here’s a recap of the conference in pictures:

DevOps World | Jenkins World 2019 - San Francisco

1D5 2235

Keynote - Evolution of the Continuous Delivery Foundation

Tracy Miranda opened the keynote explaining the evolution of the Continuous Delivery Foundation.

Keynote - Evolution of the Continuous Delivery Foundation

1D5 0437

Influencers, Creators, and Members

The influencers, creators, and members of the CD Foundation: Tracy Miranda (far left), Andy Glover (Netflix), Tara Hernandez (Google), Chris Aniszczyk (Linux Foundation), Dave Stanke (Google), Kohsuke Kawaguchi (Jenkins creator), Jayne Groll (DevOps Institute), James Strachan (Jenkins X creator). “We want to help set Jenkins up for success, into the next decade”, Tyler Croy (not in picture).

Influencers, Creators, and Members of the Continuous Delivery Foundation

1D5 1310

Contributor Summit

The inaugural Continuous Delivery Foundation Contributor Summit and it was a full house!

Continous Delivery Foudnation Contributor Summit

IMG 8264

15 Years of Jenkins

A remarkable milestone for the Jenkins project, a celebration of Jenkins turning 15…​cake included!

Fifteen Years of Jenkins

1D5 0614

Bee Diverse Luncheon

Interactive and engaging luncheon celebrating diversity

Bee Diverse Luncheon Entrance

1D5 5576

Bee Diverse Luncheon Leading Voices

1D5 5606

Bee Diverse Luncheon Group Discussions

1D5 5682

Jenkins Contributors and Experts

Jenkins contributors and experts on hand to educate and share lightning talks and provide one on one Jenkins support.

Jenkins Lightning Talks

1D5 3207

Jenkins Experts Answering Questions

1D5 2953

Jenkins Experts Discussing and Helping

IMG 8278

Jenkins Experts Gathered

1D5 3573

DevOps Superheroes

Even though the conference offered endless learning and networking possibilities, and major milestones worth celebrating, I felt the true highlight of the conference was the celebration of each individual, “You”. “You” are the super hero, the driving force behind the incredible innovations to advance technology to where it is today. Here’s celebrating the super heros in all of YOU!

DevOps Superheroes

1D5 2286

Superheroes and the Wookie

1D5 1643

Four Superheroes

1D5 2949

Kohsuke Kawaguchi - Founding Superhero

1D5 3034

A DevOps League of Superheroes

1D5 4067

Crowd of Superheroes

1D5 4243

This party will be coming to Lisbon, Portugal on December 3-5, 2019. We hope to see our EU Jenkins fans at DevOps World | Jenkins World Lisbon. Use JWFOSS for a 30% discount off your pass.

Hope to see you in Lisbon!

How to build the top mobile game for every platform imaginable

$
0
0

Context

You have been tasked with managing the Jenkins instance for the highest grossing mobile game in the world. You learn that this involves helping the game studio iterate their work against eight different target platforms, each with their SDK, on four different main pipelines, plus a lot of extra auxiliary jobs. And, of course, the studio wants all of this to go smoothly, in order to maintain a good pace of features and bugfixes for every release - a release happening every two weeks. Hitting hundreds of millions of players worldwide.

How are you going to make sure that the environment stays correctly configured, with the right versions of the required software; helping the studio maintain stability and scalability of their pipelines; ensuring operability of the Jenkins instance; improving the speed of the builds month after month?

It’s OK to sweat. You are going to need some help!

This is just a regular day in the office for a build engineer working at King. Facing a very broad problem, with high quality standards and even higher stakes. Thankfully, we are not alone. We have access to a lot of tools - either open source tools, tools developed by the studios or tools developed by our stellar build infrastructure team in Barcelona - to help carry us all the way to the publish line. We put all of these tools together, and by their powers combined, we provide fast, easily operable workflows for the studios, cutting minutes here and there, ensuring the features a smooth sail from dev, to master, to release.

I will explain all of the tricks we use at King to speed builds up, and to make Jenkins operation easier for our studios on December 4, 2019, at DevOps World | Jenkins World Lisbon. Use JWFOSS for 30% discount on registration! For now, let’s take a look at some of them.

Where do we start?

We use on-premise elastic infrastructure, spawning machines from certain templates whenever they are needed. This means that for every build, we are getting a fresh environment - no intermediate artifacts leftover or anything of the sort, which is good. That also means that we need to clone our repositories and compile everything every time, which is bad. However, we have solutions for these two problems.

We make full use of linkclones/snapshots when spawning a VM. Every night we run a bootstrapper that will power on the base image and perform whatever operations we decide on it, before turning it back into a template and re-creating the snapshot. In the case of Candy Crush, we update our caches, and this helps us cut some time off of git clone and compilation. We call this bootstrapper “cacheo”. It looks more or less like this:

Cacheo
1. Start elastic agent template image2. Connect it to Jenkins3. Perform cleanup4. Trigger git reference cache jobs5. Trigger all the builds you want cached6. Turn off template image, delete the agent and recreate the linked clone snapshot

Every studio can specify on which templates will cacheo run, and what will it do in each of them. Maybe you want to make sure your Android license is on point. Or download some packages from artifactory. Perhaps pre-load your gradle dependencies. Whatever it is, cacheo does it for you and updates your base images every night.

One of the most common uses is to pre-fill a local git cache, and when doing so, the improvement is very visible, especially on Windows:

This means, speeding up source code fetching by 55% on Windows, on average. That is a LOT!!

But what about actual compilation?

All of our major games use the same engine; we bring this code in by means of submodules. This means there is a big bunch of shared code that needs to be compiled and linked whenever we build the game. And it’s not rare that this shared code is bigger than the actual game code! Thankfully, the engine team lent us a hand, and they developed a way to package the compiled shared code. Normally, the game code lives alongside a specific version of the shared code, which doesn’t get updated too frequently. Sometimes once a month, sometimes to grab a hotfix. This translates to us potentially compiling the exact same shared code for quite some time, every time we build the game. Thanks to these prebuilt artifacts, we are able to skip a huge part of the compilation, at the cost of a simple artifactory download.

Cacheo
if generate_prebuilt_libs:
    compile_project()

    generate_empty_cmakelists()

    for dependency in dependencies:
        merge_compiled_dependency_into_metalib(dependency)
        write_dependency_to_generated_cmakelists_as_alias_for_metalib(dependency)

elif use_prebuilt_libs:
    add_generated_cmakelists_with_metalib_as_dependency()

    compile_project()

Thanks to these prebuilt libraries, we are able to skip a big chunk of the compilation, and it builds up really quickly! Iterative work on several branches, as long as they have the same engine version, gets sped up in noticeable ways. There are, however, specific cases when we do choose to build the shared code regardless, such as when we build release candidates for instance.

Just so you get an idea, times on this table are on average:

LinuxMacOSWindows

NFS

2 min 11s

2min 34s

8min 32s

Local

1 min 20s

1min 35s

3min 49s

Difference

39% faster

39% faster

55% faster

I just don’t want to have to deal with bureaucracy

Operating Jenkins can be quite complicated. Talk about “Tell me something I don’t know”, right? And with so many moving pieces (elastic infrastructure, plugins, dirty workspaces), it might not be easy for everyone to run specific maintenance tasks. We have a lot of small pipelines, created by the build infrastructure group, that we can use to diagnose and work around certain errors, as well as gather useful information that might be otherwise difficult to find. These pipelines do things like printing all the installed plugins, deleting offline on-demand agents, cleaning disconnected VMs from vSphere, or re-run puppet in a specific Jenkins instance. And any user can run these jobs, there is no need to be an admin. This allows the team to unblock themselves if they need to by using these jobs. Here’s one that I particularly like. How many times have you modified a pipeline and, when trying to run it, the first thing that happens is that Jenkins says that it needs approval?

Script Approval
importorg.jenkinsci.plugins.scriptsecurity.scripts.*@NonCPS// Disclaimer - this can have serious security consequences// Be mindful when you run this!defcall() {
    sa = ScriptApproval.get()
    toApproveScripts = sa.getPendingScripts().collect()
    println ("toApproveScripts: " + toApproveScripts)
    toApproveScripts.each {pending ->
        sa.get().approveScript(pending.getHash())
        println ("approvedScripts: " + pending.getHash())
        }
    sa.save()
}

The best part? All our Jenkins instances include these jobs, by default, so no one misses out on the fun.

iOSWindows

No prebuilts

20min 17s

40min 30s

Prebuilts

10min 2s

23min 20s

Difference

51% faster

43% faster

2019 Jenkins Board and Officer Elections Update

Next: Jenkins Health Advisor by CloudBees is here!
Previous: How to build the top mobile game for every platform imaginable
$
0
0

Jenkins Elections

The Jenkins community is conducting the 2019 elections for Board and Officer positions. The call for nominations has concluded. We received many nominations. Based on the people who are willing to accept their nomination and the uncontested officer positions, we will have 3 votes:

  1. A vote to elect 3 board members

  2. A vote to elect the Jenkins security officer

  3. A vote to elect the Jenkins events officer

Candidates

Each candidate has provided a statement to help guide voters on why they should vote for the candidate. Refer to the candidate statements for more details. The candidates running for a board position are:

  • Alex Earl

  • Oliver Gondza

  • Ullrich Hafner

  • Oleg Nenashev

  • Mark Waite

  • Zhao Xiaojie (a.k.a. Rick to many of you)

The candidates running for Security Officer are:

  • Daniel Beck

  • Wadeck Follonier

The candidates running for Events Officer are:

  • Alyssa Tong

  • Zhao Xiaojie (a.k.a. Rick to many of you)

Voter Registration

This is the first time in a while that we are running a Jenkins election; we are learning as we go. Jenkins elections aim to be very inclusive. We do not restrict elections to just code committers. Anyone who has a Jenkins account registered before September 1, 2019 is eligible to vote. Jenkins, being the successful project it is, has approximately 100 000 accounts that meet that criteria. As a result we are contacting eligible voters and requesting that they explicitly ‘opt-in’ to participate in the voting.

If you meet the criteria, you will receive an email at your registered jenkins.io email address. It will be from elections@jenkins.io with the title ‘2019 Jenkins Election - Invitation to Participate’. The email will provide election details and will include an "I want to participate" button.

Voter Registration

Voter Confirmation

Once you click on the link, you should see a confirmation screen as follows:

Voter Registered

If you do not receive the email by November 14, 2019 or if you have any problems voting, please comment on the Jenkins Election 2019 Jira issue.

Voting

The voting will officially open on November 11, 2019. Candidates will receive an email from the Condorcet internet voting sent by Kohsuke Kawaguchi. One email will be sent for each vote (so 3 in total: 1 for board, 1 for event officer and 1 for security officer). The vote will ask to rank the candidates using a screen like this:

Voter Ballot

Election Dates

Here is a summary of the key election dates:

Election results will be posted to the Jenkins developer mailing list, followed by an announcement blog post on jenkins.io.

If there are any delays to the proposed dates we will aim to communicate that as soon as we can. Thank you very much for all the candidates showing the Jenkins spirit of service to their community. We encourage everyone to register to vote and participate in the Jenkins community.

DateEvent

Now

Voter registration ongoing

Nov 11, 2019

Voting begins

Nov 17, 2019

Voter registration closes

Nov 24, 2019

Voting closes a 5:00 PM Pacific Time

Dec 3, 2019

New representatives announced

Uncontested Officer Positions

When an officer position has only one candidate that is willing to accept the nomination, there is no reason to vote on that position. The individual becomes an officer as the sole candidate for the position.

Uncontested officers include:

NameRole

Olivier Vernin

Infrastructure Officer

Oliver Gondza

Release Officer

Mark Waite

Documentation Officer

Jenkins Health Advisor by CloudBees is here!

Next: Welcome to the Matrix
Previous: 2019 Jenkins Board and Officer Elections Update
$
0
0

Angry Jenkins logo

Managing any software presents its own unique challenges. Jenkins Masters are no exception. For example,

  • How do you keep a finger on the pulse of everything going on in your Jenkins environment? Are you looking at every new defect opened in the issue tracker?

  • How do you make sure that your master or agents don’t silently fail? Are you monitoring its logs? All of its internal components? If something does go wrong, how do you fix it??

  • How do you avoid the infamous “angry Jenkins” logo?

That’s why we created Jenkins Health Advisor by CloudBees.

Here at CloudBees, we have years of experience supporting our customers who are using Jenkins, including our proprietary products build on top of Jenkins like CloudBees Core. As a result, our support team is made up of automation experts with Jenkins knowledge you can’t get anywhere else.

Automated health checks started when our support engineers created a platform so they could write rules to detect known issues on support bundles provided by our customers, and redirect them to the required knowledge source to diagnose and resolve the issue.

After years of internal usage we decided to share this service with the community and we are pleased to introduce a new free (as in beer) service available to every Jenkins user: Jenkins Health Advisor by CloudBees.

Jenkins Health Advisor by CloudBees automatically analyzes your Jenkins environment, proactively identifies potential issues and advises you of solutions with detailed email reports.

Jenkins Health Advisor by CloudBees logo

Jenkins Health Advisor by CloudBees can detect a large range of issues from simple configuration issues to security and best practices concerns - all critical elements of Jenkins implementations. Getting started is done in 3 steps, and within 24 hours you will receive your first report.

Jenkins Health Advisor by CloudBees overview

We hope that you will appreciate this service and it will help you to keep your masters healthy.

Take a few minutes to read our documentation, discover the service and don’t hesitate to contact us on the Jenkins community channels (Gitter, jenkinsci-users@googlegroups.com, …​).

Don’t miss also the opportunity to meet our support team on the "Ask the experts" booth at DevOps World | Jenkins World 2019.

Useful links:

Welcome to the Matrix

Next: Jenkins macOS native installer deprecation
Previous: Jenkins Health Advisor by CloudBees is here!
$
0
0

I often find myself needing to run the same actions on a bunch of different configurations. Up to now, that meant I had to make multiple copies of the same stages in my pipelines. When I needed to make changes, I had to make the same changes in multiple places throughout my pipeline. Maintaining even a small number of configuration was difficult for larger pipelines.

Declarative Pipeline 1.5.0-beta1 (now available from theJenkins Experimental Update site) adds a new matrix section that lets me specify a list stages once and then run that same list in parallel on multiple configurations. Let’s take a look!

Single configuration pipeline

I’ll start with a simple pipeline with build and test stages. I’m using echo steps as placeholders for my build and test actions.

Jenkinsfile
pipeline {
    agent none
    stages {
        stage('BuildAndTest') {
            agent any
            stages {
                stage('Build') {
                    steps {
                        echo 'Do Build'
                    }
                }
                stage('Test') {
                    steps {
                        echo 'Do Test'
                    }
                }
            }
        }
    }
}

Pipeline for multiple platforms and browsers

I’d like to run my build and tests on a combination of platforms and browsers. The new matrix directive lets me specify a set of axes. Each axis has a name and a list of one or more values. When the pipeline is run, Jenkins will take those and run my stages on all possible combinations of values from each axis. All cells in a matrix run in parallel (limited only by the number of available agents). Stages within each cell are run sequentially.

My matrix has two axes: PLATFORM and BROWSER. I have three values for PLATFORM and four values for BROWSER resulting in my stages being run with twelve different combinations. I’ve changed my echo steps to use the axis values for each cell.

Jenkinsfile
pipeline {
    agent none
    stages {
        stage('BuildAndTest') {
            matrix {
                agent any
                axes {
                    axis {
                        name 'PLATFORM'
                        values 'linux', 'windows', 'mac'
                    }
                    axis {
                        name 'BROWSER'
                        values 'firefox', 'chrome', 'safari', 'edge'
                    }
                }
                stages {
                    stage('Build') {
                        steps {
                            echo "Do Build for ${PLATFORM} - ${BROWSER}"
                        }
                    }
                    stage('Test') {
                        steps {
                            echo "Do Test for ${PLATFORM} - ${BROWSER}"
                        }
                    }
                }
            }
        }
    }
}
Log output (truncated)
...
[Pipeline] stage
[Pipeline] { (BuildAndTest)
[Pipeline] parallel
[Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'firefox')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'firefox')
[Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'firefox')
[Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'chrome')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'chrome')
[Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'chrome')
[Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'safari')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'safari')
[Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'safari')
[Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'edge') (hide)
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'edge')
[Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'edge')
...
Do Build for linux - safari
Do Build for linux - firefox
Do Build for windows - firefox
Do Test for linux - firefox
Do Build for mac - firefox
Do Build for linux - chrome
Do Test for windows - firefox
...

Excluding invalid combinations

Now that I have my basic matrix created, I’ve noticed that I have some invalid combinations. Microsoft Edge only runs on Windows and there isn’t a Linux version of Safari.

I can remove invalid cells from my matrix using exclude directives. Each exclude has one or more axis directives with name and values. The axis directives inside an exclude generate a set of combinations (similar to generating the matrix cells). The matrix cells that match all the values from an exclude combination are removed from the matrix. If I have more than one exclude directive, each are evaluated separately to remove cells.

When dealing with a long lists of values to exclude, I can use notValues instead of values to specify axis values we don’t want excluded. Yes, that’s a double negative, so it can get a little confusing. I try to use it only when I really need it.

In my sample pipeline below, I specifically exclude the linux, safari combination and I also exclude any platform that is notwindows with the edge browser.

This pipeline uses two axes but there is no limit on the number of axis directives.

Also, in this pipeline each exclude specifies values for both axes, but that is not required. If we wanted to run only "linux" cells, we could use the following exclude:

exclude {
    axis {
        name 'PLATFORM'
        notValues 'linux'
    }
}
pipeline {
    agent none
    stages {
        stage('BuildAndTest') {
            matrix {
                agent any
                axes {
                    axis {
                        name 'PLATFORM'
                        values 'linux', 'windows', 'mac'
                    }
                    axis {
                        name 'BROWSER'
                        values 'firefox', 'chrome', 'safari', 'edge'
                    }
                }
                excludes {
                    exclude {
                        axis {
                            name 'PLATFORM'
                            values 'linux'
                        }
                        axis {
                            name 'BROWSER'
                            values 'safari'
                        }
                    }
                    exclude {
                        axis {
                            name 'PLATFORM'
                            notValues 'windows'
                        }
                        axis {
                            name 'BROWSER'
                            values 'edge'
                        }
                    }
                }
                stages {
                    stage('Build') {
                        steps {
                            echo "Do Build for ${PLATFORM} - ${BROWSER}"
                        }
                    }
                    stage('Test') {
                        steps {
                            echo "Do Test for ${PLATFORM} - ${BROWSER}"
                        }
                    }
                }
            }
        }
    }
}
Log output (truncated)
...
[Pipeline] stage
[Pipeline] { (BuildAndTest)
[Pipeline] parallel
[Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'firefox')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'firefox')
[Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'firefox')
[Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'chrome')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'chrome')
[Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'chrome')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'safari')
[Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'safari')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'edge')
...
Do Build for linux - firefox
...

Controlling cell behavior at runtime

Inside the matrix directive I can also add "per-cell" directives. These are the same directives that I would add to a stage and they let me control the behavior of each cell in the matrix. These directives can use the axis values from their cell as part of their inputs, allowing me to customize the behavior of each cell to match its axis values.

On my Jenkins server I have configured agents with labels that match the OS for each agent ("linux-agent", "windows-agent", and "mac-agent"). To run each cell in my matrix on the appropriate operating system, I configure the label for that cell using Groovy string templating.

matrix {
    axes { ... }
    excludes { ... }
    agent {
        label "${PLATFORM}-agent"
    }
    stages { ... }// ...
}

Occasionally I run my pipeline manually from the Jenkins Web UI. When I do that, I’d like to be able to select just one platform to run. The axis and exclude directives define the static set of cells that make up the matrix. That set of combinations is generated before the start of the run, before any parameters are processed. What this means is that I can’t add or remove cells from a matrix after the job has started.

The "per-cell" directives, on the other hand, are evaluated at runtime. I can use the "per-cell" when directive inside matrix to control which cells in the matrix are executed. I’ll add a choice parameter with the list of platforms, and add conditions to the when directive, which will either let all platforms execute, or only execute cells that match my selected platform.

pipeline {
    parameters {
        choice(name: 'PLATFORM_FILTER', choices: ['all', 'linux', 'windows', 'mac'], description: 'Run on specific platform')
    }
    agent none
    stages {
        stage('BuildAndTest') {
            matrix {
                agent {
                    label "${PLATFORM}-agent"
                }
                when { anyOf {
                    expression { params.PLATFORM_FILTER == 'all' }
                    expression { params.PLATFORM_FILTER == env.PLATFORM }
                } }
                axes {
                    axis {
                        name 'PLATFORM'
                        values 'linux', 'windows', 'mac'
                    }
                    axis {
                        name 'BROWSER'
                        values 'firefox', 'chrome', 'safari', 'edge'
                    }
                }
                excludes {
                    exclude {
                        axis {
                            name 'PLATFORM'
                            values 'linux'
                        }
                        axis {
                            name 'BROWSER'
                            values 'safari'
                        }
                    }
                    exclude {
                        axis {
                            name 'PLATFORM'
                            notValues 'windows'
                        }
                        axis {
                            name 'BROWSER'
                            values 'edge'
                        }
                    }
                }
                stages {
                    stage('Build') {
                        steps {
                            echo "Do Build for ${PLATFORM} - ${BROWSER}"
                        }
                    }
                    stage('Test') {
                        steps {
                            echo "Do Test for ${PLATFORM} - ${BROWSER}"
                        }
                    }
                }
            }
        }
    }
}

If I run this Pipeline from the Jenkins UI and set the PLATFORM_FILTER parameter to mac, I’ll get something like the output below:

Log output (truncated - PLATFORM_FILTER = 'mac' )
...
[Pipeline] stage
[Pipeline] { (BuildAndTest)
[Pipeline] parallel
[Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'firefox')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'firefox')
[Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'firefox')
[Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'chrome')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'chrome')
[Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'chrome')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'safari')
[Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'safari')
[Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'edge')
...
Stage "Matrix - OS = 'linux', BROWSER = 'chrome'" skipped due to when conditional
Stage "Matrix - OS = 'linux', BROWSER = 'firefox'" skipped due to when conditional
...
Do Build for mac - firefox
Do Build for mac - chrome
Do Build for mac - safari
...
Stage "Matrix - OS = 'windows', BROWSER = 'chrome'" skipped due to when conditional
Stage "Matrix - OS = 'windows', BROWSER = 'edge'" skipped due to when conditional
...
Do Test for mac - safari
Do Test for mac - firefox
Do Test for mac - chrome
Come join me at DevOps World | Jenkins World 2019 for "Declarative Pipeline 2019: Tips, Tricks and What’s Next". I’ll go over what’s been added to Pipeline in the last year (including matrix) and discuss ideas about where pipeline should go next.

Conclusion

In this blog post, we’ve looked at how to use the matrix directive to make concise but powerful declarative pipelines. An equivalent pipeline created without matrix would easily be several times larger, and much harder to understand and maintain.

Matrix is now available from the experimental update center. It will be released to the main update center as soon as we’re done putting the finishing touches on the documentation and online help.


Jenkins macOS native installer deprecation

Next: Do Plugins Store Credentials In A Secure Way? - DevOps World | Jenkins World 2019
Previous: Welcome to the Matrix
$
0
0

In addition to WAR files and Docker images, the Jenkins project provides native installers for each weekly and LTS release. There are installers available for Linux distributions, Windows, macOS and other operating systems. There are also installers provided by third parties. You can find the list of these installers on the Downloads page.

In this blog post, we announce the upcoming deprecation of the macOS native installer. We will review the replacement options and the rollout plan.

Why?

Maintaining installers is a significant maintenance effort for the project because installers require testing and, sometimes, specific platforms and environments for packaging. When installers lose relevance for the majority of the Jenkins audience, we remove them or handover maintenance to third parties on other areas. For macOS, there are currently two types of packages: native installers with GUI for desktop versions and Homebrew packages. Since Homebrew is now a defacto standard package manager for macOS users, from the Jenkins standpoint it made sense to deprecate the native installers.

Why now? There is ongoing work on automating Jenkins Core releases within the Jenkins infrastructure. Long story short, we are moving Jenkins release pipelines to Kubernetes on Microsoft Azure. This environment does not offer macOS machines that are needed to produce native installers. If you are interested to know more, there will be a How Jenkins Builds and Delivers Jenkins in the Cloud talk presented by Olivier Vernin at DevOps World | Jenkins World 2019 Europe in Lisbon (use the JWFOSS code for a 30% discount!).

We could have used an external service for building macOS installers, but it would have added an additional point of failure and implementation/maintenance overhead. So we discussed it in the developer mailing list and agreed that it is better to just deprecate and then remove the packages.

Replacing native installers

In the case of macOS, there are two main alternatives available: managing the service manually or migrating to Homebrew packages. Before doing a migration, we highly recommend backing up your instance.

Managing Jenkins with WAR file on macOS

If your Jenkins instance was previously set up with a native installer, to update Jenkins it will be enough to replace the jenkins.war file in the installation directory and restart the instance. The services will keep running as it was configured before the migration. The default installation directory is /Applications/Jenkins/jenkins.war

Managing Jenkins with Homebrew

Installing Jenkins with Homebrew is a way to go for those who want to install Jenkins using a package manager. There are two Homebrew formulas for Jenkins: jenkins for Weekly releases and jenkins-lts for LTS ones. These packages are supported by a third party (Homebrew community), and they may be not as frequently updated as packages supported by the Jenkins project directly.

Before doing a migration from macOS Native installers to HomeBrew, please make sure to backup your Jenkins instance. There are no automatic migration tools available, and the installation may corrupt your JENKINS_HOME or service configuration files in edge cases.

If you switch to Homebrew, you will need to properly migrate the JENKINS_HOME data to the new location. We do not provide an official migration guide, but it is possible to find some guidelines on the Web.

Sample commands:

  • Install the latest Weekly version: brew install jenkins

  • Install a specific Weekly version: brew install jenkins@YOUR_VERSION

  • Start the Jenkins service: brew services start jenkins

  • Restart the Jenkins service: brew services restart jenkins

  • Update the Jenkins version: brew upgrade jenkins

For more information see the documentation for Homebrew packages on the macOS Download pages.

Rollout plan

  1. macOS native packaging is considered as deprecated starting from Jenkins 2.206 and Jenkins LTS 2.204.1

  2. For Jenkins Weekly macOS native packaging will be removed with the switch to the new Jenkins release flow. The exact date is to be determined.

    • After the change, there will be no macOS native installers produced for new Jenkins Weekly releases

    • Releases for previous versions will be available in this archive

  3. For Jenkins LTS macOS will be removed with the switch to the new Jenkins release flow in the LTS baseline. This change will happen only after the deployment of the new release flow in Jenkins Weekly.

    • After the switch, there will be no macOS native installers produced for new Jenkins LTS releases

    • Releases for previous versions will be available in this archive

See the discussion on the developer mailing list for more information.

Questions and feedback

If you have any questions or want to provide feedback, please use the developer mailing list thread mentioned above Platform SIG channels (chat, google group). Any feedback will be much appreciated because we plan more installer/ and platform deprecations in the future.

Do Plugins Store Credentials In A Secure Way? - DevOps World | Jenkins World 2019

Next: Matrix building in scripted pipeline
Previous: Jenkins macOS native installer deprecation
$
0
0
This is a speaker blog post for a DevOps World | Jenkins World 2019 talk in Lisbon, Portugal and has been posted in line with NCC Group responsible disclosure policy. Related Jenkins security advisories:2017-11-08,2017-11-16,2018-06-25,2018-07-30,2018-09-25,2019-02-19,2019-03-06,2019-03-25,2019-04-03,2019-04-17,2019-08-07,2019-09-12,2019-10-01,2019-10-16,2019-10-23. Some of the vulnerabilities have been announced without a fix, see Jenkins Security Spring Cleaning 2019. The most of the announced vulnerabilities are fixed at the moment of this blogpost publishing.

Come join us at DevOps World | Jenkins World 2019 for "The Story, the Findings and the Fixes Behind More than 100 Jenkins Plugins Vulnerabilities", a talk about the most common vulnerabilities found during research in more than 100 plugins. We’ll review how to prevent these vulnerabilities during plugin development so that a more secure Jenkins CI and CD environment can be built.

When I first began familiarising myself with Jenkins, I found myself almost overwhelmed by the amount of plugins to choose from. Most of these plugins are developed by third party developers or companies and can assist the user in a range of ways. They can extend the core functions, they can offer solutions to repetitive tasks or they can help with using a service. For example, they could help with publishing to an artifact store or spinning up cloud instances. However, before a plugin can use a network based service that requires credentials to connect, those credentials have to be typed in and saved somewhere. This raises the question, are those credentials stored securely? Or not? When I started looking at different plugins this was one of the first areas I investigated. I found a Jenkins security advisory describing this issue and came to the conclusion that this could be a problem in some plugins, albeit one that could be fixed easily. I found an example of weakly stored credentials in the Publish Over Dropbox Plugin; this plugin used a simple web form with a textbox element to display the token in the plugin’s settings page. This token was stored in plaintext:

PluginWebForm

The following Jelly code was behind the web form and shows that a password field wasn’t used:

<f:entrytitle="${%Token}"field="authorizationCode"><f:textbox/>

The related plugin .xml file contained the secret key in plaintext:

<org.jenkinsci.plugins.publishoverdropbox.impl.DropboxTokenImplplugin="publish-over-dropbox@1.2.2"><scope>GLOBAL</scope><id>woodspeed</id><description></description><authorizationCode>lYD2VnNz</authorizationCode><accessCode>lYD2VnNz</accessCode></org.jenkinsci.plugins.publishoverdropbox.impl.DropboxTokenImpl>

Jenkins offers at least two ways to store credentials in an encrypted format:

  • Using a Secret type offered by Jenkins

  • Third party plugin called Credentials Plugin

The first case is the easiest solution, because Jenkins will automatically handle the encryption and decryption.

Developers should also use the password field tag instead of the textbox field, as shown in the following Jelly control example:

<f:entrytitle="${%Secret Access Key}"help="..."><f:passwordfield="secretKey"/></f:entry>

If you would like to know what other vulnerabilities I discovered and how to fix them, come and join us for the presentation in Lisbon! In case you are unable to attend the conference, you can read more at Story of a Hundred Vulnerable Jenkins Plugins.

Matrix building in scripted pipeline

Next: Introducing the AWS Secrets Manager Credentials Provider for Jenkins
Previous: Do Plugins Store Credentials In A Secure Way? - DevOps World | Jenkins World 2019
$
0
0

With the recent announcement about matrix building you can performMatrix builds with declarative pipeline. However, if you must use scripted pipeline, then I’m going to cover how to matrix build platforms and tools using scripted pipeline. The examples in this post are modeled after the declarative pipeline matrix examples.

Matrix building with scripted pipeline

The following Jenkins scripted pipeline will build combinations across two matrix axes. However, adding more axes to the matrix is just as easy as adding another entry to the Map matrix_axes.

Jenkinsfile
// you can add more axes and this will still workMap matrix_axes = [PLATFORM: ['linux', 'windows', 'mac'],BROWSER: ['firefox', 'chrome', 'safari', 'edge']
]@NonCPSList getMatrixAxes(Map matrix_axes) {List axes = []
    matrix_axes.each { axis, values ->List axisList = []
        values.each { value ->
            axisList << [(axis): value]
        }
        axes << axisList
    }// calculate cartesian product
    axes.combinations()*.sum()
}// filter the matrix axes since// Safari is not available on Linux and// Edge is only available on WindowsList axes = getMatrixAxes(matrix_axes).findAll { axis ->
    !(axis['BROWSER'] == 'safari'&& axis['PLATFORM'] == 'linux') &&
    !(axis['BROWSER'] == 'edge'&& axis['PLATFORM'] != 'windows')
}// parallel task mapMap tasks = [failFast: false]for(int i = 0; i < axes.size(); i++) {// convert the Axis into valid values for withEnv stepMap axis = axes[i]List axisEnv = axis.collect { k, v ->"${k}=${v}"
    }// let's say you have diverse agents among Windows, Mac and Linux all of// which have proper labels for their platform and what browsers are// available on those agents.String nodeLabel = "os:${axis['PLATFORM']}&& browser:${axis['BROWSER']}"
    tasks[axisEnv.join(', ')] = { ->
        node(nodeLabel) {
            withEnv(axisEnv) {
                stage("Build") {
                    echo nodeLabel
                    sh 'echo Do Build for ${PLATFORM} - ${BROWSER}'
                }
                stage("Test") {
                    echo nodeLabel
                    sh 'echo Do Build for ${PLATFORM} - ${BROWSER}'
                }
            }
        }
    }
}

stage("Matrix builds") {
    parallel(tasks)
}

Matrix axes contain the following combinations:

[PLATFORM=linux, BROWSER=firefox]
[PLATFORM=windows, BROWSER=firefox]
[PLATFORM=mac, BROWSER=firefox]
[PLATFORM=linux, BROWSER=chrome]
[PLATFORM=windows, BROWSER=chrome]
[PLATFORM=mac, BROWSER=chrome]
[PLATFORM=windows, BROWSER=safari]
[PLATFORM=mac, BROWSER=safari]
[PLATFORM=windows, BROWSER=edge]

It is worth noting that Jenkins agent labels can contain a colon (:). Soos:linux and browser:firefox are both valid agent labels. The node expression os:linux && browser:firefox will search for Jenkins agents which have both labels.

Screenshot of matrix pipeline

The following is a screenshot of the pipeline code above running in a sandbox Jenkins environment.

Screenshot of matrix pipeline

Adding static choices

It is useful for users to be able to customize building matrices when a build is triggered. Adding static choices requires only a few changes to the above script. Static choices as in we hard code the question and matrix filters.

Jenkinsfile
Map response = [:]
stage("Choose combinations") {
    response = input(id: 'Platform',message: 'Customize your matrix build.',parameters: [
            choice(choices: ['all', 'linux', 'mac', 'windows'],description: 'Choose a single platform or all platforms to run tests.',name: 'PLATFORM'),
            choice(choices: ['all', 'chrome', 'edge', 'firefox', 'safari'],description: 'Choose a single browser or all browsers to run tests.',name: 'BROWSER')
        ])
}// filter the matrix axes since// Safari is not available on Linux and// Edge is only available on WindowsList axes = getMatrixAxes(matrix_axes).findAll { axis ->
    (response['PLATFORM'] == 'all' || response['PLATFORM'] == axis['PLATFORM']) &&
    (response['BROWSER'] == 'all' || response['BROWSER'] == axis['BROWSER']) &&
    !(axis['BROWSER'] == 'safari'&& axis['PLATFORM'] == 'linux') &&
    !(axis['BROWSER'] == 'edge'&& axis['PLATFORM'] != 'windows')
}

The pipeline code then renders the following choice dialog.

Screenshot of a dialog asking a question to customize matrix build

When a user chooses the customized options, the pipeline reacts to the requested options.

Screenshot of pipeline running requested user customizations

Adding dynamic choices

Dynamic choices means the choice dialog for users to customize the build is generated from the Map matrix_axes rather than being something a pipeline developer hard codes.

For user experience (UX), you’ll want your choices to automatically reflect the matrix axis options you have available. For example, let’s say you want to add a new dimension for Java to the matrix.

// you can add more axes and this will still workMap matrix_axes = [PLATFORM: ['linux', 'windows', 'mac'],JAVA: ['openjdk8', 'openjdk10', 'openjdk11'],BROWSER: ['firefox', 'chrome', 'safari', 'edge']
]

To support dynamic choices, your choice and matrix axis filter needs to be updated to the following.

Map response = [:]
stage("Choose combinations") {
    response = input(id: 'Platform',message: 'Customize your matrix build.',parameters: matrix_axes.collect { key, options ->
            choice(choices: ['all'] + options.sort(),description: "Choose a single ${key.toLowerCase()} or all to run tests.",name: key)
        })
}// filter the matrix axes since// Safari is not available on Linux and// Edge is only available on WindowsList axes = getMatrixAxes(matrix_axes).findAll { axis ->
    response.every { key, choice ->
        choice == 'all' || choice == axis[key]
    } &&
    !(axis['BROWSER'] == 'safari'&& axis['PLATFORM'] == 'linux') &&
    !(axis['BROWSER'] == 'edge'&& axis['PLATFORM'] != 'windows')
}

It will dynamically generate choices based on available matrix axes and will automatically filter if users customize it. Here’s an example dialog and rendered choice when the pipeline executes.

Screenshot of dynamically generated dialog for user to customize choices of matrix build

Screenshot of pipeline running user choices in a matrix

Full pipeline example with dynamic choices

The following script is the full pipeline example which contains dynamic choices.

// you can add more axes and this will still workMap matrix_axes = [PLATFORM: ['linux', 'windows', 'mac'],JAVA: ['openjdk8', 'openjdk10', 'openjdk11'],BROWSER: ['firefox', 'chrome', 'safari', 'edge']
]@NonCPSList getMatrixAxes(Map matrix_axes) {List axes = []
    matrix_axes.each { axis, values ->List axisList = []
        values.each { value ->
            axisList << [(axis): value]
        }
        axes << axisList
    }// calculate cartesian product
    axes.combinations()*.sum()
}Map response = [:]
stage("Choose combinations") {
    response = input(id: 'Platform',message: 'Customize your matrix build.',parameters: matrix_axes.collect { key, options ->
            choice(choices: ['all'] + options.sort(),description: "Choose a single ${key.toLowerCase()} or all to run tests.",name: key)
        })
}// filter the matrix axes since// Safari is not available on Linux and// Edge is only available on WindowsList axes = getMatrixAxes(matrix_axes).findAll { axis ->
    response.every { key, choice ->
        choice == 'all' || choice == axis[key]
    } &&
    !(axis['BROWSER'] == 'safari'&& axis['PLATFORM'] == 'linux') &&
    !(axis['BROWSER'] == 'edge'&& axis['PLATFORM'] != 'windows')
}// parallel task mapMap tasks = [failFast: false]for(int i = 0; i < axes.size(); i++) {// convert the Axis into valid values for withEnv stepMap axis = axes[i]List axisEnv = axis.collect { k, v ->"${k}=${v}"
    }// let's say you have diverse agents among Windows, Mac and Linux all of// which have proper labels for their platform and what browsers are// available on those agents.String nodeLabel = "os:${axis['PLATFORM']}&& browser:${axis['BROWSER']}"
    tasks[axisEnv.join(', ')] = { ->
        node(nodeLabel) {
            withEnv(axisEnv) {
                stage("Build") {
                    echo nodeLabel
                    sh 'echo Do Build for ${PLATFORM} - ${BROWSER}'
                }
                stage("Test") {
                    echo nodeLabel
                    sh 'echo Do Build for ${PLATFORM} - ${BROWSER}'
                }
            }
        }
    }
}

stage("Matrix builds") {
    parallel(tasks)
}

Background: How does it work?

The trick is in axes.combinations()*.sum(). Groovy combinations are a quick and easy way to perform acartesian product.

Here’s a simpler example of how cartesian product works. Take two simple lists and create combinations.

List a = ['a', 'b', 'c']List b = [1, 2, 3]

[a, b].combinations()

The result of [a, b].combinations() is the following.

[
    ['a', 1],
    ['b', 1],
    ['c', 1],
    ['a', 2],
    ['b', 2],
    ['c', 2],
    ['a', 3],
    ['b', 3],
    ['c', 3]
]

Instead of a, b, c and 1, 2, 3 let’s do the same example again but instead using matrix maps.

List java = [[java: 8], [java: 10]]List os = [[os: 'linux'], [os: 'freebsd']]

[java, os].combinations()

The result of [java, os].combinations() is the following.

[
    [ [java:8],  [os:linux]   ],
    [ [java:10], [os:linux]   ],
    [ [java:8],  [os:freebsd] ],
    [ [java:10], [os:freebsd] ]
]

In order for us to easily use this as a single map we must add the maps together to create a single map. For example, adding[java: 8] + [os: 'linux'] will render a single hashmap[java: 8, os: 'linux']. This means we need our list of lists of maps to become a simple list of maps so that we can use them effectively in pipelines.

To accomplish this we make use of theGroovy spread operator (*. in axes.combinations()*.sum()).

Let’s see the same java/os example again but with the spread operator being used.

List java = [[java: 8], [java: 10]]List os = [[os: 'linux'], [os: 'freebsd']]

[java, os].combinations()*.sum()

The result is the following.

[
    [ java: 8,  os: 'linux'],
    [ java: 10, os: 'linux'],
    [ java: 8,  os: 'freebsd'],
    [ java: 10, os: 'freebsd']
]

With the spread operator the end result of a list of maps which we can effectively use as matrix axes. It also allows us to do neat matrix filtering with the findAll {} Groovy List method.

Exposing a shared library pipeline step

The best user experience is to expose the above code as a shared library pipeline step. As an example, I have addedvars/getMatrixAxes.groovy to Jervis. This provides a flexible shared library step which you can copy into your own shared pipeline libraries.

The step becomes easy to use in the following way with a simple one dimension matrix.

Jenkinsfile
Map matrix_axes = [PLATFORM: ['linux', 'windows', 'mac'],
]List axes = getMatrixAxes(matrix_axes)// alternately with a user prompt//List axes = getMatrixAxes(matrix_axes, user_prompt: true)

Here’s a more complex example using a two dimensional matrix with filtering.

Jenkinsfile
Map matrix_axes = [PLATFORM: ['linux', 'windows', 'mac'],BROWSER: ['firefox', 'chrome', 'safari', 'edge']
]List axes = getMatrixAxes(matrix_axes) { Map axis ->
    !(axis['BROWSER'] == 'safari'&& axis['PLATFORM'] == 'linux') &&
    !(axis['BROWSER'] == 'edge'&& axis['PLATFORM'] != 'windows')
}

And again with a three dimensional matrix with filtering and prompting for user input.

Jenkinsfile
Map matrix_axes = [PLATFORM: ['linux', 'windows', 'mac'],JAVA: ['openjdk8', 'openjdk10', 'openjdk11'],BROWSER: ['firefox', 'chrome', 'safari', 'edge']
]List axes = getMatrixAxes(matrix_axes, user_prompt: true) { Map axis ->
    !(axis['BROWSER'] == 'safari'&& axis['PLATFORM'] == 'linux') &&
    !(axis['BROWSER'] == 'edge'&& axis['PLATFORM'] != 'windows')
}

The script approval is not necessary forShared Libraries.

If you don’t want to provide a shared step. In order to expose matrix building to end-users, you must allow the following method approval in the script approval configuration.

Script approval
staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods combinations java.util.Collection

Summary

We covered how to perform matrix builds using scripted pipeline as well as how to prompt users for customizing the matrix build. Additionally, an example was provided where we exposed getting buildable matrix axes to users as an easy to use Shared Library step via vars/getMatrixAxes.groovy. Using a shared library step is definitely the recommended way for admins to support users rather than trying to whitelist groovy methods.

Jervis shared pipeline library has supported matrix building since 2017 in Jenkins scripted pipelines. (see here andhere for an example).

Introducing the AWS Secrets Manager Credentials Provider for Jenkins

Next: Generic Webhook Trigger Plugin
Previous: Matrix building in scripted pipeline
$
0
0

API keys and secrets are difficult to handle safely, and probably something you avoid thinking about. In this post I’ll show how the new AWS Secrets Manager Credentials Provider plugin allows you to marshal your secrets into one place, and use them securely from Jenkins.

When CI/CD pipelines moved to the public cloud, credential management did not evolve with them. If you’re in this situation, you may have seen a number of tactical workarounds to keep Jenkins builds talking to the services they depend on. The workarounds range from bad (hardcoding plaintext secrets into Git) to merely painful (wrangling Hiera EYAML), but their common feature is that they tend to make copies of secrets beyond the reach of automation. This increases their attack surface, makes routine key rotation impractical, and makes remediation difficult after a breach.

The good news is that there is a better way!

AWS Secrets Manager is a comprehensive solution for secure secret storage. You define a secret just once for your whole AWS account, then you give your consumers permission to use the secrets. Secrets Manager lets you manage a secret entry (name and metadata) separately from its value, and it integrates with other AWS services that you already use:

  • Secret entry management: Manual (Web console, AWS CLI) or with an infrastructure management tool (Terraform, CloudFormation etc.)

  • Secret value management: Manual (Web console, AWS CLI) or automatic (secret rotation Lambda function).

  • Access control: AWS IAM policies (for both applications and human operators).

  • Secret encryption: Amazon KMS automatically encrypts the secret value. Use either the account’s default KMS key, or a customer-managed KMS key.

  • Auditing: AWS CloudTrail and CloudWatch Events.

A couple of teams in my company started to use Secrets Manager from Jenkins jobs by calling the AWS CLI, but this remained a niche approach as it was quite unwieldy. There was clearly an appetite to integrate key developer apps with a centralised secrets store, but production-ready integrations were needed for wider adoption. So this year I created the AWS Secrets Manager Credentials Provider plugin for Jenkins, with help from friends in the Jenkins community, to do exactly that.

This is how you set it up…​

  1. Install the plugin from the Jenkins update center.

  2. Give Jenkins read-only access to Secrets Manager with an IAM policy.

  3. (Optional) Configure the plugin, either through the Global Configuration screen or Jenkins Configuration As Code.

This is how you use it…​

  1. Create your build secrets in AWS Secrets Manager. (You can start by uploading secrets via the AWS CLI. More sophisticated methods of secret creation are also available.)

  2. View the credentials in the Jenkins UI, to check that Jenkins can see them.

  3. Bind the credentials by ID in your Jenkins job.

The provider supports the following standard Jenkins credential types:

  • Secret Text

  • Username With Password

  • SSH User Private Key

  • PKCS#12 Certificate

And it has powerful advantages over quick-fix tactical solutions:

  • Your Jenkins jobs consume the credentials with no knowledge of Secrets Manager, so they stay vendor-independent.

  • The provider caches relevant Secrets Manager API calls, for a quicker and more reliable experience.

  • The provider integrates with the ecosystem of existing Jenkins credential consumers, such as the Git and SSH Agent plugins.

  • The provider records credential usage in the central Jenkins credentials tracking log.

  • Jenkins can use multiple credentials providers concurrently, so you can incrementally migrate credentials to Secrets Manager while consuming other credentials from your existing providers.

After the plugin’s first public release, developers at other companies adopted it too. It has had contributions so far from people at Elsevier, GoDaddy, and Northeastern University, as well as the fantastic Jenkins core team. We even got fan mail for our work!

In enterprise security, "The important things are always simple. The simple things are always hard. The easy way is always mined." (@thegrugq) It’s easy to buy a shiny ‘next generation' security appliance and drop it into your network. But it’s hard to embed the security fundamentals (like secrets management, OS patching, secure development) across your organisation. This Jenkins plugin is part of the effort [1] to take one of the persistent hard problems in security, and make it easier for everyone.


1. If you’re on Azure or you run most of your workload on Kubernetes, check out the Azure Credentials Plugin and the Kubernetes Credentials Provider Plugin.

Generic Webhook Trigger Plugin

Next: 2019 Jenkins Board and Officer Elections Results
Previous: Introducing the AWS Secrets Manager Credentials Provider for Jenkins
$
0
0

This post will describe some common problems I’ve had with Jenkins and how I solved them by developing Generic Webhook Trigger Plugin.

The Problem

I was often struggling with the same issues when working with Jenkins:

  • Code duplication and security - Jenkinsfiles in every repository.

  • A branch is not a feature - Parameterized jobs on master branch often mix parameters relevant for different features.

  • Poorly documented trigger plugins - Proper documented services but poorly documented consuming plugins.

Code Duplication And Security

Having Jenkinsfiles in every Git repository allows developers to let those files diverge. Developers pushes forward with their projects and it is hard to maintain patterns to share code.

I have, almost, solved code duplication with shared libraries but it does not allow me to setup a strict pattern that must be followed. Any developer can still decide to not invoke the features provided by the shared library.

There is also the security aspect of letting developers run any code from the Jenkinsfiles. Developers might, for example, print passwords gathered from credentials. Letting developers execute any code on the Jenkins nodes just does not seem right to me.

A Branch Is Not A Feature

In Bitbucket there are projects and each project has a collection of git repositories. Something like this:

  • PROJ_1

    • REPO_1

    • REPO_2

  • PROJ_2

    • REPO_3

Lets think about some features we want to provide for these repositories:

  • Pull request verification

  • Building snapshot (or pre release if you will)

  • Building releases

If the developers are use to the repositories being organized like this in Bitbucket, should we not organize them the same way in Jenkins? And if they browse Jenkins should they not find one job per feature, like pull-request, snapshot and release? Each job with parameters only relevant for that feature. I think so! Like this:

  • / - Jenkins root

    • /PROJ_1 - A folder, lists git repositories

      • /PROJ_1/REPO_1 - A folder, lists jobs relevant for that repo.

      • /PROJ_1/REPO_1/release - A job, performs releases.

      • /PROJ_1/REPO_1/snapshot - A job, performs snapshot releases.

      • /PROJ_1/REPO_1/pull-request - A job, verifies pull requests.

  • …​

In this example, both snapshot and release jobs might work with the same git branch. The difference is the feature they provide. Their parameters can be well documented as you don’t have to mix parameters relevant for releases and those relevant for snapshots. This cannot be done with Multibranch Pipeline Plugin where you specify parameters as properties per branch.

Documentation

Webhooks are often well documented in the services providing them. See:

It bothered me that, even if I understood these webhooks, I was unable to use them. Because I needed to perform development in the plugin I was using in order to provide whatever value from the webhook to the build. That process could take months from PR to actual release. Such a simple thing should really not be an issue.

The Solution

My solution is pretty much back to basics: We have an automation server (Jenkins) and we want to trigger it on external webhooks. We want to gather information from that webhook and provide it to our build. In order to support it I have created the Generic Webhook Trigger Plugin.

The latest docs are available in the repo and I also have a fully working example with GitLab implemented using configuration-as-code. See the repository here.

Code Duplication And Security

I establish a convention that all developers must follow. Instead of letting the developers explicitly invoke the infrastructure from Jenkinsfiles. There are rules to follow, like:

  • All git repositories should be built from the root of the repo.

  • If it contains a gradlew

    • Build is done with ./gradlew build

    • Release is done with ./gradlew release

    • …​ and so on

  • If it contains a package.json

    • Build is done with npm run build

    • Release is done with npm run release

    • …​ and so on

With these rules, pipelines can be totally generic and no Jenkinsfiles are needed in the repositories. Some git repositories may, for some reason, need to disable test cases. That can be solved by allowing repositories to add a special file, perhaps jenkins-settings.json, let the infrastructure discover and act on its content.

This also helps the developers even when not doing CI. When they clone a new, to them unknown, repository they will know what commands can be issued and their semantics.

A Branch Is Not A Feature

I implement:

By integrating with the git service from Job DSL I can automatically find the git repositories. I create jobs dynamically organized in folders. Also invoking the git service to setup webhooks triggering those jobs. The jobs are ordinary pipelines, not multibranch, and they don’t use Jenkinsfile from Git but instead Jenksinfile configured in the job using Job DSL. So that all job configurations and pipelines are under version control. This is all happening here.

Documentation

The plugin uses JSONPath, and also XPath, to extract values from JSON and provide them to the build. Letting the user pick whatever is needed from the webhook. It also has a regular expression filter to allow not triggering for some conditions.

The plugin is not very big, just being the glue between the webhook, JSONPath/XPath and regular expression. All these parts are very well documented already and I do my best supporting the plugin. That way this is a very well documented solution to use!

2019 Jenkins Board and Officer Elections Results

Next: Google Summer of Code 2020 call for Project ideas and Mentors
Previous: Generic Webhook Trigger Plugin
$
0
0

Jenkins Elections

The Jenkins community has recently completed the 2019 elections for Board and Officer positions. The call for nominations concluded on Nov 25 and the election results were announced in the developer mailing list on Nov 28.

On behalf of the Jenkins community, we congratulate all elected board members and officers! We also thank all contributors who participated this year: all nominees and hundreds of voters. These are the first elections ever conducted by the Jenkins project, and it is a big milestone for the community.

Election results:

If you are interested to learn more, please see the blog post below.

Board election details

  1. Oleg Nenashev (Condorcet winner: wins contests with all other choices)

  2. Mark Waite loses to Oleg Nenashev by 181–127

  3. Ullrich Hafner loses to Oleg Nenashev by 198–115, loses to Mark Waite by 171–133

  4. Alex Earl loses to Oleg Nenashev by 225–82, loses to Ullrich Hafner by 168–128

  5. Oliver Gondža loses to Oleg Nenashev by 227–76, loses to Alex Earl by 151–136

  6. Zhao Xiaojie (aka Rick) loses to Oleg Nenashev by 233–82, loses to Oliver Gondža by 160–131

Although Mark Waite came second in the voting results, being on the board would violate the Corporate Involvement clause which states that "the number of board members affiliated with one company must be less than 50%". Based on that rule, the third seat Alex Earl will join the Jenkins board. At the same time, Mark Waite will take the newly introduced role of Documentation officer.

All new board members are elected for a 2-year term, unless they step down earlier. The estimated end of term for them is December 02, 2021. The actual date will depend on the election schedule in 2021.

Officer election details

We have reelected all 5 officers for the new 1-year term, with the estimated end of term on Dec 02, 2020.

When an officer position has only one candidate that is willing to accept the nomination, there is no reason to vote on that position. This year some nominees declined the nominations before the election happened, and 3 officer nominations were finally uncontested:Olivier Vernin - infrastructure officer,Oliver Gondža - release officer,Mark Waite - documentation officer.

Statistics

Here are some voting stats from these elections:

  • Total number of eligible accounts: 91,015

  • Total number of registered voters: 831

  • Total number of votes: 343

This election was hosted on the Condorcet Internet Voting Service (CIVS). While preparing for the elections, we discovered that CIVS is unable to support our large number of eligible voters. We created a voter registration system to identify voters and then registered those voters with CIVS. The workaround required a slight voting delay. Special thanks to Olivier Vernin and Tracy Miranda who made it possible!

What’s next for the board?

In short term, the renewed board will focus on running the Jenkins governance processes (meetings, budget approvals, funding, etc.) and defining next steps towards improving the project. One of the priorities will be to organize knowledge and permission transfers to new board members so that they can be effective in their new roles. There are also pending activities like Jenkins' transition to Continuous Delivery Foundation which require attention from board members.

For longer term, there are some ideas floating around: roadmap for key components, long-anticipated architecture changes (UX revamp, pluggable storage, cloud native Jenkins), adopting Linux Foundation best practices like Core Infrastructure Initiative, contributor onboarding, etc. Such initiatives are instrumental for further evolvement of the Jenkins project, and the board could help to facilitate them in the community. The ideas will be discussed in mailing lists and during governance meetings. If you would like to share your vision and ideas about what’s needed in the project, it is definitely a great time to do so!

Feedback

We will also also plan to conduct a public retrospective at one of the next Advocacy and Outreach SIG meetings.

Jenkins project plans to conduct elections every year. We appreciate and welcome any feedback regarding the election process. Please use the following channels for feedback and suggestions:

Google Summer of Code 2020 call for Project ideas and Mentors

Next: Happy New Year! 2019/2020 edition
Previous: 2019 Jenkins Board and Officer Elections Results
$
0
0
Google Summer of Code (GSoC) is as program where students are paid a stipend by Google to work on a free open source project. Students work on the project full-time for four months (May to August). Mentors are actively involved with students starting at the end of February when students start to work on and submit their applications. (see the timeline)

Jenkins GSoC

We are looking for project ideas and mentors to participate in GSoC 2020. GSoC project ideas are coding projects that university or college students can accomplish in about four months. The coding projects can be new features, plugins, test frameworks, infrastructure, etc. Anyone can submit a project idea, but of course we like it even better if you offer to mentor your project idea.

We accept new project ideas at any time, BUT we need a series of ideas READY before February 5th, 2020 at 7pm UTC, which is the deadline for the Jenkins organization to apply to the GSoC program. So send us your project ideas before the beginning of February so they can get a proper review by the GSoC committee and by the community.

How to submit a project idea

For 2020, we have simplified the process. Simply create a pull-request with your idea in a .adoc file in the idea folder. It is no longer necessary to submit a Google Doc, but it will still work if you want to do that. See the instructions on submitting ideas which include an .adoc template and some examples.

Current list of ideas

We currently have a list of project ideas for students to browse, copied from last year. Note that this list is subject to change.

What does mentoring involve?

Potential mentors are invited to read the information for mentors. Note that being a GSoC mentor does not require expert knowledge of Jenkins. Mentors do not work alone. We make sure that every project has at least two mentors. GSoC org admins will help to find technical advisers, so you can study together with your students.

Mentoring takes about 5 to 8 hours of work per week (more at the start, less at the end). Mentors provide guidance, coaching, and sometimes a bit of cheerleading. They review student proposals, pull-requests and the students presentations at the evaluation phase. They fill in the Google provided evaluation report form at the end of coding periods.

What do you get in exchange?

In return of mentoring, a student works on your project full time for four months. Think about the projects that you’ve always wanted to do but never had the time…​

Having a mentoring opportunity also means that you get to improve your management and people skills.

As well, up to two mentors per organization are eligible to participate in the Google Mentor Summit taking place each year. The Jenkins Org Admins try to send different mentors each year. It is also possible to win an additional seat at the summit in the "last minute draw" (Google draws mentors at random to fill the cancellations and empty seats).

See this post from one of the 2019 mentors on the kind of experience this was.

GSoC is a pretty good return on the investment!

For any question, you can find the GSoC Org Admins, mentors and participants on the GSoC SIG Gitter chat.


Happy New Year! 2019/2020 edition

Next: Atlassian's new Bitbucket Server integration for Jenkins
Previous: Google Summer of Code 2020 call for Project ideas and Mentors
$
0
0

Jenkins project congratulates all users and contributors with the New Year! Let’s take a look at some changes this year.

NewYear

Highlights

If you are interested to know more about Jenkins features introduced in 2019, stay tuned for a separate blog post about it (coming soon!).

Project updates

Highlights above do not cover all advancements we had in the project. Below you can find slides from the Jenkins contributor summit in Lisbon. There we had project updates by officers, SIG and sub-project leaders. See the slide deck to know about: Jenkins Core, Pipeline, Configuration-as-Code, Security, UX Overhaul, Jenkins Infrastructure, platform support and documentation.

Some stats and numbers

If this section seems to be too long for you, here is some infographic prepared by Tracy Miranda. As you may see, Jenkins is pretty big :)

Jenkins 2019 in numbers

Community. Over the past year we had 5433 contributors in GitHub repositories (committers, reviewers, issue submitters, etc.). We had 1892 unique committers who created 7122 pull requests and 45484 commits, bots excluded. Contributors represent 273 companies and 111 countries, 8% of contributors are recognized as independent. The most active repositories were Jenkins Core and jenkins.io. The most active month was October 2019 when we reached the record high number of contributions: 915 unique contributors, 124 of them were first-timers, thanks to Hacktoberfest!.

Jenkins core. In 2019 Jenkins core had 54 weekly and 13 LTS releases with several hundreds of notable fixes/enhancements. There was a login screen extensibility rework, many update manager and administrative monitors improvements. We also introduced support for user timezones, not speaking of emojis support 🥳. There was also a lot of housekeeping work: better APIs, codebase refresh, cleaning up static analysis warnings and removing deprecated features like Remoting CLI. The core’s components also got major updates. Only Jenkins Remoting got 11 releases with stability improvements and new features like support of inbound connections to headless Jenkins masters. There are also major incoming features like JEP-222: WebSocket Services support, UI look&feel updates, JENKINS-12548: Readonly system configuration support, Docker images for new platforms like Arm. To facilitate further changes we created a new Core pull request reviewers team and added 9 contributors there.

Plugins. There were 2654 plugin releases, and 157 NEW plugins have been hosted in the Update Center. Jenkins ecosystem got a lot of new integrations with Development and DevOps tools. Also, warm welcome back to the Scriptler Plugin which was depublished in 2017 due to security issues. If you are afraid about such plugin numbers and dependency management, there is a new Plugin Installation Manager CLI Tool which should help Jenkins users to manage plugins more efficiently.

Security. It was a hot year for the Jenkins Security Team. There were 5security advisories for the core and 20 - for plugins. In total we disclosed 288 vulnerabilities across the project, including some backlog cleaning for unmaintained plugins.Script Security Plugin was the hottest plugin with 10 critical fixes addressing various sandbox bypass vulnerabilities. Plain text storage and unprotected credentials were the most popular vulnerability type 120 disclosures in 2019. It was made possible by hundreds of reports submitted by contributors after code surveys, special thanks to Viktor Gazdag who reported the most of the issues and became the Jenkins 2019 Security MVP (check out his story here).

Infrastructure. Got Jenkins? If so, you rely on Jenkins update centers, website and issue tracker. All these and many other services are maintained by the Jenkins Infrastructure Team. This year the team handled more than 400 requests in the bugtracker, and many other informal requests. In total, more than 30 people contributed to Jenkins infrastructure this year (website content is excluded). We also deployed 4 new services, migrated 7 services from Azure Container Service to Azure Kubernetes Service and updated many other services. More changes will happen in the next months, and we are looking for new INFRA team members!

Documentation. Only last quarter we had 178 contributors to Jenkins documentation. It includes jenkins.io and other documentation hosted on GitHub, Wiki is not included. There is also ongoing migration plugin documentation from Jenkins Wiki to GitHub (announcement). Since the beginning of the project in Sep 2019, more than 150 plugin were migrated, and they got significant documentation revamp during the migration. You can see the current status https://jenkins-wiki-exporter.jenkins.io/progress. We also work on introducing changelog automation in the project.123 plugins have already adopted the new changelog tools, powered by Release Drafter. Also, we had more than 60 technical blog posts published on jenkins.io.

Configuration as Code was one of the most popular areas this year.Jenkins Configuration as Code Plugin had more than 30 releases with new features and bug fixes. More than 50 plugins have been also updated in order to offer better configuration-as-code support. As a result, the JCasC Plugin got massive adoption this year (from 2000 to almost 8000 installations), and now it becomes a de-facto standard for managing Jenkins as code. This year we also ran our very first CommunityBridge project devoted to JCasC Schema validation and developer tools.

Events and outreach programs. In 2019 we participated in multiple conferences, including FOSDEM, DevOps World | Jenkins World, SCALE. More than 40 Jenkins Area Meetups were organized across the world, and there were many other meetups devoted to Jenkins. We also kept expanding our outreach programs. In total we had 12 students who participated in Google Summer of Code, Outreachy and newly introduced Community Bridge. We also had the biggest ever Hacktoberfest with 664 pull requests and 102 participants. These outreach programs help us to deliver new features in Jenkins. For example, this year we added Multi-branch Pipeline support for Gitlab and a new Plugin Installation Manager Tool during GSoC, and Outreachy resulted in a new Audit Log Plugin.

Where did we get those stats? GitHub stats came from the CDF DevStats service. These stats include all repositories in the jenkinsci organization and most popular repositories in jenkins-infra, Jenkins X and other organizations/repositories within the project are not included. Other stats came from project reports, component changelogs, Jenkins usage statistics service, plugin releases history.

What’s next?

Year 2020 will be pretty busy for the Jenkins project. There are many long-overdue changes in the project, which need to happen if we want the project to succeed. As it was written Board elections blogpost, there are many areas to consider: UX revamp, cloud native Jenkins, pluggable storage, etc. In the coming months there will be a lot of discussions in mailing lists and special interest groups, and we invite all teams to work on their roadmaps and to communicate them in the community.

Next month we will participate in FOSDEM, and there will be a Jenkins stand there. On January 31st we will also host a traditional contributor summit in Brussels, where we will talk about next steps for the project, in terms of technical roadmaps and the project governance. If you are interested in Jenkins, stop by at our community booths and join us at the summit! See this thread for more information.

We also plan to continue all outreach programs. At the moment we are looking for Google Summer of Code 2020 mentors and project ideas (announcement), and we will be also interested to consider non-coding projects as a part of other programs like CommunityBridge. We also work on improving contribution guidelines for newcomers and expert contributors. If you are interested, please contact the Advocacy and Outreach SIG.

And even more

This blog post does not provide a full overview of what changed in the project. The Jenkins project consists of more than 2000 plugins and components which are developed by thousands of contributors. Thanks to them, a lot of changes happen in the project every day. We are cordially grateful to everybody who participates in the project, regardless of contribution size. Everything matters: new features, bug fixes, documentation, blog posts, well reported issues, Stackoverflow responses, etc. THANKS A LOT FOR ALL YOUR CONTRIBUTIONS!

So, keep updating Jenkins and exploring new features. And stay tuned, there is much more to come next year!

Atlassian's new Bitbucket Server integration for Jenkins

Next: FOSDEM 2020 is coming
Previous: Happy New Year! 2019/2020 edition
$
0
0

We know that for many of our customers Jenkins is incredibly important and its integration with Bitbucket Server is a key part of their development workflow. Unfortunately, we also know that integrating Bitbucket Server with Jenkins wasn’t always easy – it may have required multiple plugins and considerable time. That’s why earlier this year we set out to change this. We began building our own integration, and we’re proud to announce that v1.0 is out.

The new Bitbucket Server integration for Jenkins plugin, which is built and supported by Atlassian, is the easiest way to link Jenkins with Bitbucket Server. It streamlines the entire set-up process, from creating a webhook to trigger builds in Jenkins, to posting build statuses back to Bitbucket Server. It also supports smart mirroring and lets Jenkins clone from mirrors to free up valuable resources on your primary server.

Our plugin is available to install through Jenkins now. Watch this video to find out how, or read the BitBucket Server solution page to learn more about it.

Once you’ve tried it out we’d love to hear any feedback you have. To share it with us, visit https://issues.jenkins-ci.org and create an issue using the component atlassian-bitbucket-server-integration-plugin.

FOSDEM 2020 is coming

Next: A new chapter for Kohsuke
Previous: Atlassian's new Bitbucket Server integration for Jenkins
$
0
0
FOSDEM

FOSDEM 2020 is coming and with it, a lot of great folks come in town. It’s always a great moment to meet Jenkins community members, share stories and get inspired. I hope that this year will be as great as it always been and for that, we organize a few things

Things we’ll do

During the whole event, we’ll be virtually on the Gitter

On the Thursday 30 of January, there will be two workshops one about Jenkins Pipelines lead by Mark Waite, and a second one about JenkinsX by Viktor Farcic.

On the Friday 31 of January, the Jenkins project will hold a Contributor Summit where we invite active contributors and those who are interested in working on foundation projects, e.g. key architecture changes and projects (UX, JCasC, Cloud native Jenkins, etc.), governance, infrastructure. There will be no user-focused topics (no presentations, no trainings, etc.) but we will focus on defining key priorities for the project, building a roadmap and resolving issues we have in the project at the moment. We’ll end up the day with our now traditional Orval and flemish beef stew at Le Roy d’Espagne

Finally the FOSDEM, the 01 and 02 of February, we’ll all be at FOSDEM. So come and say "hi" at the Jenkins/JenkinsX stand, inside the CICD Devroom.

Or just come and share beers

Cheers

Atomium

A new chapter for Kohsuke

Next: Google Summer of Code 2019 Report
Previous: FOSDEM 2020 is coming
$
0
0

2020 is going to be a year of change for me. By the end of January, I’ll be officially stepping back from Jenkins, switching my role at CloudBees to an advisor, and turning attention to my new startup. The rest of this post is to contextualize this transition, because if you haven’t been working closely with me, this might come across as a surprise.

ThanksKohsuke

Jenkins has been an amazing journey that never stopped giving. I have loved it all - especially meeting the users around the world who made Jenkins what it is today. As the creator of the project, at some point I started wondering how to pass the torch to the next leaders, how to get people to step up and drive it forward. Today, thanks to CloudBees and the community, there is a new generation of talented and capable leaders who are passionately driving things forward - and it’s been great to see. Newly elected board members, Jenkins X folks, just to name a few. These new people bring new culture and new code, and altogether it has created a positive jolt that pushed Jenkins out of  a local optimum I talked about. They have all my support and respect. In reality, my involvement with Jenkins lately has already been largely symbolic, a little bit like an emperor of Japan or a queen of the UK. That’s why this announcement has little practical impact on the forward motion of Jenkins.

Several years ago, I used to feel like the sky would fall down if I stepped aside. Somewhere in 2019, I suddenly noticed that I wasn’t feeling like that at all anymore. The shift was gradual and steady, so I’m not sure exactly when I crossed the threshold, but in 2019 it was clear I was on the other side. That’s how I knew I could finally end this chapter of my life. 15 years with Jenkins and 9 years with CloudBees. That is a long time.

I hope you will be wondering what is my new chapter. I’m launching a new startup, Launchable, with my old time buddy Harpreet Singh. I have known him since my days at Sun Microsystems and JavaEE, and he was my partner in crime at CloudBees to build the Jenkins business from scratch. He went to Atlassian running its BitBucket business for a while, but now he and I are back sitting side by side again. A number of CloudBees people invested, including Sacha Labourey,Bob Bickel, and John Vrionis.

Through Jenkins and CloudBees, I was able to push the state of automation forward in software development. Such automation is producing a lot of data, but we are not using that data to improve our lives. It truly is a wasted gold mine. Launchable is working on harnessing that information to improve developer productivity. I wrote a separate blog post to discuss more about my thinking.

Lastly, even though I’m moving on from CloudBees as a full-time employee, I’m not completely going away. I’ll be still in the CloudBees orbit, as an advisor. I’m still very much invested both emotionally and financially in CloudBees. I’m still a big fan, and I’ll continue to cheer for them, but from the sideline. The same with Jenkins. I’m still on the governance board, ensuring the continuity. I’m also still on the Technical Oversight Committee of the Continuous Delivery Foundation, though my chairperson term will expire in March.

I’m incredibly grateful for the undeserved opportunity and the privilege given to me during this chapter. I was surrounded by wonderful, inspiring, and talented people, from whom I learned a lot. I can only hope that I was able to make a positive impact, and give something back in return to them. I won’t name names, but you know who you are, and we’ll stay in touch.

This year is going to be truly exciting for me. To infinity and beyond!!

Google Summer of Code 2019 Report

Next: WebSocket
Previous: A new chapter for Kohsuke
$
0
0

Google Summer of Code is much more than a summer internship program, it is a year-round effort for the organization and some community members. Now, after the DevOps World | Jenkins World conference in Lisbon and final retrospective meetings, we can say that GSoC 2019 is officially over. We would like to start by thanking all participants: students, mentors, subject matter experts and all other contributors who proposed project ideas, participated in student selection, in community bonding and in further discussions and reviews. Google Summer of Code is a major effort which would not be possible without the active participation of the Jenkins community.

In this blogpost we would like to share the results and our experience from the previous year.

Results

Highlights

Project details

We held the final presentations as Jenkins Online Meetups in late August and Google published the results on Sept 3rd. The final presentations can be found here:Part 1,Part 2,Part 3. We also presented the2019 Jenkins GSoC report at the DevOps World | Jenkins World San Francisco and at theDevOps World | Jenkins World 2019 Lisbon conferences.

In the following sections, we present a brief summary of each project, links to the coding phase 3 presentations, and to the final products.

Role Strategy Plugin Performance Improvements

Role Strategy Plugin is one of the most widely used authorization plugins for Jenkins, but it has never been famous for performance due to architecture issues and regular expression checks for project roles.Abhyudaya Sharma was working on this project together with hist mentors:Oleg Nenashev, Runze Xia and Supun Wanniarachchi. He started the project from creating a new Micro-benchmarking Framework for Jenkins Plugins based on JMH, created benchmarks and achieved a 3501% improvement on some real-world scenarios. Then he went further and created a new Folder-based Authorization Strategy Plugin which offers even better performance for Jenkins instances where permissions are scoped to folders. During his project Abhyudaya also fixed the Jenkins Configuration-as-Code support in Role Strategy and contributed several improvements and fixes to the JCasC Plugin itself.

Role strategy performance improvements

Plugins Installation Manager CLI Tool/Library

Natasha Stopa was working on a new CLI tool for plugin management, which should unify features available in other tools like install-plugins.sh in Docker images. It also introduced many new features like YAML configuration format support, listing of available updates and security fixes. The newly created tool should eventually replace the previous ones. Natasha’s mentors: Kristin Whetstone, Jon Brohauge and Arnab Banerjee. Also, many contributors from Platform SIG and JCasC plugin team joined the project as a key stakeholders and subject-matter experts.

Plugin Manager Tool YAML file

Working Hours Plugin - UI Improvements

Jenkins UI and frontend framework are a common topic in the Jenkins project, especially in recent months after the new UX SIG was established.Jack Shen was working on exploring new ways to build Jenkins Web UI together with his mentor Jeff Pearce. Jack updated the Working Hours Plugin to use UI controls provided by standard React libraries. Then he documented his experienced and created template for plugins with React-based UI.

Web UI controls in React

Remoting over Apache Kafka with Kubernetes features

Long Le Vu Nguyen was working on extended Kubernetes support in the Remoting over Apache Kafka Plugin. His mentors were Andrey Falco and Pham vu Tuan who was our GSoC 2018 student and the plugin creator. During this project Long has added a new agent launcher which provisions Jenkins agents in Kubernetes and connects them to the master. He also created a Cloud API implementation for it and a new Helm chart which can provision Jenkins as entire system in Kubernetes, with Apache Kafka enabled by default. All these features were released in Remoting over Apache Kafka Plugin 2.0.

Jenkins in Kubernetes with Apache Kafka

Multi-branch Pipeline support for Gitlab SCM

Parichay Barpanda was working on the new GitLab Branch Source Plugin with Multi-branch Pipeline Jobs and Folder Organisation support. His mentors wereMarky Jackson-Taulia,Justin Harringa,Zhao Xiaojie andJoseph Petersen. The plugin scans the projects, importing the pipeline jobs it identifies based on the criteria provided. After a project is imported, Jenkins immediately runs the jobs based on the Jenkinsfile pipeline script and notifies the status to GitLab Pipeline Status. This plugin also provides GitLab server configuration which can be configured in Configure System or via Jenkins Configuration as Code (JCasC). read more about this project in the GitLab Branch Source 1.0 announcement.

Gitlab Multi-branch Pipeline support

Projects which were not completed

Not all projects have been completed this year. We were also working on Artifact Promotion plugin for Jenkins Pipeline and on Cloud Features for External Workspace Manager Plugin, but unfortunately both projects were stopped after coding phase 1. Anyway, we got a lot of experience and takeaways in these areas (see linked Jira tickets!. We hope that these stories will be implemented by Jenkins contributors at some point.Google Summer of Code 2020 maybe?

Running the GSoC program at our organization level

Here are some of the things our organization did before and during GSoC behind the scenes. To prepare for the influx of students, we updated all our GSoC pages and wrote down all the knowledge we accumulated over the years of running the program. We started preparing in October 2018, long before the official start of the program. The main objective was to address the feedback we got during GSoC 2018 retrospectives.

Project ideas. We started gathering project ideas in the last months of 2018. We prepared a list of project ideas in a Google doc, and we tracked ownership of each project in a table of that document. Each project idea was further elaborated in its own Google doc. We find that when projects get complicated during the definition phase, perhaps they are really too complicated and should not be done.

Since we wanted all the project ideas to be documented the same way, we created a template to guide the contributors. Most of the project idea documents were written by org admins or mentors, but occasionally a student proposed a genuine idea. We also captured contact information in that document such as GitHub and Gitter handles, and a preliminary list of potential mentors for the project. We embedded all the project documents on our website.

Mentor and student guidelines. We updated the mentor information page with details on what we expect mentors to do during the program, including the number of hours that are expected from mentors, and we even have a section on preventing conflict of interest. When we recruit mentors, we point them to the mentor information page.

We also updated the student information page. We find this is a huge time saver as every student contacting us has the same questions about joining and participating in the program. Instead of re-explaining the program each time, we send them a link to those pages.

Application phase. Students started to reach out very early on as well, many weeks before GSoC officially started. This was very motivating. Some students even started to work on project ideas before the official start of the program.

Project selection. This year the org admin team had some very difficult decisions to make. With lots of students, lots of projects and lots of mentors, we had to request the right number of slots and try to match the projects with the most chances of success. We were trying to form mentor teams at the same time as we were requesting the number of slots, and it was hard to get responses from all mentors in time for the deadline. Finally we requested fewer slots than we could have filled. When we request slots, we submit two numbers: a minimum and a maximum. The GSoC guide states that:

  • The minimum is based on the projects that are so amazing they really want to see these projects occur over the summer,

  • and the maximum number should be the number of solid and amazing projects they wish to mentor over the summer.

We were awarded minimum. So we had to make very hard decisions: we had to decide between "amazing" and "solid" proposals. For some proposals, the very outstanding ones, it’s easy. But for the others, it’s hard. We know we cannot make the perfect decision, and by experience, we know that some students or some mentors will not be able to complete the program due to uncontrollable life events, even for the outstanding proposals. So we have to make the best decision knowing that some of our choices won’t complete the program.

Community Bonding. We have found that the community bonding phase was crucial to the success of each project. Usually projects that don’t do well during community bonding have difficulties later on. In order to get students involved in the community better, almost all projects were handled under the umbrella of Special Interest Groups so that there were more stakeholders and communications.

Communications. Every year we have students who contact mentors via personal messages. Students, if you are reading this, please do NOT send us personal messages about the projects, you will not receive any preferential treatment. Obviously, in open source we want all discussions to be public, so students have to be reminded of that regularly. In 2019 we are using Gitter chat for most communications, but from an admin point of view this is more fragmented than mailing lists. It is also harder to search. Chat rooms are very convenient because they are focused, but from an admin point of view, the lack of threads in Gitter makes it hard to get an overview. Gitter threads were added recently (Nov 2019) but do not yet work well on Android and iOS. We adopted Zoom Meetings towards the end of the program and we are finding it easier to work with than Google Hangouts.

Status tracking. Another thing that was hard was to get an overview of how all the projects were doing once they were running. We made extensive use of Google sheets to track lists of projects and participants during the program to rank projects and to track statuses of project phases (community bonding, coding, etc.). It is a challenge to keep these sheets up to date, as each project involves several people and several links. We have found it time consuming and a bit hard to keep these sheets up to date, accurate and complete, especially up until the start of the coding phase.

Perhaps some kind of objective tracking tool would help. We used Jenkins Jira for tracking projects, with each phase representing a separate sprint. It helped a lot for successful projects. In our organization, we try to get everyone to beat the deadlines by a couple of days, because we know that there might be events such as power outages, bad weather (happens even in Seattle!), or other uncontrolled interruptions, that might interfere with submitting project data. We also know that when deadlines coincide with weekends, there is a risk that people may forget.

Retrospective. At the end of our project, we also held a retrospective and captured some ideas for the future. You can find the notes here. We already addressed the most important comments in our documentation and project ideas for the next year.

Recognition

Last year, we wanted to thank everyone who participated in the program by sending swag. This year, we collected all the mailing addresses we could and sent to everyone we could the 15-year Jenkins special edition T-shirt, and some stickers. This was a great feel good moment. I want to personally thank Alyssa Tong her help on setting aside the t-shirt and stickers.

swag before shipping

Mentor summit

Each year Google invites two or more mentors from each organization to the Google Summer of Code Mentor Summit. At this event, hundreds of open-source project maintainers and mentors meet together and have unconference sessions targeting GSoC, community management and various tools. This year the summit was held in Munich, and we sent Marky Jackson and Oleg Nenashev as representatives there.

Apart from discussing projects and sharing chocolate, we also presented Jenkins there, conducted a lightning talk and hosted the unconference session about automation bots for GitHub. We did not make a team photo there, so try to find Oleg and Marky on this photo:

GSoC2019 Mentor summit

GSoC Team at DevOps World | Jenkins World

We traditionally use GSoC organization payments and travel grants to sponsor student trips to major Jenkins-related events. This year four students traveled to the DevOps World | Jenkins World conferences in San-Francisco and Lisbon. Students presented their projects at the community booth and at the contributor summits, and their presentations got a lot of traction in the community!

Thanks a lot to Google and CloudBees who made these trips possible. You can find a travel report from Natasha Stopa here, more travel reports are coming soon.

gsoc2019 team jw usgsoc2019 team jw lisbon

Conclusion

This year, five projects were successfully completed. We find this to be normal and in line with what we hear from other participating organizations.

Taking the time early to update our GSoC pages saved us a lot of time later because we did not have to repeat all the information every time someone contacted us. We find that keeping track of all the mentors, the students, the projects, and the meta information is a necessary but time consuming task. We wish we had a tool to help us do that. Coordinating meetings and reminding participants of what needs to be accomplished for deadlines is part of the cheerleading aspect of GSoC, we need to keep doing this.

Lastly, I want to thank again all participants, we could not do this without you. Each year we are impressed by the students who do great work and bring great contributions to the Jenkins community.

GSoC 2020?

Yes, there will be Google Summer of Code 2020! We plan to participate, and we are looking for project ideas, mentors and students. Jenkins GSoC pages have been already updated towards the next year, and we invite everybody interested to join us next year!

Viewing all 1087 articles
Browse latest View live