Robomerge config for initial branching / regular merging between streams

Hello, we’re activelly trying to use Robomerge but find it a bit harsh to understand just out of docs & sample config how to set it up in few scenarios. Could we ask you to help us with defining proper config (or sharing sample that you are using in production - data anonymized) so that we can get the best out of it please?

So far what I have understood is that Epic is using 3 named things:

  • Nodes: standalone stream/depot (source or target for data)
  • Edges: merge and path definitions how to move data from 1 node to other
  • Bots: Small applications (“threads” ?) that will run for different kind of logics. I.e. bot for slack communication, bot for core services, bot for single edge execution, bot for checking for new CLs

Following this understanding, below I’m sharing several cases we’ve run into and we would appreciate any feedack/experience sharing & possible right config to make that:

  1. We are in the middle of project and we would like to set-up new stream and start merging there. Our usual flow is to create new stream manually, then run p4 copy command and get exact copy of what we had on stream. After that we’d like to enable merging with the Robomerge. Logically it is something you want to define on the Edge definition (is it `branchspecs` ?) so that it affects “merging” just to one stream (and not multiple) -- and it should be done by using `initialCL` ?
    1. We tried to use it as one in sample but that didn’t work.
    2. `branchspecs` name (`ROBOMERGE Main -> Sample`) is created automatically and we must repurpose it? Can we define the “force merge” just in branchspecs or we need to have in both Node definition and Edge definition?
    3. Instead of using `p4 copy` command, can we instead setup just base stream and use robomerge to copy everything? What config would I use for that scenario?
  2. There are several types/modes of merging for the edges mentioned in the UI, could you please provide sample config for each of those situation:
    1. merge on request - this one should be defined in Node (`branches[0].flowsTo`) by specifying to which Node it can branch to, that’s it, right?
    2. gated merged - What gating does it allow? can we filter files/extensions? or is it based on directories / CL numbers? How can we use it?
    3. automatic merge- this one should be defined in Node (in both properties? `branches[0].flowsTo` AND `branches[0].forceFlowTo`) and it will automatically start merging all CLs?
    4. default flow - what does it mean that it is “default”? You can specify this in multiple places and it is not so obvious why we would anything to be “default” here?

Adding our current config below as file (if there is anything we can ommit / skip, or is missing, pls let us know).

Steps to Reproduce

To begin with I want to clarify that while Robomerge is shared with licensees we do not officially support it and, as you have found, do not have official or exhaustive documentation of it.

Nodes: standalone stream/depot (source or target for data)

Edges: merge and path definitions how to move data from 1 node to other

Bots: Small applications (“threads” ?) that will run for different kind of logics. I.e. bot for slack communication, bot for core services, bot for single edge execution, bot for checking for new CLs

Nodes/Edges you are correct about. Bots are an organizational method of grouping nodes and appear in the robomerge webpage as a tab. Each bot is defined by by a branchmap.json file. Different streams can appear in multiple bots, but typically only one would be the “defaultbot” for that stream.

Our usual flow is to create new stream manually, then run p4 copy command and get exact copy of what we had on stream. After that we’d like to enable merging with the Robomerge. Logically it is something you want to define on the Edge definition (is it `branchspecs` ?) so that it affects “merging” just to one stream (and not multiple) -- and it should be done by using `initialCL` ?

initialCL can be used once when setting up an edge relationship in the branchmap, but in practice we don’t use it much as it is a bit awkward. By default a new edge will set its start point to the head of the source stream at the moment it is added. If we need to set that back to something earlier we typically we simply shift click the lastCL on the robomerge page for that edge and set the value to what we want it to be.

Instead of using `p4 copy` command, can we instead setup just base stream and use robomerge to copy everything? What config would I use for that scenario?

That would likely be a very slow process. p4 copy or p4 populate to set up the stream is our workflow

merge on request - this one should be defined in Node (`branches[0].flowsTo`) by specifying to which Node it can branch to, that’s it, right?

automatic merge- this one should be defined in Node (in both properties? `branches[0].flowsTo` AND `branches[0].forceFlowTo`) and it will automatically start merging all CLs?

Yes this is generally correct. AutoMerge is an edge you want to push all* changes from while merge on request is for an edge you want to be able to push some changes but not all along. With AutoMerge you can prevent some changes/files via branchspecs, stream views, exclude authors, exclude descriptions, as well as #robomerge directives to skip (e.g #robomerge -Main). For merge on request, you can then use #robomerge <target> in the changelist description or reconsider the change on that edge to move it along.

gated merged - What gating does it allow? can we filter files/extensions? or is it based on directories / CL numbers? How can we use it?

gated merges allow the setting of a changelist that will limit the point to which the change is merged up to. This can be set directly in the branchmap.json to an absolute value or to the path in perforce of a json file that contains the CL. The format of the json is as follows

{

“Change”: “43014968”,

“Url”: “https://horde.devtools.epicgames.com/job/6836339a166f9b76e352d3f2

}

The Url is optional, and if present will turn the green “gate” CL in to a link that takes you to that address.

Gates with a Url are typically automatically updated based on the results of CI jobs, gates without the Url are referred to as manual gates and can be manually updated or updated via the robomerge page by left clicking the green CL# and entering the new target CL.

default flow - what does it mean that it is “default”? You can specify this in multiple places and it is not so obvious why we would anything to be “default” here?

Default flow is a mostly antiquated feature that only hasn’t been removed as we are a bit unsure if an external user might be relying on it. We do not use it for anything anymore, and in the past it was used as a hack around robomerge’s reluctance to allow cyclic auto-merging which we now explicitly allow when you opt-in to it by flagging an edge as ignoreInCycleDetection

Looking at your config a few points to make:

We don’t use integrationWindow for anything anymore, I don’t know how well it still works.

For stream based depots there is generally no need to specify rootPath or streamSubpath. streamSubpath can occasionally be useful when trying to limit what is being merged, but its lack of expressiveness means you are usually better off using a perforce branch mapping and specifying that in either the branchspecs (for bi-directional) section or on an edge (for single-direction filtering).

isDefaultBot is going to be true (or omitted) in most cases. The only time you want to be using isDefaultBot false is when you have a stream represented in two different bots and you need to be clear which bot is the default (accepts #robomerge commands without the [bot] clarifier) and which should only accept explicit directives for that bot.

There is a very simple example branchmap included in the documentation folder of robomerge which shows the most basic setup.

Apologies that there is not more documentation at this time, but prioritizing external support for the tool is not on the current roadmap.