Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/mkobit/jenkins-pipeline-shared-libraries-gradle-plugin

Gradle plugin to help with build and test of Jenkins Pipeline Shared Libraries (see https://jenkins.io/doc/book/pipeline/shared-libraries/)
https://github.com/mkobit/jenkins-pipeline-shared-libraries-gradle-plugin

gradle gradle-plugin gradle-plugin-kotlin jenkins-pipeline jenkins-shared-library testing

Last synced: about 2 months ago
JSON representation

Gradle plugin to help with build and test of Jenkins Pipeline Shared Libraries (see https://jenkins.io/doc/book/pipeline/shared-libraries/)

Awesome Lists containing this project

README

        

= Jenkins Pipeline Shared Library Gradle Plugin
:toc:
:supports-gradle: 5.0+
:github-repo-id: jenkins-pipeline-shared-libraries-gradle-plugin
:uri-github-releases: https://github.com/mkobit/{github-repo-id}/releases
:uri-jenkins-test-harness: https://github.com/jenkinsci/jenkins-test-harness.git
:uri-jenkins-shared-library-docs: https://jenkins.io/doc/book/pipeline/shared-libraries/
:uri-jenkins-pipeline-unit: https://github.com/lesfurets/JenkinsPipelineUnit
:uri-consumer-example: https://github.com/mkobit/jenkins-pipeline-shared-library-example
:uri-build-status-image: https://circleci.com/gh/mkobit/{github-repo-id}/tree/master.svg?style=svg
:circle-ci-status-badge: image:{uri-build-status-image}["CircleCI", link="https://circleci.com/gh/mkobit/{github-repo-id}/tree/master"]
:uri-version-badge-image: https://img.shields.io/maven-metadata/v/https/plugins.gradle.org/m2/com/mkobit/jenkins/pipelines/jenkins-pipeline-shared-libraries-gradle-plugin/maven-metadata.xml.svg?label=Gradle Plugin Portal
:uri-gradle-support-badge-image: https://img.shields.io/badge/Supports%20Gradle-{supports-gradle}-blue.svg
:supports-gradle-badge: image:{uri-gradle-support-badge-image}["Gradle Version"]
:uri-gradle-plugin-portal: https://plugins.gradle.org/plugin/com.mkobit.jenkins.pipelines.shared-library
:uri-zenhub-badge: https://raw.githubusercontent.com/ZenHubIO/support/master/zenhub-badge.png
:version-badge: image:{uri-version-badge-image}["Plugin Version", link="{uri-gradle-plugin-portal}"]
:zenhub-badge: image:{uri-zenhub-badge}["ZenHub Badge", link="https://www.zenhub.com/"]

{circle-ci-status-badge}
{version-badge}
{supports-gradle-badge}
{zenhub-badge}

NOTE: This documentation is for the `HEAD` of the repository.
To see documentation at a specific version see the link:{uri-github-releases}[GitHub Releases page]

== Purpose

This plugin intends to help with development of link:{uri-jenkins-shared-library-docs}[_Shared Libraries_].

.Features
* Basic Groovy compilation to validate source code
* Unit test using link:{uri-jenkins-pipeline-unit}[_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 link:https://stackoverflow.com/questions/4611230/no-suitable-classloader-found-for-grab[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 link:{uri-jenkins-test-harness}[_Jenkins Test Harness_]
* Code completion in IDE

== Example Consumer

See the link:{uri-consumer-example}[example repository] for a demonstration of using this plugin.

== 5 minute onboarding

. Consume plugin from Gradle plugin portal
+
[source, kotlin]
----
plugins {
id("com.mkobit.jenkins.pipelines.shared-library") version "x.x.x"
}
----
. Set up preferred test dependencies (for example, JUnit or Spock)
+
[source, groovy]
----
repositories {
jcenter()
}

dependencies {
testImplementation(group: 'junit', name: 'junit', version: '4.12')
}
----
. Write some shared library code
+
.Library class - `src/com/mkobit/LibHelper.groovy`
[source, 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`
[source, groovy]
----
def call() {
echo 'Hello from myGlobal'
}
----

. Write integration tests by utilizing a local `JenkinsRule` and setting up the shared library
+
.Integration tests - `test/integration/groovy/com/mkobit/JenkinsGlobalLibraryUsageTest.groovy`
[source, 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`
[source, kotlin]
----
sharedLibrary {
coreVersion = "2.86"
testHarnessVersion = "2.24"
pluginDependencies {
workflowCpsGlobalLibraryPluginVersion = "2.8"
dependency("io.jenkins.blueocean", "blueocean-web", "1.2.4")
}
}
----

NOTE: Due to link:https://github.com/gradle/kotlin-dsl/issues/380[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.

[source, kotlin]
----
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 link:https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/SourceSet.html#getImplementationConfigurationName--[`sourceSets.integrationTest.implementationConfigurationName`] and link:https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/SourceSet.html#getRuntimeOnlyConfigurationName--[`sourceSets.integrationTest.runtimeOnlyConfigurationName`]).
If you have a specific use case please file an issue.