[PYTHON] What are the "pipeline" and "{...}" in the Jenkins Pipeline pipeline {...} (for Groovy beginners, for experienced languages)

background

I decided to write Jenkins Pipeline at work. I was happy to copy the sample and see Hello World, but I have a question like this.

What are these pipeline and{...}? What kind of grammar rules are they?

Jenkinsfile


pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'echo "Hello World"'
            }
        }
    }
}

The Jenkinsfile itself looks like just a data structure (a JSON or YAML companion). So there must be some rules. But I can't find the page where it is written. When I asked an engineer at work, I found that Jenkinsfile is a Groovy program.

After that, I will write down what I researched myself and how it compares with other languages.

What are the answers to "pipeline" and "{...}"

pipeline is ** method name ** {...} is ** closure **

pipeline {...} is a syntax that passes the closure {...} as a ** argument ** to the pipeline method.

Since pipeline is a method, when running Jenkinsfile

def pipeline(Closure cl) {
    //Preprocessing
    //Call closure
    cl();
    //Post-processing
}

A method defined as is loaded (from somewhere). (The above code is a little different to be exact. See supplement)

More details

groovy method call

If you write the above pipeline call redundantly,

pipeline({ ->
    //processing
})

is. Write groovy closures like {x, y-> x + y}, like {argument-> process}. If there is no argument, the argument-> part can be omitted [^ 1]. If you omit the argument

[^ 1]: To be precise, the behavior is different between {-> processing} and {processing}.

pipeline({
    //processing
})

It will be in the form of. Also, the parentheses of the method call can be omitted if there are arguments, so

pipeline {
    //processing
}

Will be. It has the same shape as the Jenkins file.

closure

Closures are anonymous functions that behave as if they were running on the caller of a method. This explanation is easy to understand. Closure --Apache Groovy Tutorial

If you try to write in another language

Contrast Groovy closures with other languages. (For languages that cannot be written here, please add in the comments)

Ruby Groovy

pipeline {
    //processing
}

Is the notation of Ruby

pipeline {
  #processing
}

Corresponds to the notation. It looks the same. You can see that Groovy is strongly influenced by Ruby. Ruby blocks are called closures in Groovy. The difference between blocks and closures is easy to understand on this page. Exploring other languages for Rubyist [5th] Groovy

JavaScript

Groovy

pipeline {
    //processing
}

Is the notation of JavaScript

pipeline(() => {
    //processing
})

Corresponds to the notation. In JavaScript, the parentheses of the method call cannot be omitted, and even if there is no argument, the parentheses surrounding the argument cannot be omitted, but in Groovy it can be omitted.

Java Groovy

pipeline {
    //processing
}

Is the notation of Java

pipeline(() -> {
    //processing
})

Corresponds to. Like JavaScript, Java does not allow you to omit the method call parentheses and the parentheses surrounding the arguments if there are no arguments. In Groovy these two are optional.

Python Groovy

pipeline {
    //processing
}

There is no corresponding notation in Python, but if you dare to write it

pipeline(lambda:processing)

is. In Python, lambda expressions can't span multiple lines, but in Groovy they do.

Supplement

Above, the pipeline method is

def pipeline(Closure cl) {
    //Preprocessing
    //Call closure
    cl();
    //Post-processing
}

I wrote that it looks like this, but to be exact, it's a little different. We are doing a delegate to limit the functions that can be used within the closure. I couldn't find the source for the pipeline method, but here's the more realistic code:

def pipeline(@DelegatesTo(PipelineSpec) Closure cl) {
    def pipelineSpec = new PipelineSpec()
    def code = cl.rehydrate(pipelineSpec, this, this)
    code.resolveStrategy = Closure.DELEGATE_ONLY
    code()
}

In the text, in order to give priority to clarity, the closure is called as it is.

Reference material

-Closure --Apache Groovy Tutorial

Afterword

While I was creating the Jenkinsfile, I was in a state of "I'm working with copy and paste, but I don't know why it's working", but I understood that it was a Groovy program and grasped the actual situation. There are still few articles on Jenkins Pipeline, so I hope I can continue to write what I learned.

Recommended Posts

What are the "pipeline" and "{...}" in the Jenkins Pipeline pipeline {...} (for Groovy beginners, for experienced languages)
[For beginners] Why are the "weights" and "bias" of neural networks necessary?
[Minecraft] What are the important items in survival?
Rock-paper-scissors poi in Python for beginners (answers and explanations)
[For beginners] Install the package in the Anaconda environment (Janome)
Financial Forecasting Feature Engineering: What are the features in financial forecasting?
Search for variables in pandas.DataFrame and get the corresponding row.
Compete for file IO in various languages and compare speeds
What beginners learned from the basics of variables in python
I implemented N-Queen in various languages and measured the speed
Since the font size and window size are large in Zoom for Linux, I made it smaller
What is the interface for ...
About the need for the first slash in the subscriber name and publisher name
[PyTorch] Make sure the model and dataset are in cuda mode
What automation should I do in RPA, VBA, and programming languages?
Don't learn Java and C ++! !! Languages for beginners [more carefully selected]
What are the directories such as Linux, / etc and / var / log?