Genera un add-on Plone con cookieplone e ci
applica le convenzioni RedTurtle: backend su zc.buildout/setuptools, CI senza i job
che per un add-on non servono, release di backend e frontend via trusted publishing.
Niente da installare:
uvx --from git+https://github.com/RedTurtle/redturtle-cookieplone redturtle-cookieplone create -o .Per rigenerare l'identico a mesi di distanza, pinna il tag:
uvx --from git+https://github.com/RedTurtle/redturtle-cookieplone@v1.0.0 redturtle-cookieplone create -o .Serve uv >= 0.4, git, e per il frontend make, node, jq.
| comando | cosa fa |
|---|---|
create |
genera con cookieplone e applica tutto il resto |
align |
applica l'overlay a un repo gia' generato |
scope |
rinomina il pacchetto npm sotto uno scope |
integrate |
collega l'add-on a un progetto Volto 17 ospite |
prompts |
stampa le domande del wizard, in JSON |
--dry-run e' un flag globale: va prima del sottocomando
(redturtle-cookieplone --dry-run align <repo>).
Senza opzioni, le domande le fa il wizard di cookieplone, poi lo script prosegue da solo. E' il modo da usare a mano.
redturtle-cookieplone create -o .Fa in sequenza, fermandosi al primo errore: cookieplone → align → scope →
make -C frontend install → make -C frontend format.
L'ultimo passo non e' cosmetico: cookieplone genera un settings.ts che viola il
.prettierrc dello stesso repo, quindi senza formattare la CI fallisce su
make lint al primo push. Con --no-install il passo salta, e va lanciato a mano.
Non interattivo, con --title (servono anche --description, --project-slug,
--github-organization):
redturtle-cookieplone create \
--title "RER Linkchecker" --description "..." \
--project-slug rer-linkchecker --python-package-name rer.linkchecker \
--github-organization RegioneER \
--plone-version 6.2.0 --volto-version 19.3.0 \
--scope @redturtle -o .| opzione | default |
|---|---|
--scope |
nessuno; con @redturtle il nome npm nasce gia' scoped |
--template |
monorepo_addon |
--container-registry |
github |
--docs / --no-docs |
docs generate |
--plone-version, --volto-version |
l'ultima rilasciata, risolta via rete |
--answers-file |
un .cookieplone.json da cui partire |
--no-install |
salta make -C frontend install |
Ogni generazione lascia un .cookieplone.json nel repo: ripassandolo con
--answers-file si rifa' la stessa cosa, template incluso. Le opzioni sulla riga di
comando vincono su quel file.
Volto 17 non e' generabile (cookieplone accetta da 18.0.0-alpha.43 in su), quindi
un add-on nuovo non e' integrabile in io-Comune finche' la migrazione non e' fatta.
redturtle-cookieplone align <repo>Idempotente. Fa otto cose:
- scrive
backend/setup.py, lo shim per installarlo come develop egg da buildout; - adatta
backend/pyproject.toml:licensein forma{ text = ... }e blocchi[tool.setuptools]; toglie un eventuale<3.xdarequires-python, che fa fallirecheck-python-versionsquando upstream aggiunge un Python ai classifier; - rimuove dalle workflow i job
releaseestorybook, con i loro riferimenti; - aggiunge
.github/workflows/npm.ymle.github/workflows/pypi.yml, che pubblicano al push di un tag autenticandosi via OIDC; - mette
publish = falseinrepository.toml, cosi'repoplonenon pubblica in locale: aggiorna versioni e changelog e crea il tag; - installa
scripts/release.sh,scripts/bootstrap-npm.she i targetrelease/bootstrap-npmnel Makefile; - sostituisce
workspace:*con le versioni pubblicate nelle devDependencies dell'add-on, ricavandole da@plone/volto@<versione>.
Opzione: --volto-version (default: il tag di frontend/mrs.developer.json).
Va lanciato prima di make -C frontend install — e' quello che fa create.
Al contrario il lockfile va rigenerato, e align avvisa.
Con create --scope non serve. Su un repo gia' generato senza scope:
redturtle-cookieplone scope <repo> --scope @redturtleRinomina solo dove il nome e' un nome e non un path: la cartella
frontend/packages/volto-<slug>/ non si tocca. Non farlo a mano, sono otto file.
Dopo, rigenera il lockfile con make -C frontend install (la CI gira con
--frozen-lockfile).
Fissa anche "@scope:registry" in publishConfig. Serve: un @scope:registry
nell'~/.npmrc dirotta npm publish su un altro registry senza dare errore.
--registry punta altrove (default npmjs.org).
make bootstrap-npmPubblica la prima versione e stampa i valori da incollare nel trusted publisher (npm lo accetta solo su un pacchetto che esiste gia'). Idempotente.
Il trust si configura dal sito, non da CLI: pacchetto → Settings → Trusted
Publisher → GitHub Actions, organizzazione, repository, file di workflow npm.yml.
Lascia attivo il permesso di publish: dal 20 maggio 2026 non e' piu' implicito.
Prima di lanciarlo, controlla che GITHUB_SLUG in scripts/bootstrap-npm.sh sia il
repo dove girano le Actions: il binding OIDC e' sensibile alle maiuscole.
Prerequisito esterno: l'organizzazione @redturtle deve esistere su npm e devi avere
i permessi di publish.
Da pypi.org → account → Publishing, dichiara un pending publisher: nome del
progetto, owner e repository GitHub, file di workflow pypi.yml, eventuale
environment (se lo usi, va messo anche nel job). Alla prima pubblicazione PyPI crea il
progetto. Nessuna publish manuale.
Il pending publisher non prenota il nome.
make releaseAggiorna versioni e changelog e crea il tag. Non pubblica: al push del tag partono
pypi.yml e npm.yml via OIDC. In locale non serve nessun token; GITHUB_TOKEN e'
opzionale, solo per la GitHub release.
Il dist-tag lo deriva il workflow dalla versione: 1.0.0-alpha.23 → alpha, 1.0.0 →
latest. Finche' pubblichi solo prerelease, latest resta alla prima versione
pubblicata; se serve prima, npm dist-tag add.
I tre pezzi non sono atomici. Se il tag c'e' ma una publish e' fallita, non rifare la release: rilancia da GitHub Actions il workflow fallito passando il tag.
Per provare la publish senza bruciare una release, replicando la CI:
git clone <repo> /tmp/citest && cd /tmp/citest/frontend
pnpm install --frozen-lockfile
pnpm --filter <npm-name> publish --dry-run --no-git-checks --tag alphaPer sviluppare un add-on non ancora rilasciato dentro io-Comune o derivati. Metti il
checkout sotto src/addons/ dell'ospite, poi:
redturtle-cookieplone integrate <progetto-ospite> <path-addon> --theme <addon-tema>Aggiunge il workspace yarn, il path in jsconfig.json, la dichiarazione nel tema, le
resolutions per le devDependencies workspace:* e una riga in .eslintignore. Non
tocca il repo dell'add-on.
Poi yarn install, e verifica:
node -e "
const {AddonConfigurationRegistry} = require('@plone/volto/addon-registry');
const reg = new AddonConfigurationRegistry(process.cwd());
console.log(reg.packages['<npm-name>']);
"Deve dare isRegisteredAddon: true e isPublishedPackage: false.
redturtle-cookieplone prompts [template] [--tag <branch|tag|sha>]JSON con key, prompt, help, type, default, choices, derived per ogni
domanda. Riconosce da se' il formato v2 (cookieplone 2.0) e v1.
Template: project, monorepo_addon, backend_addon, frontend_addon,
aurora_addon, aurora_cmfplone, volto_nick, aurora_nick,
aurora_nick_embedded, documentation_starter.
make -C frontend buildva lanciato dalla root del repo. Altrovemakeesce con No such file or directory, e con una pipe versotaill'exit code diventa 0. Usacd <repo> && set -o pipefail && ....- Il bundle non e' in
frontend/build/ma infrontend/core/packages/volto/build/: in un monorepo add-on si compila Volto core con l'add-on dentro. - Il repo generato ha un
git initsenza commit: il primo commit lo fai tu. - Per vedere il diff di
alignserve una baseline, perche' tutto e' untracked:git -C <repo> add -A(senza commit), poialign, poigit diff. redturtle-cookieplone align <repo> --dry-runfallisce:--dry-runva prima del sottocomando.
COOKIEPLONE_REPOSITORY (path locale o repo remoto dei template) e
COOKIEPLONE_REPOSITORY_TAG (branch/tag) valgono anche qui; prompts legge dalla
prima se punta a una directory.
Per lavorare su questo repo: AGENTS.md.