Commit Graph
18 Commits
Author SHA1 Message Date
nocobase[bot] a1c353b825 chore: merge release 2026-10-12.3 into v3-develop [skip ci]
current app-template-default version: 1.0.0-beta.64
2026-10-12 04:56:14 +00:00
chenos 693e43d86b ci(skills): distribute v3 skills on source updates (#10769)
* ci(skills): distribute v3 skills on source updates

* refactor: rename app plugin development skill
2026-10-12 11:17:39 +08:00
nocobase[bot] 372b4039ef chore: merge release 2026-10-12.1 into v3-develop [skip ci]
current app-template-default version: 1.0.0-beta.63
2026-10-12 01:07:21 +00:00
nocobase[bot] ebcef43801 chore: merge release 2026-10-09.2 into v3-develop [skip ci]
current app-template-default version: 1.0.0-beta.58
2026-10-09 12:53:25 +00:00
nocobase-studio[bot]andPiEgg a6758ecb55 PM-119: Complete v3 repository reference migration (#10597)
Co-authored-by: PiEgg <marksz@teamsz.xyz>
2026-10-09 04:40:25 -04:00
nocobase[bot] 6f38530b05 chore: release 2026-10-05.1 [skip ci]
current app-template-default version: 1.0.0-beta.54
2026-10-05 02:17:53 +00:00
chenos 463a7a8f38 feat(app-testing): test applications on any dialect, with a portability check and every server dialect in CI (#525)
* chore(db-testing): fail tests that choose a dialect outside the database packages

pnpm db-tests:check reads every test and test helper outside the database
packages and fails on a dialect package import, ':memory:', dialect: 'sqlite',
PRAGMA, sqlite_master or a trigger. A test whose subject is a dialect says so
with a db-test-portability marker and a reason; template tests, which ship to
users, are exempted in the script instead. The app-server, app-cli and
template tests still to be ported with @nocobase/app-testing are listed as
pending, and the check fails once an entry is no longer needed. It runs in
pnpm check and in the Quality workflow next to the dependency checks.

* feat(db-testing): select every package that tests with db-testing through test:db --all

* feat(db-testing): run db-testing tests on every server dialect

* feat(create-plugin): generate database tests on db-testing

* test(create-plugin): keep the generated-test assertion clear of the portability check

* fix(db-testing): clean up a partial create, drop Oracle test users before 23ai, and run one provisioner contract everywhere

`createSqlTestDatabaseProvisioner()` drops what earlier create statements made when a later one fails, since the caller never receives the drop() that would; a failing first statement is left alone, because the name may belong to something that predates the run.

The Oracle provisioner drops a test user through a PL/SQL block that ignores only ORA-01918, instead of `drop user if exists`, which only 23ai accepts, and grants the materialized view and synonym privileges a migration may need.

`describeTestDatabaseProvisioner()` treats `listProvisioned` as optional throughout and drops the stale-run database in a finally, so a failed assertion leaves nothing behind. PostgreSQL and MySQL run it in place of their own provisioner tests.

* chore(db-testing): report every stale exemption and catch the SQLite driver in the portability check

A listed file or a marker that no longer covers a violation is reported, and so is a file both marked and listed, so every kind of exemption only shrinks. New rules catch a `better-sqlite3` or `sqlite3` import, a knex `client` naming either, and a dialect package imported by a name built at run time; the PRAGMA rule matches SQL rather than prose that mentions it. The `config init` test's marker reads as a sentence.

* test: take the pending database tests' databases from @nocobase/db-testing

Fifteen of the eighteen test files the portability check still listed as pending no longer choose a dialect. app-server's collections artifact, doctor, provider and task-plan tests, its repository routes and app-cli's db command tests run on databases provisioned by @nocobase/db-testing, one per connection they name, instead of SQLite files and in-memory databases. The examples template's article, analytics, numeric, permission-seed and workflow tests do the same; its articles migration test is a describeMigration. The cases whose subject is SQLite itself move to files marked sqlite-only or dialect-specific: a dry run not creating a missing SQLite file, and the driver loaded for a configured dialect. The examples template's external CRM test stays on its SQLite stand-in and is exempted in the check, since a template's tests ship to users and carry no marker.

PENDING keeps only the three templates' app-server tests, which move with @nocobase/app-testing.

* fix(db): only read in a dry run of rollback and repair

A migrator's rollback and repair, and a seeder's repair, took the task lock, ensured the history table and, for rollback, upgraded legacy checksums before looking at dryRun. On a database no task had run on, `nocobase db rollback --dry-run` (and redo, which goes through it) and `db repair --dry-run` therefore created the history and lock tables while reporting that nothing changed. SQLite hid it: a dry run against a database file that does not exist yet takes a separate read-only path, and every server database exists.

A dry run now reads history the way history() does, treating a missing table as empty history, and takes no lock. The migrator and seeder integration suites assert that these dry runs create nothing on every dialect, and the app-cli dry-run test no longer tolerates bookkeeping tables.

* feat(app-cli): let a bound test command load a configuration file of its own

bindAppCommand() takes configPath and hands it to the application's runtime the way APP_CONFIG_FILE is, so a command's test can run against a configuration it wrote, such as one naming a test database.

* feat(app-plugin-authentication): sign in from other packages' tests through a ./testing entry

signIn() signs in through the application's own sign-in route and returns a session whose fetch sends requests as that user, so a test can exercise the real authentication and authorization chain instead of an x-test-user header or a hand-written authenticationToken. DEFAULT_ADMIN_CREDENTIALS names the administrator the default seed creates.

* fix(db): keep in-process task lock claims per connection, not per connection name

Two Database Managers in one process each have a connection called main on databases of their own; one migrating while the other did failed with TaskLockBusyError although they never shared a database. The claims are now kept by the Database Connection a migration connection was made from, so the same connection still fails fast while another one under the same name proceeds; managers on the same database still take turns through the lock row. db-testing drops the queue that ran its test databases' migrations and seeds one after another to avoid the error.

* feat(app-testing): start an application on test databases of its own

@nocobase/app-testing/server's createTestApp() starts an application through its own standalone server on databases provisioned by @nocobase/db-testing, through the configuration file a deployment's own config.yml goes through, and installs it on start; createAppTest() is the Vitest fixture around it. ./cli carries @nocobase/app-cli/testing and bindTestAppCommand(), which points the application a command opens at a test configuration. Both re-export the layer below, so an application's or a plugin's tests depend on this package alone.

* test(templates): run the application tests on app-testing and check authorization through a real session

The three templates' application server tests start the template on test databases written by createTestAppConfig() instead of SQLite files, and the examples template's database tests take their API from @nocobase/app-testing/server, which every template now depends on for development. The portability check's pending list is empty and goes away; a template's SQLite-only test stays in EXEMPT.

The examples template signs in through its own sign-in route as the administrator and as a seeded proposal engineer, and checks that the sales confidentiality restriction leaves confidential quotes out of the engineer's list and in the administrator's, and that they appear once the restriction is no longer assigned. The nocobase-app-development Skill and AGENTS.md describe testing through the whole application.

* test: take plugin and example test fixtures from @nocobase/app-testing alone

Plugins, examples and the create-plugin generator import database fixtures
from @nocobase/app-testing/server and the command runner from
@nocobase/app-testing/cli instead of @nocobase/db-testing and
@nocobase/app-cli/testing, and depend on @nocobase/app-testing alone.
The database test portability check now fails when a test in a plugin, an
example or a template imports either lower layer directly; libraries and
tools keep using them. AGENTS.md, the db-testing README and the
app-development commands reference describe the single entry.

* fix: select app-testing users in test:db --all and keep each Skill's test entry its own

`pnpm test:db <dialect> --all` selected packages by a declared
@nocobase/db-testing, so once plugins, examples and templates moved to
@nocobase/app-testing the nightly Database tests workflow would have
stopped running them on PostgreSQL and MySQL. It now selects packages that
are or declare either one.

The command-authoring block shared by the application and plugin Skills
ended with the Test section, which now names a different runner in each:
@nocobase/app-testing/cli for an application, and the released
@nocobase/app-cli/testing in the global plugin Skill. The section moves
after the shared block in both.
2026-10-03 10:38:59 -04:00
nocobase[bot] 28c7522b3d chore: release 2026-09-26.1 [skip ci] 2026-09-26 03:51:49 +00:00
chenos ec92b20eda feat(app-cli)!: AppCommand authoring API and one --json envelope for every command (#441)
* feat(app-cli)!: add the AppCommand authoring API on the root entry

AppCommand exposes rootDir, withApp(({ app, env }) => ...), setStatus and
appPath() flags; --json prints one envelope for success and failure, and
CommandError carries a code, suggestions and details. The authoring API moves
from ./plugins to the package root, a ./testing entry provides
bindAppCommand, the runner closes runtimes a command left open, and console
logs of an application a command creates go to stderr.

* feat(app-cli)!: move every command to the AppCommand output contract

Built-in, plugin and generated commands extend AppCommand, return their
result, and throw CommandError on failure, so --json prints one envelope for
every command. Plugin commands reach the application through withApp() and
take appPath() flags; the CLI example's artifact build is a devCommand.

The testing entry exports runAppCommand next to bindAppCommand, dev-config's
ESLint presets refuse the patterns the contract forbids in cli/, app-cli is
registered as identity-sensitive, and the application and plugin-development
Skills each carry the command-authoring guide, kept identical by a test.

* feat(app-cli): keep command diagnostics on stderr and behind NOCOBASE_CLI_DEBUG

An AppCommand's logToStderr keeps writing under --json: stderr never carries
the document, so progress and confirmations no longer disappear for the agent
that asked for JSON. A CommandError keeps its cause off the chain oclif prints,
and NOCOBASE_CLI_DEBUG prints the redacted error chain behind any command's
failure, from source or dist, replacing release's own handling. The Skills
describe using the application's logger inside withApp() for records that
belong in its log files.

* feat(app-cli): make commands discoverable, previewable and recoverable for agents

- `nocobase commands --json` lists every registered command with its source,
  arguments, flags and whether it takes --json, --dry-run and --force; a
  deployment lists no development command.
- Invalid usage suggests the flag or command that was probably meant and the
  command's --help, drops oclif's trailing hint from the message, and always
  exits 2.
- db apply, rollback, redo and reset take --dry-run and return the plan;
  FORCE_REQUIRED carries that plan and the --force/--dry-run forms; a busy task
  lock fails with DATABASE_LOCKED, backed by TaskLockBusyError in
  @nocobase/db. Help examples lead with --dry-run.
- release reports upload and deployment progress on stderr while it waits.
- The runner no longer exits 13 with an unsettled top-level await when a
  reader such as `| head` closes stdout early.

* fix(app-cli): address review findings on the command contract

- withApp() and the db commands report a failure to put the application away as a warning instead of failing work that already succeeded or replacing the failure it ended in; a rerun of `db rollback` no longer rolls back a second batch
- suggestions and config init's next steps name `node <dist>/cli/index.js` in a built dist/, which has no pnpm; AppCommand gains `this.cliCommand(args)` for the same in a command's own suggestions
- usage errors never repeat a typed value, list allowed values and the flags a conflict involves, and release upload/deploy report them as INVALID_USAGE like every other command; `this.error()` reports COMMAND_FAILED rather than invalid usage
- NOCOBASE_CLI_DEBUG prints a failure's diagnostics once, and oclif's raw stack no longer replaces the message and its suggestions
- appPath() defaults declared in baseFlags resolve against the application root
- every --dry-run answers success-noop, and so does a db command that found nothing to do
- a dry run creates no SQLite file that does not exist yet: drivers may report hasStorage(), and a dry run then answers for an empty database without connecting
- the runner's safety net destroys a leaked runtime's scope even when shutdown fails
- a command bound without an id is named after its class, and the Skills' examples name app commands as the runner does

* fix(app-cli): address the remaining review threads on the command contract

- a single misspelled topic, such as `plugn`, now suggests that topic's help instead of only the full command list
- `commands --json` marks an appPath() default with `defaultRelativeTo: "application-root"`, matching what --help says
- the reason oclif gives for a `combinable` conflict is repeated instead of collapsing to a generic message: the pattern expected "Only of the following" where oclif writes "Only the following"
- the runner's own EPIPE handler is removed: it never installed, because @oclif/core swallows EPIPE on stdout at import, and exiting there would have skipped withApp() and the runner's cleanup; a test now covers a command that keeps printing after its reader leaves

* test(ai-employee): give the Skills tests' first render room to load the page

The first render in the file waits for the employee heading with findBy's default 1 s, which the page's import graph can outlast when CI runs every package's tests at once. The Tools tests hit the same wait and got a 10 s timeout in #413; the Skills tests now match.

* test(app-cli): inspect a workspace of the test's own rather than the repository

The workspace-root inspection test from #439 scanned the real repository's packages/, where other app-cli tests create and delete temporary applications under tests/.tmp while they run. Run together, the scan read one mid-write and the inspection failed. It now builds the one-application workspace it needs.
2026-09-25 19:57:00 -07:00
chenos dbf5631e1f fix: clear the leftovers of the CLI consolidation (#439)
* chore: replace the command ids left over from the CLI consolidation

The scheduler and template-print documentation still named `schedule sync`
and `skills:sync`, the template reference pages showed `pnpm migrate`, and the
global create-app Skill taught `pnpm config:*` scripts that applications no
longer carry. The create-app smoke test now records `<topic> <command>` ids
directly instead of mapping them back to the old script names.

* chore: drop references to the removed client:inspect and server:inspect

Application inspection was removed in #329, but the plugin-development
Skill, skills/README.md and a few comments still sent readers to
`client:inspect` and `server:inspect`. `plugin inspect` covers registration
state only, so the guidance now points there for registration and drops the
composition diagnostics. The authentication test that asserts no command is
prescribed now checks for `config init` rather than the old script name.

* fix: clear the remaining leftovers of the CLI consolidation

A second sweep after #431, #434, #437 and #438 found guidance and code that
still described the old command line.

- `plugin inspect` suggested the removed `pnpm plugin:register` and
  `pnpm skills:sync` scripts; it now suggests `pnpm nocobase plugin register`
  and `skills sync` with the flags that located the App, and the remaining
  colon-form hints name the real commands.
- The Default template never registered the scheduler's CLI entry, so the
  documented `pnpm nocobase scheduler sync` did not exist there.
- `@refinedev/cli` and `tsc-alias` are spawned by `nocobase build` and are now
  declared as optional peers of `@nocobase/app-cli`.
- `peers:check` covers `@nocobase/app-cli` again after its move to
  `packages/app`, and `deps:check` scans plugin `cli/` sources and source
  directories named `dist`.
- Skills, templates, plugin AGENTS.md copies, READMEs and the docs site now
  describe current commands, the `metadata/` directory from #437, the Hub
  archive path, `release` availability and the two `dist/package.json`
  scripts. Examples and Hub ignore `/.env`.

* fix: address review threads on the CLI leftovers

- the templates' Docker build contexts exclude build output where builds write it (each workspace package's dist/, the documentation sites') instead of every directory named dist/, so a source directory with that name, such as app-cli's dist commands, needs no exception
- `plugin inspect` suggests `skills sync --package <full name>` rather than the compatibility `--plugin`, and a test covers suggestions for a `--workspace-root`/`--app` inspection
- the CLI example Skill states when two plugin topics collide: once the scope and an `app-plugin-` prefix are removed
- `peers:check` fails on a manifest that does not parse instead of leaving the package out
- the smoke test's fake pnpm records a top-level command such as `nocobase build` by its own id, reading the top-level commands from app-cli
- the plugins changeset no longer lists create-app, whose change another changeset already covers
2026-09-25 19:34:23 -07:00
chenos 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.
2026-09-25 01:28:45 -07:00
PiEgg 009ebed5a5 docs: remove internal documentation and stale references (#223) 2026-09-15 10:08:06 +08:00
github-actions[bot] 41ae8a49f6 chore: release 2026-09-11.1 2026-09-11 08:29:35 +00:00
PiEgg e9f796d123 feat(cli): let plugins register build and dev hooks (#185) 2026-09-10 18:08:52 +08:00
github-actions[bot] a224e3111e chore: release 2026-09-09.2 2026-09-09 08:37:05 +00:00
PiEgg 52d1107672 feat: declare dependencies so the right ones reach each side (#151) 2026-09-09 16:13:05 +08:00
github-actions[bot] aeb9177ef7 chore: release 2026-09-09.1 2026-09-09 02:48:31 +00:00
PiEgg ec576ba059 feat(cli): let plugins contribute commands to an app's CLI (#150) 2026-09-08 17:27:15 +08:00