For the vast majority of _standard_ projects, the features of the ready-made pipelines should be enough to implement [Continuous Delivery](https://martinfowler.com/bliki/ContinuousDelivery.html) with little effort in a best-practice compliant way.
If you miss a feature or discover a bug in one of our pipelines, please see if there is already an [open issue in our GitHub repository](https://github.com/SAP/jenkins-library/issues) and if not, open a new one.
To do so, create a file called `<StageName>.groovy` (for example, `Acceptance.groovy` or `lint.groovy`) in `.pipeline/extensions/` in the source code repository of your application.
* For the general purpose pipeline, you can find them in [the pipeline source file](https://github.com/SAP/jenkins-library/blob/master/vars/piperPipeline.groovy).
The centrally maintained pipeline checks if such a file exists and if it does, executes it.
A parameter of type `Map` that contains the following keys is passed to the extension:
*`script`: Defines the global script environment of the `Jenkinsfile` run. This makes sure that the correct configuration environment can be passed to project "Piper" steps and allows access to the `commonPipelineEnvironment`, for example. When calling a piper step in an extension, the script object has to be passed using `script: params.script`.
*`originalStage`: Allows you to execute the "original" stage at any place in your script. If omitting a call to `originalStage()`, only your code is executed.
*`stageName`: Name of the current stage
*`config`: Configuration of the stage and general config (including all defaults)
Here is a simple example for such an extension, which you can use as a starting point:
```groovy
void call(Map params) {
//access stage name
echo "Start - Extension for stage: ${params.stageName}"
//access config
echo "Current stage config: ${params.config}"
//execute original stage as defined in the template
A linter is a tool that can check the source code for certain stylistic criteria. Many teams choose to use a linter to ensure a common programming style.
For example, if you want to use [Checkstyle](https://checkstyle.sourceforge.io/) in your codebase, you might use an extension similar to this one in a file called `.pipeline/extensions/Build.groovy` in your project:
This builds the application and optionally runs ESLint on JavaScript/TypeScript source files and static checks using PMD and SpotBugs tools as these are standard features of General Purpose Pipeline.
Secondly, we run the checkstyle maven plugin using the `mavenExecute` Jenkins library step as provided by project "Piper".
This serves as an example for how flexible you can re-use what project "Piper" already provides in your extension.
Finally, we use the Jenkins [Warnings NG plugin](https://plugins.jenkins.io/warnings-ng/) and its step `recordIssues` to make the findings visible in the Jenkins user interface.
This example can be adapted for other linters of your choice.
Be sure to checkout the _Library steps_ section of this documentation if you want to do this.
Project "Piper" provides some basic building blocks such as `dockerExecute` and the already mentioned `mavenExecute` which might be helpful.
## 2. Modified Ready-Made Pipeline
This option describes how you can copy and paste one of the centrally maintained pipelines to make changes to it that are not possible otherwise.
For example, you can't change the order of stages and the stages that run in parallel or add new stages to a centrally maintained pipeline.
A _modified Ready-Made Pipeline_ allows you to modify your [declarative pipeline based on the syntax Jenkins provides](https://jenkins.io/doc/book/pipeline/syntax/#declarative-pipeline).
`myCustomPipeline.groovy` contains the modified pipeline code of the [general purpose pipeline](https://github.com/SAP/jenkins-library/blob/master/vars/piperPipeline.groovy).
The name of your custom pipeline _must_ differ from the other pipelines provided by project "Piper" because Jenkins requires names across multiple libraries to be unique.
This library must be placed in a Git repository, which is available for Jenkins and must be configured in Jenkins [as documented here](https://jenkins.io/doc/book/pipeline/shared-libraries/#using-libraries).
Regardless of which of the above options you choose, one downside of this approach is that your pipeline will be out of sync with the centrally maintained pipelines at some point in time.
We strongly recommend doing _as little modification as possible_ to fulfil your requirements.
Please be aware that stages may have dependencies on each other.
By default, Jenkins uses the `master` branch of shared libraries.
This way, you're always automatically using the latest and greatest version.
The downside is that in rare cases, breaking changes might happen.
Another potential issue is that your builds are not _repeatable_, that means building the same version of your application twice _might_ have a different result.
For those reasons, you might want to consider to fix versions to a released version like in this example: `@Library('my-shared-library@v1.0') _`<br/>
To stay up to date with the latest releases, you can ["watch" releases for those repositories on GitHub](https://help.github.com/en/github/receiving-notifications-about-activity-on-github/watching-and-unwatching-releases-for-a-repository).
!!! note "When to go with a modified ready-made pipeline"
This option is right for you if none of the provided ready-made pipelines serves your purpose, and individual stage extensions don't provide enough flexibility.
When you consider adding additional capabilities, your first stop should be the [Jenkins Pipeline Steps Reference](https://jenkins.io/doc/pipeline/steps/).
Here you get an overview of what kind of capabilities are already available and a list of related parameters, which you can use to customize the existing implementation.
The provided information should help you understand and extend the functionality of your pipeline.
Since project "Piper" fully builds on [Jenkins Pipelines as Code](https://jenkins.io/doc/book/pipeline-as-code/), you can also go with your own pipeline from scratch in a `Jenkinsfile`.
If you choose this option, you will be decoupled from the innovations provided with project "Piper", unless you re-use stages (as indicated above under [_2. Modified ready-made pipelines_](/extensibility.md#2-modified-ready-made-pipeline)), for example.