Parameterizing Libraries
One of the major benefits of organizing your pipeline code into libraries is the ability to reuse these libraries across different teams.
In order to achieve this level of reusability, it’s best to externalize hard coded values as parameters that can be set from the pipeline configuration repository.
Pass Parameters Through the Pipeline Configuration
When specifying a library to be loaded, users can also pass arbitrary configurations to the library:
libraries{
example{ (1)
someField = "my value" (2)
nested{ (3)
someOtherField = 11 (4)
}
}
}
1 | The name of the library to be loaded |
2 | A root level library configuration option |
3 | A block name to pass nested configuration |
4 | A nested library configuration |
|
Accessing Library Configurations Within Steps
The Jenkins Templating Engine injects a config
variable into each step. This config
variable is a map whose keys are the library parameters that have been provided through the pipeline configuration.
The config
variable is only resolvable within a library step and only contains the configuration for the step’s library.
If you need to access the entire aggregated pipeline configuration, JTE injects a |
Validating Library Configurations
The pipeline configuration file is a custom DSL "builder" syntax that takes arbitrary parameters. This design has simplified the implementation of the Jenkins Templating Engine while increasing its extensibility.
The downside of this approach is that users can define whatever fields they want to. For library developers, this means that a mechanism is needed to validate user configurations passed to libraries.
The Library Configuration File
The root of a library can contain an optional library_config.groovy
file. Through the library configuration, library developers are able to perform basic types of validation against the library configuration.
The library configuration file follows the following format:
fields{ (1)
required{} (2)
optional{} (3)
}
1 | the fields block is used to specify expected library configurations |
2 | library configurations that are required are listed in the required block |
3 | library configurations that are optional (meaning they likely have a default value) are listed in the optional block |
Within the required
and optional
blocks, list the parameters the library supports in a parameterName = <Validation Type>
format.
If a libary does not include a library configuration file, then users can supply arbitrary parameters to the library from the pipeline configuration. If a library does include a library configuration file, then users will only be able to supply parameters thare are listed within the |
The library configuration supports several different validation types for library parameters.
Type Validation
Type validation confirms that a library parameter is an instance of a particular type.
The supported types for comparison are:
The current options for data types to test for are:
-
boolean / Boolean
-
String
-
Integer / int
-
Double
-
BigDecimal
-
Float
-
Number
For example,
fields{
required{
parameterA = String (1)
parameterB = Number (2)
parameterC = Boolean (3)
}
optional{
parameterD = String (4)
parameterE = Boolean (5)
}
}
1 | ensures that parameterA was configured and is an instance of a String |
2 | ensures that parameterB was configured and is an instance of a Number |
3 | ensures that parameterC was configured and is an instance of a Boolean |
4 | if parameterD was configured, ensures it is a String |
5 | if parameterE was configured, ensures it is a Boolean |
Enum Validation
The enum validation ensures that a library parameter value is one of the options defined by a list in the library configuration.
For example,
fields{
required{
parameterA = [ "a", "b", 11 ] (1)
}
}
1 | ensures that parameterA was configured and is set to either "a", "b", or 11 |
Regular Expression Validation
Regular expression validation uses Groovy’s match operator to determine if the parameter value is matched by the regular expression.
For example
fields{
required{
parameterA = ~/^s.*/ (1)
}
}
1 | ensures that parameterA starts with s |
Nested Parameters
Library parameters can be arbitrarily nested within the pipeline configuration.
For example, the following pipeline configuration would be valid to pass the example.nestedParameter
parameter to a library named testing
.
libraries{
testing{
example{
nestedParameter = 11
}
}
}
To validate that example.nestedParameter
is a configured and is a number, the library configuration would be:
fields{
required{
example{
nestedParameter = Number
}
}
}
To validate nested library parameters in the library configuration, nest their validation in the same structure within the |
Advanced Library Validations
For library parameter validations that more complex than what can be accomplished through the library configuration functionality, library developers can alternatively create a step annotated with the @Validate
Lifecycle Hook.
Methods within steps annotated with @Validate
will execute prior to the pipeline template.
For example, if a library wanted to validate a more complex use case such as ensuring a library parameter named threshold
was greater than or equal to zero but less than or equal to 100 the following could be implemetned:
@Validate (1)
void call(context){ (2)
if(config.threshold < 0 || config.threshold > 100){ (3)
error "Library parameter 'threshold' must be within the range of: 0 <= threshold <= 100" (4)
}
}
1 | The @Validate annotation marks a method defined within a step to be invoked prior to template execution. |
2 | This example defines a call() method, but the method name can be any valid Groovy method name. |
3 | Here, a Groovy if statement is used to validate that the threshold parameter fall within a certain range. |
4 | If the threshold variable does not meet the criteria, the Jenkins pipeline error step is used to fail the build. The warning step could also be used if the pipeline user should be notified but the build should continue. |
This approach allows library developers to use Groovy to validate arbitrarily complex library parameter constraints. The method annotated with @Validate
can be in its own step file or added as an additional method within an existing step file.
The example above assumes that the |