Run the global presubmit on Presubmit-Ready+2

The change contains the following modification:
  - Use Presubmit-Ready instead of Verified for marking a change as ready
    to be tested. Verified will later be restricted to be set only by
    the CI system.
  - Add a parameter (CHANGE_NUMBER) to the global job and trigger a review
    of a change.
  - Extract the list of change Presubmit-Ready+2 and trigger the global pipeline
    for those changes.

Change-Id: I847bf79bc2898497e1e719c0a0eeb4a5e0d4eede
diff --git a/jenkins/gerrit-verifier.groovy b/jenkins/gerrit-verifier.groovy
index 3288dc0..b4b9c8d 100644
--- a/jenkins/gerrit-verifier.groovy
+++ b/jenkins/gerrit-verifier.groovy
@@ -36,18 +36,37 @@
   }
 }
 
+// Run the global presubmit job for a given change
+def globalPresubmit(gerrit, change) {
+  def refspec = "+" + change.ref + ":" + change.ref.replaceAll('ref/', 'ref/remotes/origin/')
+  gerrit.addReviewer(change.number)
+  build job: "CR/global-verifier", propagate: false, wait: false, parameters: [
+    [$class: 'StringParameterValue', name: 'REFSPEC', value: refspec],
+    [$class: 'StringParameterValue', name: 'BRANCH', value: change.sha1],
+    [$class: 'StringParameterValue', name: 'CHANGE_NUMBER', value: change.number.toString()]]
+}
+
 timeout(2) {
   def changes = [:]
   // Get open gerrit changes that were verified but not yet processed
   stage("Get changes") {
     def acceptedChanges = gerrit.getVerifiedChanges()
+    def changesForGlobalPresubmit = gerrit.getVerifiedChanges("project:bazel", 2)
     if (acceptedChanges) {
       echo "Gerrit has " + acceptedChanges.size() + " change(s) to be verified"
       for (int i = 0; i < acceptedChanges.size(); i++) {
         def change = acceptedChanges[i]
         changes[change.number] = { -> buildChange(gerrit, change) }
       }
-    } else {
+    }
+    if (changesForGlobalPresubmit) {
+      echo "Gerrit has " + changesForGlobalPresubmit.size() + " change(s) waiting for global presubmit"
+      for (int i = 0; i < changesForGlobalPresubmit.size(); i++) {
+        def change = changesForGlobalPresubmit[i]
+        changes[change.number] = { -> globalPresubmit(gerrit, change) }
+      }
+    }
+    if (!changes && !changesForGlobalPresubmit) {
       echo "No change to be verified"
     }
   }
diff --git a/jenkins/jobs/BUILD b/jenkins/jobs/BUILD
index 52b641f..6052cfc 100644
--- a/jenkins/jobs/BUILD
+++ b/jenkins/jobs/BUILD
@@ -28,7 +28,7 @@
     project_url = "http://bazel.io",
     substitutions = JOBS_SUBSTITUTIONS,
     deps = glob(["%s.*.tpl" % job]),
-) for job in BAZEL_JOBS.keys() if job != "Global/pipeline"]
+) for job in BAZEL_JOBS.keys() if job != "Global/pipeline" and job != "CR/global-verifier"]
 
 jenkins_job(
     name = "Global/pipeline",
@@ -39,6 +39,15 @@
     ],
 )
 
+jenkins_job(
+    name = "CR/global-verifier",
+    config = "CR-global.xml.tpl",
+    deps = [
+        ":configs/bootstrap.json",
+        ":global.groovy",
+    ],
+)
+
 # TODO(dmarting): activate Tensorflow on mac (missing dependencies)
 bazel_github_job(
     name = "TensorFlow",
@@ -166,6 +175,12 @@
         "HEAD",
         "latest",
     ],
