Jenkinsfile 10 KB
Newer Older
1
// INTEL CONFIDENTIAL
2
// Copyright 2017-2019 Intel Corporation All Rights Reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// The source code contained or described herein and all documents related to the
// source code ("Material") are owned by Intel Corporation or its suppliers or
// licensors. Title to the Material remains with Intel Corporation or its
// suppliers and licensors. The Material may contain trade secrets and proprietary
// and confidential information of Intel Corporation and its suppliers and
// licensors, and is protected by worldwide copyright and trade secret laws and
// treaty provisions. No part of the Material may be used, copied, reproduced,
// modified, published, uploaded, posted, transmitted, distributed, or disclosed
// in any way without Intel's prior express written permission.
// No license under any patent, copyright, trade secret or other intellectual
// property right is granted to or conferred upon you by disclosure or delivery of
// the Materials, either expressly, by implication, inducement, estoppel or
// otherwise. Any license under such intellectual property rights must be express
// and approved by Intel in writing.

// Set LABEL variable if empty or not declared
try{ if(LABEL.trim() == "") {throw new Exception();} }catch(Exception e){LABEL="onnx && ci"}; echo "${LABEL}"
20
if(DOCKER_REGISTRY.trim() == "") {throw new Exception("Missing Docker registry url!");}
21
// CI settings and constants
22
PROJECT_NAME = "ngraph_cpp"
23
CI_ROOT = "ngraph/.ci/onnx/jenkins"
24
DOCKER_CONTAINER_NAME = "jenkins_ngraph-onnx_ci"
25 26
NGRAPH_GIT_ADDRESS = "https://github.com/NervanaSystems/ngraph.git"
ONNX_GIT_ADDRESS = "https://github.com/NervanaSystems/ngraph-onnx.git"
27
JENKINS_GITHUB_CREDENTIAL_ID = "7157091e-bc04-42f0-99fd-dc4da2922a55"
28 29 30 31 32
ONNX_BRANCH = "$CHANGE_BRANCH"
GIT_PR_AUTHOR_EMAIL=""
GIT_COMMIT_AUTHOR_EMAIL=""
GIT_COMMIT_HASH=""
GIT_COMMIT_SUBJECT=""
33

34 35 36 37 38 39 40 41 42
// workaround for aborting previous builds on PR update
// TODO: Move to plugin based solution as soon as it's available
@NonCPS
def killPreviousRunningJobs() {
    def jobname = env.JOB_NAME
    def buildnum = env.BUILD_NUMBER.toInteger()

    def job = Jenkins.instance.getItemByFullName(jobname)
    for (build in job.builds) {
43 44
        if (!build.isBuilding()){
            continue;
45
        }
46
        if (buildnum == build.getNumber().toInteger()){
47 48 49 50 51 52 53 54
            continue;
        }
        echo "Kill task = ${build}"
        build.doStop();
    }
}

def cloneRepository(String jenkins_github_credential_id, String ngraph_git_address, String onnx_git_address) {
55 56
    stage('Clone Repos') {
        try {
57
            sh "git clone $onnx_git_address -b $CHANGE_BRANCH ."
58 59
        }
        catch (Exception e) {
60
            ONNX_BRANCH = "master"
61
            sh """
62
                echo "WARNING! Failed to clone ngraph-onnx branch $CHANGE_BRANCH ! Falling back to master."
63
                echo "EXCEPTION: $e"
64 65 66 67 68 69 70 71 72
            """
            checkout([$class: 'GitSCM',
                branches: [[name: "master"]],
                doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', timeout: 30]], submoduleCfg: [],
                userRemoteConfigs: [[credentialsId: "${jenkins_github_credential_id}",
                url: "${onnx_git_address}"]]])
        }
        dir ("ngraph") {
                checkout([$class: 'GitSCM',
73
                    branches: [[name: "$CHANGE_BRANCH"]],
74 75 76
                    doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', timeout: 30]], submoduleCfg: [],
                    userRemoteConfigs: [[credentialsId: "${jenkins_github_credential_id}",
                    url: "${ngraph_git_address}"]]])
77 78 79 80
                GIT_PR_AUTHOR_EMAIL = sh (script: 'git log -1 --pretty="format:%ae" ', returnStdout: true).trim()
                GIT_COMMIT_AUTHOR_EMAIL = sh (script: 'git log -1 --pretty="format:%ce" ', returnStdout: true).trim()
                GIT_COMMIT_HASH = sh (script: 'git log -1 --pretty="format:%H" ', returnStdout: true).trim()
                GIT_COMMIT_SUBJECT = sh (script: 'git log -1 --pretty="format:%s" ', returnStdout: true).trim()
81 82 83 84
        }
    }
}

