mirror of
https://github.com/n8n-io/n8n.git
synced 2026-08-30 18:01:23 +08:00
refactor: Standardize package import/export flag naming in n8n-cli (#34998)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,7 @@ n8n-cli package export -w abc --include-variable-values=false -o export.n8np
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `-w, --workflow-id` | Workflow ID to include. Repeat the flag to export several. |
|
||||
| `-f, --folder-id` | Folder ID to include with its nested folders. Repeat the flag to export several. |
|
||||
| `--folder-id` | Folder ID to include with its nested folders. Repeat the flag to export several. |
|
||||
| `-p, --project-id` | Project ID to include. Repeat the flag to export several. |
|
||||
| `-o, --output` | File to write the package to. Defaults to `export.n8np`. |
|
||||
| `--include-variable-values` | `true` (default) or `false`. Whether values of variables referenced by the exported workflows are bundled into the package. When `false`, variables still travel as name/type files (and in the package requirements), just without their values. |
|
||||
@@ -44,7 +44,7 @@ Import a `.n8np` archive into a project.
|
||||
|
||||
```bash
|
||||
n8n-cli package import --file=export.n8np
|
||||
n8n-cli package import --file=export.n8np --project=<id> --workflow-conflict-policy=skip
|
||||
n8n-cli package import --file=export.n8np --project-id=<id> --workflow-conflict-policy=skip
|
||||
n8n-cli package import --file=export.n8np --workflow-conflict-policy=fail --credential-missing-mode=must-preexist
|
||||
n8n-cli package import --file=export.n8np --workflow-conflict-policy=fail --bindings='{"credentials":{"<sourceId>":"<targetId>"}}'
|
||||
```
|
||||
@@ -53,8 +53,8 @@ n8n-cli package import --file=export.n8np --workflow-conflict-policy=fail --bind
|
||||
|------|-------------|
|
||||
| `--file` | Path to the `.n8np` package file. (required) |
|
||||
| `--workflow-conflict-policy` | What to do when a workflow already exists by source ID: `new-version` (default), `fail`, or `skip`. |
|
||||
| `--project` | Target project ID. Defaults to your personal project. |
|
||||
| `--folder` | Target folder ID within the project. Defaults to the project root. |
|
||||
| `-p, --project-id` | Target project ID. Defaults to your personal project. (alias: `--project`) |
|
||||
| `--folder-id` | Target folder ID within the project. Defaults to the project root. (alias: `--folder`) |
|
||||
| `--workflow-publishing-policy` | Whether imported workflows end up published. `preserve-published-state` (instance default) never publishes drafts — an updated workflow is republished only when it was already published and the package workflow is published too; `match-source` follows the package workflow's published flag; `publish-all` publishes every imported workflow; `unpublish-all` leaves new workflows unpublished and unpublishes updated ones. |
|
||||
| `--workflow-id-policy` | Whether imported workflows keep their source ID (`source`) or receive a new one (`new`). |
|
||||
| `--missing-node-type-mode` | What to do when a workflow uses a node type — or a version of a node type — this instance does not have. `fail` (instance default) rejects the import before anything is written, listing every missing node type and the workflows that use it; `import-anyway` imports the package, but the affected workflows are never published by the import, regardless of the publishing policy. |
|
||||
|
||||
@@ -13,8 +13,8 @@ const packageRoot = process.cwd();
|
||||
|
||||
interface ImportFlags {
|
||||
file: string;
|
||||
project?: string;
|
||||
folder?: string;
|
||||
projectId?: string;
|
||||
folderId?: string;
|
||||
workflowConflictPolicy?: string;
|
||||
workflowPublishingPolicy?: string;
|
||||
workflowIdPolicy?: string;
|
||||
@@ -59,8 +59,8 @@ describe('package import command', () => {
|
||||
it('forwards workflowPublishingPolicy and all sibling options to the import API', async () => {
|
||||
const { command, importPackage } = stubCommand({
|
||||
file: '/tmp/export.n8np',
|
||||
project: 'p-1',
|
||||
folder: 'f-1',
|
||||
projectId: 'p-1',
|
||||
folderId: 'f-1',
|
||||
workflowConflictPolicy: 'fail',
|
||||
workflowPublishingPolicy: 'publish-all',
|
||||
workflowIdPolicy: 'new',
|
||||
@@ -153,6 +153,32 @@ describe('package import command', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('resolves the --project-id and --folder-id flags', async () => {
|
||||
const importPackage = await runWithArgv([
|
||||
'--file=/tmp/export.n8np',
|
||||
'--project-id=p-1',
|
||||
'--folder-id=f-1',
|
||||
]);
|
||||
|
||||
expect(importPackage).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
expect.objectContaining({ projectId: 'p-1', folderId: 'f-1' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('resolves the backward-compatible --project and --folder aliases', async () => {
|
||||
const importPackage = await runWithArgv([
|
||||
'--file=/tmp/export.n8np',
|
||||
'--project=p-1',
|
||||
'--folder=f-1',
|
||||
]);
|
||||
|
||||
expect(importPackage).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
expect.objectContaining({ projectId: 'p-1', folderId: 'f-1' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects the removed --conflict-policy flag', async () => {
|
||||
const config = await Config.load(packageRoot);
|
||||
const command = new PackageImport(
|
||||
|
||||
@@ -25,7 +25,6 @@ export default class PackageExport extends BaseCommand {
|
||||
aliases: ['workflow-id'],
|
||||
}),
|
||||
folderId: Flags.string({
|
||||
char: 'f',
|
||||
description: 'Folder ID to include with its nested folders (repeat for multiple)',
|
||||
multiple: true,
|
||||
aliases: ['folder-id'],
|
||||
|
||||
@@ -10,7 +10,7 @@ export default class PackageImport extends BaseCommand {
|
||||
|
||||
static override examples = [
|
||||
'<%= config.bin %> package import --file=export.n8np',
|
||||
'<%= config.bin %> package import --file=export.n8np --project=<id> --workflow-conflict-policy=skip',
|
||||
'<%= config.bin %> package import --file=export.n8np --project-id=<id> --workflow-conflict-policy=skip',
|
||||
'<%= config.bin %> package import --file=export.n8np --workflow-conflict-policy=fail --credential-missing-mode=must-preexist',
|
||||
'<%= config.bin %> package import --file=export.n8np --workflow-conflict-policy=fail --bindings=\'{"credentials":{"<sourceId>":"<targetId>"}}\'',
|
||||
];
|
||||
@@ -18,11 +18,14 @@ export default class PackageImport extends BaseCommand {
|
||||
static override flags = {
|
||||
...BaseCommand.baseFlags,
|
||||
file: Flags.string({ description: 'Path to the .n8np package file', required: true }),
|
||||
project: Flags.string({
|
||||
projectId: Flags.string({
|
||||
char: 'p',
|
||||
description: 'Target project ID (defaults to your personal project)',
|
||||
aliases: ['project-id', 'project'],
|
||||
}),
|
||||
folder: Flags.string({
|
||||
folderId: Flags.string({
|
||||
description: 'Target folder ID within the project (defaults to the project root)',
|
||||
aliases: ['folder-id', 'folder'],
|
||||
}),
|
||||
workflowConflictPolicy: Flags.string({
|
||||
description: 'What to do when a workflow already exists in the target project',
|
||||
@@ -107,8 +110,8 @@ export default class PackageImport extends BaseCommand {
|
||||
result = await client.importPackage(
|
||||
{ buffer, filename: path.basename(flags.file) },
|
||||
{
|
||||
projectId: flags.project,
|
||||
folderId: flags.folder,
|
||||
projectId: flags.projectId,
|
||||
folderId: flags.folderId,
|
||||
workflowConflictPolicy: flags.workflowConflictPolicy,
|
||||
workflowPublishingPolicy: flags.workflowPublishingPolicy,
|
||||
workflowIdPolicy: flags.workflowIdPolicy,
|
||||
|
||||
Reference in New Issue
Block a user