Skip to content

mkobit/jenkins-pipeline-shared-libraries-gradle-plugin

Repository files navigation

Jenkins Pipeline Shared Library Gradle Plugin

CircleCI Plugin Version Gradle Version ZenHub Badge

Note
This documentation is for the HEAD of the repository. To see documentation at a specific version see the GitHub Releases page

Purpose

This plugin intends to help with development of Shared Libraries.

Features
  • Basic Groovy compilation to validate source code

  • Unit test using Jenkins Pipeline Unit

  • Usage of plugin and Jenkins core classes in library

  • @Grab support for libraries (testing limited to @JenkinsRule style integration tests due to an issue)

  • @NonCPS annotation can be used in main source code

  • Source code generation to assist with development (for example, com.mkobit.jenkins.pipelines.codegen.LocalLibraryRetriever)

  • Integration test using the Jenkins Test Harness

  • Code completion in IDE

Example Consumer

See the example repository for a demonstration of using this plugin.

5 minute onboarding

  1. Consume plugin from Gradle plugin portal

    plugins {
      id("com.mkobit.jenkins.pipelines.shared-library") version "x.x.x"
    }
  2. Set up preferred test dependencies (for example, JUnit or Spock)

    repositories {
      jcenter()
    }
    
    dependencies {
      testImplementation(group: 'junit', name: 'junit', version: '4.12')
    }
  3. Write some shared library code

    Library class - src/com/mkobit/LibHelper.groovy
    package com.mkobit
    
    class LibHelper {
      private script
      LibHelper(script) {
        this.script = script
      }
    
      void sayHelloTo(String name) {
        script.echo("LibHelper says hello to $name!")
      }
    }
    Global variable - vars/myGlobal.groovy
    def call() {
      echo 'Hello from myGlobal'
    }
  4. Write integration tests by utilizing a local JenkinsRule and setting up the shared library

    Integration tests - test/integration/groovy/com/mkobit/JenkinsGlobalLibraryUsageTest.groovy
    package com.mkobit
    
    import com.mkobit.jenkins.pipelines.codegen.LocalLibraryRetriever
    import org.jenkinsci.plugins.workflow.libs.GlobalLibraries
    import org.jenkinsci.plugins.workflow.libs.LibraryConfiguration
    import org.jenkinsci.plugins.workflow.libs.LibraryRetriever
    import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition
    import org.jenkinsci.plugins.workflow.job.WorkflowJob
    import org.jenkinsci.plugins.workflow.job.WorkflowRun
    import org.junit.Before
    import org.junit.Rule
    import org.junit.Test
    import org.jvnet.hudson.test.JenkinsRule
    
    class JenkinsGlobalLibraryUsageTest {
    
      @Rule
      public JenkinsRule rule = new JenkinsRule()
    
      @Before
      void configureGlobalLibraries() {
        rule.timeout = 30
        final LibraryRetriever retriever = new LocalLibraryRetriever()
        final LibraryConfiguration localLibrary =
          new LibraryConfiguration('testLibrary', retriever)
        localLibrary.implicit = true
        localLibrary.defaultVersion = 'unused'
        localLibrary.allowVersionOverride = false
        GlobalLibraries.get().setLibraries(Collections.singletonList(localLibrary))
      }
    
      @Test
      void testingMyLibrary() {
        CpsFlowDefinition flow = new CpsFlowDefinition('''
            import com.mkobit.LibHelper
    
            final libHelper = new LibHelper(this)
            libHelper.sayHelloTo('mkobit')
        '''.stripIndent(), true)
        WorkflowJob workflowJob = rule.createProject(WorkflowJob, 'project')
        workflowJob.definition = flow
        WorkflowRun result = rule.buildAndAssertSuccess(workflowJob)
        rule.assertLogContains('LibHelper says hello to mkobit!', result)
      }
    
      @Test
      void testingMyGlobalVar() {
        CpsFlowDefinition flow = new CpsFlowDefinition('''
            import myGlobal
    
            myGlobal()
        '''.stripIndent(), true)
        WorkflowJob workflowJob = rule.createProject(WorkflowJob, 'project')
        workflowJob.definition = flow
        WorkflowRun result = rule.buildAndAssertSuccess(workflowJob)
        rule.assertLogContains('Hello from myGlobal', result)
      }
    }

Configuring Versions

The sharedLibrary extension can be used to add additional plugin dependencies, Groovy version dependency, Jenkins Core dependency, etc. As of right now, most of the workflow-type plugins are automatically added based on default or configured versions. See the code for full details, but here is an example of what you can configure:

Groovy build script - build.gradle
sharedLibrary {
  coreVersion = "2.86"
  testHarnessVersion = "2.24"
  pluginDependencies {
    workflowCpsGlobalLibraryPluginVersion = "2.8"
    dependency("io.jenkins.blueocean", "blueocean-web", "1.2.4")
  }
}
Note
Due to kotlin-dsl/380, you will nee to use the .set methods instead of assignment. For example, coreVersion.set("2.86") is required.

Limitations/Restrictions

Jenkins Public Default Repository

The repository at https://repo.jenkins-ci.org is added to the repository list to retrieve the Jenkins artifacts. This decision was made to simplify first use by new consumers.

If you do not wish to use this default, remove the repository after applying the plugin.

repositories.removeIf { it.name == "JenkinsPublic" }

Then, you can add your own repository in normal Gradle fashion.

Consuming the Gradle Configurations

There are several configurations that are created to group the different types of Jenkins dependencies used in this plugin. It is not recommended that you consume/extendsFrom these configurations as they may be changed underneath. Instead, use the configurations for each source set and make alterations to them (like sourceSets.integrationTest.implementationConfigurationName and sourceSets.integrationTest.runtimeOnlyConfigurationName). If you have a specific use case please file an issue.