85 86
def pullImage(configurationMaps) {
    Closure pullMethod = { configMap ->
87
        sh """
88 89
            ${CI_ROOT}/utils/docker.sh pull \
                                --docker_registry=${DOCKER_REGISTRY} \
90
                                --name=${configMap["projectName"]} \
91
                                --version=${configMap["name"]} || return 1
92 93
        """
    }
94
    UTILS.createStage("Pull_image", pullMethod, configurationMaps)
95 96
}

97
def runDockerContainers(configurationMaps) {
98
    Closure runContainerMethod = { configMap ->
99
        UTILS.propagateStatus("Pull_image", configMap["name"])
100 101 102
        sh """
            mkdir -p ${HOME}/ONNX_CI
            ${CI_ROOT}/utils/docker.sh start \
103
                                --docker_registry=${DOCKER_REGISTRY} \
104 105 106 107 108 109
                                --name=${configMap["projectName"]} \
                                --version=${configMap["name"]} \
                                --container_name=${configMap["dockerContainerName"]} \
                                --volumes="-v ${WORKSPACE}/${BUILD_NUMBER}:/logs -v ${HOME}/ONNX_CI:/home -v ${WORKDIR}:/root"
        """
    }
110
    UTILS.createStage("Run_docker_containers", runContainerMethod, configurationMaps)
111 112
}

113
def prepareEnvironment(configurationMaps) {
114
    Closure prepareEnvironmentMethod = { configMap ->
115
        UTILS.propagateStatus("Run_docker_containers", configMap["dockerContainerName"])
116 117
        sh """
            docker cp ${CI_ROOT}/utils/docker.sh ${configMap["dockerContainerName"]}:/home
118
            docker exec ${configMap["dockerContainerName"]} bash -c "/root/${CI_ROOT}/prepare_environment.sh --no-incremental"
119 120
        """
    }
121
    UTILS.createStage("Prepare_environment", prepareEnvironmentMethod, configurationMaps)
122 123
}

124
def runToxTests(configurationMaps) {
125
    Closure runToxTestsMethod = { configMap ->
126
        UTILS.propagateStatus("Prepare_environment", configMap["dockerContainerName"])
127 128 129 130 131
        sh """
            NGRAPH_WHL=\$(docker exec ${configMap["dockerContainerName"]} find /root/ngraph/python/dist/ -name 'ngraph*.whl')
            docker exec -e TOX_INSTALL_NGRAPH_FROM=\${NGRAPH_WHL} ${configMap["dockerContainerName"]} tox -c /root/
        """
    }
132
    UTILS.createStage("Run_tox_tests", runToxTestsMethod, configurationMaps)
133 134
}

135
def cleanup(configurationMaps) {
136 137
    Closure cleanupMethod = { configMap ->
        sh """
138
            docker exec ${configMap["dockerContainerName"]} bash -c 'rm -rf ~/*' || true
139 140 141 142 143
            cd ${HOME}/ONNX_CI
            ./docker.sh chmod --container_name=${configMap["dockerContainerName"]} --directory="/logs" --options="-R 777" || true
            ./docker.sh stop --container_name=${configMap["dockerContainerName"]} || true
            ./docker.sh remove --container_name=${configMap["dockerContainerName"]} || true
            ./docker.sh clean_up || true
144
            rm -rf ${HOME}/ONNX_CI/docker.sh
145 146 147
            rm -rf ${WORKSPACE}/${BUILD_NUMBER}
        """
    }
148
    UTILS.createStage("Cleanup", cleanupMethod, configurationMaps, true)
149 150
}

