docs: document --workspace_status_command

Add docs for the --workspace_status_command flag.

Fixes https://github.com/bazelbuild/bazel/issues/4220

RELNOTES: none
PiperOrigin-RevId: 184492241
diff --git a/site/docs/user-manual.html b/site/docs/user-manual.html
index 0c4a9b5..46a9fce 100644
--- a/site/docs/user-manual.html
+++ b/site/docs/user-manual.html
@@ -2412,6 +2412,107 @@
   for copying and pasting to a shell prompt.
 </p>
 
+<h3 id='workspace_status'>Options that control how Bazel embeds workspace status information
+into binaries ("stamping")</h3>
+
+<p>
+  Use these options to "stamp" Bazel-built binaries: to embed additional information into the
+  binaries, such as the source control revision or other workspace-related information. You can use
+  this mechanism with rules that support the <code>stamp</code> attribute, such as
+  <code>genrule</code>, <code>cc_binary</code>, and more.
+</p>
+
+<h4 id='flag--workspace_status_command'><code class='flag'>--workspace_status_command <var>program</var></code></h4>
+<p>
+  This flag lets you specify a binary that Bazel runs before each build. The program can report
+  information about the status of the workspace, such as the current source control revision.
+</p>
+<p>
+  The flag's value must be a path to a native program. On Linux/macOS this may be any executable.
+  On Windows this must be a native binary, typically an ".exe", ".bat", or a ".cmd" file.
+</p>
+
+<p>
+  The program should print zero or more key/value pairs to standard output, one entry on each line,
+  then exit with zero (otherwise the build fails). The key names can be anything but they may only
+  use upper case letters and underscores. The first space after the key name separates it from the
+  value. The value is the rest of the line (including additional whitespaces).
+</p>
+<p>
+  Bazel partitions the keys into two buckets: "stable" and "volatile". (The names "stable" and
+  "volatile" are a bit counter-intuitive, so don't think much about them.)
+</p>
+
+<p>Bazel then writes the key-value pairs into two files:</p>
+<ul>
+  <li>
+    <code>bazel-out/stable-status.txt</code> contains all keys and values where the key's name
+    starts with <code>STABLE_</code>
+  </li>
+  <li><code>bazel-out/volatile-status.txt</code> contains the rest of the keys and their values</li>
+</ul>
+
+<p>The contract is:</p>
+<ul>
+  <li>
+    <p>
+      "stable" keys' values should change rarely, if possible. If the contents of
+      <code>stable-status.txt</code> change, it invalidates the actions that depend on them. In
+      other words, if a stable key's value changes, it'll make Bazel rebuild stamped actions.
+      Therefore the stable status should not contain things like timestamps, because they change all
+      the time, and would make Bazel rebuild the stamped actions with each build.
+    </p>
+    <p>Bazel always outputs the following stable keys:</p>
+    <ul>
+      <li><code>BUILD_EMBED_LABEL</code>: value of <code class='flag'>--embed_label</code></li>
+      <li><code>BUILD_HOST</code>: the name of the host machine that Bazel is running on</li>
+      <li><code>BUILD_USER</code>: the name of the user that Bazel is running as</li>
+    </ul>
+  </li>
+  <li>
+    <p>
+      "volatile" keys' values may change often. Bazel expects them to change all the time, like
+      timestamps do, and duly updates the <code>volatile-status.txt</code> file. In order to avoid
+      rebuilding stamped actions all the time though, <b>Bazel pretends that the volatile file never
+      changes</b>. In other words, if the volatile status file is the only one whose contents
+      changed, that will not invalidate actions that depend on it. If other inputs of the actions
+      have changed, then Bazel rebuilds that action, and the action will use the updated volatile
+      status, but just the volatile status changing alone will not invalidate the action.
+    </p>
+    <p>Bazel always outputs the following volatile keys:</p>
+    <ul>
+      <li>
+        <code>BUILD_TIMESTAMP</code>: time of the build in milliseconds since the Unix Epoch (the
+        value of <code>System.currentTimeMillis()</code>)
+      </li>
+    </ul>
+  </li>
+</ul>
+
+<p>
+  On Linux/macOS you can pass <code class='flag'>--workspace_status_command=/bin/true</code> to
+  disable retrieving workspace status, because <code>true</code> does nothing successfully (exits
+  with zero) and prints no output. On Windows you can pass the path of MSYS's <code>true.exe</code>
+  for the same effect.
+</p>
+
+<p>If the workspace status command fails (exits non-zero) for any reason, the build will fail.</p>
+
+<p>Example program on Linux using Git:</p>
+
+<pre>
+#!/bin/bash
+echo "CURRENT_TIME $(date +%s)"
+echo "RANDOM_HASH $(cat /dev/urandom | head -c16 | md5sum 2>/dev/null | cut -f1 -d' ')"
+echo "STABLE_GIT_COMMIT $(git rev-parse HEAD)"
+echo "STABLE_USER_NAME $USER"
+</pre>
+
+<p>
+  Pass this program's path with <code>--workspace_status_command</code>, and the stable status file
+  will include the STABLE lines and the volatile status file will include the rest of the lines.
+</p>
+
 <h4 id='flag--stamp'><code class='flag'>--[no]stamp</code></h4>
 <p>
   This option controls whether stamping is enabled for