Skip to content

Commit 0d15358

Browse files
authored
Merge pull request #108 from eea/develop
Release 9.0.0: Volto 18 support
2 parents 648d648 + fd752cc commit 0d15358

25 files changed

Lines changed: 703 additions & 476 deletions

.husky/pre-commit

Lines changed: 0 additions & 2 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file. Dates are d
44

55
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
66

7+
### [9.0.0](https://github.com/eea/volto-columns-block/compare/8.1.1...9.0.0) - 27 March 2026
8+
9+
#### :rocket: New Features
10+
11+
- feat: Volto 18 support - refs #287700 [Nilesh - [`7123bf9`](https://github.com/eea/volto-columns-block/commit/7123bf9486f21d465df3ce4021f9e982acad934b)]
12+
13+
#### :house: Internal changes
14+
15+
16+
#### :hammer_and_wrench: Others
17+
18+
- test: Fix make test [Alin V. (Claudiu) - [`9caf722`](https://github.com/eea/volto-columns-block/commit/9caf7229e2cf5e300b74d6dbede86b9a62d86dcf)]
19+
- tests: Fix Sonar Qube tags - refs #297339 [Alin Voinea - [`ac6e3da`](https://github.com/eea/volto-columns-block/commit/ac6e3da9f9731a88cc7776045513f7fbca31ae2c)]
720
### [8.1.1](https://github.com/eea/volto-columns-block/compare/8.1.0...8.1.1) - 16 February 2026
821

922
#### :bug: Bug Fixes

DEVELOP.md

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,50 +26,54 @@
2626

2727
### Or add @eeacms/volto-columns-block to your Volto project
2828

29-
Before starting make sure your development environment is properly set. See [Volto Developer Documentation](https://docs.voltocms.com/getting-started/install/)
29+
Before starting, make sure your development environment is properly set up.
30+
See the official Plone documentation for
31+
[Install Plone with Cookieplone](https://6.docs.plone.org/install/create-project-cookieplone.html)
32+
and
33+
[Install an add-on in development mode in Volto 18 and 19](https://6.docs.plone.org/volto/development/add-ons/install-an-add-on-dev-18.html).
3034

31-
1. Make sure you have installed `yo`, `@plone/generator-volto` and `mrs-developer`
35+
For new Volto 18+ projects, use Cookieplone. It includes `mrs-developer` by default.
3236

33-
npm install -g yo @plone/generator-volto mrs-developer
37+
1. Create a new Volto project with Cookieplone
3438

35-
1. Create new volto app
36-
37-
yo @plone/volto my-volto-project --addon @eeacms/volto-columns-block --skip-install
38-
cd my-volto-project
39+
uvx cookieplone project
40+
cd project-title
3941

4042
1. Add the following to `mrs.developer.json`:
4143

4244
{
4345
"volto-columns-block": {
46+
"output": "packages",
4447
"url": "https://github.com/eea/volto-columns-block.git",
4548
"package": "@eeacms/volto-columns-block",
4649
"branch": "develop",
4750
"path": "src"
4851
}
4952
}
5053

51-
1. Install
54+
1. Add `@eeacms/volto-columns-block` to the `addons` key of your project's `volto.config.js`
5255
53-
make develop
54-
yarn
56+
1. Install or refresh the project setup
5557
56-
1. Start backend
58+
make install
5759
58-
docker run --pull always -it --rm --name plone -p 8080:8080 -e SITE=Plone plone/plone-backend
60+
1. Start backend
5961
60-
...wait for backend to setup and start - `Ready to handle requests`:
62+
make backend-start
6163
62-
...you can also check http://localhost:8080/Plone
64+
...wait for backend to set up and start with `Ready to handle requests`
6365
6466
1. Start frontend
6567
66-
yarn start
68+
make frontend-start
6769
6870
1. Go to http://localhost:3000
6971
7072
1. Happy hacking!
7173
72-
cd src/addons/volto-columns-block/
74+
cd packages/volto-columns-block/
75+
76+
For legacy Volto 17 projects, keep using the yarn-based workflow from the Volto 17 documentation.
7377
7478
## Cypress
7579
@@ -81,7 +85,7 @@ project where you added `volto-columns-block` to `mrs.developer.json`
8185
Go to:
8286
8387
```BASH
84-
cd src/addons/volto-columns-block/
88+
cd packages/volto-columns-block/
8589
```
8690
8791
Start:

Dockerfile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
# syntax=docker/dockerfile:1
22
ARG VOLTO_VERSION
3-
FROM eeacms/frontend-builder:${VOLTO_VERSION}
3+
FROM plone/frontend-builder:${VOLTO_VERSION}
44

55
ARG ADDON_NAME
66
ARG ADDON_PATH
7+
ENV HOST="0.0.0.0"
8+
9+
USER root
10+
RUN apt-get update -q \
11+
&& apt-get install -qy --no-install-recommends \
12+
chromium libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb \
13+
&& rm -rf /var/lib/apt/lists/*
14+
USER node
715

816
COPY --chown=node:node ./ /app/src/addons/${ADDON_PATH}/
917

1018
RUN /setupAddon
19+
RUN yarn add jest-junit
1120
RUN yarn install
1221

1322
ENTRYPOINT ["yarn"]

Jenkinsfile

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
pipeline {
2-
tools {
3-
jdk 'Java17'
4-
}
52
agent {
63
node { label 'docker-host' }
74
}
85

96
environment {
107
GIT_NAME = "volto-columns-block"
118
NAMESPACE = "@eeacms"
12-
SONARQUBE_TAGS = "volto.eea.europa.eu,climate-energy.eea.europa.eu,forest.eea.europa.eu,biodiversity.europa.eu,www.eea.europa.eu-ims,industry.eea.europa.eu,water.europa.eu-freshwater,demo-www.eea.europa.eu,clmsdemo.devel6cph.eea.europa.eu,water.europa.eu-marine,climate-adapt.eea.europa.eu,climate-advisory-board.devel4cph.eea.europa.eu,climate-advisory-board.europa.eu,www.eea.europa.eu-en,insitu.copernicus.eu,ask.copernicus.eu,land.copernicus.eu"
9+
SONARQUBE_TAGS = "volto.eea.europa.eu,climate-energy.eea.europa.eu,forest.eea.europa.eu,biodiversity.europa.eu,industry.eea.europa.eu,water.europa.eu-freshwater,demo-www.eea.europa.eu,clmsdemo.devel6cph.eea.europa.eu,water.europa.eu-marine,climate-adapt.eea.europa.eu,climate-advisory-board.devel4cph.eea.europa.eu,climate-advisory-board.europa.eu,www.eea.europa.eu-en,www.eea.europa.eu,insitu.copernicus.eu,ask.copernicus.eu,land.copernicus.eu"
1310
DEPENDENCIES = ""
1411
BACKEND_PROFILES = "eea.kitkat:testing"
1512
BACKEND_ADDONS = ""
1613
VOLTO = "17"
17-
VOLTO16_BREAKING_CHANGES = "no"
14+
VOLTO18_BREAKING_CHANGES = "no"
1815
IMAGE_NAME = BUILD_TAG.toLowerCase()
1916
}
2017

@@ -242,11 +239,17 @@ pipeline {
242239
script {
243240
def scannerHome = tool 'SonarQubeScanner'
244241
def nodeJS = tool 'NodeJS'
242+
if (env.CHANGE_ID) {
243+
env.sonarParams = " -Dsonar.pullrequest.base=${env.CHANGE_TARGET} -Dsonar.pullrequest.branch=${env.CHANGE_BRANCH} -Dsonar.pullrequest.key=${env.CHANGE_ID} "
244+
}
245+
else {
246+
env.sonarParams = " -Dsonar.branch.name=${env.BRANCH_NAME}"
247+
}
245248
withSonarQubeEnv('Sonarqube') {
246249
sh '''sed -i "s#/app/src/addons/${GIT_NAME}/##g" xunit-reports/coverage/lcov.info'''
247250
sh '''sed -i "s#src/addons/${GIT_NAME}/##g" xunit-reports/coverage/lcov.info'''
248-
sh "export PATH=${scannerHome}/bin:${nodeJS}/bin:$PATH; sonar-scanner -Dsonar.javascript.lcov.reportPaths=./xunit-reports/coverage/lcov.info,./cypress-coverage/coverage/lcov.info -Dsonar.sources=./src -Dsonar.projectKey=$GIT_NAME-$BRANCH_NAME -Dsonar.projectVersion=$BRANCH_NAME-$BUILD_NUMBER"
249-
sh '''try=5; while [ \$try -gt 0 ]; do curl -s -XPOST -u "${SONAR_AUTH_TOKEN}:" "${SONAR_HOST_URL}api/project_tags/set?project=${GIT_NAME}-${BRANCH_NAME}&tags=${SONARQUBE_TAGS},${BRANCH_NAME}" > set_tags_result; if [ \$(grep -ic error set_tags_result ) -eq 0 ]; then try=0; else cat set_tags_result; echo "... Will retry"; sleep 15; try=\$(( \$try - 1 )); fi; done'''
251+
sh "export PATH=${scannerHome}/bin:${nodeJS}/bin:$PATH; sonar-scanner -Dsonar.javascript.lcov.reportPaths=./xunit-reports/coverage/lcov.info,./cypress-coverage/coverage/lcov.info -Dsonar.sources=./src -Dsonar.projectKey=$GIT_NAME -Dsonar.projectName=$GIT_NAME -Dsonar.projectVersion=\$(jq -r '.version' package.json) ${env.sonarParams}"
252+
sh '''try=5; while [ \$try -gt 0 ]; do curl -s -XPOST -u "${SONAR_AUTH_TOKEN}:" "${SONAR_HOST_URL}api/project_tags/set?project=${GIT_NAME}&tags=${SONARQUBE_TAGS}" > set_tags_result; if [ \$(grep -ic error set_tags_result ) -eq 0 ]; then try=0; else cat set_tags_result; echo "... Will retry"; sleep 15; try=\$(( \$try - 1 )); fi; done'''
250253
}
251254
}
252255
}
@@ -256,75 +259,75 @@ pipeline {
256259
}
257260
}
258261

259-
stage('Volto 16') {
262+
stage('Volto 18') {
260263
agent { node { label 'integration'} }
261-
when {
264+
when {
262265
environment name: 'SKIP_TESTS', value: ''
263-
not { environment name: 'VOLTO16_BREAKING_CHANGES', value: 'yes' }
266+
not { environment name: 'VOLTO18_BREAKING_CHANGES', value: 'yes' }
264267
}
265268
stages {
266269
stage('Build test image') {
267270
steps {
268-
sh '''docker build --pull --build-arg="VOLTO_VERSION=16" --build-arg="ADDON_NAME=$NAMESPACE/$GIT_NAME" --build-arg="ADDON_PATH=$GIT_NAME" . -t $IMAGE_NAME-frontend16'''
271+
sh '''docker build --pull --build-arg="VOLTO_VERSION=18-yarn" --build-arg="ADDON_NAME=$NAMESPACE/$GIT_NAME" --build-arg="ADDON_PATH=$GIT_NAME" . -t $IMAGE_NAME-frontend18'''
269272
}
270273
}
271274

272-
stage('Unit tests Volto 16') {
275+
stage('Unit tests Volto 18') {
273276
steps {
274277
script {
275278
try {
276-
sh '''docker run --name="$IMAGE_NAME-volto16" --entrypoint=make --workdir=/app/src/addons/$GIT_NAME $IMAGE_NAME-frontend16 test-ci'''
277-
sh '''rm -rf xunit-reports16'''
278-
sh '''mkdir -p xunit-reports16'''
279-
sh '''docker cp $IMAGE_NAME-volto16:/app/junit.xml xunit-reports16/'''
279+
sh '''docker run --name="$IMAGE_NAME-volto18" --entrypoint=make --workdir=/app/src/addons/$GIT_NAME $IMAGE_NAME-frontend18 test-ci'''
280+
sh '''rm -rf xunit-reports18'''
281+
sh '''mkdir -p xunit-reports18'''
282+
sh '''docker cp $IMAGE_NAME-volto18:/app/junit.xml xunit-reports18/'''
280283
} finally {
281284
catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') {
282-
junit testResults: 'xunit-reports16/junit.xml', allowEmptyResults: true
285+
junit testResults: 'xunit-reports18/junit.xml', allowEmptyResults: true
283286
}
284-
sh script: '''docker rm -v $IMAGE_NAME-volto16''', returnStatus: true
287+
sh script: '''docker rm -v $IMAGE_NAME-volto18''', returnStatus: true
285288
}
286289
}
287290
}
288291
}
289292

290-
stage('Integration tests Volto 16') {
293+
stage('Integration tests Volto 18') {
291294
steps {
292295
script {
293296
try {
294-
sh '''docker run --pull always --rm -d --name="$IMAGE_NAME-plone16" -e SITE="Plone" -e PROFILES="$BACKEND_PROFILES" -e ADDONS="$BACKEND_ADDONS" eeacms/plone-backend'''
295-
sh '''docker run -d --shm-size=4g --link $IMAGE_NAME-plone16:plone --name="$IMAGE_NAME-cypress16" -e "RAZZLE_INTERNAL_API_PATH=http://plone:8080/Plone" --entrypoint=make --workdir=/app/src/addons/$GIT_NAME $IMAGE_NAME-frontend16 start-ci'''
296-
frontend = sh script:'''docker exec --workdir=/app/src/addons/${GIT_NAME} $IMAGE_NAME-cypress16 make check-ci''', returnStatus: true
297+
sh '''docker run --pull always --rm -d --name="$IMAGE_NAME-plone18" -e SITE="Plone" -e PROFILES="$BACKEND_PROFILES" -e ADDONS="$BACKEND_ADDONS" eeacms/plone-backend'''
298+
sh '''docker run -d --shm-size=4g --link $IMAGE_NAME-plone18:plone --name="$IMAGE_NAME-cypress18" -e "RAZZLE_INTERNAL_API_PATH=http://plone:8080/Plone" --entrypoint=make --workdir=/app/src/addons/$GIT_NAME $IMAGE_NAME-frontend18 start-ci'''
299+
frontend = sh script:'''docker exec --workdir=/app/src/addons/${GIT_NAME} $IMAGE_NAME-cypress18 make check-ci''', returnStatus: true
297300
if ( frontend != 0 ) {
298-
sh '''docker logs $IMAGE_NAME-cypress16; exit 1'''
301+
sh '''docker logs $IMAGE_NAME-cypress18; exit 1'''
299302
}
300-
sh '''timeout -s 9 1800 docker exec --workdir=/app/src/addons/${GIT_NAME} $IMAGE_NAME-cypress16 make cypress-ci'''
303+
sh '''timeout -s 9 1800 docker exec --workdir=/app/src/addons/${GIT_NAME} $IMAGE_NAME-cypress18 make cypress-ci'''
301304
} finally {
302305
try {
303306
if ( frontend == 0 ) {
304-
sh '''rm -rf cypress-videos16 cypress-results16 cypress-coverage16 cypress-screenshots16'''
305-
sh '''mkdir -p cypress-videos16 cypress-results16 cypress-coverage16 cypress-screenshots16'''
306-
videos = sh script: '''docker cp $IMAGE_NAME-cypress16:/app/src/addons/$GIT_NAME/cypress/videos cypress-videos16/''', returnStatus: true
307-
sh '''docker cp $IMAGE_NAME-cypress16:/app/src/addons/$GIT_NAME/cypress/reports cypress-results16/'''
308-
screenshots = sh script: '''docker cp $IMAGE_NAME-cypress16:/app/src/addons/$GIT_NAME/cypress/screenshots cypress-screenshots16''', returnStatus: true
307+
sh '''rm -rf cypress-videos18 cypress-results18 cypress-coverage18 cypress-screenshots18'''
308+
sh '''mkdir -p cypress-videos18 cypress-results18 cypress-coverage18 cypress-screenshots18'''
309+
videos = sh script: '''docker cp $IMAGE_NAME-cypress18:/app/src/addons/$GIT_NAME/cypress/videos cypress-videos18/''', returnStatus: true
310+
sh '''docker cp $IMAGE_NAME-cypress18:/app/src/addons/$GIT_NAME/cypress/reports cypress-results18/'''
311+
screenshots = sh script: '''docker cp $IMAGE_NAME-cypress18:/app/src/addons/$GIT_NAME/cypress/screenshots cypress-screenshots18''', returnStatus: true
309312

310-
archiveArtifacts artifacts: 'cypress-screenshots16/**', fingerprint: true, allowEmptyArchive: true
313+
archiveArtifacts artifacts: 'cypress-screenshots18/**', fingerprint: true, allowEmptyArchive: true
311314

312315
if ( videos == 0 ) {
313-
sh '''for file in $(find cypress-results16 -name *.xml); do if [ $(grep -E 'failures="[1-9].*"' $file | wc -l) -eq 0 ]; then testname=$(grep -E 'file=.*failures="0"' $file | sed 's#.* file=".*\\/\\(.*\\.[jsxt]\\+\\)" time.*#\\1#' ); rm -f cypress-videos16/videos/$testname.mp4; fi; done'''
314-
archiveArtifacts artifacts: 'cypress-videos16/**/*.mp4', fingerprint: true, allowEmptyArchive: true
316+
sh '''for file in $(find cypress-results18 -name *.xml); do if [ $(grep -E 'failures="[1-9].*"' $file | wc -l) -eq 0 ]; then testname=$(grep -E 'file=.*failures="0"' $file | sed 's#.* file=".*\\/\\(.*\\.[jsxt]\\+\\)" time.*#\\1#' ); rm -f cypress-videos18/videos/$testname.mp4; fi; done'''
317+
archiveArtifacts artifacts: 'cypress-videos18/**/*.mp4', fingerprint: true, allowEmptyArchive: true
315318
}
316319
}
317320
} finally {
318321
catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') {
319-
junit testResults: 'cypress-results16/**/*.xml', allowEmptyResults: true
322+
junit testResults: 'cypress-results18/**/*.xml', allowEmptyResults: true
320323
}
321324
catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') {
322-
sh '''docker logs $IMAGE_NAME-cypress16'''
325+
sh '''docker logs $IMAGE_NAME-cypress18'''
323326
}
324-
sh script: "docker stop $IMAGE_NAME-cypress16", returnStatus: true
325-
sh script: "docker stop $IMAGE_NAME-plone16", returnStatus: true
326-
sh script: "docker rm -v $IMAGE_NAME-plone16", returnStatus: true
327-
sh script: "docker rm -v $IMAGE_NAME-cypress16", returnStatus: true
327+
sh script: "docker stop $IMAGE_NAME-cypress18", returnStatus: true
328+
sh script: "docker stop $IMAGE_NAME-plone18", returnStatus: true
329+
sh script: "docker rm -v $IMAGE_NAME-plone18", returnStatus: true
330+
sh script: "docker rm -v $IMAGE_NAME-cypress18", returnStatus: true
328331
}
329332
}
330333
}
@@ -337,7 +340,7 @@ pipeline {
337340
post {
338341
always {
339342
sh script: "docker rmi $IMAGE_NAME-frontend", returnStatus: true
340-
sh script: "docker rmi $IMAGE_NAME-frontend16", returnStatus: true
343+
sh script: "docker rmi $IMAGE_NAME-frontend18", returnStatus: true
341344
}
342345
}
343346
}
@@ -363,7 +366,7 @@ pipeline {
363366
script {
364367
sh '''echo "Error" > checkresult.txt'''
365368
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
366-
sh '''set -o pipefail; docker run -i --rm --pull always --name="$IMAGE_NAME-gitflow-sn" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_NAME="$GIT_NAME" eeacms/gitflow /checkSonarqubemaster.sh | grep -v "Found script" | tee checkresult.txt'''
369+
sh '''set -o pipefail; docker run -i --rm --pull always --name="$IMAGE_NAME-gitflow-sn" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_NAME="$GIT_NAME" eeacms/gitflow /checkSonarqubemasterV2.sh | grep -v "Found script" | tee checkresult.txt'''
367370
}
368371

369372
publishChecks name: 'SonarQube', title: 'Sonarqube Code Quality Check', summary: 'Quality check on the SonarQube metrics from branch develop, comparing it with the ones from master branch. No bugs are allowed',
@@ -413,4 +416,3 @@ pipeline {
413416
}
414417
}
415418
}
416-

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ endif
4646
DIR=$(shell basename $$(pwd))
4747
NODE_MODULES?="../../../node_modules"
4848
PLONE_VERSION?=6
49-
VOLTO_VERSION?=17
49+
VOLTO_VERSION?=18-yarn
5050
ADDON_PATH="${DIR}"
5151
ADDON_NAME="@eeacms/${ADDON_PATH}"
5252
DOCKER_COMPOSE=PLONE_VERSION=${PLONE_VERSION} VOLTO_VERSION=${VOLTO_VERSION} ADDON_NAME=${ADDON_NAME} ADDON_PATH=${ADDON_PATH} docker compose
@@ -90,11 +90,11 @@ cypress-run: ## Run cypress integration tests
9090

9191
.PHONY: test
9292
test: ## Run jest tests
93-
${DOCKER_COMPOSE} run -e CI=1 frontend test
93+
${DOCKER_COMPOSE} run --no-deps -e CI=1 frontend test
9494

9595
.PHONY: test-update
9696
test-update: ## Update jest tests snapshots
97-
${DOCKER_COMPOSE} run -e CI=1 frontend test -u
97+
${DOCKER_COMPOSE} run --no-deps -e CI=1 frontend test -u
9898

9999
.PHONY: stylelint
100100
stylelint: ## Stylelint

0 commit comments

Comments
 (0)