The SCM polling mechanism in Jenkins seems to be inconsistent. The comparison between the remote repository revision and the baseline revision of the project works differently in these two scenarios:
- In normal operation, the remote revision is checked against the revision of the most recent build of the project, regardless of its result (FAILED, SUCCESS, etc.).
- After a Jenkins restart, the remote revision is checked against the revision of the last SUCCESSFUL build of the project.
This is relevant specially because Jenkins always keeps at least one successful build, even if the project is configured to keep only the last N builds.
As an example, let's say the build succeeded one year ago, and since then all builds failed. The revision checked out one year ago is far beyond the revision of the last (failed) build, so on a Jenkins restart these projects will always trigger a new build. In normal operation, with a polling every few minutes, no new builds are triggered as the revision comparison is made against the most recent failed build. In my organization this leads to dozens of unnecessary builds every time Jenkins restarts.
Digging a bit into the code, I think I found the root cause:
In normal operation, all SCM checkouts triggers the onCheckout method here:
There, the pollingBaselines array is populated with the baseline revision of any new checkout that occurs. This array is kept in memory as long as the server is running, and it's used for baseline comparison.
But pollingBaselines is a transient variable, so it won't persist on a restart. So, here:
After a restart, the poll() method grabs the value from co.pollingBaseline. "co" comes from perhapsCompleteBuild, which comes from getLastSuccessfulBuild(), and hence there's the problem.
I'm using wokflow-job-2.0, but I think this part of the code hasn't changed in the last version (2.32).
Thanks for the support.