This looks good to me, just added some comments and suggestions inline. Nothing super big!
I'm a little concerned Start and Launch are interchangeable and don't convey what's different about the operations here - I think it makes sense in the context of a RunLauncher, but I'd sort of prefer startPipelineExecution and startPipelineExecutionUsingLauncher or something like that?
I'm a little nervous about having the getVariables() method return an untyped object - would be kinda nice if we could detect that the function was out-of-date / broken if the variable schema changes. Maybe use StartPipelineExecutionVariables | LaunchPipelineExecutionVariables here?
May not need to be optional since the UI shows a spinner in place of this button until the pipeline is ready.
It looks like this may be unused now?
If it's not unused, we may still want to move ownership of this mutation down into the PipelineExecutionButtonGroup, it's odd to have execution kicked off in two separate code paths.
You could potentially expose a public method on a PipelineExecutionButtonGroup class component and use a ref to invoke it ala:
Silly nit but I think this can just be pipeline.name here since we validate pipeline is non null above.
I'm a little concerned Start and Launch are interchangeable and don't convey what's different about the operations here
Ya this is definitely just a first pass to be able to test things - needs some UX thought and love from you 😉