To capture discussion with abayer my proposal has been revised some: currently I think the best solution is to create a new Step for JUnit or other test results, but not attach an action to the FlowNode generated by this step exection. Instead, when run, the step will attach a reference to the FlowNodeId in the TestResult. Thus, each test result will be assignable to the exact point within the run where it was generated.
Implementation-side, this is what I'm thinking:
1. New step (not just a wrapper) for JUnit result archiving.
2. The step.run method in its execution will invoke a new version of the JUnitResultArchiver.perform method, which takes a (nullable) FlowNodeId parameter or similar.
3. The existing API will be modified to invoke the new API using a null FlowNodeId.
4. The test results will get a (nullable) field for the flowNodeId, probably on the TestAction or TestResult action. This allows us to associate the result with the time of generation.
5. The new JUnitResultArchiver perform method will set this flowNodeId field to store the information.
6. For non-pipeline builds, or archived results before this, we need to handle null values (and allow serializing/deserializing without the field set).
7. If we can find a good way, JUnitResultArchiver may will to look to see if it is inside a pipeline run and attach this field when the old perform API is called, by looking at the current heads for a FlowNode that might be an achiving step.
UI representation here TBD.
It is possibly worth calling the flowNodeId field something else, to allow for other uses and not make it 100% pipeline specific. I am not sure.
I didn't notice this ticket until after I wrote https://github.com/jenkinsci/junit-plugin/pull/27 and https://github.com/jenkinsci/parallel-test-executor-plugin/pull/16
My suggested approach doesn't provide any visual difference in the test report, since suite names isn't rendered anywhere iiuc. But it serves a way for other parts of the flow to use that info, like the parallel test executor.