Find Jenkins projects that build periodically

Article ID:360032285111
3 minute readKnowledge base

Issue

  • How to identify Jenkins projects that build periodically

  • I want to list all recent builds triggered by Jenkins cron scheduler

Description

Jenkins provides a cron-like feature to periodically build a project. This feature is primarily for using Jenkins as a cron replacement, and it is not ideal for continuously building software projects. When people first start continuous integration, they are often so used to the idea of regularly scheduled builds like nightly/weekly that they use this feature.

However, the point of continuous integration is to start a build as soon as a change is made, to provide a quick feedback to the change. To do that you need to hook up SCM change notification to Jenkins. Webhooks provide a way for notifications to be delivered to an external web server whenever certain actions occur on a repository or organization. The interested reader can refer to:

Resolution

So, how do we identify all these projects that build periodically on a Jenkins instance.

Bash script

Open a terminal window and change to JENKINS_HOME/jobs folder. Every Jenkins project is stored in an independent, isolated folder. For example, Hello project stores its files under JENKINS_HOME/jobs/Hello folder. Project configuration is stored inside that folder in the config.xml file.

  • For a job where the Build periodically option is disabled, the XML element <triggers/> is empty.

  • For a freestyle job with Build periodically option enabled, we expect to see the XML <trigger> element set similar to

  <triggers>
    <hudson.triggers.TimerTrigger>
      <spec>45 9-16/2 * * 1-5</spec>
    </hudson.triggers.TimerTrigger>
  </triggers>
  • For a pipeline project, we should see the XML element similar to

<string>hudson.triggers.TimerTrigger</string>
triggers {
   cron(&apos;H/4 * * * *&apos;)
}

So, we want to identify all the projects where the Build periodically option is enabled. Under JENKINS_HOME/jobs search for every config.xml file that contains <hudson.triggers.TimerTrigger>. In a terminal window run the following command:

find $JENKINS_HOME/jobs -name config.xml -exec grep -l 'triggers.TimerTrigger' {} +

Groovy script

A groovy script that lets you identify the user who triggered the last build for each job, i.e. AUTOMATION or regular account. This script does not disable triggers, but provides the insight what projects should be modified. Copy the script and run it via Manage Jenkins  Script console.

Jenkins.instance.getAllItems(Job).each{
  def jobBuilds=it.getBuilds()

      // Check the last build only
      jobBuilds[0].each { build ->
        def runningSince = groovy.time.TimeCategory.minus( new Date(), build.getTime() )
        def currentStatus = build.buildStatusSummary.message
        def cause = build.getCauses()[0] //we keep the cause

      //triggered by a user
      def user = cause instanceof Cause.UserIdCause? cause.getUserId():null;

      if( !user ) {
        println "[AUTOMATION] ${build}"
      }
      else
      {
        println "[${user}] ${build}"
      }
    }
}
return

To make the script run faster, we check only the last build of a project, i.e. jobBuilds[0].each {. If you want to get the trigger cause for every project and every build, use jobBuilds.each { build -> instead.

Searching over all builds would be very time/resource consuming task on a Jenkins instance with thousands of builds.

Disable Build Periodically

For a Freestyle project, we simply need to disable the Build periodically option. A groovy script can do it for us.

For a Pipeline project, i.e. org.jenkinsci.plugins.workflow.job.WorkflowJob, the Build periodically option auto-enables if the Jenkinsfile contains triggers { ... } instruction. Thus, you may want to modify the Jenkins file directly, rather then to temporary disable Build periodically option in the configuration page.

The script below iterates over all the projects, and check whether a job has Build periodically trigger enabled. If the project type is Freestyle job the Build periodically trigger will be disabled. Otherwise, it prints the name of the project without modifying the Build periodically trigger setting.

To run the script, open Manage Jenkins  Script Console and copy the script. Then click on the Run button.

import hudson.model.*
import hudson.triggers.*
TriggerDescriptor TIMER_TRIGGER_DESCRIPTOR = Hudson.instance.getDescriptorOrDie(TimerTrigger.class)

for(item in Jenkins.instance.getAllItems(Job))
{
  def timertrigger = item.getTriggers().get(TIMER_TRIGGER_DESCRIPTOR)
  if (timertrigger) {
    if (item.class.canonicalName == "hudson.model.FreeStyleProject") {
      item.removeTrigger(TIMER_TRIGGER_DESCRIPTOR)
      println(item.name + " Build periodically disabled");
    }
    else {
      println(item.name + " Build periodically remains enabled; not as Freestyle project");
    }
  }
}