diff --git a/Jenkinsfile b/Jenkinsfile index d43da6e0bee04..79d3c93006cb6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -40,7 +40,12 @@ kibanaPipeline(timeoutMinutes: 135, checkPrChanges: true) { 'xpack-ciGroup9': kibanaPipeline.xpackCiGroupProcess(9), 'xpack-ciGroup10': kibanaPipeline.xpackCiGroupProcess(10), 'xpack-accessibility': kibanaPipeline.functionalTestProcess('xpack-accessibility', './test/scripts/jenkins_xpack_accessibility.sh'), - 'xpack-siemCypress': kibanaPipeline.functionalTestProcess('xpack-siemCypress', './test/scripts/jenkins_siem_cypress.sh'), + 'xpack-siemCypress': { processNumber -> + whenChanged(['x-pack/legacy/plugins/siem/', 'x-pack/test/siem_cypress/']) { + kibanaPipeline.functionalTestProcess('xpack-siemCypress', './test/scripts/jenkins_siem_cypress.sh')(processNumber) + } + }, + // 'xpack-visualRegression': kibanaPipeline.functionalTestProcess('xpack-visualRegression', './test/scripts/jenkins_xpack_visual_regression.sh'), ]), ]) diff --git a/vars/prChanges.groovy b/vars/prChanges.groovy index a9eb9027a0597..d7f46ee7be23e 100644 --- a/vars/prChanges.groovy +++ b/vars/prChanges.groovy @@ -1,3 +1,6 @@ +import groovy.transform.Field + +public static @Field PR_CHANGES_CACHE = null def getSkippablePaths() { return [ @@ -36,9 +39,13 @@ def areChangesSkippable() { } def getChanges() { - withGithubCredentials { - return githubPrs.getChanges(env.ghprbPullId) + if (!PR_CHANGES_CACHE && env.ghprbPullId) { + withGithubCredentials { + PR_CHANGES_CACHE = githubPrs.getChanges(env.ghprbPullId) + } } + + return PR_CHANGES_CACHE } def getChangedFiles() { diff --git a/vars/whenChanged.groovy b/vars/whenChanged.groovy new file mode 100644 index 0000000000000..c58ec83f2b051 --- /dev/null +++ b/vars/whenChanged.groovy @@ -0,0 +1,57 @@ +/* + whenChanged('some/path') { yourCode() } can be used to execute pipeline code in PRs only when changes are detected on paths that you specify. + The specified code blocks will also always be executed during the non-PR jobs for tracked branches. + + You have the option of passing in path prefixes, or regexes. Single or multiple. + Path specifications are NOT globby, they are only prefixes. + Specifying multiple will treat them as ORs. + + Example Usages: + whenChanged('a/path/prefix/') { someCode() } + whenChanged(startsWith: 'a/path/prefix/') { someCode() } // Same as above + whenChanged(['prefix1/', 'prefix2/']) { someCode() } + whenChanged(regex: /\.test\.js$/) { someCode() } + whenChanged(regex: [/abc/, /xyz/]) { someCode() } +*/ + +def call(String startsWithString, Closure closure) { + return whenChanged([ startsWith: startsWithString ], closure) +} + +def call(List startsWithStrings, Closure closure) { + return whenChanged([ startsWith: startsWithStrings ], closure) +} + +def call(Map params, Closure closure) { + if (!githubPr.isPr()) { + return closure() + } + + def files = prChanges.getChangedFiles() + def hasMatch = false + + if (params.regex) { + params.regex = [] + params.regex + print "Checking PR for changes that match: ${params.regex.join(', ')}" + hasMatch = !!files.find { file -> + params.regex.find { regex -> file =~ regex } + } + } + + if (!hasMatch && params.startsWith) { + params.startsWith = [] + params.startsWith + print "Checking PR for changes that start with: ${params.startsWith.join(', ')}" + hasMatch = !!files.find { file -> + params.startsWith.find { str -> file.startsWith(str) } + } + } + + if (hasMatch) { + print "Changes found, executing pipeline." + closure() + } else { + print "No changes found, skipping." + } +} + +return this