151
def notifyByEmail() {
152 153
    configurationMaps = []
    configurationMaps.add([
154
        "name": "Notify"
155
    ])
156
    String notifyPeople = "$GIT_PR_AUTHOR_EMAIL, $GIT_COMMIT_AUTHOR_EMAIL"
157
    Closure notifyMethod = { configMap ->
158
        if(currentBuild.result == "FAILURE") {
159
            emailext (
160
                subject: "NGraph-Onnx CI: NGraph PR $CHANGE_ID $currentBuild.result!",
161 162 163
                body: """
                    <table style="width:100%">
                        <tr><td>Status:</td> <td>${currentBuild.result}</td></tr>
164 165 166 167 168 169
                        <tr><td>Pull Request Title:</td> <td>$CHANGE_TITLE</td></tr>
                        <tr><td>Pull Request:</td> <td><a href=$CHANGE_URL>$CHANGE_ID</a> </td></tr>
                        <tr><td>Branch:</td> <td>$CHANGE_BRANCH</td></tr>
                        <tr><td>Commit Hash:</td> <td>$GIT_COMMIT_SUBJECT</td></tr>
                        <tr><td>Commit Subject:</td> <td>$GIT_COMMIT_HASH</td></tr>
                        <tr><td>Jenkins Build:</td> <td> <a href=$RUN_DISPLAY_URL> ${BUILD_NUMBER} </a> </td></tr>
170
                        <tr><td>nGraph-ONNX Branch:</td> <td>${ONNX_BRANCH}</td></tr>
171 172 173 174 175 176
                    </table>
                """,
                to: "${notifyPeople}"
            )
        }
    }
177
    UTILS.createStage("Notify", notifyMethod, configurationMaps, true)
178 179 180
}

def main(String label, String projectName, String projectRoot, String dockerContainerName, String jenkins_github_credential_id, String ngraph_git_address, String onnx_git_address) {
181
    killPreviousRunningJobs()
182
    node(label) {
183
        timeout(activity: true, time: 15) {
184 185 186 187
            WORKDIR = "${WORKSPACE}/${BUILD_NUMBER}"
            def configurationMaps;
            try {
                dir ("${WORKDIR}") {
188
                    cloneRepository(jenkins_github_credential_id, ngraph_git_address, onnx_git_address)
189 190 191 192
                    // Load CI API
                    UTILS = load "${CI_ROOT}/utils/utils.groovy"
                    result = 'SUCCESS'
                    // Create configuration maps
193
                    configurationMaps = UTILS.getDockerEnvList(projectName, dockerContainerName, projectRoot)
194
                    // Execute CI steps
195
                    pullImage(configurationMaps)
196 197 198
                    runDockerContainers(configurationMaps)
                    prepareEnvironment(configurationMaps)
                    runToxTests(configurationMaps)
199 200
                }
            }
201
            catch(Exception e) {
202
                // Set result to ABORTED if exception contains exit code of a process interrupted by SIGTERM
203
                if (e.toString().contains("FlowInterruptedException")) {
204 205 206 207 208
                    currentBuild.result = "ABORTED"
                } else {
                    currentBuild.result = "FAILURE"
                }
            }
209
            finally {
210 211
                cleanup(configurationMaps)
                notifyByEmail()
212 213 214 215 216 217
            }
        }
    }
}

main(LABEL, PROJECT_NAME, CI_ROOT, DOCKER_CONTAINER_NAME, JENKINS_GITHUB_CREDENTIAL_ID, NGRAPH_GIT_ADDRESS, ONNX_GIT_ADDRESS)