Merge branch 'stable-3.5' into stable-3.6

* stable-3.5:
  Bump version to v3.5.4.4
  Bump version to v3.4.8.6
  Consider robot comments as mutable ref for validation
  Introduce isUpToDateUnchecked for silent global-refdb checks
  Add Bazel build instructions
  Define the artifact as Gerrit plugin
  Set version to v3.5.4.3

Change-Id: Iba6328e535a9cc612f0d5a57f0f51ffed64ec6cd
diff --git a/BUILD b/BUILD
index be3ed79..7cb0408 100644
--- a/BUILD
+++ b/BUILD
@@ -7,12 +7,12 @@
     "PLUGIN_DEPS",
     "PLUGIN_DEPS_NEVERLINK",
     "PLUGIN_TEST_DEPS",
+    "gerrit_plugin",
 )
 
-java_library(
+gerrit_plugin(
     name = "global-refdb",
     srcs = glob(["src/main/java/**/*.java"]),
-    deps = PLUGIN_DEPS_NEVERLINK,
 )
 
 junit_tests(
diff --git a/README.md b/README.md
index 8249d8c..81da677 100644
--- a/README.md
+++ b/README.md
@@ -19,4 +19,50 @@
 ## Metrics
 
 Global ref-database expose metrics to measure the global ref-database operation latency.
-List of the available metrics can be found [here](./metrics.md).
\ No newline at end of file
+List of the available metrics can be found [here](./metrics.md).
+
+## How to build
+
+This libModule is built like a Gerrit in-tree plugin, using Bazelisk.
+
+### Build in Gerrit tree
+
+Create a symbolic link of the repository source to the Gerrit source tree /plugins/global-refdb directory.
+
+Example:
+
+git clone https://gerrit.googlesource.com/gerrit
+git clone https://gerrit.googlesource.com/modules/global-refdb
+cd gerrit/plugins
+ln -s ../../global-refdb .
+From the Gerrit source tree issue the command bazelsk build plugins/global-refdb
+
+Example:
+
+```
+bazelisk build plugins/global-refdb
+```
+
+The libModule jar file is created under basel-bin/plugins/global-refdb/global-refdb.jar
+
+To execute the tests run bazelisk test plugins/global-refdb/... from the Gerrit source tree.
+
+Example:
+
+```
+bazelisk test plugins/global-refdb/...
+```
+
+## How to import into Eclipse as a project
+
+Add `global-refdb` in the `CUSTOM_PLUGINS` section of the `tools/bzl/plugins.bzl`.
+
+Example:
+
+```
+CUSTOM_PLUGINS = [
+    "global-refdb",
+]
+```
+
+Run `tools/eclipse/project.py` for generating or updating the Eclipse project.
\ No newline at end of file
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/GlobalRefDatabase.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/GlobalRefDatabase.java
index dbc52e8..df1e20a 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/GlobalRefDatabase.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/GlobalRefDatabase.java
@@ -33,6 +33,26 @@
   boolean isUpToDate(Project.NameKey project, Ref ref) throws GlobalRefDbLockException;
 
   /**
+   * Check in global ref-db if ref is up-to-date, without locking, warnings or checked exceptions.
+   *
+   * <p>Differently from the regular {@link #isUpToDate(com.google.gerrit.entities.Project.NameKey,
+   * Ref)} this method is suitable for checking the status of the local-ref against the global-refdb
+   * without having any intention to update its value in a transaction.
+   *
+   * <p>The concrete implementations of GlobalRefDatabase must provide a specific implementation for
+   * this method that does not create any warnings in the logs.
+   *
+   * @param project project name of the ref
+   * @param ref to be checked against global ref-db
+   * @return true if it is; false otherwise
+   * @since 3.4.8.5
+   */
+  default boolean isUpToDateUnchecked(Project.NameKey project, Ref ref) {
+    throw new UnsupportedOperationException(
+        "isUpToDateUnchecked() is not supported by " + this.getClass().getName());
+  }
+
+  /**
    * Compare a reference, and put if it is up-to-date with the current.
    *
    * <p>Two reference match if and only if they satisfy the following:
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/SharedRefEnforcement.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/SharedRefEnforcement.java
index a765975..4e8b2f7 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/SharedRefEnforcement.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/SharedRefEnforcement.java
@@ -14,6 +14,8 @@
 
 package com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb;
 
+import com.google.gerrit.entities.RefNames;
+
 /** Type of enforcement to implement between the local and shared RefDb. */
 public interface SharedRefEnforcement {
   public enum EnforcePolicy {
@@ -54,7 +56,9 @@
   default boolean isRefToBeIgnoredBySharedRefDb(String refName) {
     return refName == null
         || refName.startsWith("refs/draft-comments")
-        || (refName.startsWith("refs/changes") && !refName.endsWith("/meta"))
+        || (refName.startsWith("refs/changes")
+            && !refName.endsWith("/meta")
+            && !refName.endsWith(RefNames.ROBOT_COMMENTS_SUFFIX))
         || refName.startsWith("refs/cache-automerge");
   }
 }
diff --git a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/DefaultSharedRefEnforcementTest.java b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/DefaultSharedRefEnforcementTest.java
index a9f0cb2..d8f5ff7 100644
--- a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/DefaultSharedRefEnforcementTest.java
+++ b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/dfsrefdb/DefaultSharedRefEnforcementTest.java
@@ -17,6 +17,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
+import com.google.gerrit.entities.RefNames;
 import org.eclipse.jgit.lib.Ref;
 import org.junit.Test;
 
@@ -39,6 +40,14 @@
   }
 
   @Test
+  public void aChangeRobotCommentsShouldNotBeIgnored() {
+    Ref robotCommentsMutableRef =
+        newRef("refs/changes/01/1" + RefNames.ROBOT_COMMENTS_SUFFIX, AN_OBJECT_ID_1);
+    assertThat(refEnforcement.getPolicy(A_TEST_PROJECT_NAME, robotCommentsMutableRef.getName()))
+        .isEqualTo(EnforcePolicy.REQUIRED);
+  }
+
+  @Test
   public void aCacheAutomergeShouldBeIgnored() {
     Ref immutableChangeRef = newRef("refs/cache-automerge/01/1/1000000", AN_OBJECT_ID_1);
     assertThat(refEnforcement.getPolicy(A_TEST_PROJECT_NAME, immutableChangeRef.getName()))