多步骤自动化流程

Running multiple steps

Pipelines are made up of multiple steps that allow you to build, test and deploy applications. Jenkins Pipeline allows you to compose multiple steps in an easy way that can help you model any sort of automation process.

Think of a “step” like a single command which performs a single action. When a step succeeds it moves onto the next step. When a step fails to execute correctly the Pipeline will fail.

When all the steps in the Pipeline have successfully completed, the Pipeline is considered to have successfully executed.

Linux, BSD, and Mac OS

On Linux, BSD, and Mac OS (Unix-like) systems, the sh step is used to execute a shell command in a Pipeline.

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'echo "Hello World"'
                sh '''
                    echo "Multiline shell steps works too"
                    ls -lah
                '''
            }
        }
    }
}
Jenkinsfile (Scripted Pipeline)
node {
    stage('Build') {
        sh 'echo "Hello World"'
        sh '''
            echo "Multiline shell steps works too"
            ls -lah
        '''
    }
}

Windows

Windows-based systems should use the bat step for executing batch commands.

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                bat 'set'
            }
        }
    }
}
Jenkinsfile (Scripted Pipeline)
node {
    stage('Build') {
        bat 'set'
    }
}

Timeouts, retries and more

There are some powerful steps that “wrap” other steps which can easily solve problems like retrying (retry) steps until successful or exiting if a step takes too long (timeout).

Jenkinsfile (Declarative Pipeline)

pipeline {
agent any
stages {
stage(‘Deploy’) {
steps {
retry(3) {
sh ‘./flakey-deploy.sh’
}

            timeout(time: 3, unit: 'MINUTES') {
                sh './health-check.sh'
            }
        }
    }
}

}

Jenkinsfile (Scripted Pipeline)
node {
    stage('Deploy') {
        retry(3) {
            sh './flakey-deploy.sh'
        }

        timeout(time: 3, unit: 'MINUTES') {
            sh './health-check.sh'
        }
    }
}

The “Deploy” stage retries the flakey-deploy.sh script 3 times, and then waits for up to 3 minutes for the health-check.sh script to execute. If the health check script does not complete in 3 minutes, the Pipeline will be marked as having failed in the “Deploy” stage.

“Wrapper” steps such as timeout and retry may contain other steps, including timeout or retry.

We can compose these steps together. For example, if we wanted to retry our deployment 5 times, but never want to spend more than 3 minutes in total before failing the stage:

Jenkinsfile (Declarative Pipeline)

pipeline {
agent any
stages {
stage(‘Deploy’) {
steps {
timeout(time: 3, unit: ‘MINUTES’) {
retry(5) {
sh ‘./flakey-deploy.sh’
}
}
}
}
}
}

Jenkinsfile (Scripted Pipeline)

node {
stage(‘Deploy’) {
timeout(time: 3, unit: ‘MINUTES’) {
retry(5) {
sh ‘./flakey-deploy.sh’
}
}
}
}

Finishing up

When the Pipeline has finished executing, you may need to run clean-up steps or perform some actions based on the outcome of the Pipeline. These actions can be performed in the post section.

Jenkinsfile (Declarative Pipeline)

pipeline {
agent any
stages {
stage(‘Test’) {
steps {
sh ‘echo “Fail!”; exit 1’
}
}
}
post {
always {
echo ‘This will always run’
}
success {
echo ‘This will run only if successful’
}
failure {
echo ‘This will run only if failed’
}
unstable {
echo ‘This will run only if the run was marked as unstable’
}
changed {
echo ‘This will run only if the state of the Pipeline has changed’
echo ‘For example, if the Pipeline was previously failing but is now successful’
}
}
}

Jenkinsfile (Scripted Pipeline)
node {
    try {
        stage('Test') {
            sh 'echo "Fail!"; exit 1'
        }
        echo 'This will run only if successful'
    } catch (e) {
        echo 'This will run only if failed'

        // Since we're catching the exception in order to report on it,
        // we need to re-throw it, to ensure that the build is marked as failed
        throw e
    } finally {
        def currentResult = currentBuild.result ?: 'SUCCESS'
        if (currentResult == 'UNSTABLE') {
            echo 'This will run only if the run was marked as unstable'
        }

        def previousResult = currentBuild.previousBuild?.result
        if (previousResult != null && previousResult != currentResult) {
            echo 'This will run only if the state of the Pipeline has changed'
            echo 'For example, if the Pipeline was previously failing but is now successful'
        }

        echo 'This will always run'
    }
}
Donate - Support to make this site better.
捐助 - 支持我让我做得更好.