Targets can now be configured add exec_properties on top of the platform's exec_properties
See https://docs.google.com/document/d/1w3fu8zu_sRw_gK1dFAvkY2suhbQQ82tc0zdjet-dpCI/edit#heading=h.5mcn15i0e1ch

RELNOTES: introducing per-target exec_properties
PiperOrigin-RevId: 265540815
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index b11ba26..f73e723 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -410,7 +410,12 @@
   public ActionOwner getActionOwner() {
     if (actionOwner == null) {
       actionOwner =
-          createActionOwner(rule, aspectDescriptors, getConfiguration(), getExecutionPlatform());
+          createActionOwner(
+              rule,
+              aspectDescriptors,
+              getConfiguration(),
+              getTargetExecProperties(),
+              getExecutionPlatform());
     }
     return actionOwner;
   }
@@ -508,20 +513,28 @@
             AnalysisUtils.isStampingEnabled(this, getConfiguration()), key, getConfiguration());
   }
 
+  private static ImmutableMap<String, String> computeExecProperties(
+      Map<String, String> targetExecProperties, @Nullable PlatformInfo executionPlatform) {
+    Map<String, String> execProperties = new HashMap<>();
+
+    if (executionPlatform != null) {
+      execProperties.putAll(executionPlatform.execProperties());
+    }
+
+    // If the same key occurs both in the platform and in target-specific properties, the
+    // value is taken from target-specific properties (effectively overriding the platform
+    // properties).
+    execProperties.putAll(targetExecProperties);
+    return ImmutableMap.copyOf(execProperties);
+  }
+
   @VisibleForTesting
   public static ActionOwner createActionOwner(
       Rule rule,
       ImmutableList<AspectDescriptor> aspectDescriptors,
       BuildConfiguration configuration,
+      Map<String, String> targetExecProperties,
       @Nullable PlatformInfo executionPlatform) {
-    ImmutableMap<String, String> execProperties;
-    if (executionPlatform != null) {
-      execProperties = executionPlatform.execProperties();
-    } else {
-      execProperties = ImmutableMap.of();
-    }
-    // TODO(agoulti): Insert logic to include per-target execution properties
-
     return ActionOwner.create(
         rule.getLabel(),
         aspectDescriptors,
@@ -531,7 +544,7 @@
         configuration.checksum(),
         configuration.toBuildEvent(),
         configuration.isHostConfiguration() ? HOST_CONFIGURATION_PROGRESS_TAG : null,
-        execProperties,
+        computeExecProperties(targetExecProperties, executionPlatform),
         executionPlatform);
   }
 
@@ -1202,6 +1215,14 @@
     return constraintSemantics;
   }
 
+  public Map<String, String> getTargetExecProperties() {
+    if (isAttrDefined(RuleClass.EXEC_PROPERTIES, Type.STRING_DICT)) {
+      return attributes.get(RuleClass.EXEC_PROPERTIES, Type.STRING_DICT);
+    } else {
+      return ImmutableMap.of();
+    }
+  }
+
   @Override
   @Nullable
   public PlatformInfo getExecutionPlatform() {