Include is_source_spec_final in resultdb/update_invocation call

Chromium will be setting is_source_spec_final to True so it
can use the new query stability luci analysis endpoint with improved
latency ingestion.

https://source.chromium.org/chromium/infra/infra_superproject/+/main:infra/go/src/go.chromium.org/luci/resultdb/proto/v1/invocation.proto;l=216;drc=c17c886f7b645efd3f68fe0c169cfe1dc47151d8

Bug: b/346598710
Change-Id: I017dd97a369e3ad952181d140629f41fb0d275c6
Reviewed-on: https://chromium-review.googlesource.com/c/infra/luci/recipes-py/+/5627411
Commit-Queue: Stephanie Kim <kimstephanie@google.com>
Reviewed-by: Patrick Meiring <meiring@google.com>
diff --git a/README.recipes.md b/README.recipes.md
index 202a952..24addf9 100644
--- a/README.recipes.md
+++ b/README.recipes.md
@@ -3481,7 +3481,7 @@
 
 &mdash; **def [assert\_enabled](/recipe_modules/resultdb/api.py#50)(self):**
 
-&mdash; **def [config\_test\_presentation](/recipe_modules/resultdb/api.py#784)(self, column_keys=(), grouping_keys=('status',)):**
+&mdash; **def [config\_test\_presentation](/recipe_modules/resultdb/api.py#790)(self, column_keys=(), grouping_keys=('status',)):**
 
 Specifies how the test results should be rendered.
 
@@ -3683,7 +3683,7 @@
   For value format, see [`QueryTestVariantsResponse` message]
   (http://shortn/_hv3edsXidO)
 
-&mdash; **def [unwrap](/recipe_modules/resultdb/api.py#770)(self, cmd: list[str]):**
+&mdash; **def [unwrap](/recipe_modules/resultdb/api.py#776)(self, cmd: list[str]):**
 
 Reverses the wrap command
 
@@ -3706,7 +3706,7 @@
 This updates the inclusions of the current invocation specified in the
 LUCI_CONTEXT.
 
-&mdash; **def [update\_invocation](/recipe_modules/resultdb/api.py#514)(self, parent_inv='', step_name=None, source_spec=None, baseline_id=None, instructions=None):**
+&mdash; **def [update\_invocation](/recipe_modules/resultdb/api.py#514)(self, parent_inv='', step_name=None, source_spec=None, is_source_spec_final=None, baseline_id=None, instructions=None):**
 
 Makes a call to the UpdateInvocation API to update the invocation
 
@@ -3715,6 +3715,8 @@
   step_name (str): name of the step.
   source_spec (luci.resultdb.v1.SourceSpec): The source information
     to apply to the given invocation.
+  is_source_spec_final (bool): Whether the source spec is final and won't
+    be changed again.
   baseline_id (str): Baseline identifier for this invocation, usually of
     the format {buildbucket bucket}:{buildbucket builder name}. For example,
     'try:linux-rel'. Baselines are used to detect new tests in invocations.
@@ -3743,7 +3745,7 @@
   A BatchCreateArtifactsResponse proto message listing the artifacts that
   were created.
 
-&mdash; **def [wrap](/recipe_modules/resultdb/api.py#621)(self, cmd, test_id_prefix='', base_variant=None, test_location_base='', base_tags=None, coerce_negative_duration=False, include=False, realm='', location_tags_file='', require_build_inv=True, exonerate_unexpected_pass=False, inv_properties='', inv_properties_file='', inherit_sources=False, sources='', sources_file='', baseline_id=''):**
+&mdash; **def [wrap](/recipe_modules/resultdb/api.py#627)(self, cmd, test_id_prefix='', base_variant=None, test_location_base='', base_tags=None, coerce_negative_duration=False, include=False, realm='', location_tags_file='', require_build_inv=True, exonerate_unexpected_pass=False, inv_properties='', inv_properties_file='', inherit_sources=False, sources='', sources_file='', baseline_id=''):**
 
 Wraps the command with ResultSink.
 
diff --git a/recipe_modules/resultdb/api.py b/recipe_modules/resultdb/api.py
index b01502c..abcd87e 100644
--- a/recipe_modules/resultdb/api.py
+++ b/recipe_modules/resultdb/api.py
@@ -515,6 +515,7 @@
                         parent_inv='',
                         step_name=None,
                         source_spec=None,
+                        is_source_spec_final=None,
                         baseline_id=None,
                         instructions=None):
     """Makes a call to the UpdateInvocation API to update the invocation
@@ -524,6 +525,8 @@
       step_name (str): name of the step.
       source_spec (luci.resultdb.v1.SourceSpec): The source information
         to apply to the given invocation.
+      is_source_spec_final (bool): Whether the source spec is final and won't
+        be changed again.
       baseline_id (str): Baseline identifier for this invocation, usually of
         the format {buildbucket bucket}:{buildbucket builder name}. For example,
         'try:linux-rel'. Baselines are used to detect new tests in invocations.
@@ -535,6 +538,8 @@
     field_mask_paths = []
     if source_spec:
       field_mask_paths.append('source_spec')
+    if is_source_spec_final:
+      field_mask_paths.append('is_source_spec_final')
     if baseline_id:
       field_mask_paths.append('baseline_id')
     if instructions:
@@ -544,6 +549,7 @@
         invocation=invocation_pb2.Invocation(
             name=parent_inv or self.current_invocation,
             source_spec=source_spec,
+            is_source_spec_final=is_source_spec_final,
             baseline_id=baseline_id,
             instructions=instructions),
         update_mask=field_mask_pb2.FieldMask(paths=field_mask_paths),
diff --git a/recipe_modules/resultdb/examples/update_invocation.py b/recipe_modules/resultdb/examples/update_invocation.py
index ec5ea98..21a3320 100644
--- a/recipe_modules/resultdb/examples/update_invocation.py
+++ b/recipe_modules/resultdb/examples/update_invocation.py
@@ -34,6 +34,7 @@
               gitiles_commit=gitiles_commit,
               changelists=gerrit_changes,
           )),
+      is_source_spec_final=True,
       baseline_id='try:linux-rel',
       instructions=instruction_pb.Instructions(
           instructions=[