Include configuration mnemonic in action execution error messages

When an action execution fails, `CommandFailureUtils.describeCommandFailure` previously formatted the error without the configuration mnemonic/checksum:

Before:
```
ERROR: /path/to/pkg/BUILD:1:1: CppCompile hello_binary.o failed: (Exit 1): gcc failed: error executing CppCompile command (from target //:hello_binary) /usr/bin/gcc ...
```

If `//:hello_binary` failed when built under a configuration transition (e.g. as a dependency of `//:broken_hello_filegroup`), users could not see from the error output why the action failed in that context but succeeded when built directly.

After:
```
ERROR: /path/to/pkg/BUILD:1:1: CppCompile hello_binary.o failed: (Exit 1): gcc failed: error executing CppCompile command (from target //:hello_binary [k8-fastbuild-ST-4e2b1c0a]) /usr/bin/gcc ...
```

This CL includes the configuration checksum / mnemonic in action execution error messages, making transition-specific failures immediately identifiable.

Fixes part of https://github.com/bazelbuild/bazel/issues/18139.

PiperOrigin-RevId: 970402874
Change-Id: Iba3dab59f3e0a2229f5e1ccea5db9589727d05c7
diff --git a/src/main/java/com/google/devtools/build/lib/util/CommandFailureUtils.java b/src/main/java/com/google/devtools/build/lib/util/CommandFailureUtils.java
index 203e0c7..5a899a8 100644
--- a/src/main/java/com/google/devtools/build/lib/util/CommandFailureUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/util/CommandFailureUtils.java
@@ -174,7 +174,13 @@
     output.append(mnemonic);
     output.append(" command ");
     if (targetDescription != null) {
-      output.append("(from ").append(targetDescription).append(") ");
+      output.append("(from ").append(targetDescription);
+      if (configurationChecksum != null
+          && !configurationChecksum.isEmpty()
+          && !configurationChecksum.equals("null")) {
+        output.append(" [").append(configurationChecksum).append("]");
+      }
+      output.append(") ");
     }
     if (verbose) {
       output.append("\n  ");
diff --git a/src/test/java/com/google/devtools/build/lib/util/CommandFailureUtilsTest.java b/src/test/java/com/google/devtools/build/lib/util/CommandFailureUtilsTest.java
index 9f69abe..19f5a1e 100644
--- a/src/test/java/com/google/devtools/build/lib/util/CommandFailureUtilsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/util/CommandFailureUtilsTest.java
@@ -55,7 +55,7 @@
             "local");
     assertThat(message)
         .isEqualTo(
-            "sh failed: error executing Mnemonic command (from target //foo:bar) "
+            "sh failed: error executing Mnemonic command (from target //foo:bar [cfg12345]) "
                 + "/bin/sh -c 'echo Some errors 1>&2; echo Some output; exit 42'");
   }
 
@@ -86,7 +86,7 @@
     assertThat(message)
         .isEqualTo(
             """
-            sh failed: error executing Mnemonic command (from target //foo:bar)\s
+            sh failed: error executing Mnemonic command (from target //foo:bar [cfg12345])\s
               (exec env - \\
                 FOO=foo \\
                 PATH=/usr/bin:/bin:/sbin \\
@@ -126,12 +126,11 @@
             "local");
     assertThat(message)
         .isEqualTo(
-            "some_command failed: error executing Mnemonic command (from target //foo:bar) "
-                + "some_command arg1 arg2 arg3 arg4 arg5 arg6 'with spaces' arg8 '*' arg10 "
-                + "arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 "
-                + "arg19 arg20 arg21 arg22 arg23 arg24 arg25 arg26 "
-                + "arg27 arg28 arg29 arg30 arg31 "
-                + "... (remaining 8 arguments skipped)");
+            "some_command failed: error executing Mnemonic command (from target //foo:bar"
+                + " [cfg12345]) some_command arg1 arg2 arg3 arg4 arg5 arg6 'with spaces' arg8 '*'"
+                + " arg10 arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20 arg21 arg22"
+                + " arg23 arg24 arg25 arg26 arg27 arg28 arg29 arg30 arg31 ... (remaining 8"
+                + " arguments skipped)");
   }
 
   @Test
@@ -164,7 +163,7 @@
     assertThat(message)
         .isEqualTo(
             """
-            some_command failed: error executing Mnemonic command (from target //foo:bar)\s
+            some_command failed: error executing Mnemonic command (from target //foo:bar [cfg12345])\s
               (cd /my/working/directory && \\
               exec env - \\
                 FOO=foo \\
@@ -205,11 +204,11 @@
             "local");
     assertThat(message)
         .isEqualTo(
-            "some_command failed: error executing Mnemonic command (from target //foo:bar)"
-                + " some_command arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12"
-                + " arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20 arg21 arg22 arg23 arg24 arg25"
-                + " arg26 arg27 arg28 arg29 arg30 arg31 arg32 arg33 ... (remaining 1 argument"
-                + " skipped)");
+            "some_command failed: error executing Mnemonic command (from target //foo:bar"
+                + " [cfg12345]) some_command arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10"
+                + " arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20 arg21 arg22 arg23"
+                + " arg24 arg25 arg26 arg27 arg28 arg29 arg30 arg31 arg32 arg33 ... (remaining 1"
+                + " argument skipped)");
   }
 
   @Test
@@ -264,4 +263,26 @@
             # Runner: remote\
             """);
   }
+
+  @Test
+  public void describeCommandFailure_nullConfigurationChecksum() throws Exception {
+    Label target = Label.parseCanonicalUnchecked("//foo:bar");
+    String[] args = new String[] {"/bin/sh", "-c", "echo error; exit 1"};
+    Map<String, String> env = new LinkedHashMap<>();
+    String message =
+        CommandFailureUtils.describeCommandFailure(
+            false,
+            "Mnemonic",
+            Arrays.asList(args),
+            env,
+            null,
+            null,
+            "target " + target,
+            null,
+            "local");
+    assertThat(message)
+        .isEqualTo(
+            "sh failed: error executing Mnemonic command (from target //foo:bar) /bin/sh -c"
+                + " 'echo error; exit 1'");
+  }
 }