| So I suspect the affected users are not configuring jobs through the UI. When I configure the job via the UI, then the ID gets assigned correctly. So unless somebody can show otherwise, this smells a lot like "user error" (not necessarily that it is the user's fault for the error mind) Case in point, I took my own Jenkins and created a fresh multibranch project and added a GitSCMSource via the UI and saved => I inspected the config.xml on-disk manually and we have:
<sources class="jenkins.branch.MultiBranchProject$BranchSourceList" plugin="branc...@2.0.18">
<data>
<jenkins.branch.BranchSource>
<source class="jenkins.plugins.git.GitSCMSource" plugin="g...@3.7.0">
<id>d3e70531-9f4d-4a7b-972f-339296b80997</id>
<remote></remote>
<credentialsId></credentialsId>
<traits>
<jenkins.plugins.git.traits.BranchDiscoveryTrait/>
</traits>
</source>
<strategy class="jenkins.branch.DefaultBranchPropertyStrategy">
<properties class="empty-list"/>
</strategy>
</jenkins.branch.BranchSource>
</data>
<owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
</sources>
which matches exactly the id that is in memory. My initial suspect would be code like the job-dsl plugin. If the user was relying on an accidental side-effect that resulted in the id getting queried before the save, then that would explain things. As I understand, CodeValet uses some automatic configuration mechanism to define jobs... looks like that mechanism is not assigning an id before configuring the list of BranchSources. Now in https://github.com/jenkinsci/scm-api-plugin/blob/master/docs/consumer.adoc#scmsourceowner-contract we have
Ensure that SCMSource.setOwner(owner) has been called before any SCMSource instance is returned from either SCMSourceOwner.getSCMSources() or SCMSourceOwner.getSCMSource(id).
We should probably make more a explicit part of the contract of a SCMSourceOwner that all SCMSource instances that are added to the owner must have an id assigned before ownership is set (or we can fall back to ensuring an id has been assigned as a (minimal) side-effect of calling SCMSource.setOwner(owner). That would minimize the issue for users, but probably should be a separate ticket. I also thought I had documented somewhere (but I cannot find where... and https://github.com/jenkinsci/branch-api-plugin/blob/master/docs/user.adoc seems considerably more anemic than I thought I had left it) that it was critical - if using stuff like JobDSL - that you must assign an id... Hmmm https://github.com/jenkinsci/scm-api-plugin/blob/master/docs/implementation.adoc#implementing-jenkinsscmapiscmsource has a note on IDs...
SCMSource IDs The SCMSource’s IDs are used to help track the SCMSource that a SCMHead instance originated from.
If - and only if - you are certain that you can construct a definitive ID from the configuration details of your SCMSource then implementations are encouraged to use a computed ID.
When instantiating an SCMSource from a SCMNavigator the navigator is responsible for assigning IDs such that two observations of the same source will always have the same ID.
In all other cases, implementations should use the default generated ID mechanism when the ID supplied to the constructor is null.
An example of how a generated ID could be definitively constructed would be:
Start with the definitive URL of the server including the port
Append the name of the source
Append a SHA-1 hash of the other configuration options (this is because users can add the same source with different configuration options)
If users add the same source with the same configuration options twice to the same owner, with the above ID generation scheme, it should not matter as both sources would be idempotent.
By starting with the server URL and then appending the name of the source we might be able to more quickly route events.
The observant reader will spot the issue above, namely that we need to start from an URL that is definitive. Most SCM systems can be accessed via multiple URLs. For example, GitHub can be accessed at both https://github.com/ and https://github.com./. For internal source control systems, this can get even more complex as some users may configure using the IP address, some may configure using a hostname without a domain, some may configure using a fully qualified hostname… also ID generation should not require a network connection or any external I/O.
But that was not the note I thought I wrote. |