diff --git a/core/src/main/java/hudson/model/Job.java b/core/src/main/java/hudson/model/Job.java index e4d54d44b375..a393e33c9a6b 100644 --- a/core/src/main/java/hudson/model/Job.java +++ b/core/src/main/java/hudson/model/Job.java @@ -34,6 +34,7 @@ import hudson.BulkChange; import hudson.EnvVars; import hudson.Extension; +import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.FeedAdapter; import hudson.PermalinkList; @@ -346,12 +347,42 @@ public boolean isKeepDependencies() { } /** - * Allocates a new buildCommand number. + * Allocates a new build number. + * @see BuildNumberAssigner */ - public synchronized int assignBuildNumber() throws IOException { - int r = nextBuildNumber++; - saveNextBuildNumber(); - return r; + public int assignBuildNumber() throws IOException { + return ExtensionList.lookupFirst(BuildNumberAssigner.class).assignBuildNumber(this, this::saveNextBuildNumber); + } + + /** + * Alternate strategy for assigning build numbers. + */ + @Restricted(Beta.class) + public interface BuildNumberAssigner extends ExtensionPoint { + /** + * Implementation of {@link Job#assignBuildNumber}. + */ + int assignBuildNumber(Job job, SaveNextBuildNumber saveNextBuildNumber) throws IOException; + /** + * Provides an externally accessible alias for {@link Job#saveNextBuildNumber}, which is {@code protected}. + * ({@link #getNextBuildNumber} and {@link #fastUpdateNextBuildNumber} are already accessible.) + */ + interface SaveNextBuildNumber { + void call() throws IOException; + } + } + + @Restricted(DoNotUse.class) + @Extension(ordinal = -1000) + public static final class DefaultBuildNumberAssigner implements BuildNumberAssigner { + @Override + public int assignBuildNumber(Job job, SaveNextBuildNumber saveNextBuildNumber) throws IOException { + synchronized (job) { + int r = job.nextBuildNumber++; + saveNextBuildNumber.call(); + return r; + } + } } /**