Use a pipeline job for the Benchmark job

This delete the last non-pipeline job and should fix the issue
with parsing XML files on the benchmark job.

Change-Id: Iabc8e252e45c6f994f2c69cb17e67a019a442983
diff --git a/docs/jobs.md b/docs/jobs.md
index 9a1fa91..2f6cecd 100644
--- a/docs/jobs.md
+++ b/docs/jobs.md
@@ -10,8 +10,6 @@
 
 * `benchmark`: job running continously to produce benchmarks of
    Bazel published at [perf.bazel.build](https://perf.bazel.build).
-* `maintenance/push-benchmark`: job running after `benchmark` to publish
-   the performance test to the website.
 * `maintenance/install-bazel`: job that install Bazel release on all the slaves.
 * `maintenance/gerrit-verifier`: job to detect pending reviews on Gerrit that
    need validation (that have been marked as `Presubmit-Ready`).
diff --git a/jenkins/jobs/BUILD b/jenkins/jobs/BUILD
index 8bc06fc..0ce94b7 100644
--- a/jenkins/jobs/BUILD
+++ b/jenkins/jobs/BUILD
@@ -12,7 +12,7 @@
 jenkins_job(
     name = "benchmark",
     config = "benchmark.xml.tpl",
-    project_url = "http://bazel.io",
+    deps = [":benchmark.groovy"],
 )
 
 [jenkins_job(
@@ -24,12 +24,6 @@
 ) for job in ["nightly", "presubmit", "release"]]
 
 jenkins_job(
-    name = "maintenance/push-benchmark",
-    config = "push-benchmark.xml.tpl",
-    project_url = "http://bazel.io",
-)
-
-jenkins_job(
     name = "maintenance/install-bazel",
     config = "install-bazel.xml.tpl",
     deps = [":install-bazel.groovy"],
diff --git a/jenkins/jobs/benchmark.groovy b/jenkins/jobs/benchmark.groovy
new file mode 100644
index 0000000..29ea027
--- /dev/null
+++ b/jenkins/jobs/benchmark.groovy
@@ -0,0 +1,81 @@
+// Copyright (C) 2017 The Bazel Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This is the one pipeline to rule them all
+import build.bazel.ci.BazelUtils
+import java.util.concurrent.TimeUnit
+
+def newChanges = false
+def filename = "output/build_${currentBuild.getId()}.json"
+
+timeout(time: 20, unit: TimeUnit.HOURS) {
+  node("benchmark") {
+    stage("Clone") {
+      recursiveGit(repository: "https://bazel.googlesource.com/bazel",
+                   branch: "master")
+    }
+
+    // Build the benchmark binary
+    def utils = new BazelUtils()
+    utils.bazel = bazelPath("latest", "linux-x86_64")
+    utils.script = this
+    utils.writeRc()
+    stage("Building benchmark") {
+      utils.build(["//src/tools/benchmark/java/com/google/devtools/build/benchmark"])
+    }
+
+    // Run the benchmark
+    stage("Running benchmark") {
+      def workspace = pwd()
+      // Get only version from Bazel, not from the Jenkins lib.
+      // Unfortunately we do not have the origin information so we filter out
+      // commit by "nobody".
+      def versions = []
+      for (def lst : currentBuild.getChangeSets()) {
+        for (def item : lst) {
+          if (!item.author.toString().equals("nobody")) {
+            versions <<= "--versions=${item.commitId}"
+          }
+        }
+      }
+      if (versions.isEmpty()) {
+        echo "No new changes, skipping"
+      } else {
+        newChanges = true
+        def args = [
+          "bazel-bin/src/tools/benchmark/java/com/google/devtools/build/benchmark/benchmark",
+          "--workspace=${workspace}/benchmark_workspace",
+          "--output=${workspace}/${filename}"] + versions
+        dir("output") { writeFile file:"dummy", text: "" }
+        utils.commandWithBazelOnPath(args.join(" "))
+        stash name:"benchmark-results", includes:filename
+      }
+    }
+  }
+}
+
+stage("Deploying benchmark results") {
+  if (newChanges) {
+    node("deploy") {
+      // TODO(dmarting): since we are moving deployment of website we should
+      // also move the deployment of benchmark out of bazel.
+      recursiveGit(repository: "https://bazel.googlesource.com/bazel",
+                   branch: "master")
+      unstash "benchmark-results"
+      sh """
+bash -c 'source scripts/ci/build.sh; push_benchmark_output_to_site ${filename} perf.bazel.build'
+"""
+    }
+  }
+}
diff --git a/jenkins/jobs/benchmark.xml.tpl b/jenkins/jobs/benchmark.xml.tpl
index 4ab52e7..2d77ee6 100644
--- a/jenkins/jobs/benchmark.xml.tpl
+++ b/jenkins/jobs/benchmark.xml.tpl
@@ -14,13 +14,15 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 -->
-<project>
+<flow-definition>
   <actions/>
   <description>Run Bazel benchmark for new changes</description>
   <keepDependencies>false</keepDependencies>
   <properties>
+    <org.jenkinsci.plugins.workflow.job.properties.DisableConcurrentBuildsJobProperty/>
     <com.coravy.hudson.plugins.github.GithubProjectProperty>
-      <projectUrl>{{ variables.GITHUB_URL }}</projectUrl>
+      <projectUrl>https://github.com/bazelbuild/bazel/</projectUrl>
+      <displayName></displayName>
     </com.coravy.hudson.plugins.github.GithubProjectProperty>
     <jenkins.model.BuildDiscarderProperty>
       <strategy class="hudson.tasks.LogRotator">
@@ -30,106 +32,19 @@
         <artifactNumToKeep>-1</artifactNumToKeep>
       </strategy>
     </jenkins.model.BuildDiscarderProperty>
+    <org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
+      <triggers>
+        {% if variables.production == "true" %}
+        <hudson.triggers.TimerTrigger>
+          <spec>@midnight</spec>
+        </hudson.triggers.TimerTrigger>
+        {% endif %}
+      </triggers>
+    </org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
   </properties>
-  <scm class="hudson.plugins.git.GitSCM">
-    <configVersion>2</configVersion>
-    <userRemoteConfigs>
-      <hudson.plugins.git.UserRemoteConfig>
-        <refspec>+refs/heads/*:refs/remotes/origin/* +refs/notes/*:refs/notes/*</refspec>
-        <url>{{ variables.GITHUB_URL }}</url>
-      </hudson.plugins.git.UserRemoteConfig>
-    </userRemoteConfigs>
-    <branches>
-      <hudson.plugins.git.BranchSpec>
-        <name>master</name>
-      </hudson.plugins.git.BranchSpec>
-    </branches>
-    <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
-    <submoduleCfg class="list"/>
-    <extensions>
-      <hudson.plugins.git.extensions.impl.CleanBeforeCheckout/>
-      <hudson.plugins.git.extensions.impl.AuthorInChangelog/>
-    </extensions>
-  </scm>
-  <quietPeriod>5</quietPeriod>
-  <assignedNode>benchmark</assignedNode>
-  <canRoam>false</canRoam>
-  <disabled>false</disabled>
-  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
-  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
-  <triggers>
-    <hudson.triggers.TimerTrigger>
-      <spec>H H * * *</spec>
-    </hudson.triggers.TimerTrigger>
-  </triggers>
-  <concurrentBuild>false</concurrentBuild>
-  <builders>
-    <hudson.tasks.Shell>
-        <command>#!/bin/bash
-echo &quot;Getting all the changes...&quot;
-curl &quot;http://ci.bazel.io/view/Bazel%20bootstrap%20and%20maintenance/job/Bazel-Benchmark/$BUILD_NUMBER/api/xml?wrapper=changes&amp;xpath=//changeSet//commitId&quot; &gt; change.log
-sed change.log -i -e &quot;s/&lt;\/commitId&gt;/\n/g; s/&lt;commitId&gt;//g; s/&lt;changes&gt;//g; s/&lt;\/changes&gt;//g&quot;
-if [ ! -s change.log ]; then
-  echo &quot;No new changes. Exit.&quot;
-  exit 0
-fi
-
-# Add bazel to the PATH
-PATH=$PATH:$HOME/.bazel/latest/bin
-
-# build benchmark
-echo "Building benchmark..."
-bazel build src/tools/benchmark/java/com/google/devtools/build/benchmark \
-    --spawn_strategy=standalone --genrule_strategy=standalone
-
-# run benchmark
-filename=&quot;build_$BUILD_NUMBER.json&quot;
-version_string=&quot;&quot;
-while read line
-do
-  version_string+=&quot; --versions=${line}&quot;
-done &lt; change.log
-
-mkdir output
-bazel-bin/src/tools/benchmark/java/com/google/devtools/build/benchmark/benchmark \
-    --workspace=${WORKSPACE}/benchmark_workspace \
-    --output=${WORKSPACE}/output/${filename} \
-    ${version_string}
-        </command>
-    </hudson.tasks.Shell>
-  </builders>
-  <publishers>
-    <hudson.tasks.ArtifactArchiver>
-      <artifacts>output/*.json</artifacts>
-      <allowEmptyArchive>true</allowEmptyArchive>
-      <onlyIfSuccessful>false</onlyIfSuccessful>
-      <fingerprint>false</fingerprint>
-      <defaultExcludes>true</defaultExcludes>
-    </hudson.tasks.ArtifactArchiver>
-    <hudson.plugins.parameterizedtrigger.BuildTrigger>
-      <configs>
-        <hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
-          <configs>
-            <hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
-          </configs>
-          <projects>maintenance/push-benchmark</projects>
-          <condition>UNSTABLE_OR_BETTER</condition>
-          <triggerWithNoParameters>false</triggerWithNoParameters>
-        </hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
-      </configs>
-    </hudson.plugins.parameterizedtrigger.BuildTrigger>
-  </publishers>
-  <buildWrappers>
-    <hudson.plugins.build__timeout.BuildTimeoutWrapper>
-      <strategy class="hudson.plugins.build_timeout.impl.AbsoluteTimeOutStrategy">
-        <timeoutMinutes>1200</timeoutMinutes>
-      </strategy>
-      <operationList>
-        <hudson.plugins.build__timeout.operations.FailOperation/>
-        <hudson.plugins.build__timeout.operations.WriteDescriptionOperation>
-          <description>Timed out</description>
-        </hudson.plugins.build__timeout.operations.WriteDescriptionOperation>
-      </operationList>
-    </hudson.plugins.build__timeout.BuildTimeoutWrapper>
-  </buildWrappers>
-</project>
+  <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition">
+    <script>{{ imports['//jenkins/jobs:benchmark.groovy'] }}</script>
+    <sandbox>true</sandbox>
+  </definition>
+  <triggers/>
+</flow-definition>
diff --git a/jenkins/jobs/push-benchmark.xml.tpl b/jenkins/jobs/push-benchmark.xml.tpl
deleted file mode 100644
index 62dbdd3..0000000
--- a/jenkins/jobs/push-benchmark.xml.tpl
+++ /dev/null
@@ -1,99 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!--
-  Copyright 2017 The Bazel Authors. All rights reserved.
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<project>
-  <actions/>
-  <description>Push benchmark output to site</description>
-  <keepDependencies>false</keepDependencies>
-  <properties>
-    <com.coravy.hudson.plugins.github.GithubProjectProperty>
-      <projectUrl>{{ variables.GITHUB_URL }}</projectUrl>
-    </com.coravy.hudson.plugins.github.GithubProjectProperty>
-    <jenkins.model.BuildDiscarderProperty>
-      <strategy class="hudson.tasks.LogRotator">
-        <daysToKeep>-1</daysToKeep>
-        <numToKeep>25</numToKeep>
-        <artifactDaysToKeep>-1</artifactDaysToKeep>
-        <artifactNumToKeep>-1</artifactNumToKeep>
-      </strategy>
-    </jenkins.model.BuildDiscarderProperty>
-  </properties>
-  <scm class="hudson.plugins.git.GitSCM">
-    <configVersion>2</configVersion>
-    <userRemoteConfigs>
-      <hudson.plugins.git.UserRemoteConfig>
-        <refspec>+refs/heads/*:refs/remotes/origin/* +refs/notes/*:refs/notes/*</refspec>
-        <url>{{ variables.GITHUB_URL }}</url>
-      </hudson.plugins.git.UserRemoteConfig>
-    </userRemoteConfigs>
-    <branches>
-      <hudson.plugins.git.BranchSpec>
-        <name>origin/master</name>
-      </hudson.plugins.git.BranchSpec>
-    </branches>
-    <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
-    <submoduleCfg class="list"/>
-    <extensions>
-      <hudson.plugins.git.extensions.impl.CleanBeforeCheckout/>
-      <hudson.plugins.git.extensions.impl.AuthorInChangelog/>
-    </extensions>
-  </scm>
-  <quietPeriod>5</quietPeriod>
-  <assignedNode>deploy</assignedNode>
-  <canRoam>false</canRoam>
-  <disabled>false</disabled>
-  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
-  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
-  <triggers/>
-  <concurrentBuild>false</concurrentBuild>
-  <builders>
-    <hudson.plugins.copyartifact.CopyArtifact>
-      <project>Bazel-Benchmark</project>
-      <filter>output/*.json</filter>
-      <target>input</target>
-      <excludes/>
-      <selector class="hudson.plugins.copyartifact.TriggeredBuildSelector">
-        <fallbackToLastSuccessful>true</fallbackToLastSuccessful>
-        <upstreamFilterStrategy>UseGlobalSetting</upstreamFilterStrategy>
-      </selector>
-      <flatten>true</flatten>
-      <doNotFingerprintArtifacts>false</doNotFingerprintArtifacts>
-    </hudson.plugins.copyartifact.CopyArtifact>
-    <hudson.tasks.Shell>
-      <command>#!/bin/bash
-source scripts/ci/build.sh
-
-for i in $(find input -name &quot;*.json&quot;); do
-  push_benchmark_output_to_site &quot;$i&quot; &quot;perf.bazel.build&quot;
-done
-      </command>
-    </hudson.tasks.Shell>
-  </builders>
-  <publishers/>
-  <buildWrappers>
-    <hudson.plugins.build__timeout.BuildTimeoutWrapper>
-      <strategy class="hudson.plugins.build_timeout.impl.AbsoluteTimeOutStrategy">
-        <timeoutMinutes>480</timeoutMinutes>
-      </strategy>
-      <operationList>
-        <hudson.plugins.build__timeout.operations.FailOperation/>
-        <hudson.plugins.build__timeout.operations.WriteDescriptionOperation>
-          <description>Timed out</description>
-        </hudson.plugins.build__timeout.operations.WriteDescriptionOperation>
-      </operationList>
-    </hudson.plugins.build__timeout.BuildTimeoutWrapper>
-  </buildWrappers>
-</project>
diff --git a/jenkins/lib/src/build/bazel/ci/BazelUtils.groovy b/jenkins/lib/src/build/bazel/ci/BazelUtils.groovy
index dd02b4b..4e03f5f 100644
--- a/jenkins/lib/src/build/bazel/ci/BazelUtils.groovy
+++ b/jenkins/lib/src/build/bazel/ci/BazelUtils.groovy
@@ -75,6 +75,17 @@
     }
   }
 
+  // Execute a shell/batch command with bazel as a command on the path
+  def commandWithBazelOnPath(script) {
+    this.script.withEnv(["PATH=${new File(this.bazel).parent}:${this.script.env.PATH}",
+          "BAZEL=${this.bazel}"] + envs) {
+      if (isWindows) {
+        this.script.bat script
+      } else {
+        this.script.sh "#!/bin/sh -x\n${script}"
+      }
+    }
+  }
 
   // Write a RC file to consume by the other step
   def writeRc(build_opts = [],
diff --git a/jenkins/lib/vars/bazelJob.groovy b/jenkins/lib/vars/bazelJob.groovy
index e1541c1..ed24bcd 100644
--- a/jenkins/lib/vars/bazelJob.groovy
+++ b/jenkins/lib/vars/bazelJob.groovy
@@ -52,14 +52,7 @@
 
   if(!config.configuration.isEmpty()) {
     stage("${stage_prefix}Configuration") {
-      withEnv(["PATH=${new File(config.binary).parent}:${env.PATH}",
-              "BAZEL=${config.binary}"]) {
-        if (isUnix()) {
-          sh "#!/bin/sh -x\n${config.configuration.join('\n')}"
-        } else {
-          bat config.configuration.join('\n')
-        }
-      }
+      utils.commandWithBazelOnPath(config.configuration.join("\n"))
     }
   }