[Skymeld] Add build-info.txt and build-changelist.txt

These 2 were missing from Skymeld.

PiperOrigin-RevId: 466694881
Change-Id: I52772f2797a4dcda059cd33ded238dd6c0f5c5e6
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
index 17dadf6..9a35e7c 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
@@ -543,7 +543,7 @@
     ImmutableSet.Builder<Artifact> artifactsToBuild = ImmutableSet.builder();
 
     // build-info and build-changelist.
-    Collection<Artifact> buildInfoArtifacts =
+    ImmutableList<Artifact> buildInfoArtifacts =
         skyframeExecutor.getWorkspaceStatusArtifacts(eventHandler);
     Preconditions.checkState(buildInfoArtifacts.size() == 2, buildInfoArtifacts);
 
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
index 6eacd7e..ccb5d42 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -2251,6 +2251,7 @@
         ":top_level_conflict_exception",
         ":transitive_target_key",
         "//src/main/java/com/google/devtools/build/lib/actions",
+        "//src/main/java/com/google/devtools/build/lib/actions:action_lookup_data",
         "//src/main/java/com/google/devtools/build/lib/actions:action_lookup_key",
         "//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster",
         "//src/main/java/com/google/devtools/build/lib/analysis:config/build_configuration",
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BuildDriverFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/BuildDriverFunction.java
index 4e18a9b..6f6289f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BuildDriverFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BuildDriverFunction.java
@@ -101,7 +101,7 @@
    * with the appropriate CompletionFunctions. This is the bridge between the conceptual analysis &
    * execution phases.
    *
-   * <p>TODO(b/199053098): implement build-info, build-changelist, coverage & exception handling.
+   * <p>TODO(b/240944910): implement coverage.
    */
   @Nullable
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
index 9c1c7ce..cdea3c1 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java
@@ -34,6 +34,7 @@
 import com.google.devtools.build.lib.actions.ActionLookupKey;
 import com.google.devtools.build.lib.actions.ActionLookupValue;
 import com.google.devtools.build.lib.actions.AnalysisGraphStatsEvent;
+import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.ArtifactFactory;
 import com.google.devtools.build.lib.actions.ArtifactPrefixConflictException;
 import com.google.devtools.build.lib.actions.BuildFailedException;
@@ -603,7 +604,7 @@
       throws InterruptedException, ViewCreationFailedException, BuildFailedException,
           TestExecException {
     Stopwatch analysisWorkTimer = Stopwatch.createStarted();
-    EvaluationResult<BuildDriverValue> evaluationResult;
+    EvaluationResult<SkyValue> evaluationResult;
 
     ImmutableSet<SkyKey> newKeys =
         ImmutableSet.<SkyKey>builderWithExpectedSize(ctKeys.size() + topLevelAspectsKeys.size())
@@ -615,6 +616,9 @@
       largestTopLevelKeySetCheckedForConflicts = newKeys;
     }
 
