From e97045dfe967327e87da0e07ea9133d5de1883df Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Thu, 26 Feb 2026 01:18:56 +0100 Subject: [PATCH] Add volto topic with frontend domains for Plone Volto projects New `volto` topic with 6 domains: - volto.core: pnpm install via mrs-developer, sentinel tracking, start/build/clean - volto.lint: eslint/prettier/stylelint, appends to CHECK_TARGETS/FORMAT_TARGETS - volto.test: jest unit tests + CI mode - volto.i18n: translation sync via pnpm --filter - volto.storybook: storybook dev server and build - volto.acceptance: cypress E2E tests with docker backend Also updates templates.py to generate check/format aggregate targets when the volto topic is used (not just qa). --- pyproject.toml | 1 + src/mxmake/templates.py | 2 +- src/mxmake/topics.py | 1 + src/mxmake/topics/volto/acceptance.mk | 56 +++++++++++++++++++ src/mxmake/topics/volto/core.mk | 79 +++++++++++++++++++++++++++ src/mxmake/topics/volto/i18n.mk | 25 +++++++++ src/mxmake/topics/volto/lint.mk | 32 +++++++++++ src/mxmake/topics/volto/metadata.ini | 3 + src/mxmake/topics/volto/storybook.mk | 31 +++++++++++ src/mxmake/topics/volto/test.mk | 32 +++++++++++ 10 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 src/mxmake/topics/volto/acceptance.mk create mode 100644 src/mxmake/topics/volto/core.mk create mode 100644 src/mxmake/topics/volto/i18n.mk create mode 100644 src/mxmake/topics/volto/lint.mk create mode 100644 src/mxmake/topics/volto/metadata.ini create mode 100644 src/mxmake/topics/volto/storybook.mk create mode 100644 src/mxmake/topics/volto/test.mk diff --git a/pyproject.toml b/pyproject.toml index 402acf08..961beb0f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,6 +76,7 @@ qa = "mxmake.topics:qa" system = "mxmake.topics:system" applications = "mxmake.topics:applications" i18n = "mxmake.topics:i18n" +volto = "mxmake.topics:volto" [build-system] requires = ["hatchling", "hatch-vcs", "hatch-fancy-pypi-readme"] diff --git a/src/mxmake/templates.py b/src/mxmake/templates.py index 5e95a88a..61c33b94 100644 --- a/src/mxmake/templates.py +++ b/src/mxmake/templates.py @@ -282,7 +282,7 @@ def template_variables(self) -> dict[str, typing.Any]: fqns = sorted([domain.fqn for domain in self.domains]) additional_targets = {} topics = {domain.topic for domain in self.domains} - additional_targets["qa"] = "qa" in topics + additional_targets["qa"] = bool(topics & {"qa", "volto"}) # return template variables return { "settings": settings, diff --git a/src/mxmake/topics.py b/src/mxmake/topics.py index 68ff6b46..346ff712 100644 --- a/src/mxmake/topics.py +++ b/src/mxmake/topics.py @@ -303,3 +303,4 @@ def set_domain_runtime_depends(domains: list[Domain]) -> None: system = Topic(name="system", directory=topics_dir / "system") applications = Topic(name="applications", directory=topics_dir / "applications") i18n = Topic(name="i18n", directory=topics_dir / "i18n") +volto = Topic(name="volto", directory=topics_dir / "volto") diff --git a/src/mxmake/topics/volto/acceptance.mk b/src/mxmake/topics/volto/acceptance.mk new file mode 100644 index 00000000..92282d94 --- /dev/null +++ b/src/mxmake/topics/volto/acceptance.mk @@ -0,0 +1,56 @@ +#:[acceptance] +#:title = Volto Acceptance +#:description = Acceptance testing for Volto projects using Cypress. +#:depends = volto.core +#: +#:[target.volto-acceptance-backend-start] +#:description = Start Docker-based Plone acceptance backend. +#: +#:[target.volto-acceptance-frontend-dev-start] +#:description = Start acceptance frontend in development mode. +#: +#:[target.volto-acceptance-test] +#:description = Run Cypress acceptance tests in interactive mode. +#: +#:[target.volto-ci-acceptance-test] +#:description = Run Cypress acceptance tests in headless CI mode. +#: +#:[setting.VOLTO_ACCEPTANCE_BACKEND_IMAGE] +#:description = Docker image for Plone acceptance backend. +#:default = plone/server-acceptance:6 +#: +#:[setting.VOLTO_CYPRESS_CONFIG] +#:description = Path to Cypress configuration file. +#:default = cypress.config.js +#: +#:[setting.VOLTO_CYPRESS_SPEC_PATTERN] +#:description = Glob pattern for Cypress test specs. +#:default = cypress/tests/**/*.{js,jsx,ts,tsx} + +############################################################################## +# volto acceptance +############################################################################## + +.PHONY: volto-acceptance-backend-start +volto-acceptance-backend-start: + @echo "Start Plone acceptance backend" + @docker run -it --rm -p 55001:55001 $(VOLTO_ACCEPTANCE_BACKEND_IMAGE) + +.PHONY: volto-acceptance-frontend-dev-start +volto-acceptance-frontend-dev-start: $(VOLTO_TARGET) + @echo "Start acceptance frontend in development mode" + @RAZZLE_API_PATH=http://127.0.0.1:55001/plone pnpm start + +.PHONY: volto-acceptance-test +volto-acceptance-test: $(VOLTO_TARGET) + @echo "Run Cypress acceptance tests" + @pnpm --filter @plone/volto exec cypress open \ + --config-file $(CURRENT_DIR)/$(VOLTO_CYPRESS_CONFIG) \ + --config specPattern=$(CURRENT_DIR)'/$(VOLTO_CYPRESS_SPEC_PATTERN)' + +.PHONY: volto-ci-acceptance-test +volto-ci-acceptance-test: $(VOLTO_TARGET) + @echo "Run Cypress CI acceptance tests" + @pnpm --filter @plone/volto exec cypress run \ + --config-file $(CURRENT_DIR)/$(VOLTO_CYPRESS_CONFIG) \ + --config specPattern=$(CURRENT_DIR)'/$(VOLTO_CYPRESS_SPEC_PATTERN)' diff --git a/src/mxmake/topics/volto/core.mk b/src/mxmake/topics/volto/core.mk new file mode 100644 index 00000000..73919aee --- /dev/null +++ b/src/mxmake/topics/volto/core.mk @@ -0,0 +1,79 @@ +#:[core] +#:title = Volto Core +#:description = Plone Volto frontend project setup. Provides targets for +#: installing, starting, building, and cleaning a Volto project using pnpm +#: workspaces and mrs-developer. +#:depends = core.base +#: +#:[target.volto-install] +#:description = Install Volto frontend packages using pnpm and mrs-developer. +#: +#:[target.volto-build-deps] +#:description = Build Volto workspace dependencies (@plone/registry, +#: @plone/components). +#: +#:[target.volto-start] +#:description = Start Volto development server with hot reload. +#: +#:[target.volto-build] +#:description = Build production bundle. +#: +#:[target.volto-dirty] +#:description = Build :ref:`volto-install` target on next make run. +#: +#:[target.volto-clean] +#:description = Remove installed packages and cloned Volto core. +#: +#:[setting.VOLTO_ADDON_NAME] +#:description = The pnpm package name of the Volto addon in this project. +#: Used for ``pnpm --filter`` commands. +#:default = +#: +#:[setting.VOLTO_MRS_DEVELOPER_PARAMS] +#:description = Additional parameters for ``mrs-developer missdev``. +#:default = --no-config --fetch-https + +############################################################################## +# volto core +############################################################################## + +CURRENT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + +VOLTO_TARGET:=$(SENTINEL_FOLDER)/volto.sentinel +$(VOLTO_TARGET): $(SENTINEL) package.json mrs.developer.json + @echo "Install Volto frontend packages" + @pnpm dlx mrs-developer missdev $(VOLTO_MRS_DEVELOPER_PARAMS) + @pnpm install + @touch $(VOLTO_TARGET) + +.PHONY: volto-install +volto-install: $(VOLTO_TARGET) + +.PHONY: volto-build-deps +volto-build-deps: $(VOLTO_TARGET) + @echo "Build Volto workspace dependencies" + @pnpm --filter @plone/registry build + @pnpm --filter @plone/components build + +.PHONY: volto-start +volto-start: $(VOLTO_TARGET) + @echo "Start Volto development server" + @pnpm start + +.PHONY: volto-build +volto-build: $(VOLTO_TARGET) volto-build-deps + @echo "Build Volto production bundle" + @pnpm build + +.PHONY: volto-dirty +volto-dirty: + @rm -f $(VOLTO_TARGET) + +.PHONY: volto-clean +volto-clean: volto-dirty + @rm -rf core node_modules + +INSTALL_TARGETS+=volto-install +RUN_TARGET?=volto-start +DIRTY_TARGETS+=volto-dirty +CLEAN_TARGETS+=volto-clean diff --git a/src/mxmake/topics/volto/i18n.mk b/src/mxmake/topics/volto/i18n.mk new file mode 100644 index 00000000..c232501f --- /dev/null +++ b/src/mxmake/topics/volto/i18n.mk @@ -0,0 +1,25 @@ +#:[i18n] +#:title = Volto i18n +#:description = Translation management for Volto frontend projects. +#:depends = volto.core +#: +#:[target.volto-i18n] +#:description = Sync i18n translations for the Volto addon. +#: +#:[target.volto-ci-i18n] +#:description = Check that i18n translations are in sync (fails if not). + +############################################################################## +# volto i18n +############################################################################## + +.PHONY: volto-i18n +volto-i18n: $(VOLTO_TARGET) + @echo "Sync Volto i18n" + @pnpm --filter $(VOLTO_ADDON_NAME) i18n + +.PHONY: volto-ci-i18n +volto-ci-i18n: $(VOLTO_TARGET) + @echo "Check Volto i18n sync" + @pnpm --filter $(VOLTO_ADDON_NAME) i18n && \ + git diff -G'^[^"POT]' --exit-code diff --git a/src/mxmake/topics/volto/lint.mk b/src/mxmake/topics/volto/lint.mk new file mode 100644 index 00000000..8e061a82 --- /dev/null +++ b/src/mxmake/topics/volto/lint.mk @@ -0,0 +1,32 @@ +#:[lint] +#:title = Volto Lint +#:description = Code linting and formatting for Volto frontend projects. +#: Runs ESLint, Prettier, and Stylelint via pnpm scripts. +#:depends = volto.core +#: +#:[target.volto-lint] +#:description = Run ESLint, Prettier, and Stylelint checks. +#: +#:[target.volto-format] +#:description = Run ESLint, Prettier, and Stylelint with auto-fix. + +############################################################################## +# volto lint +############################################################################## + +.PHONY: volto-lint +volto-lint: $(VOLTO_TARGET) + @echo "Run Volto lint checks" + @pnpm lint + @pnpm prettier + @pnpm stylelint --allow-empty-input + +.PHONY: volto-format +volto-format: $(VOLTO_TARGET) + @echo "Run Volto format" + @pnpm lint:fix + @pnpm prettier:fix + @pnpm stylelint:fix + +CHECK_TARGETS+=volto-lint +FORMAT_TARGETS+=volto-format diff --git a/src/mxmake/topics/volto/metadata.ini b/src/mxmake/topics/volto/metadata.ini new file mode 100644 index 00000000..db4e9f8f --- /dev/null +++ b/src/mxmake/topics/volto/metadata.ini @@ -0,0 +1,3 @@ +[metadata] +title = Volto +description = Plone Volto (React) frontend domains. diff --git a/src/mxmake/topics/volto/storybook.mk b/src/mxmake/topics/volto/storybook.mk new file mode 100644 index 00000000..cc3dfb54 --- /dev/null +++ b/src/mxmake/topics/volto/storybook.mk @@ -0,0 +1,31 @@ +#:[storybook] +#:title = Volto Storybook +#:description = Storybook integration for Volto component development. +#:depends = volto.core +#: +#:[target.volto-storybook-start] +#:description = Start Storybook development server on port 6006. +#: +#:[target.volto-storybook-build] +#:description = Build static Storybook site. +#: +#:[setting.VOLTO_STORYBOOK_PORT] +#:description = Port for Storybook development server. +#:default = 6006 + +############################################################################## +# volto storybook +############################################################################## + +VOLTO_STORYBOOK_BUILD_DIR?=$(CURRENT_DIR)/.storybook-build + +.PHONY: volto-storybook-start +volto-storybook-start: $(VOLTO_TARGET) + @echo "Start Volto Storybook" + @pnpm run storybook + +.PHONY: volto-storybook-build +volto-storybook-build: $(VOLTO_TARGET) + @echo "Build Volto Storybook" + @mkdir -p $(VOLTO_STORYBOOK_BUILD_DIR) + @pnpm run storybook-build -o $(VOLTO_STORYBOOK_BUILD_DIR) diff --git a/src/mxmake/topics/volto/test.mk b/src/mxmake/topics/volto/test.mk new file mode 100644 index 00000000..e0d5da99 --- /dev/null +++ b/src/mxmake/topics/volto/test.mk @@ -0,0 +1,32 @@ +#:[test] +#:title = Volto Test +#:description = Unit testing for Volto frontend projects using Jest. +#:depends = volto.core +#: +#:[target.volto-test] +#:description = Run Volto unit tests. +#: +#:[target.volto-ci-test] +#:description = Run Volto unit tests in CI mode with i18n pre-build and +#: jest addon configuration. +#: +#:[setting.VOLTO_TEST_COMMAND] +#:description = Command to run Volto unit tests. +#:default = pnpm test + +############################################################################## +# volto test +############################################################################## + +.PHONY: volto-test +volto-test: $(VOLTO_TARGET) + @echo "Run Volto unit tests" + @$(VOLTO_TEST_COMMAND) + +.PHONY: volto-ci-test +volto-ci-test: $(VOLTO_TARGET) + @echo "Run Volto CI unit tests" + @VOLTOCONFIG=$(CURRENT_DIR)/volto.config.js \ + pnpm --filter @plone/volto i18n + @CI=1 RAZZLE_JEST_CONFIG=$(CURRENT_DIR)/jest-addon.config.js \ + pnpm run --filter @plone/volto test --passWithNoTests