Add shared actions to the execution graph.

Currently, only the action that wins the execution race is represented in the execution graph. Dependency edges on actions which lose the shared action execution race are not represented. This could result in an underestimated critical path.

With this change, shared actions all share the same execution graph node. Artifacts from the executed action are guaranteed to already exist in the execution graph because `ActionCompletionEvent` is posted prior to construction of `ActionStepOrResult.Finished`, which is needed for the shared action to observe it as done. Nevertheless, I used `logUnexpected` to avoid a crash if this assumption does not hold.

PiperOrigin-RevId: 506140972
Change-Id: Ia2d5e48c524a1afab198d3c61f21a5d893aa1cee
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionState.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionState.java
index fa51941..b9dca2f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionState.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionState.java
@@ -22,6 +22,7 @@
 import com.google.devtools.build.lib.actions.ActionLookupData;
 import com.google.devtools.build.lib.actions.Artifact.OwnerlessArtifactWrapper;
 import com.google.devtools.build.lib.actions.LostInputsActionExecutionException;
+import com.google.devtools.build.lib.actions.SharedActionEvent;
 import com.google.devtools.build.lib.bugreport.BugReport;
 import com.google.devtools.build.lib.skyframe.ActionExecutionValue.ActionTransformException;
 import com.google.devtools.build.skyframe.SkyFunction;
@@ -126,12 +127,16 @@
       result = state.get();
     }
     sharedActionCallback.actionCompleted();
+
+    ActionExecutionValue transformed;
     try {
-      return result.transformForSharedAction(action);
+      transformed = result.transformForSharedAction(action);
     } catch (ActionTransformException e) {
       throw new IllegalStateException(
           String.format("Cannot share %s and %s", this.actionLookupData, actionLookupData), e);
     }
+    env.getListener().post(new SharedActionEvent(result, transformed));
+    return transformed;
   }
 
   private static void scheduleRestart(Environment env) {