Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Return Status Help #158

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 100 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,106 @@ Pipeline steps locking agents and workspaces, and running external processes tha

## Documentation

* [Changelog](https://github.com/jenkinsci/workflow-durable-task-step-plugin/releases)
The nodes and processes plugin also called workflow durable task steps locks jenkins agents with the processes running on them, thereby adding durability to workflows. This ensures Pipelines can resume after an unforseeable restart.

### Pipelines

The plugin provides a `ws` step to allocate a workspace, however, this is created automatically using the `node` step. The [Pipeline Syntax Snippet Generator](https://www.jenkins.io/doc/book/pipeline/getting-started/#snippet-generator) guides the user on usage, practical examples and more information.

### Node

A node is the machine on which Jenkins runs, it is part of the Jenkins environment and is capable of executing a Pipeline.
The `agent` syntax is equivalent to the `node` syntax except in different spheres. agent is a [declarative syntax](https://www.jenkins.io/doc/book/pipeline/#declarative-pipeline-fundamentals) that is used to specify the executor and workspace on which the Pipeline will be executed while node is [scripted syntax](https://www.jenkins.io/doc/book/pipeline/#scripted-pipeline-fundamentals) that is used to execute Pipelines (and any stages contained within it), on any available agent/node

### Processes

A process in Jenkins can be defined as the continuous integration and continuous delivery of builds, tests, analysis, and deployment of projects and any other scenario that can be automated. The steps in these processes are documented in the jenkinsfile which can be created manually or added automatically using Blue Ocean.

Examples of nodes and processes in respect to declarative and scripted pipeline
1. A scripted pipeline example can be found [here](https://www.jenkins.io/doc/book/pipeline/#scripted-pipeline-fundamentals)

2. A declarative pipeline example can be found [here](https://www.jenkins.io/doc/book/pipeline/#declarative-pipeline-fundamentals), refer to the [Pipeline Syntax Snippet Generator](https://www.jenkins.io/doc/book/pipeline/getting-started/#snippet-generator) and for more information

### Using multiple agents and setting labels

It is possible to run Jenkins pipeline on multiple agents. Pipelines that can run on low resource can be paired with equal powered agents and high resource agents with equal powered pipelines to avoid unnecessarily long build time.

A declarative pipeline with multiple agents:

```
pipeline {
agent none
stages {
stage('Build') {
agent any
steps {
checkout scm
sh 'make'
stash includes: '**/target/*.jar', name: 'app'
}
}
stage('Test on Linux') {
agent {
label 'linux'
}
steps {
unstash 'app'
sh 'make check'
}
post {
always {
junit '**/target/*.xml'
}
}
}
stage('Test on Windows') {
agent {
label 'windows'
}
steps {
unstash 'app'
bat 'make check'
}
post {
always {
junit '**/target/*.xml'
}
}
}
}
}
```
A scripted pipeline with multiple agents

```
stage('Test') {
node('linux') {
checkout scm
try {
unstash 'app'
sh 'make check'
}
finally {
junit '**/target/*.xml'
}
}
node('windows') {
checkout scm
try {
unstash 'app'
bat 'make check'
}
finally {
junit '**/target/*.xml'
}
}
}
```
Refer to this [article](https://docs.cloudbees.com/docs/admin-resources/latest/automating-with-jenkinsfile/using-multiple-agents) for a detailed explanation.

## Changelog

[Changelog](https://github.com/jenkinsci/workflow-durable-task-step-plugin/releases)

## License

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,50 @@
When using the <code>returnStdout</code> flag, you probably wish to prefix this with <code>@</code>,
lest the command itself be included in the output.
</div>

<p>The bat step is used to run pipelines on a windows environment,
if your pipeline will run on a Linux environment, use the <code><a href='https://www.jenkins.io/doc/pipeline/steps/workflow-durable-task-step/'>sh</a></code> step.
<p>To use the bat step, you have to first point it to the path where your bat file exists, and then 'call' command to trigger that bat file. Examples below:</p>
<b>This example calls mybat.bat file inside the example folder, extra backslashes are always added to every backslash</b>
<p>Use the <a href="https://www.jenkins.io/doc/book/pipeline/getting-started/#snippet-generator">Pipeline Snippet Generator</a> to generate the example</p>
<p><code>bat 'C:\\example\\mybat.bat'</code></p>

<p>An example of a declarative pipeline executing a bat step with the command set</p>
<p><code>
<blockquote>
pipeline {
agent any
stages {
stage('Build') {
steps {
bat 'set'
}
}
}
}
</blockquote>
</code></p>

<p>Use the <a href="https://www.jenkins.io/doc/book/pipeline/getting-started/#snippet-generator">Pipeline Snippet Generator</a> to generate this example</p>
<p><b>Print out all the environment variables seen by Windows.</b></p>
<p><code>echo bat(returnStdout: true, script: 'set')</code></p>

<p><b>Print out the content of the PATH environment variable on Windows</b></p>
<p><code>bat 'echo %PATH%'</code></p>

<p><b>Add the keyword call when running a multi-line script and need the commands to execute sequentially
</b></p>

<p>Failure to do so will result in only the first line
executing. You can also use ''&'' to chain commands into a single line
but this will make your commands hard to read and prone to mistakes.</p>
<p>Use the <a href="https://www.jenkins.io/doc/book/pipeline/getting-started/#snippet-generator">Pipeline Snippet Generator</a> to generate this example</p>
<p><code>
<blockquote>
bat """
call c:\path\to\conda activate my_env
cd c:\\path\\to\\scripts
call python test.py ${argument}
"""
</blockquote>
</code></p>
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,23 @@
If this option is checked, the return value of the step will instead be the status code.
You may then compare it to zero, for example.
</div>
<p>The return status step is used to return the exit status of a script. 0 equals true in shell. An exit code
of 1 will cause jenkins to abort.
</p>
<p>Use the
<a href="https://www.jenkins.io/doc/book/pipeline/getting-started/#snippet-generator">Pipeline Snippet Generator</a>
to generate this example by checking the <code>returnStatus</code> option
</p>
<p><code>sh returnStatus: true, script: 'mvn test'</code></p>

<p>You can use an if statement to ascertain if the exit status returned 0 or not by assigning your script to
a variable.
</p>
<p><code>int status = sh returnStatus: true, script: 'mvn test'</code></p>
<code>
if (status != 0){
//Take Action
}
</code>
<p>While it is not advisable, use <code>set +e</code> to ignore the exit status code 1 when running shell script</p>
<p>See <code><a href="https://www.jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script">sh</a></code> documentation for this value</p>
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,36 @@
Otherwise the system default shell will be run, using the <code>-xe</code> flags
(you can specify <code>set +e</code> and/or <code>set +x</code> to disable those).
</p>
<p>Use the <a href="https://www.jenkins.io/doc/book/pipeline/getting-started/#snippet-generator">Pipeline Snippet Generator</a> to generate a sample pipeline script for the sh step
A few examples of usage include:</p>

<b>Creating an output folder</b>
<p><code>sh "mkdir -p output"</code></p>

<b>Returning the current directory Pipeline is running in.</b>
<p><code>sh "ls -la ${pwd()}"</code></p>

<b>Making HTTP requests </b>
<p><code>sh "curl -X POST --data-urlencode \'payload=${payload}\' ${slackURL}"</code></p>

<b>Running tests in the same workspace that the project was built </b>
<p><code>sh 'mvn test'</code></p>

<b>Escaping script content from groovy interpretation </b>>
<p>The triple-double-quote (""") string literal syntax allows for variable/expression substitution (interpolation), so the backslash (\) is interpreted as a special character "escape".</p>
<p>Since the first open parentheses is not such a special character, Groovy compilation fails. If your intent is to have literal backslashes in the resulting string, you need to escape the backslashes. That is, use a double-backslash (\\) to substitute for one literal backslash</p>
<p>Use the <a href="https://www.jenkins.io/doc/book/pipeline/getting-started/#snippet-generator">Pipeline Snippet Generator</a> to generate this example</p>
<p><code>sh ("""
sed "s/(AssemblyInformationalVersion\\(\\")(.*)(\\")/\\1${productVersion}\\3/g"
AssemblyInfoGlobal/AssemblyInfoGlobal.cs -r
""")</code>
</p>

<b>Adding shell script as part of Groovy interpolation </b>>
<p>For double quoted string, Groovy will do interpolation on the string firstly.</p>
<p>Because the variables are runtime variables of the shell, rather than the variables of Groovy runtime. Groovy can't find the responding value from Groovy variable stack to replace the variables during interpolation.</p>
<p>So you need to escape all $ if you use double quotes or simply use single quotes which does not support interpolation</p>
<p>Use the <a href="https://www.jenkins.io/doc/book/pipeline/getting-started/#snippet-generator">Pipeline Snippet Generator</a> to generate this example</p>
<p><code>sh(returnStdout: true, script: "cd \$it; PLAN=\$(terragrunt plan --terragrunt-source-update | landscape);
echo \$PLAN; CHANGES=\$(echo \$PLAN | tail -2); echo \$CHANGES"</code></p>
</div>