+    build_opts = [
+        "--verbose_failures",
+        # TODO(pcloudy): This is only for Windows.
+        # Remove it after wrapper-less CROSSTOOL becomes default
+        "--action_env=NO_MSVC_WRAPPER=1",
+    ],
     config = ":configs/bazel-tests.json",
     configure = [
         "source scripts/ci/build.sh",
@@ -179,20 +194,14 @@
     project = "bazel",
     substitutions = {"GLOBAL_USE_UPSTREAM_BRANCH": "True"},
     targets = [],
-    build_opts = [
-        "--verbose_failures",
-        # TODO(pcloudy): This is only for Windows.
-        # Remove it after wrapper-less CROSSTOOL becomes default
-        "--action_env=NO_MSVC_WRAPPER=1",
-    ],
     test_opts = [
         "-k",
         "--test_output=errors",
         "--build_tests_only",
     ],
     tests = [
-        "//scripts/...",
         "filter(\"^(?!//src/test/docker).*$\", //src/test/...)",
+        "//scripts/...",
         "//third_party/ijar/...",
         "//tools/android/...",
     ],
diff --git a/jenkins/jobs/CR-global.xml.tpl b/jenkins/jobs/CR-global.xml.tpl
new file mode 100644
index 0000000..d68eea9
--- /dev/null
+++ b/jenkins/jobs/CR-global.xml.tpl
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<flow-definition>
+  <actions/>
+  <description>Global pipeline to bootstrap bazel and runs all downstream jobs</description>
+  <keepDependencies>false</keepDependencies>
+  <properties>
+    <org.jenkinsci.plugins.workflow.job.properties.DisableConcurrentBuildsJobProperty/>
+    <com.coravy.hudson.plugins.github.GithubProjectProperty>
+      <projectUrl>https://github.com/bazelbuild/bazel/</projectUrl>
+      <displayName></displayName>
+    </com.coravy.hudson.plugins.github.GithubProjectProperty>
+    <hudson.model.ParametersDefinitionProperty>
+      <parameterDefinitions>
+        <hudson.model.StringParameterDefinition>
+          <name>BRANCH</name>
+          <description>The branch to build</description>
+          <defaultValue>master</defaultValue>
+        </hudson.model.StringParameterDefinition>
+        <hudson.model.StringParameterDefinition>
+          <name>REFSPEC</name>
+          <description>The refspec to fetch</description>
+          <defaultValue>+refs/heads/*:refs/remotes/origin/*</defaultValue>
+        </hudson.model.StringParameterDefinition>
+        <hudson.model.TextParameterDefinition>
+          <name>EXTRA_BAZELRC</name>
+          <description>To inject new option to the .bazelrc file in downstream projects.</description>
+          <defaultValue></defaultValue>
+        </hudson.model.TextParameterDefinition>
+        <hudson.model.StringParameterDefinition>
+          <name>CHANGE_NUMBER</name>
+          <description>Number of the change being tested, for information only.</description>
+          <defaultValue></defaultValue>
+        </hudson.model.StringParameterDefinition>
+      </parameterDefinitions>
+    </hudson.model.ParametersDefinitionProperty>
+    <org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
+      <triggers/>
+    </org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
+  </properties>
+  <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition">
+    <script>
+json_config = '''{{ raw_imports['//jenkins/jobs:configs/bootstrap.json'].replace('\\', '\\\\').replace("'", "\\'") }}'''
+restrict_configuration = {{ variables.RESTRICT_CONFIGURATION }}
+mail_recipient = ""
+gerritReview("https://bazel-review.googlesource.com/",
+    "/opt/secrets/gerritcookies",
+    "Bazel CI &lt;ci.bazel@gmail.com&gt;",
+    params.CHANGE_NUMBER,
+    params.BRANCH) {
+  {{ imports['//jenkins/jobs:global.groovy'] }}
+}</script>
+    <sandbox>true</sandbox>
+  </definition>
+  <triggers/>
+</flow-definition>
diff --git a/jenkins/jobs/global.xml.tpl b/jenkins/jobs/global.xml.tpl
index 885ef29..1fbf5ef 100644
--- a/jenkins/jobs/global.xml.tpl
+++ b/jenkins/jobs/global.xml.tpl
@@ -42,7 +42,8 @@
 json_config = '''{{ raw_imports['//jenkins/jobs:configs/bootstrap.json'].replace('\\', '\\\\').replace("'", "\\'") }}'''
 restrict_configuration = {{ variables.RESTRICT_CONFIGURATION }}
 mail_recipient = "{{ variables.BAZEL_BUILD_RECIPIENT }}"
-{{ imports['//jenkins/jobs:global.groovy'] }}</script>
+{{ imports['//jenkins/jobs:global.groovy'] }}
+  </script>
     <sandbox>true</sandbox>
   </definition>
   <triggers/>
diff --git a/jenkins/jobs/jobs.bzl b/jenkins/jobs/jobs.bzl
index f9e58ff..2131147 100644
--- a/jenkins/jobs/jobs.bzl
+++ b/jenkins/jobs/jobs.bzl
@@ -67,6 +67,7 @@
     "Bazel": ALL_PLATFORMS + BSD_PLATFORMS,
     "Github-Trigger": UNIX_PLATFORMS,
     "Global/pipeline": [],
+    "CR/global-verifier": [],
     "Bazel-Install": [],
     "Bazel-Install-Trigger": [],
 }
diff --git a/jenkins/lib/src/build/bazel/ci/GerritUtils.groovy b/jenkins/lib/src/build/bazel/ci/GerritUtils.groovy
index 6bba64d..8b78d71 100644
--- a/jenkins/lib/src/build/bazel/ci/GerritUtils.groovy
+++ b/jenkins/lib/src/build/bazel/ci/GerritUtils.groovy
@@ -175,9 +175,9 @@
   @NonCPS
   def getVerifiedChanges(filter = "", verifiedLevel = 1, maxChanges = 0) {
     def changesJson = query("status:open -reviewer:${reviewerEmail} ${filter}",
-			    maxChanges).findAll { change ->
-        def verified = change.labels.Verified
-        return (verified != null) && verified.all.any({ it.value >= verifiedLevel })
+                            maxChanges).findAll { change ->
+        def verified = change.labels.get("Presubmit-Ready", [])
+        return verified.all.any({ it.value == verifiedLevel })
     }.collect {
       it ->
         def sha1 = it.current_revision
diff --git a/jenkins/test/test_url_answer.sh b/jenkins/test/test_url_answer.sh
index 2825f59..5bf1ead 100755
--- a/jenkins/test/test_url_answer.sh
+++ b/jenkins/test/test_url_answer.sh
@@ -26,6 +26,8 @@
 
 test_ok_status "/job/Global/job/pipeline/"
 test_ok_status "/job/Github-Trigger/"
+test_ok_status "/job/CR/job/gerrit-verifier"
+test_ok_status "/job/CR/job/global-verifier"
 
 test_ok_status "/job/rules_closure/"
 test_ok_status "/job/PR/job/rules_closure/"