Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 46 additions & 12 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,62 @@ separately, under different licences.
| `backend/` | `pas.plugins.identity` | PyPI, GPL-2.0-only |
| `frontend/packages/identity-core/` | `@plone-collective/identity-core` | Not yet published; MIT |
| `frontend/packages/volto-identity/` | `@plone-collective/volto-identity` | npm, MIT |
| `frontend/packages/aurora-identity/` | `@plone-collective/aurora-identity` | Not yet published; MIT |
| `frontend/aurora/` | Development harness running Plone Aurora with the add-on | — |
| `docs/` | The published documentation and its screenshot harness | — |

They live together on purpose: a REST API payload and the component that reads
it change in one commit, and a reference page cannot drift from the source it
documents.

`identity-core` holds what the Volto add-on shares with the planned Aurora
add-on ([#132](https://github.com/collective/pas-plugins-identity/issues/132)):
the REST payload types, the endpoint table, the framework-free helpers and the
login components. An ESLint override in `frontend/.eslintrc.js` rejects any
`identity-core` holds what the Volto add-on shares with the Aurora add-on
([#132](https://github.com/collective/pas-plugins-identity/issues/132)): the
REST payload types, the endpoint table, the framework-free helpers, the login
components and the callback card. An ESLint override in `frontend/.eslintrc.js` rejects any
import of Volto, Aurora, Redux, a router or an i18n library in it. React,
`react-aria-components` and `@plone/components` are allowed, because both
frontends have them. Code that needs anything else belongs in the add-on.

Core components get translations, links and icons from `useIdentityUI()`.
Each add-on provides them through an `IdentityUIProvider`; Volto's is
`VoltoIdentityUI`, wrapped around every container that renders one.
Each add-on provides them through an `IdentityUIProvider` -- `VoltoIdentityUI`
and `AuroraIdentityUI` -- wrapped around every container that renders one.
Core's styles are plain CSS: Aurora has no Sass compiler.

Core declares its messages with `defineMessages` imported from `#i18n`, never
by a relative path: the extractor recognises the call by that import name
(`identity-core/babel.config.js`). A message declared any other way is
silently left out of the catalogue.

`frontend/core` is **not ours**. It is a `mrs.developer` checkout of Volto,
excluded by `frontend/.gitignore`. Never edit it, never cite it as this
project's convention, and ignore any `AGENTS.md` found inside it.
silently left out of the catalogue. Core owns those translations; the Aurora
add-on's `locales/*/common.json` are generated from them by `pnpm i18n` in
`frontend/aurora`, and are never edited by hand.

### Two harnesses share `frontend/packages`

`frontend/` is the Volto harness and `frontend/aurora/` the Aurora one. Each is
its own pnpm workspace, with its own `mrs.developer` checkout in `core/`, its
own React (18 and 19) and its own pnpm (10 and 11). Both install
`identity-core`, so its `node_modules` points at whichever harness installed
last. Each harness corrects for that, and a change touching it has to keep
doing so:

- **Bundling:** `volto-identity/razzle.extend.js` aliases core's peer
dependencies to Volto's copies, and `frontend/aurora/harness/vite.extend.js`
deduplicates them in Aurora. Without them a page bundles two Reacts.
- **Typechecking:** each package's `typecheck` uses a `tsconfig.typecheck.json`
that maps core's peers to that package's own copies and, in the add-ons,
includes core's sources, so core is typechecked against both frontends'
types. Those mappings never go in `tsconfig.json`: Volto turns every
add-on's `tsconfig.json` `paths` into webpack aliases, and a path pointing
at type declarations leaves webpack nothing to bundle.
- **Storybook:** its story globs stay inside `packages/*/src`. A wider glob
follows `aurora-identity`'s `node_modules` into Aurora's own stories.
- **Catalogues:** a package used by both workspaces may use `catalog:` only for
entries both catalogues define, and `workspace:*` only for packages both
workspaces have.

`frontend/core` and `frontend/aurora/core` are **not ours**. They are
`mrs.developer` checkouts of Volto and Aurora, excluded by their harness's
`.gitignore`. Never edit them, never cite them as this project's convention,
and ignore any `AGENTS.md` found inside them.

## Setup

Expand All @@ -48,6 +78,8 @@ make install # both halves
make backend-create-site # first run only
make backend-start # http://localhost:8080/
make frontend-start # http://localhost:3000/, second shell
make aurora-install # optional: the Aurora harness
make aurora-start # http://localhost:3000/, instead of Volto
```

`make backend-install` and `make frontend-install` do one half each. Python is
Expand All @@ -62,6 +94,7 @@ Run these before proposing a commit. CI runs the same ones.
| `make check` | root | `make format` then `make lint`, both halves |
| `make test` | root | `make backend-test` and `make frontend-test` |
| `make check-imports` | `backend/` | The core/server layer boundary |
| `make aurora-lint`, `make aurora-test` | root | The Aurora add-on. Needs `make aurora-install`; **not run by CI yet** |
| `make docs-build` | root | Sphinx with `-W`, warnings as errors |
| `make vale` | `docs/` | Prose style. **Errors must be zero**; warnings are advisory |

Expand Down Expand Up @@ -103,7 +136,7 @@ and `make lint`.

### Every change carries a news fragment

There are four towncrier scopes. A change adds one fragment to each scope it
There are five towncrier scopes. A change adds one fragment to each scope it
touches:

| Scope | Folder |
Expand All @@ -112,6 +145,7 @@ touches:
| Backend | `backend/news/` |
| Frontend | `frontend/packages/volto-identity/news/` |
| Frontend core | `frontend/packages/identity-core/news/` |
| Aurora add-on | `frontend/packages/aurora-identity/news/` |

Name it `<issue>.<type>`, or `+<slug>.<type>` when no issue exists. Types:
`breaking`, `feature`, `bugfix`, `documentation`, `internal`, `tests`. Write in
Expand Down
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,29 @@ frontend-test: ## Test frontend codebase
@echo "Test frontend"
$(MAKE) -C "./frontend/" test

###########################################
# Aurora
###########################################
.PHONY: aurora-install
aurora-install: ## Install the Aurora harness (frontend/aurora)
$(MAKE) -C "./frontend/aurora/" install

.PHONY: aurora-start
aurora-start: ## Start Aurora with the add-on on http://localhost:3000
$(MAKE) -C "./frontend/aurora/" start

.PHONY: aurora-build
aurora-build: ## Build Aurora with the add-on
$(MAKE) -C "./frontend/aurora/" build

.PHONY: aurora-lint
aurora-lint: ## Lint and typecheck the Aurora add-on
$(MAKE) -C "./frontend/aurora/" lint

.PHONY: aurora-test
aurora-test: ## Test the Aurora add-on
$(MAKE) -C "./frontend/aurora/" ci-test

###########################################
# Backend
###########################################
Expand Down
17 changes: 14 additions & 3 deletions docs/docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ traps that are only discoverable by hitting them.
| Directory | Holds |
|---|---|
| `backend/` | The Plone add-on `pas.plugins.identity`, its test suite, and the demo stack's own package. |
| `frontend/` | The Volto add-on `@plone-collective/volto-identity` and its Storybook stories, and `@plone-collective/identity-core`, the framework-agnostic part a future Aurora add-on will share. |
| `frontend/` | The Volto add-on `@plone-collective/volto-identity` and its Storybook stories, the Plone Aurora add-on `@plone-collective/aurora-identity`, and `@plone-collective/identity-core`, the part both share. `frontend/aurora/` is a harness running Aurora with its add-on. |
| `docs/` | These pages, and the screenshot harness that illustrates them. |

They are one repository on purpose. A change to a REST API payload and the
Expand All @@ -36,7 +36,7 @@ checkout.

The two packages are released separately, under different licences:
`pas.plugins.identity` is GPL-2.0-only on PyPI, `@plone-collective/volto-identity`
is MIT on npm. `@plone-collective/identity-core` is MIT, and not published yet.
is MIT on npm. `@plone-collective/identity-core` and `@plone-collective/aurora-identity` are MIT, and not published yet.

## Set up a checkout

Expand Down Expand Up @@ -73,6 +73,15 @@ Then, in a second shell:
make frontend-start # http://localhost:3000/
```

To run Plone Aurora instead of Volto, install its harness once and start it in
place of `make frontend-start`. It uses port 3000 as well, so stop the other
first:

```shell
make aurora-install
make aurora-start # http://localhost:3000/
```

To see the whole package working at once instead, run the two-site federation
in Docker: {doc}`tutorials/federation-demo`.

Expand All @@ -85,6 +94,7 @@ Run these before opening a pull request. CI runs the same ones.
| `make check` | `make format` then `make lint`, across both halves |
| `make test` | `make backend-test` and `make frontend-test` |
| `make check-imports`, from `backend/` | That core never imports the `[server]` layer |
| `make aurora-lint`, `make aurora-test` | The Aurora add-on, once `make aurora-install` has run. CI does not run these yet |
| `make docs-build` | The documentation, with warnings as errors |
| `make -C docs vale` | Prose style. **Errors must be zero**; warnings are advisory |

Expand Down Expand Up @@ -123,14 +133,15 @@ inside a function does not get past it. That is deliberate—see
### Changelog

Every change carries a [towncrier](https://towncrier.readthedocs.io/) news
fragment. There are four scopes, and a change adds one to each it touches:
fragment. There are five scopes, and a change adds one to each it touches:

| Scope | Folder |
|---|---|
| Repository and documentation | `news/` |
| Backend | `backend/news/` |
| Frontend | `frontend/packages/volto-identity/news/` |
| Frontend core | `frontend/packages/identity-core/news/` |
| Aurora add-on | `frontend/packages/aurora-identity/news/` |

Name it `<issue>.<type>` when an issue exists, `+<slug>.<type>` when none does.
The types are `breaking`, `feature`, `bugfix`, `documentation`, `internal` and
Expand Down
7 changes: 5 additions & 2 deletions frontend/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,12 @@ const defaultRazzleOptions = {
};

module.exports = {
// Each package's `src` only. `packages/**` also reaches every package's
// `node_modules`, and through `aurora-identity`'s symlinks the stories of
// Aurora's own packages, which do not build against Volto.
stories: [
'../packages/**/*.mdx',
'../packages/**/*.stories.@(js|jsx|ts|tsx)',
'../packages/*/src/**/*.mdx',
'../packages/*/src/**/*.stories.@(js|jsx|ts|tsx)',
],
addons: [
'@storybook/addon-links',
Expand Down
16 changes: 16 additions & 0 deletions frontend/aurora/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.*project
.settings/
.vscode
*~
acceptance/cypress/videos/
acceptance/node_modules
acceptance/results/
playwright-report/
test-results/
.storybook-build
build
core
node_modules
results
yarn.lock
/public
23 changes: 23 additions & 0 deletions frontend/aurora/.pnpmfile.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* eslint-disable */
const fs = require('fs');
const path = require('path');

const catalogPath = path.resolve(__dirname, 'core/catalog.json');
let catalog = {};
if (fs.existsSync(catalogPath)) {
const catalogData = fs.readFileSync(catalogPath, 'utf-8');
catalog = JSON.parse(catalogData);
} else {
console.error('Catalog file does not exist at:', catalogPath);
}

module.exports = {
hooks: {
updateConfig(config) {
if (config.catalogs) {
config.catalogs.default ??= catalog;
}
return config;
},
},
};
3 changes: 3 additions & 0 deletions frontend/aurora/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.storybook
CHANGELOG.md
README.md
4 changes: 4 additions & 0 deletions frontend/aurora/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"trailingComma": "all",
"singleQuote": true
}
32 changes: 32 additions & 0 deletions frontend/aurora/.stylelintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"extends": [
"stylelint-config-idiomatic-order"
],
"plugins": [
"stylelint-prettier"
],
"overrides": [
{
"files": [
"**/*.less"
],
"customSyntax": "postcss-less"
},
{
"files": [
"**/*.overrides"
],
"customSyntax": "postcss-less"
},
{
"files": [
"**/*.scss"
],
"customSyntax": "postcss-scss"
}
],
"rules": {
"prettier/prettier": true,
"order/properties-alphabetical-order": null
}
}
93 changes: 93 additions & 0 deletions frontend/aurora/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
### Defensive settings for make:
# https://tech.davis-hansson.com/p/make/
SHELL:=bash
.ONESHELL:
.SHELLFLAGS:=-eu -o pipefail -c
.SILENT:
.DELETE_ON_ERROR:
MAKEFLAGS+=--warn-undefined-variables
MAKEFLAGS+=--no-builtin-rules

CURRENT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

# Recipe snippets for reuse

# We like colors
# From: https://coderwall.com/p/izxssa/colored-makefile-for-golang-projects
RED=`tput setaf 1`
GREEN=`tput setaf 2`
RESET=`tput sgr0`
YELLOW=`tput setaf 3`

GIT_FOLDER=$(CURRENT_DIR)/.git


ADDON_NAME='@plone-collective/aurora-identity'

.PHONY: help
help: ## Show this help
@echo -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)"

# Dev Helpers

.PHONY: install
install: ## Install Aurora and the add-on for development
@echo "$(GREEN)Install$(RESET)"
pnpm dlx mrs-developer missdev --no-config --fetch-https
pnpm i
make build-deps

.PHONY: start
start: ## Start Aurora on http://localhost:3000, reloading the add-on on change
pnpm start

.PHONY: build
build: ## Build a production bundle of Aurora with the add-on
pnpm build

core/packages/registry/dist: $(shell find core/packages/registry/src -type f)
pnpm --filter @plone/registry build

core/packages/components/dist: $(shell find core/packages/components/src -type f)
pnpm --filter @plone/components build

core/packages/client/dist: $(shell find core/packages/client/src -type f)
pnpm --filter @plone/client build

core/packages/helpers/dist: $(shell find core/packages/helpers/src -type f)
pnpm --filter @plone/helpers build

core/packages/react-router/dist: $(shell find core/packages/react-router/src -type f)
pnpm --filter @plone/react-router build

.PHONY: build-deps
build-deps: core/packages/registry/dist core/packages/components/dist core/packages/client/dist core/packages/react-router/dist core/packages/helpers/dist ## Build Aurora's library packages

.PHONY: i18n
i18n: ## Regenerate the add-on's catalogues from identity-core's
pnpm --filter $(ADDON_NAME) i18n

.PHONY: ci-i18n
ci-i18n: ## Check the add-on's catalogues match identity-core's
pnpm --filter $(ADDON_NAME) i18n && git diff --exit-code -- ../packages/aurora-identity/locales

.PHONY: format
format: ## Format the add-on
pnpm prettier:fix
pnpm lint:fix
pnpm stylelint:fix

.PHONY: lint
lint: ## Lint and typecheck the add-on
pnpm lint
pnpm typecheck
pnpm prettier
pnpm stylelint --allow-empty-input

.PHONY: test
test: ## Run the add-on's unit tests
pnpm test

.PHONY: ci-test
ci-test: ## Run the add-on's unit tests once
CI=1 pnpm test --run
3 changes: 3 additions & 0 deletions frontend/aurora/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import eslintConfig from './core/eslint.config.mjs';

export default eslintConfig;
Loading
Loading