【问题标题】:Only build projects if something has changed仅在发生更改时才构建项目
【发布时间】:2017-06-30 20:06:36
【问题描述】:

我们想把我们的项目分成更小的部分。我们当前的 CI 流程会经过一个简短的测试阶段,然后运行一个部署脚本。但是,如果其中一个子项目没有任何变化,我们不想为此进行构建。

没有管道的 Jenkins 支持 SCM 配置中的排除(我们使用 git),基于此,您可以配置特定的作业以运行。但是,当使用管道时,我怎么知道是否应该构建这部分?如何访问受上次推送影响的路径?

目前我们的脚本非常简单,我们希望尽可能简单。

我们正在使用scripteddeclarative 语法,但找不到好的解决方案。

声明性:

#!groovy​
pipeline {
    agent any
    tools {
        nodejs '8.1'
    }
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        # Only continue, if something has changed

        stage('Install') {
            steps {
                sh 'npm install'
            }
        }

        stage('Test') {
            steps {
                sh 'npm run test-jenkins'
            }
            post {
                always {
                    junit "artifacts/test/report.xml"
                }
            }
        }
    }
}

脚本:

#!groovy​
node {
    def nodejs = tool name: '8.1', type: 'jenkins.plugins.nodejs.tools.NodeJSInstallation'
    env.PATH = "${nodejs}/bin:${env.PATH}"

    stage('Checkout') {
        checkout scm
    }

    # Only continue, if something has changed


    stage('Install') {
        sh 'npm install'
    }

    stage('Test') {
        try {
            sh 'npm run test-jenkins'
        } finally {
            junit "artifacts/test/report.xml"
        }
    }
}

【问题讨论】:

  • 构建完成后,为当前提交打一个标签。在下一个构建中,比较新的提交和标签。如果它们不是相同的提交(或者如果您只关心文件内容,则为树),请继续。并且在新构建完成后,将标签从之前的提交重置为当前的提交。
  • @ElpieKay 这行得通!非常感谢。我会写下来并作为答案发布。
  • 没关系。很高兴它有帮助。 =)

标签: node.js git jenkins jenkins-pipeline


【解决方案1】:

感谢ElpieKay's fast comment 我的问题,我们现在有了一个优雅的解决方案:

  1. 在成功构建时为当前提交添加标签
  2. 在下一个构建中比较新提交和更改标记

我们使用multi-branch pipeline 和并行构建我们在同一个源根目录下拥有的多个项目。我们遍历项目 (serviceX) 并检查相应目录的更改:

def projects = ['service1', 'service2']
def builders = [:]
for (p in projects) {
    def label = p

    builders[label] = {
        def tag = "${BRANCH_NAME}_last"
        node {
            echo "Checking for changes compared to ${tag} in directory ${label}"
            try {
                sh "./check-for-changes ${tag} ${label}"
            } catch (ignored) {
                echo "Nothing to do"
                return
            }
            dir (label) {
                stage(label + ": Install") {
                    sh "npm install"
                }

                stage(label + ": Test") {
                    try {
                        sh "npm run test-jenkins"
                    } finally {
                        junit 'artifacts/test/report.xml'
                    }
                }

                echo "Setting tag for the last build on this branch"
                sh "git tag -f ${tag}"
            }
        }
    }
}

parallel builders

...以及检查更改的脚本:

#!/bin/bash
SHA_PREV=$1
if [ -z ${SHA_PREV} ]; then
    echo "Usage: `basename $0` <tag> <path>"
    exit 1
fi

CHECK_PATH=$2
if [ -z ${CHECK_PATH} ]; then
    echo "Usage: `basename $0` <tag> <path>"
    exit 1
fi

if `git rev-parse ${SHA_PREV} >/dev/null 2>&1`; then
    echo "Found previous tag: ${SHA_PREV}"
else
    SHA_PREV=`git rev-list --max-parents=0 HEAD`
    echo "Using initial commit: ${SHA_PREV}"
fi

changes=`git diff --name-only ${SHA_PREV} HEAD | grep ${CHECK_PATH}/`
if [ ! -n "${changes}" ]; then
    echo "No changes found"
    exit 2 # no changes found
fi

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    相关资源
    最近更新 更多