diff --git a/.backportrc.json b/.backportrc.json
new file mode 100644
index 0000000000..83a13c5e4a
--- /dev/null
+++ b/.backportrc.json
@@ -0,0 +1,3 @@
+{
+ "autoMerge": true
+}
diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml
new file mode 100644
index 0000000000..39f9129962
--- /dev/null
+++ b/.github/workflows/backport.yml
@@ -0,0 +1,24 @@
+name: Automatic backport action
+
+on:
+ pull_request_target:
+ types: ["closed"]
+
+jobs:
+ backport:
+ name: Backport PR
+ runs-on: ubuntu-latest
+ steps:
+ - name: Backport Action
+ uses: sqren/backport-github-action@v9.3.0
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ auto_backport_label_prefix: backport-to-
+
+ - name: Info log
+ if: ${{ success() }}
+ run: cat ~/.backport/backport.info.log
+
+ - name: Debug log
+ if: ${{ failure() }}
+ run: cat ~/.backport/backport.debug.log
diff --git a/.github/workflows/georchestra-gn4.yml b/.github/workflows/georchestra-gn4.yml
index 2aa7a701c1..ee8d54355a 100644
--- a/.github/workflows/georchestra-gn4.yml
+++ b/.github/workflows/georchestra-gn4.yml
@@ -12,6 +12,7 @@ env:
jobs:
build:
+ if: "!startsWith(github.event.head_commit.message, '[skip ci] ')"
runs-on: ubuntu-latest
timeout-minutes: 40
steps:
@@ -68,20 +69,3 @@ jobs:
name: geonetwork.war
path: web/target/geonetwork.war
- - name: "Login onto docker-hub"
- if: github.repository == 'georchestra/geonetwork' && github.actor != 'dependabot[bot]' && github.ref == 'refs/heads/georchestra-gn4.2.x' && github.event_name != 'pull_request'
- uses: docker/login-action@v1
- with:
- username: '${{ secrets.DOCKER_HUB_USERNAME }}'
- password: '${{ secrets.DOCKER_HUB_PASSWORD }}'
-
- - name: "Pushing branch image to docker-hub"
- if: github.repository == 'georchestra/geonetwork' && github.actor != 'dependabot[bot]' && github.ref == 'refs/heads/georchestra-gn4.2.x' && github.event_name != 'pull_request'
- run: |
- docker push georchestra/geonetwork:${DOCKER_TAG}
-
- - name: "Pushing latest image to docker-hub"
- if: github.repository == 'georchestra/geonetwork' && github.actor != 'dependabot[bot]' && github.ref == 'refs/heads/georchestra-gn4.2.x' && github.event_name != 'pull_request'
- run: |
- docker tag georchestra/geonetwork:${DOCKER_TAG} georchestra/geonetwork:latest
- docker push georchestra/geonetwork:latest
diff --git a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java
index e84b20acf1..754ad2eee9 100644
--- a/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java
+++ b/csw-server/src/main/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2Es.java
@@ -68,7 +68,7 @@ public class CswFilter2Es extends AbstractFilterVisitor {
" %s\n" +
" ]\n" +
" ,\"filter\":{\"query_string\":{\"query\":\"{@}\"}}}"; //, "minimum_should_match" : 1
- private final String templateOr = " {\"bool\": {\n" +
+ private static final String TEMPLATE_OR = " {\"bool\": {\n" +
" \"should\": [\n" +
" %s\n" +
" ]\n" +
@@ -78,7 +78,7 @@ public class CswFilter2Es extends AbstractFilterVisitor {
" %s\n" +
" ]\n" +
" ,\"filter\":{\"query_string\":{\"query\":\"{@}\"}}, \"minimum_should_match\" : 1}";
- private final String templateMatch = "{\"query_string\": {\n" +
+ private static final String TEMPLATE_MATCH = "{\"query_string\": {\n" +
" \"fields\": [\"%s\"],\n" +
" \"query\": \"%s\"\n" +
" }}";
diff --git a/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java b/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java
index 524c064ab7..12e65b6f55 100644
--- a/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java
+++ b/csw-server/src/test/java/org/fao/geonet/kernel/csw/services/getrecords/es/CswFilter2EsTest.java
@@ -232,6 +232,82 @@ void testPropertyIsLikeSpecialChars() throws IOException {
assertFilterEquals(expected2, input2);
}
+ @Test
+ void testPropertyIsEqualToSpecialChars() throws IOException {
+ final String input =
+ "\n" //
+ + " \n" //
+ + " OnlineResourceType\n" //
+ + " OGC:WMS\n" //
+ + " \n" //
+ + " ";
+
+ // EXPECTED:
+ final ObjectNode expected = EsJsonHelper.boolbdr(). //
+ must(array(queryStringPart("OnlineResourceType", "OGC\\:WMS"))). //
+ filter(queryStringPart()). //
+ bld();
+
+ assertFilterEquals(expected, input);
+ }
+
+ @Test
+ void testPropertyIsLike() throws IOException {
+
+ final String input =
+ "\n" //
+ + " \n" //
+ + " AnyText\n" //
+ + " s\\_rvice\\%\n" //
+ + " \n" //
+ + " ";
+
+ // EXPECTED:
+ final ObjectNode expected = EsJsonHelper.boolbdr(). //
+ must(array(queryStringPart("AnyText", "s?rvice*"))). //
+ filter(queryStringPart()). //
+ bld();
+
+ assertFilterEquals(expected, input);
+ }
+
+ @Test
+ void testPropertyIsLikeSpecialChars() throws IOException {
+
+ final String input =
+ "\n" //
+ + " \n" //
+ + " AnyText\n" //
+ + " \"service\"\n" //
+ + " \n" //
+ + " ";
+
+ // EXPECTED:
+ final ObjectNode expected = EsJsonHelper.boolbdr(). //
+ must(array(queryStringPart("AnyText", "\\\"service\\\""))). //
+ filter(queryStringPart()). //
+ bld();
+
+ assertFilterEquals(expected, input);
+
+
+ final String input2 =
+ "\n" //
+ + " \n" //
+ + " AnyText\n" //
+ + " OGC:WMS\\%\n" //
+ + " \n" //
+ + " ";
+
+ // EXPECTED:
+ final ObjectNode expected2 = EsJsonHelper.boolbdr(). //
+ must(array(queryStringPart("AnyText", "OGC\\:WMS*"))). //
+ filter(queryStringPart()). //
+ bld();
+
+ assertFilterEquals(expected2, input2);
+ }
+
@Test
void testLogicalAnd() throws IOException {
diff --git a/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js b/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js
index 7a7f6ea10f..0ff7a5bc36 100644
--- a/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js
+++ b/web-ui/src/main/resources/catalog/components/common/openlayers/olMapDirective.js
@@ -60,7 +60,7 @@
var map = scope.$eval(prop);
var target = element[0];
- var resizeObserver = new ResizeObserver(function () {
+ var resizeObserver = new ResizeObserver(function() {
map.updateSize();
resizeObserver.unobserve(target);
});
diff --git a/web/src/docker/Dockerfile b/web/src/docker/Dockerfile
index e5d405a93c..4c4c5392de 100644
--- a/web/src/docker/Dockerfile
+++ b/web/src/docker/Dockerfile
@@ -9,6 +9,8 @@ COPY --chown=jetty:jetty . /
# Temporary switch to root
USER root
+RUN mkdir -p /docker-entrypoint.d
+RUN chown jetty:jetty /docker-entrypoint.d
RUN mkdir -p /mnt/geonetwork_datadir && \
chown jetty:jetty /mnt/geonetwork_datadir
diff --git a/web/src/docker/docker-entrypoint.sh b/web/src/docker/docker-entrypoint.sh
index 4c54157358..34ff73817e 100755
--- a/web/src/docker/docker-entrypoint.sh
+++ b/web/src/docker/docker-entrypoint.sh
@@ -2,9 +2,19 @@
DIR=/docker-entrypoint.d
+# Executing custom scripts located in CUSTOM_SCRIPTS_DIRECTORY if environment variable is set
+if [[ -z "${CUSTOM_SCRIPTS_DIRECTORY}" ]]; then
+ echo "[INFO] No CUSTOM_SCRIPTS_DIRECTORY env variable set"
+else
+ echo "[INFO] CUSTOM_SCRIPTS_DIRECTORY env variable set to ${CUSTOM_SCRIPTS_DIRECTORY}"
+ cp -v "${CUSTOM_SCRIPTS_DIRECTORY}"/* "$DIR"
+ echo "[INFO] End copying custom scripts"
+fi
+
if [[ -d "$DIR" ]]
then
- /bin/run-parts --verbose "$DIR"
+ # Regex is needed to execute all kind of files, including sh files. Warning : --regex not available in alpine images.
+ /bin/run-parts --verbose "$DIR" --regex='.*'
fi
exec "$@"