mirror of
https://github.com/nocobase/nocobase.git
synced 2026-10-16 15:07:08 +08:00
@nocobase/app-cli-client@0.1.0-beta.2
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c796cb909b | feat(app-client)!: remove settings and dev route surfaces, Hub and AI employee (#10642) | ||
|
|
a4ee8aa542 |
feat(app-installer): generalise hub-installer into app-installer for deployment archives (#451)
* feat(app-server): keep standalone storage under APP_STORAGE_DIR and record build metadata A standalone application reads APP_STORAGE_DIR for its storage directory, so a deployment whose code root is replaced per release keeps one storage directory. The Hub template still honours HUB_STORAGE_DIR when APP_STORAGE_DIR is unset. pnpm build records nocobase.basePath and nocobase.builtAt in dist/package.json, and the templates' ecosystem.config.js derives the pm2 process name from the application's package name, overridable with APP_PM2_NAME. * refactor(app-installer): rename @nocobase/hub-installer to @nocobase/app-installer A pure rename ahead of generalising the installer beyond the Hub: the package directory, name and bin, its unreleased changesets, the smoke script and its workflow, and pnpm unreleased:hub-smoke, now unreleased:installer-smoke. The package was never published, so nothing outside this repository refers to the old name. Behaviour is unchanged. * refactor(app-installer): generalise the installer's layout, state and backups Releases are named by version and build time (releases/<version>_<time>/app), so two builds of one version are two releases; upgrade --rebuild becomes an ordinary upgrade to a fresh build, which removes the staging and swap logic. installer.json records the application name, base path and source. The runtime variables move to app.env with APP_STORAGE_DIR (and HUB_STORAGE_DIR for Hub releases published before it), health and URLs follow the release's base path, and backups cover every SQLite database config.yml declares. Messages name the application rather than the Hub, and the pm2 name defaults to the directory. * feat(app-installer): install and upgrade from a deployment archive install takes --archive <dist.tar.gz> or --template hub[@version], one of them and only one. An archive is unpacked with the tar library pnpm build packs it with, so a server needs no tar and no pnpm; its manifest names the release, and an archive without a base path and build time, built for another machine, or lacking the dialect's driver is refused with the build command that fixes it. upgrade --archive requires the same application name and base path and refuses an older version; a release writing its data inside itself is refused as well. An upgrade takes the kind of source the install did. * feat(app-installer): source-aware status and rollback advice, free-port suggestion status and rollback tell an archive installation to build its archive again for this machine's Node and upgrade to it, where a template installation gets upgrade --rebuild; status reports the source and skips the registry for an archive installation. install names a free port when the chosen one is taken. The README documents both sources, release ids, app.env and every error code. * test(app-installer): smoke both sources in CI and unreleased:installer-smoke The smoke script takes --source template or --source archive. The archive run installs a deployment archive, upgrades to a later build of the same version, rolls back, restores the database after a migrating upgrade, and rolls back automatically from a build that fails to start. CI gains a job that builds the default template's archive from the checkout and runs it; unreleased:installer- smoke creates and builds an application from the snapshot and runs both. install reports the release's build time. The template alignment test no longer expects each template to name its own pm2 process. * docs: document app-installer and rename its global Skill The global nocobase-hub-installer Skill becomes nocobase-app-installer and covers both sources: building and installing a deployment archive, and the Hub template. The nocobase-deployment Skill offers app-installer for a standalone server, and the documentation site gains a page for it, with the Hub page, the deployment overview, operations and standalone pages updated. Examples that run published Hub images keep HUB_STORAGE_DIR, which those images still read. The unreleased installer changesets, written for the Hub-only package, are replaced by one describing the package as it now ships. * docs: name only APP_STORAGE_DIR in the deployment pages The Hub pages, operations page and the app-development Skill no longer document HUB_STORAGE_DIR: nothing has been released under the old name that the documentation needs to keep serving. * refactor: drop HUB_STORAGE_DIR in favour of APP_STORAGE_DIR The Hub template no longer reads HUB_STORAGE_DIR, which removes its own path policy: the runtime applies APP_STORAGE_DIR for every standalone application. app-installer stops writing the old name for a Hub installation. Nothing has been released under the old name that has to keep working; a deployment that sets only HUB_STORAGE_DIR renames it before upgrading. * fix(app-installer): write HUB_STORAGE_DIR for a Hub until one reads APP_STORAGE_DIR Every Hub release published so far reads only HUB_STORAGE_DIR, so a template install of one kept its data inside the release and was refused with STORAGE_IN_RELEASE. The installer writes the old name beside APP_STORAGE_DIR for a Hub installation again; a Hub that reads APP_STORAGE_DIR ignores it. Remove it once such a release is published. * fix(app-installer): address review findings on PR 451 Recognise a Hub by its manifest's nocobase.templateKind rather than by the install source, so a Hub project deployed from an archive keeps its App Host child (treekill off) and its confirmations name the hosted applications; installer.json records the kind. Suggestions no longer carry a placeholder in a command meant to run as printed, and every rebuild suggestion made during an upgrade builds for the installed base path. An unreadable config.yml stops an upgrade with CONFIG_UNREADABLE instead of passing as "no databases". rollback --to <version> resolves to the newest build of that version other than the running one. The upgrade prechecks are hoisted out of both source branches, and tests cover the storage check rolling an upgrade back and an unrecorded release directory being adopted. * docs(skills): route Hub installs and app-installer deployments to nocobase-app-installer nocobase-create-app is for installing, creating or trying NocoBase, and hands a request to install a Hub, or to deploy an application with app-installer, to nocobase-app-installer. Only a Hub whose own code will change is created as a project. Both Skills now carry the same routing table, and their descriptions name what each is for and what it hands over. |
||
|
|
3c56455152 |
feat(scripts): add unreleased:hub-smoke for the Hub installer (#446)
* feat(hub-installer): install a Hub from the published template Add @nocobase/hub-installer for servers that run an unmodified Hub. `install <dir>` resolves the template version, generates and builds the Hub in `.build/<version>/` with create-app, unpacks only the deployment archive into `releases/<version>/hub`, writes `hub.env` and `config.yml` outside the release, applies the migrations with the release's own CLI, switches `current`, and starts the Hub with pm2 until `/hub/api/healthz` answers. A failure before the switch removes everything it wrote. `status` reports the current version, health, pm2 process, releases, Node compatibility and whether the registry has a newer version. The pm2 configuration runs `node` itself with the entry file as its argument, because pm2's fork mode loads a script through a wrapper where `import.meta.main` is false and the Hub never starts. A smoke test installs the published template on Debian bookworm with Node 24 on pull requests that touch the package, and daily, since the template ships no lockfile and a new dependency release can break it. * feat(hub-installer): upgrade and roll back a Hub `upgrade` builds the new release beside the running one, or reuses a release already on disk, and checks it with its own `config check` and `db apply --dry-run` before any downtime. It then stops the Hub, copies the SQLite database, config.yml and hub.env to backups/, switches `current`, migrates and starts the new release behind a health check. A failure after the switch rolls back automatically, restoring the database when the new release may have migrated it: exit 3 when the previous release is healthy again, 4 when it is not. Releases beyond `--keep` are pruned. `rollback` returns to the release the last upgrade came from and restores the pre-upgrade database only when that upgrade migrated. An operation interrupted during the downtime is recorded in installer.json: status reports it, upgrade refuses to stack on it, and rollback recovers by undoing an interrupted upgrade or finishing an interrupted rollback. Both commands confirm first or take `--yes`, and a non-SQLite database requires `--backup-done`. The smoke test now upgrades from a copy of the installed release and rolls back, exercising the downtime path without a second build. * feat(scripts): add unreleased:hub-smoke for the Hub installer `pnpm unreleased:hub-smoke` installs a Hub with the snapshot's hub-installer from the local registry, checks it, upgrades from a copy registered as an older release, rolls back and checks again. It runs pm2 under a short temporary PM2_HOME, stops it afterwards, and keeps the Hub and its logs outside the repository. The CI smoke test can only see changes to the installer itself: it installs the published template. This covers changes to the Hub template, app-cli, app-host and create-app before they are released. Both run scripts/smoke-hub-installer.mjs, which replaces the inline checks the workflow carried, so the local and CI checks cannot drift. * fix(hub-installer): address the install review - Refuse a pm2 name that is already registered: `pm2 start` on a taken name restarts that process with this install's environment instead of starting a new one, and START_FAILED then deleted it. - Check before the first write that the port binds, that every `--set-from-env` variable is set, and bound `--port` and `--health-timeout`; a regular file at the target is a precheck error. - SIGINT/SIGTERM stop the running step and let the failure handling clean up; a second signal exits. Children run in their own process group, so a timeout or interrupt stops what pnpm started, and the promise settles only once the group has exited. - Write the pm2 config and installer.json before switching `current`, so the switch is the last write before starting; remove parents the install created; keep `.build/` on failure under `--keep-source`. - Fail fast when pm2 reports the new process as crashed, instead of waiting out the health timeout. - `status` no longer starts the pm2 daemon; the lock is linked into place with its pid already written; dist-tags use `hasOwn`; `install --help` prints help; `config set` values are masked in output; an unsupported Node exits 2. - The smoke test builds the package and runs dist/, and also runs on lockfile and workspace changes. - Tests drive `install()` through a fake of every child process it starts, and runCommand through real process groups. * fix(hub-installer): address the upgrade and rollback review rollback: - Restore only from a backup that holds a database. An external database is never in one, so a Hub on PostgreSQL or MySQL used to stop, fail to restore, and stay down. - Keep installer.json in step with the `current` link: `current` is written only after the link moves. A failed stop changes nothing and exits 1; a target that does not start stays pending, and running rollback again retries it, restore included. - Recover an interrupted upgrade by what it actually did: before the switch nothing was migrated, so the old release is just started; an interrupted rollback keeps its backup and restores it again. upgrade: - Record the backup in `pending` only once it is complete, and mark the switch before the link moves; remove a half-written backup on abort. - Move the switch inside the rollback's error handling. - Write the successful result before pruning, then prune. - Never prune the release upgraded from; `--keep` is at least 2. - Keep the new release, and the pending state, when the automatic rollback fails too, so `rollback` can finish or return to it. - Refuse a downgrade; reuse a recorded release only when it was built for this machine, otherwise rebuild it and replace its record. - Check that the pm2 process belongs to this root and that the port is free once the Hub is stopped; wait for health failing fast on a crashed process; read the state under the lock; UTC backup names. Flow tests drive both commands through the fake world: exit 3 and 4, recovery after each, external databases, stop failures, interrupted upgrades, rebuilds, ownership and pruning. The smoke test pins the upgrade target to the installed version. * test(scripts): cover the restore and automatic rollback paths in the Hub smoke test The smoke test upgraded to a copy of the same release, which applies no migrations, so the rollback never restored the database and no upgrade ever failed. It now also rolls back an upgrade recorded as migrating and checks that a table written after it is gone, and upgrades to a release whose server entry throws, expecting exit 3 with UPGRADE_ROLLED_BACK and the previous release healthy again. Both scripts refuse port 13010, where the Hub's App Host listens; a Hub on it failed its health check with no clear reason. |
||
|
|
02d54029a8 |
refactor(app-cli)!: merge nb3-cli and app-tools into one application command line (#431)
* refactor(templates): drop the forwarding files in cli/ The templates re-exported @nocobase/app-cli through cli/database-command.ts, cli/hub-publishing.ts and cli/commands/i18n-check.ts, and passed createAppCommands through cli/standard-commands.ts. cli/commands/index.ts now calls createAppCommands itself, the shared i18n check test lives in app-cli, and app-plugin-hub imports publishToHub from the package rather than from a template. app-cli drops the ./database-command and ./commands/i18n-check subpaths that only those files used. * refactor(app-cli)!: absorb nb3-cli and app-tools into one command line @nocobase/app-cli now provides the nocobase bin and carries the command assembly, the plugin contract and plugin/Skill management from nb3-cli, and the dev, build, start and server-deps tooling from app-tools. Both packages are removed. Commands are found by path under src/commands and an application's cli/commands, and the runner locates the application from the nearest package.json (nocobase.templateKind or nocobase.buildTarget) or NOCOBASE_APP_ROOT. A built-in command is dispatched without importing the application's plugins. Development commands are not registered in a built dist/, and the tooling they need is declared as optional peers. build and dev hand the plugins' hooks to the scripts in NOCOBASE_CLI_HOOKS instead of asking a second process. Consumed changesets in .changeset/pre name the removed packages and are renamed to @nocobase/app-cli, as the app-client consolidation did, so the next prerelease run can still read them. * refactor(plugins)!: take the CLI topic from the package name A plugin's CLI topic is now its package name without the scope and app-plugin- prefix, so the scheduler's commands move from schedule to scheduler and the CLI example's from demo to cli-example; the built-in topics avoid every plugin name. The workflow plugin's check and build are devCommands, which a built dist/ leaves out. Plugins and the create-plugin template peer on @nocobase/app-cli instead of @nocobase/nb3-cli, and the workflow tests and skill-eval harness run the Default template's CLI through the bin with NOCOBASE_APP_ROOT. * refactor(templates)!: run every command through the nocobase bin The templates drop scripts/*.mjs, cli/index.ts and cli/commands/index.ts. Their scripts are postinstall, dev, build, start and the quality checks; every other command is pnpm nocobase <topic> <command>, which pnpm resolves to the bin without a script. The Default template enables the Hub commands with nocobase.cli.publishing, and all three declare tar for the build's --tar. create-app runs pnpm nocobase skills sync and prints the new next steps. The smoke script and the repository's template tests follow the new layout. * docs: describe the merged CLI and use the new command ids AGENTS.md, the application and plugin-development Skills, the docs site, package READMEs and runtime messages now name nocobase db repair, config init, locales check, release upload and the other new ids instead of the removed app-topic ids and script aliases. The upgrade Skill gains the step-by-step move to the new layout, which the changeset points to. The global nocobase-create-app Skill and skills/README.md are left for a follow-up after the release, because they reach users on merge. * chore: cover the packages whose Skills name the new command ids * refactor(app-cli)!: name the Collection and build commands by what they act on db doctor compares Collection metadata with the schema, not migrations, so it becomes collections doctor beside collections generate, and db holds only migrations, seeds and locks. server-deps retarget and verify are two steps of the build, run again on an existing dist/, so they become build retarget and build verify. A dist topic was considered and rejected: a commands/dist directory is ignored by the repository's .gitignore, Prettier and ESLint. Topic and command descriptions now say application rather than app and Skill rather than skill, package describes the one thing it does, and skills sync mentions the .claude/skills links it writes. * refactor(app-cli)!: move retarget and verify to a dist topic as dist retarget and dist check Both act on an existing dist/ and never build, so they belong to a dist topic rather than under build, which returns to being a plain command. verify becomes check, the verb every other checking command uses (config check, locales check, workflow check). A dist directory is ignored by the repository's .gitignore, both Prettier ignore files and the shared ESLint preset, and commands are found by their directory, so src/commands/dist/ gets an exception in each of the four with a comment saying why. tests/command-files.test.ts fails if any command file is ignored by git, Prettier or ESLint, so losing an exception cannot go unnoticed. The templates' AGENTS.md warns applications away from those directory names in cli/commands/. * docs(app-skills): add a command-line reference for the application CLI nocobase-app-development gains references/cli.md: a task-to-command map, the agent conventions --help does not state (--json, exit codes, --dry-run, and that db reset, rollback, redo and repair refuse without --force outside a terminal, which is not to be worked around), how to read the data-model snapshot and keep it fresh, how to write an application command, and what a built dist/ registers. The Skill links it before any pnpm nocobase command; the deployment Skill notes dist retarget, dist check and running commands in dist/; the three templates' AGENTS.md keep only the essentials and point to the reference instead of repeating it. |
||
|
|
57c0f6cf95 |
chore(scripts): rename local-registry commands to unreleased (#406)
The local-registry:* commands sat next to pnpm registry, which builds shadcn Registry items, and read as a local variant of it. What they do is test the unreleased checkout as published packages, so they are now unreleased:*, with verify renamed to smoke and stop to clean. Clean also removes a session prepared under the old names, which would otherwise keep holding the port. |