+    ImmutableList<Artifact> workspaceStatusArtifacts =
+        skyframeExecutor.getWorkspaceStatusArtifacts(eventHandler);
+
     ImmutableSet<BuildDriverKey> buildDriverCTKeys =
         ctKeys.stream()
             .map(
@@ -664,6 +668,7 @@
           evaluationResult =
               skyframeExecutor.evaluateBuildDriverKeys(
                   eventHandler,
+                  /*additionalArtifacts=*/ workspaceStatusArtifacts,
                   buildDriverCTKeys,
                   buildDriverAspectKeys,
                   keepGoing,
@@ -923,9 +928,9 @@
   }
 
   private static ImmutableSet<ConfiguredTarget> getExclusiveTests(
-      EvaluationResult<BuildDriverValue> evaluationResult) {
+      EvaluationResult<SkyValue> evaluationResult) {
     ImmutableSet.Builder<ConfiguredTarget> exclusiveTests = ImmutableSet.builder();
-    for (BuildDriverValue value : evaluationResult.values()) {
+    for (SkyValue value : evaluationResult.values()) {
       if (value instanceof ExclusiveTestBuildDriverValue) {
         exclusiveTests.add(
             ((ExclusiveTestBuildDriverValue) value).getExclusiveTestConfiguredTarget());
@@ -984,7 +989,7 @@
 
   private static ImmutableSet<ConfiguredTarget> getSuccessfulConfiguredTargets(
       int expectedSize,
-      EvaluationResult<BuildDriverValue> evaluationResult,
+      EvaluationResult<SkyValue> evaluationResult,
       Set<BuildDriverKey> buildDriverCTKeys,
       @Nullable TopLevelActionConflictReport topLevelActionConflictReport) {
     ImmutableSet.Builder<ConfiguredTarget> cts = ImmutableSet.builderWithExpectedSize(expectedSize);
@@ -993,7 +998,7 @@
           && !topLevelActionConflictReport.isErrorFree(bdCTKey.getActionLookupKey())) {
         continue;
       }
-      BuildDriverValue value = evaluationResult.get(bdCTKey);
+      BuildDriverValue value = (BuildDriverValue) evaluationResult.get(bdCTKey);
       if (value == null) {
         continue;
       }
@@ -1006,7 +1011,7 @@
 
   private static ImmutableMap<AspectKey, ConfiguredAspect> getSuccessfulAspectMap(
       int expectedSize,
-      EvaluationResult<BuildDriverValue> evaluationResult,
+      EvaluationResult<SkyValue> evaluationResult,
       Set<BuildDriverKey> buildDriverAspectKeys,
       @Nullable TopLevelActionConflictReport topLevelActionConflictReport) {
     // There can't be duplicate Aspects after resolving --aspects, so this is safe.
@@ -1017,7 +1022,7 @@
           && !topLevelActionConflictReport.isErrorFree(bdAspectKey.getActionLookupKey())) {
         continue;
       }
-      BuildDriverValue value = evaluationResult.get(bdAspectKey);
+      BuildDriverValue value = (BuildDriverValue) evaluationResult.get(bdAspectKey);
       if (value == null) {
         // Skip aspects that couldn't be applied to targets.
         continue;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeErrorProcessor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeErrorProcessor.java
index 442a3e7..0f1c1db 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeErrorProcessor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeErrorProcessor.java
@@ -27,6 +27,7 @@
 import com.google.common.flogger.GoogleLogger;
 import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
 import com.google.devtools.build.lib.actions.ActionExecutionException;
+import com.google.devtools.build.lib.actions.ActionLookupData;
 import com.google.devtools.build.lib.actions.ActionLookupKey;
 import com.google.devtools.build.lib.actions.BuildFailedException;
 import com.google.devtools.build.lib.actions.InputFileErrorException;
@@ -431,6 +432,17 @@
           /*loadingRootCauses=*/ ImmutableSet.of());
     }
 
+    // Only possible with actions generating build-info.txt and build-changelist.txt.
+    if (errorKey.argument() instanceof ActionLookupData) {
+      return IndividualErrorProcessingResult.create(
+          /*actionConflicts=*/ ImmutableMap.of(),
+          getExecutionDetailedExitCodeFromCause(result, cause),
+          /*rootCauses=*/ cause instanceof ActionExecutionException
+              ? ((ActionExecutionException) cause).getRootCauses()
+              : NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+          /*loadingRootCauses=*/ ImmutableSet.of());
+    }
+
     Preconditions.checkState(
         errorKey.argument() instanceof ConfiguredTargetKey,
         "expected '%s' to be a TopLevelAspectsKey or ConfiguredTargetKey",
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index bfa9950..de7c037 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -1215,18 +1215,21 @@
   }
 
   /** Returns the build-info.txt and build-changelist.txt artifacts. */
-  public Collection<Artifact> getWorkspaceStatusArtifacts(ExtendedEventHandler eventHandler)
+  public ImmutableList<Artifact> getWorkspaceStatusArtifacts(ExtendedEventHandler eventHandler)
       throws InterruptedException {
-    // Should already be present, unless the user didn't request any targets for analysis.
-    EvaluationResult<WorkspaceStatusValue> result =
-        evaluate(
-            ImmutableList.of(WorkspaceStatusValue.BUILD_INFO_KEY),
-            /*keepGoing=*/ true,
-            /*numThreads=*/ 1,
-            eventHandler);
-    WorkspaceStatusValue value =
-        Preconditions.checkNotNull(result.get(WorkspaceStatusValue.BUILD_INFO_KEY));
-    return ImmutableList.of(value.getStableArtifact(), value.getVolatileArtifact());
+    try (SilentCloseable c =
+        Profiler.instance().profile("SkyframeExecutor.getWorkspaceStatusArtifact")) {
+      // Should already be present, unless the user didn't request any targets for analysis.
+      EvaluationResult<WorkspaceStatusValue> result =
+          evaluate(
+              ImmutableList.of(WorkspaceStatusValue.BUILD_INFO_KEY),
+              /*keepGoing=*/ true,
+              /*numThreads=*/ 1,
+              eventHandler);
+      WorkspaceStatusValue value =
+          Preconditions.checkNotNull(result.get(WorkspaceStatusValue.BUILD_INFO_KEY));
+      return ImmutableList.of(value.getStableArtifact(), value.getVolatileArtifact());
+    }
   }
 
   @VisibleForTesting
@@ -2218,9 +2221,14 @@
   /**
    * Evaluates the given collections of CT/Aspect BuildDriverKeys. This is part of
    * https://github.com/bazelbuild/bazel/issues/14057, internal: b/147350683.
+   *
+   * <p>Also creates build-info.txt and build-changelist.txt.
+   *
+   * <p>Expected SkyValue types: BuildDriverValue, WorkspaceStatusValue.
    */
-  EvaluationResult<BuildDriverValue> evaluateBuildDriverKeys(
+  EvaluationResult<SkyValue> evaluateBuildDriverKeys(
       ExtendedEventHandler eventHandler,
+      ImmutableList<Artifact> additionalArtifacts,
       Set<BuildDriverKey> buildDriverCTKeys,
       Set<BuildDriverKey> buildDriverAspectKeys,
       boolean keepGoing,
@@ -2242,7 +2250,9 @@
               .setEventHandler(eventHandler)
               .build();
       return memoizingEvaluator.evaluate(
-          Iterables.concat(buildDriverCTKeys, buildDriverAspectKeys), evaluationContext);
+          Iterables.concat(
+              Artifact.keys(additionalArtifacts), buildDriverCTKeys, buildDriverAspectKeys),
+          evaluationContext);
     } finally {
       // No more analysis expected after this.
       perCommandSyscallCache.noteAnalysisPhaseEnded();
diff --git a/src/test/java/com/google/devtools/build/lib/buildtool/BUILD b/src/test/java/com/google/devtools/build/lib/buildtool/BUILD
index 56170b9..b71de7a 100644
--- a/src/test/java/com/google/devtools/build/lib/buildtool/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/buildtool/BUILD
@@ -647,6 +647,7 @@
         "//src/main/java/com/google/devtools/build/lib/skyframe:top_level_status_events",
         "//src/main/java/com/google/devtools/build/lib/vfs",
         "//src/test/java/com/google/devtools/build/lib/buildtool/util",
+        "//src/test/java/com/google/devtools/build/lib/testutil:TestConstants",
         "//third_party:guava",
         "//third_party:junit4",
         "//third_party:truth",
diff --git a/src/test/java/com/google/devtools/build/lib/buildtool/SkymeldBuildIntegrationTest.java b/src/test/java/com/google/devtools/build/lib/buildtool/SkymeldBuildIntegrationTest.java
index 27dd29f..ad398d5 100644
--- a/src/test/java/com/google/devtools/build/lib/buildtool/SkymeldBuildIntegrationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/buildtool/SkymeldBuildIntegrationTest.java
@@ -15,6 +15,7 @@
 
 import static com.google.common.collect.ImmutableSet.toImmutableSet;
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.lib.testutil.TestConstants.WORKSPACE_NAME;
 import static org.junit.Assert.assertThrows;
 
 import com.google.common.collect.ImmutableSet;
@@ -162,6 +163,12 @@
 
     assertThat(analysisEventsSubscriber.getTopLevelEntityAnalysisConcludedEvents()).hasSize(2);
     assertSingleAnalysisPhaseCompleteEventWithLabels("//foo:foo", "//foo:bar");
+
+    assertThat(directories.getOutputPath(WORKSPACE_NAME).getRelative("build-info.txt").isFile())
+        .isTrue();
+    assertThat(
+            directories.getOutputPath(WORKSPACE_NAME).getRelative("build-changelist.txt").isFile())
+        .isTrue();
   }
 
   @Test