@sanity/workflow-cli 0.13.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +40 -27
- package/dist/commands/editorial-workflows/abort.d.ts +1 -0
- package/dist/commands/editorial-workflows/abort.js +2 -2
- package/dist/commands/editorial-workflows/definition/delete.d.ts +1 -0
- package/dist/commands/editorial-workflows/definition/delete.js +2 -2
- package/dist/commands/editorial-workflows/definition/diff.d.ts +1 -0
- package/dist/commands/editorial-workflows/definition/diff.js +2 -2
- package/dist/commands/editorial-workflows/deploy.d.ts +2 -1
- package/dist/commands/editorial-workflows/deploy.js +15 -9
- package/dist/commands/editorial-workflows/diagnose.d.ts +1 -0
- package/dist/commands/editorial-workflows/diagnose.js +2 -2
- package/dist/commands/editorial-workflows/fire-action.d.ts +1 -0
- package/dist/commands/editorial-workflows/fire-action.js +2 -2
- package/dist/commands/editorial-workflows/nuke.d.ts +2 -1
- package/dist/commands/editorial-workflows/nuke.js +13 -9
- package/dist/commands/editorial-workflows/set-stage.d.ts +1 -0
- package/dist/commands/editorial-workflows/set-stage.js +2 -2
- package/dist/commands/editorial-workflows/start.d.ts +1 -0
- package/dist/commands/editorial-workflows/start.js +2 -2
- package/dist/lib/context.d.ts +36 -13
- package/dist/lib/context.js +27 -6
- package/dist/lib/fail.js +1 -1
- package/dist/lib/flags.d.ts +27 -5
- package/dist/lib/flags.js +17 -1
- package/dist/lib/nuke.d.ts +15 -14
- package/dist/lib/nuke.js +27 -8
- package/dist/lib/prompt.d.ts +14 -0
- package/dist/lib/prompt.js +4 -0
- package/dist/lib/select-deployment.d.ts +41 -16
- package/dist/lib/select-deployment.js +55 -38
- package/oclif.manifest.json +131 -19
- package/package.json +8 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @sanity/workflow-cli
|
|
2
2
|
|
|
3
|
+
## 0.20.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6e2a066: Ambiguous deployment/resource selection now prompts on an interactive terminal instead of only erroring. When a config has several deployments and no selector is given, `start`, `definition diff`, and `definition delete` show the same deployment picker `deploy` already offered. The instance-targeted commands (`abort`, `set-stage`, `fire-action`, `diagnose`) show that picker too when the config spans several resources — the interactive counterpart to their `--deployment` selector, reading from the chosen deployment's resource. Non-interactive runs (CI, piped output) keep the existing errors asking for `--deployment`/`--tag`, and `nuke` still requires an explicit selector — for a destructive command, naming exactly what is swept is the right friction.
|
|
8
|
+
- 7c4dd86: Reduce guard lifecycle request volume and chunk orphan cleanup transactions.
|
|
9
|
+
- e860898: **BREAKING:** Published Editorial Workflows packages now ship as one fixed release stack and require exact-version peers for every shared runtime package. Install the matching stack so the engine, reactive core, adapters, tools, and UI cannot silently load private or version-skewed copies.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- efb4cd9: Error detail below the ✖ headline is no longer dimmed. Validation output, auth hints, and errors caught by command wrappers now render in legible red so the information users need to act on remains readable.
|
|
14
|
+
- Updated dependencies [bce09fc]
|
|
15
|
+
- Updated dependencies [efb4cd9]
|
|
16
|
+
- Updated dependencies [46b0285]
|
|
17
|
+
- Updated dependencies [ab5e454]
|
|
18
|
+
- Updated dependencies [8a76c67]
|
|
19
|
+
- Updated dependencies [e3122cc]
|
|
20
|
+
- Updated dependencies [7e8f459]
|
|
21
|
+
- Updated dependencies [98e488e]
|
|
22
|
+
- Updated dependencies [7c4dd86]
|
|
23
|
+
- @sanity/workflow-engine@0.20.0
|
|
24
|
+
|
|
25
|
+
## 0.14.0
|
|
26
|
+
|
|
27
|
+
### Minor Changes
|
|
28
|
+
|
|
29
|
+
- 59b40fd: **BREAKING:** deployment selection now keys on the deployment `name`, selected with `--deployment`. Deployment-targeted commands (`start`, `definition diff`, `definition delete`, `nuke`) take `--deployment` as the precise selector; `--tag` still selects while it names exactly one deployment and errors listing the candidates when it spans several. `deploy --tag <tag>` now deploys every deployment carrying the tag (a tag is an environment group); `--deployment` deploys one, `--all-tags` deploys everything, and the three are mutually exclusive. `nuke` requires exactly one of `--deployment` / `--tag`, and refuses when another same-tag deployment sweeps an overlapping resource — guard document ids embed only the tag, so within a shared dataset the sweep cannot tell the deployments' guards apart and would delete the other's live locks. The interactive deploy prompt selects by name with the tag as its description. Read commands keep `--tag` as an optional filter — a repeated tag fans reads out across every resource it is deployed to.
|
|
30
|
+
- de7ccfa: The instance-keyed commands (`diagnose`, `abort`, `set-stage`, `fire-action`) accept `--deployment <name>` to choose which resource to read the instance from — the precise selector consistent with the deployment-targeted commands. `--deployment` names one deployment and reads from the resource it targets; `--tag` stays the optional narrower it was, and the instance's own tag partition still comes from the loaded instance itself, never from the flag. This closes the dead end where a tag repeated across several resources left these commands unable to resolve a resource, and the "spans multiple resources" failures now point at `--deployment` as the remedy.
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- Updated dependencies [24b11dd]
|
|
35
|
+
- Updated dependencies [2005ab7]
|
|
36
|
+
- Updated dependencies [24b11dd]
|
|
37
|
+
- Updated dependencies [59b40fd]
|
|
38
|
+
- @sanity/workflow-engine@0.19.0
|
|
39
|
+
|
|
3
40
|
## 0.13.0
|
|
4
41
|
|
|
5
42
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -49,7 +49,8 @@ project will fail on cross-resource reads.
|
|
|
49
49
|
|
|
50
50
|
The CLI is configured by a `sanity.workflow.ts` (or `.js`/`.mjs`) discovered in
|
|
51
51
|
the directory you run from. It exports a config built with
|
|
52
|
-
`defineWorkflowConfig`, declaring
|
|
52
|
+
`defineWorkflowConfig`, declaring your **deployments** (typically one per
|
|
53
|
+
environment):
|
|
53
54
|
|
|
54
55
|
```ts
|
|
55
56
|
import {defineWorkflowConfig} from '@sanity/workflow-engine/define'
|
|
@@ -60,7 +61,7 @@ export default defineWorkflowConfig({
|
|
|
60
61
|
deployments: [
|
|
61
62
|
{
|
|
62
63
|
expectedMinReaderModel: 2,
|
|
63
|
-
name: 'production',
|
|
64
|
+
name: 'production', // the deployment's unique identity (lowercase letters, digits, dashes)
|
|
64
65
|
tag: 'prod', // the environment partition the engine's docs are scoped to
|
|
65
66
|
workflowResource: {type: 'dataset', id: 'acme.workflows'}, // where those docs live
|
|
66
67
|
resourceAliases: [
|
|
@@ -76,11 +77,23 @@ export default defineWorkflowConfig({
|
|
|
76
77
|
})
|
|
77
78
|
```
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
`name` is the deployment's identity: unique across the config and constrained
|
|
81
|
+
to the same grammar as `tag`. Tags group deployments by environment and may
|
|
82
|
+
repeat, as long as no two deployments share both a `workflowResource` and a
|
|
83
|
+
`tag` — that pair is the storage partition, and the config rejects the
|
|
84
|
+
collision naming both entries.
|
|
85
|
+
|
|
86
|
+
Pick a deployment with `--deployment <name>`; with a single deployment configured you
|
|
87
|
+
can omit it. `--tag <tag>` also works on single-deployment commands while the
|
|
88
|
+
tag names exactly one deployment — on `deploy` it targets every deployment
|
|
89
|
+
carrying the tag (a tag is an environment group). With several configured, a
|
|
90
|
+
bare interactive run presents a keyboard-driven deployment selector (by name,
|
|
91
|
+
tag alongside) — on `deploy`, `start`, and `definition diff`/`delete`, and on
|
|
92
|
+
the instance-targeted commands (`abort`, `set-stage`, `fire-action`,
|
|
93
|
+
`diagnose`) when the config spans several resources. In CI or another
|
|
94
|
+
non-interactive shell, the command fails asking for `--deployment` or `--tag`
|
|
95
|
+
(`deploy` also suggests `--all-tags`) instead of blocking for input.
|
|
96
|
+
`--all-tags` deploys every deployment in the config in one run: a failure in one doesn't
|
|
84
97
|
stop the rest — the run continues, prints a summary of what failed, and exits
|
|
85
98
|
non-zero. The client's project + dataset are derived from the deployment's
|
|
86
99
|
`workflowResource`, and `deploy` expands each definition's `@<handle>:`
|
|
@@ -143,26 +156,26 @@ stale compiled output.
|
|
|
143
156
|
|
|
144
157
|
## Command status
|
|
145
158
|
|
|
146
|
-
| Command
|
|
147
|
-
|
|
|
148
|
-
| `deploy`
|
|
149
|
-
| `deploy --all-tags`
|
|
150
|
-
| `deploy --check`
|
|
151
|
-
| `deploy --dry-run`
|
|
152
|
-
| `deploy --only <name>`
|
|
153
|
-
| `start <name>`
|
|
154
|
-
| `list`
|
|
155
|
-
| `show <instance-id>`
|
|
156
|
-
| `diagnose <instance-id>`
|
|
157
|
-
| `tail <instance-id>`
|
|
158
|
-
| `abort <instance-id>`
|
|
159
|
-
| `set-stage <instance-id> --to <stage>`
|
|
160
|
-
| `fire-action <instance-id>`
|
|
161
|
-
| `definition list`
|
|
162
|
-
| `definition show <name>`
|
|
163
|
-
| `definition diff <name>`
|
|
164
|
-
| `definition delete <name>`
|
|
165
|
-
| `nuke --tag <tag>`
|
|
159
|
+
| Command | Status |
|
|
160
|
+
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
161
|
+
| `deploy` | wired — calls `workflow.deployDefinitions` over the selected deployment's definitions |
|
|
162
|
+
| `deploy --all-tags` | wired — deploys every deployment in the config, continuing past per-deployment failures |
|
|
163
|
+
| `deploy --check` | wired — runs `validateDefinition` over the local batch + a duplicate-name check |
|
|
164
|
+
| `deploy --dry-run` | wired — fetches existing docs and renders a coloured JSON diff per change |
|
|
165
|
+
| `deploy --only <name>` | wired — filters deploy/check/dry-run to one definition by `name` |
|
|
166
|
+
| `start <name>` | wired — calls `workflow.startInstance` (`--field` for input fields) |
|
|
167
|
+
| `list` | wired — `client.fetch` over `sanity.workflow.instance` documents (`--definition <name>` to filter) |
|
|
168
|
+
| `show <instance-id>` | wired — `client.getDocument` |
|
|
169
|
+
| `diagnose <instance-id>` | wired — calls `workflow.diagnose`, classifies why the instance is/isn't progressing |
|
|
170
|
+
| `tail <instance-id>` | wired — `client.listen()` over the instance, prints new history entries |
|
|
171
|
+
| `abort <instance-id>` | wired — calls `workflow.abortInstance` (hard stop: cancels pending effects, removes guards) |
|
|
172
|
+
| `set-stage <instance-id> --to <stage>` | wired — calls `workflow.setStage` (admin override: skips declared transitions/filters; enter lifecycle + cascade still run) |
|
|
173
|
+
| `fire-action <instance-id>` | wired — `workflow.availableActions` lists actions; `workflow.fireAction` fires one |
|
|
174
|
+
| `definition list` | wired — `client.fetch` over `sanity.workflow.definition` documents |
|
|
175
|
+
| `definition show <name>` | wired — `client.fetch`, latest version unless `--version` |
|
|
176
|
+
| `definition diff <name>` | wired — diffs the in-code definition against the deployed latest (`--version` to pin) |
|
|
177
|
+
| `definition delete <name>` | wired — calls `workflow.deleteDefinition` (refuses on live instances unless `--cascade`) |
|
|
178
|
+
| `nuke --deployment <name>` / `nuke --tag <tag>` | wired — dev-period reset (exists only until the versioned upgrade framework): deletes every engine-owned doc for the deployment's tag (instances, definitions, guards across resources); exactly one selector required; refuses while another same-tag deployment sweeps an overlapping resource (guard ids embed only the tag); plan + typed confirm |
|
|
166
179
|
|
|
167
180
|
## Telemetry
|
|
168
181
|
|
|
@@ -10,6 +10,7 @@ export default class Abort extends WorkflowCommand {
|
|
|
10
10
|
};
|
|
11
11
|
static flags: {
|
|
12
12
|
reason: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
deployment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
14
|
tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
15
|
};
|
|
15
16
|
run(): Promise<void>;
|
|
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
3
3
|
import { workflow } from '@sanity/workflow-engine';
|
|
4
4
|
import { WorkflowCommand } from "../../lib/base-command.js";
|
|
5
5
|
import { resolveInstanceContext } from "../../lib/context.js";
|
|
6
|
-
import {
|
|
6
|
+
import { instanceFlags } from "../../lib/flags.js";
|
|
7
7
|
import { buildOperationArgs } from "../../lib/operation-args.js";
|
|
8
8
|
import { runWriteVerb } from "../../lib/ops-report.js";
|
|
9
9
|
export default class Abort extends WorkflowCommand {
|
|
@@ -17,7 +17,7 @@ export default class Abort extends WorkflowCommand {
|
|
|
17
17
|
instanceId: Args.string({ required: true, description: 'Workflow instance id.' }),
|
|
18
18
|
};
|
|
19
19
|
static flags = {
|
|
20
|
-
...
|
|
20
|
+
...instanceFlags,
|
|
21
21
|
reason: Flags.string({ description: 'Reason for aborting (recorded in history).' }),
|
|
22
22
|
};
|
|
23
23
|
async run() {
|
|
@@ -12,6 +12,7 @@ export default class DefinitionDelete extends WorkflowCommand {
|
|
|
12
12
|
version: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
13
|
cascade: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
14
|
reason: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
deployment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
16
|
tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
17
|
};
|
|
17
18
|
run(): Promise<void>;
|
|
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
3
3
|
import { workflow, } from '@sanity/workflow-engine';
|
|
4
4
|
import { WorkflowCommand } from "../../../lib/base-command.js";
|
|
5
5
|
import { resolveContext } from "../../../lib/context.js";
|
|
6
|
-
import {
|
|
6
|
+
import { deploymentFlags } from "../../../lib/flags.js";
|
|
7
7
|
import { baseEngineArgs } from "../../../lib/operation-args.js";
|
|
8
8
|
import { runWriteVerb } from "../../../lib/ops-report.js";
|
|
9
9
|
export default class DefinitionDelete extends WorkflowCommand {
|
|
@@ -20,7 +20,7 @@ export default class DefinitionDelete extends WorkflowCommand {
|
|
|
20
20
|
name: Args.string({ required: true, description: 'Workflow definition name.' }),
|
|
21
21
|
};
|
|
22
22
|
static flags = {
|
|
23
|
-
...
|
|
23
|
+
...deploymentFlags,
|
|
24
24
|
version: Flags.integer({
|
|
25
25
|
description: 'Delete only this deployed version (default: every version).',
|
|
26
26
|
}),
|
|
@@ -9,6 +9,7 @@ export default class DefinitionDiff extends WorkflowCommand {
|
|
|
9
9
|
};
|
|
10
10
|
static flags: {
|
|
11
11
|
version: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
deployment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
14
|
};
|
|
14
15
|
run(): Promise<void>;
|
|
@@ -5,7 +5,7 @@ import { WorkflowCommand } from "../../../lib/base-command.js";
|
|
|
5
5
|
import { resolveContext } from "../../../lib/context.js";
|
|
6
6
|
import { fetchDeployedDefinition, selectDefinitions, validateOrFail, } from "../../../lib/definitions.js";
|
|
7
7
|
import { diffReport } from "../../../lib/diff.js";
|
|
8
|
-
import {
|
|
8
|
+
import { deploymentFlags } from "../../../lib/flags.js";
|
|
9
9
|
import { deploymentToTarget } from "../../../lib/select-deployment.js";
|
|
10
10
|
export default class DefinitionDiff extends WorkflowCommand {
|
|
11
11
|
static aliases = ['definition:diff'];
|
|
@@ -18,7 +18,7 @@ export default class DefinitionDiff extends WorkflowCommand {
|
|
|
18
18
|
name: Args.string({ required: true, description: 'Workflow definition name.' }),
|
|
19
19
|
};
|
|
20
20
|
static flags = {
|
|
21
|
-
...
|
|
21
|
+
...deploymentFlags,
|
|
22
22
|
version: Flags.integer({ description: 'Deployed version to diff against (default: latest).' }),
|
|
23
23
|
};
|
|
24
24
|
async run() {
|
|
@@ -15,12 +15,13 @@ export default class Deploy extends WorkflowCommand {
|
|
|
15
15
|
static description: string;
|
|
16
16
|
static examples: string[];
|
|
17
17
|
static flags: {
|
|
18
|
+
tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
19
|
'all-tags': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
19
20
|
'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
20
21
|
check: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
21
22
|
only: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
22
23
|
'share-defs': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
23
|
-
|
|
24
|
+
deployment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
24
25
|
};
|
|
25
26
|
run(): Promise<void>;
|
|
26
27
|
/** Deploy (or diff, for `--dry-run`) one deployment's definitions.
|
|
@@ -8,9 +8,9 @@ import { clientFor, resolveTokenOrFail } from "../../lib/client.js";
|
|
|
8
8
|
import { selectDefinitions, validateOrFail } from "../../lib/definitions.js";
|
|
9
9
|
import { diffReport } from "../../lib/diff.js";
|
|
10
10
|
import { fail, isAuthRejection } from "../../lib/fail.js";
|
|
11
|
-
import {
|
|
11
|
+
import { deploymentFlags } from "../../lib/flags.js";
|
|
12
12
|
import { loadWorkflowConfig } from "../../lib/load-config.js";
|
|
13
|
-
import { deploymentToTarget, selectDeployments } from "../../lib/select-deployment.js";
|
|
13
|
+
import { deploymentLabel, deploymentToTarget, selectDeployments, } from "../../lib/select-deployment.js";
|
|
14
14
|
import { shareDefinitionsAfterDeploy } from "../../lib/share-definitions.js";
|
|
15
15
|
import { cliTelemetry } from "../../lib/telemetry.js";
|
|
16
16
|
import { groupBanner } from "../../lib/ui.js";
|
|
@@ -18,6 +18,7 @@ export default class Deploy extends WorkflowCommand {
|
|
|
18
18
|
static aliases = ['deploy'];
|
|
19
19
|
static description = 'Validate, diff, and deploy workflow definitions to the resource bound by the selected deployment.';
|
|
20
20
|
static examples = [
|
|
21
|
+
'<%= config.bin %> deploy --deployment review-prod',
|
|
21
22
|
'<%= config.bin %> deploy --tag prod',
|
|
22
23
|
'<%= config.bin %> deploy --all-tags',
|
|
23
24
|
'<%= config.bin %> deploy --check',
|
|
@@ -25,11 +26,15 @@ export default class Deploy extends WorkflowCommand {
|
|
|
25
26
|
'<%= config.bin %> deploy --only productLaunch',
|
|
26
27
|
];
|
|
27
28
|
static flags = {
|
|
28
|
-
...
|
|
29
|
+
...deploymentFlags,
|
|
30
|
+
tag: Flags.string({
|
|
31
|
+
description: 'Workflow environment tag (e.g. prod, test) — deploys every deployment carrying the tag (a tag is an environment group).',
|
|
32
|
+
exclusive: ['deployment'],
|
|
33
|
+
}),
|
|
29
34
|
'all-tags': Flags.boolean({
|
|
30
|
-
description: 'Deploy every deployment in the config, not just
|
|
35
|
+
description: 'Deploy every deployment in the config, not just a selection.',
|
|
31
36
|
default: false,
|
|
32
|
-
exclusive: ['tag'],
|
|
37
|
+
exclusive: ['tag', 'deployment'],
|
|
33
38
|
}),
|
|
34
39
|
'dry-run': Flags.boolean({
|
|
35
40
|
description: 'Validate + diff against the deployed version; do not write.',
|
|
@@ -51,7 +56,11 @@ export default class Deploy extends WorkflowCommand {
|
|
|
51
56
|
const { flags } = await this.parse(Deploy);
|
|
52
57
|
validateModeFlags(flags.check, flags['dry-run']);
|
|
53
58
|
const config = await loadWorkflowConfig();
|
|
54
|
-
const batches = buildBatches(await selectDeployments(config, {
|
|
59
|
+
const batches = buildBatches(await selectDeployments(config, {
|
|
60
|
+
name: flags.deployment,
|
|
61
|
+
tag: flags.tag,
|
|
62
|
+
allTags: flags['all-tags'],
|
|
63
|
+
}), flags.only);
|
|
55
64
|
const log = (line) => this.log(line);
|
|
56
65
|
if (flags.check) {
|
|
57
66
|
await reconcileBatches({
|
|
@@ -145,9 +154,6 @@ export function validateModeFlags(check, dryRun) {
|
|
|
145
154
|
fail('Pass either --check or --dry-run, not both.');
|
|
146
155
|
}
|
|
147
156
|
}
|
|
148
|
-
function deploymentLabel({ name, tag }) {
|
|
149
|
-
return `${name} (${tag})`;
|
|
150
|
-
}
|
|
151
157
|
export function buildBatches(deployments, only) {
|
|
152
158
|
return deployments.map((deployment) => {
|
|
153
159
|
const context = deployments.length > 1 ? `${deploymentLabel(deployment)} — ` : '';
|
|
@@ -40,6 +40,7 @@ export default class Diagnose extends WorkflowCommand {
|
|
|
40
40
|
};
|
|
41
41
|
static flags: {
|
|
42
42
|
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
43
|
+
deployment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
43
44
|
tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
44
45
|
};
|
|
45
46
|
run(): Promise<void>;
|
|
@@ -5,7 +5,7 @@ import logSymbols from 'log-symbols';
|
|
|
5
5
|
import { WorkflowCommand } from "../../lib/base-command.js";
|
|
6
6
|
import { resolveInstanceContext } from "../../lib/context.js";
|
|
7
7
|
import { fail, failureDetail } from "../../lib/fail.js";
|
|
8
|
-
import {
|
|
8
|
+
import { instanceFlags, jsonFlags } from "../../lib/flags.js";
|
|
9
9
|
import { baseEngineArgs } from "../../lib/operation-args.js";
|
|
10
10
|
import { formatTimestamp, sectionHeader, activityIcon } from "../../lib/ui.js";
|
|
11
11
|
import { instanceHeader } from "./show.js";
|
|
@@ -223,7 +223,7 @@ export default class Diagnose extends WorkflowCommand {
|
|
|
223
223
|
instanceId: Args.string({ required: true, description: 'Workflow instance id.' }),
|
|
224
224
|
};
|
|
225
225
|
static flags = {
|
|
226
|
-
...
|
|
226
|
+
...instanceFlags,
|
|
227
227
|
...jsonFlags,
|
|
228
228
|
};
|
|
229
229
|
async run() {
|
|
@@ -41,6 +41,7 @@ export default class FireAction extends WorkflowCommand {
|
|
|
41
41
|
activity: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
42
42
|
action: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
43
43
|
param: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
|
|
44
|
+
deployment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
44
45
|
tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
45
46
|
};
|
|
46
47
|
run(): Promise<void>;
|
|
@@ -5,7 +5,7 @@ import logSymbols from 'log-symbols';
|
|
|
5
5
|
import { WorkflowCommand } from "../../lib/base-command.js";
|
|
6
6
|
import { resolveInstanceContext } from "../../lib/context.js";
|
|
7
7
|
import { fail, failOnThrow, failureDetail } from "../../lib/fail.js";
|
|
8
|
-
import {
|
|
8
|
+
import { instanceFlags, jsonFlags } from "../../lib/flags.js";
|
|
9
9
|
import { baseEngineArgs } from "../../lib/operation-args.js";
|
|
10
10
|
import { cascadeTail, opsAppliedLines, runWriteVerb, } from "../../lib/ops-report.js";
|
|
11
11
|
import { parseParams } from "../../lib/params.js";
|
|
@@ -93,7 +93,7 @@ export default class FireAction extends WorkflowCommand {
|
|
|
93
93
|
instanceId: Args.string({ required: true, description: 'Workflow instance id.' }),
|
|
94
94
|
};
|
|
95
95
|
static flags = {
|
|
96
|
-
...
|
|
96
|
+
...instanceFlags,
|
|
97
97
|
activity: Flags.string({
|
|
98
98
|
description: 'Activity the action belongs to. Required to fire; omit --action to list.',
|
|
99
99
|
}),
|
|
@@ -5,7 +5,8 @@ export default class Nuke extends WorkflowCommand {
|
|
|
5
5
|
static description: string;
|
|
6
6
|
static examples: string[];
|
|
7
7
|
static flags: {
|
|
8
|
-
|
|
8
|
+
deployment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
10
|
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
11
|
};
|
|
11
12
|
run(): Promise<void>;
|
|
@@ -7,7 +7,7 @@ import { clientFor, resolveApiHost, resolveTokenOrFail } from "../../lib/client.
|
|
|
7
7
|
import { dedupeResources } from "../../lib/context.js";
|
|
8
8
|
import { fail } from "../../lib/fail.js";
|
|
9
9
|
import { loadWorkflowConfig } from "../../lib/load-config.js";
|
|
10
|
-
import { confirmationMatches, executeNuke, formatNukeSummary, involvedTargets, planCounts, renderNukePlan, resolveNukePlan, } from "../../lib/nuke.js";
|
|
10
|
+
import { confirmationMatches, executeNuke, formatNukeSummary, involvedTargets, planCounts, refuseOverlappingNuke, renderNukePlan, resolveNukePlan, sweptResources, } from "../../lib/nuke.js";
|
|
11
11
|
import { runWriteVerb } from "../../lib/ops-report.js";
|
|
12
12
|
import { canPromptOnStderr } from "../../lib/prompt.js";
|
|
13
13
|
import { selectDeployment } from "../../lib/select-deployment.js";
|
|
@@ -19,13 +19,17 @@ export default class Nuke extends WorkflowCommand {
|
|
|
19
19
|
'resource). Content documents are never touched. Prints a dry-run plan, then requires you to ' +
|
|
20
20
|
'type back every involved dataset (--force skips the prompt; the plan still prints).';
|
|
21
21
|
static examples = [
|
|
22
|
-
'<%= config.bin %> nuke --
|
|
22
|
+
'<%= config.bin %> nuke --deployment plugin-dev',
|
|
23
23
|
'<%= config.bin %> nuke --tag plugin-dev --force',
|
|
24
24
|
];
|
|
25
25
|
static flags = {
|
|
26
|
+
deployment: Flags.string({
|
|
27
|
+
description: 'The deployment name to reset.',
|
|
28
|
+
exactlyOne: ['deployment', 'tag'],
|
|
29
|
+
}),
|
|
26
30
|
tag: Flags.string({
|
|
27
|
-
description: 'The deployment tag to reset
|
|
28
|
-
|
|
31
|
+
description: 'The deployment tag to reset (while it names exactly one deployment).',
|
|
32
|
+
exactlyOne: ['deployment', 'tag'],
|
|
29
33
|
}),
|
|
30
34
|
force: Flags.boolean({
|
|
31
35
|
description: 'Skip the confirmation prompt (for scripts/CI). The plan still prints.',
|
|
@@ -35,7 +39,8 @@ export default class Nuke extends WorkflowCommand {
|
|
|
35
39
|
async run() {
|
|
36
40
|
const { flags } = await this.parse(Nuke);
|
|
37
41
|
const config = await loadWorkflowConfig();
|
|
38
|
-
const deployment = selectDeployment(config, { tag: flags.tag });
|
|
42
|
+
const deployment = await selectDeployment(config, { name: flags.deployment, tag: flags.tag });
|
|
43
|
+
refuseOverlappingNuke(config.deployments, deployment);
|
|
39
44
|
const targets = buildTargets(deployment, await resolveTokenOrFail());
|
|
40
45
|
const plan = await resolveNukePlan({ tag: deployment.tag, targets });
|
|
41
46
|
const apiHost = resolveApiHost() ?? 'https://api.sanity.io (production default)';
|
|
@@ -58,12 +63,11 @@ export default class Nuke extends WorkflowCommand {
|
|
|
58
63
|
}
|
|
59
64
|
}
|
|
60
65
|
function buildTargets(deployment, token) {
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
return dedupeResources([engineResource, ...aliasResources]).map((resource) => ({
|
|
66
|
+
const engineGdr = resourceGdr(deployment.workflowResource);
|
|
67
|
+
return dedupeResources(sweptResources(deployment)).map((resource) => ({
|
|
64
68
|
resource,
|
|
65
69
|
client: clientFor(resource, token),
|
|
66
|
-
holdsEngineDocs: resourceGdr(resource) ===
|
|
70
|
+
holdsEngineDocs: resourceGdr(resource) === engineGdr,
|
|
67
71
|
}));
|
|
68
72
|
}
|
|
69
73
|
async function confirmOrFail(targets) {
|
|
@@ -12,6 +12,7 @@ export default class SetStage extends WorkflowCommand {
|
|
|
12
12
|
static flags: {
|
|
13
13
|
to: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
14
|
reason: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
deployment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
16
|
tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
17
|
};
|
|
17
18
|
run(): Promise<void>;
|
|
@@ -3,7 +3,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
3
3
|
import { workflow } from '@sanity/workflow-engine';
|
|
4
4
|
import { WorkflowCommand } from "../../lib/base-command.js";
|
|
5
5
|
import { resolveInstanceContext } from "../../lib/context.js";
|
|
6
|
-
import {
|
|
6
|
+
import { instanceFlags } from "../../lib/flags.js";
|
|
7
7
|
import { buildOperationArgs } from "../../lib/operation-args.js";
|
|
8
8
|
import { cascadeTail, opsAppliedLines, runWriteVerb, } from "../../lib/ops-report.js";
|
|
9
9
|
export default class SetStage extends WorkflowCommand {
|
|
@@ -20,7 +20,7 @@ export default class SetStage extends WorkflowCommand {
|
|
|
20
20
|
}),
|
|
21
21
|
};
|
|
22
22
|
static flags = {
|
|
23
|
-
...
|
|
23
|
+
...instanceFlags,
|
|
24
24
|
to: Flags.string({
|
|
25
25
|
required: true,
|
|
26
26
|
description: 'Target stage name.',
|
|
@@ -13,6 +13,7 @@ export default class Start extends WorkflowCommand {
|
|
|
13
13
|
version: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
14
|
field: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
|
|
15
15
|
'instance-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
deployment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
17
|
tag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
18
|
};
|
|
18
19
|
run(): Promise<void>;
|
|
@@ -5,7 +5,7 @@ import { WorkflowCommand } from "../../lib/base-command.js";
|
|
|
5
5
|
import { resolveContext } from "../../lib/context.js";
|
|
6
6
|
import { fetchDeployedDefinition } from "../../lib/definitions.js";
|
|
7
7
|
import { fail, failOnThrow, failureDetail } from "../../lib/fail.js";
|
|
8
|
-
import {
|
|
8
|
+
import { deploymentFlags, jsonFlags } from "../../lib/flags.js";
|
|
9
9
|
import { baseEngineArgs } from "../../lib/operation-args.js";
|
|
10
10
|
import { runWriteVerb } from "../../lib/ops-report.js";
|
|
11
11
|
import { parseParams } from "../../lib/params.js";
|
|
@@ -23,7 +23,7 @@ export default class Start extends WorkflowCommand {
|
|
|
23
23
|
name: Args.string({ required: true, description: 'Workflow definition name.' }),
|
|
24
24
|
};
|
|
25
25
|
static flags = {
|
|
26
|
-
...
|
|
26
|
+
...deploymentFlags,
|
|
27
27
|
version: Flags.integer({
|
|
28
28
|
description: 'Definition version to start from (default: highest deployed).',
|
|
29
29
|
}),
|
package/dist/lib/context.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SanityClient } from '@sanity/client';
|
|
2
2
|
import { type WorkflowConfig, type WorkflowDeployment, type WorkflowInstance, type WorkflowResource } from '@sanity/workflow-engine';
|
|
3
3
|
import type { EngineScope } from './operation-args.ts';
|
|
4
|
+
import { type ChooseDeploymentName } from './select-deployment.ts';
|
|
4
5
|
export interface DeploymentContext {
|
|
5
6
|
deployment: WorkflowDeployment;
|
|
6
7
|
client: SanityClient;
|
|
@@ -13,11 +14,12 @@ export interface InstanceContext {
|
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
16
|
* The resolution a WRITE shares: discover the config, pick the deployment for
|
|
16
|
-
* `--tag` (or the sole one), and build an authenticated
|
|
17
|
-
* deployment's resource. A write acts on one specific
|
|
18
|
-
* single, definite target is exactly what it needs.
|
|
17
|
+
* `--deployment` or `--tag` (or the sole one), and build an authenticated
|
|
18
|
+
* client for that deployment's resource. A write acts on one specific
|
|
19
|
+
* deployment, so a single, definite target is exactly what it needs.
|
|
19
20
|
*/
|
|
20
21
|
export declare function resolveContext(flags: {
|
|
22
|
+
deployment?: string | undefined;
|
|
21
23
|
tag?: string | undefined;
|
|
22
24
|
}): Promise<DeploymentContext>;
|
|
23
25
|
/** One resource a read inspects, with its authenticated client. */
|
|
@@ -34,8 +36,9 @@ export interface ReadTarget {
|
|
|
34
36
|
*
|
|
35
37
|
* Untagged, this is every distinct resource the config mentions — a read is
|
|
36
38
|
* harmless to fan out, so "show me what's deployed" spans the whole config.
|
|
37
|
-
* `--tag` narrows to
|
|
38
|
-
* the run, however many
|
|
39
|
+
* `--tag` narrows to the resources deployed under that tag (tags may repeat
|
|
40
|
+
* across deployments). The token resolves once for the run, however many
|
|
41
|
+
* targets it spans.
|
|
39
42
|
*/
|
|
40
43
|
export declare function resolveReadTargets(flags: {
|
|
41
44
|
tag?: string | undefined;
|
|
@@ -44,14 +47,15 @@ export declare function resolveReadTargets(flags: {
|
|
|
44
47
|
* The first occurrence wins its position, so a caller-ordered list (e.g. the
|
|
45
48
|
* engine resource first) keeps its lead entry. */
|
|
46
49
|
export declare function dedupeResources(resources: WorkflowResource[]): WorkflowResource[];
|
|
47
|
-
/** The distinct resources a read targets:
|
|
48
|
-
*
|
|
49
|
-
* mention ({@link dedupeResources}). */
|
|
50
|
+
/** The distinct resources a read targets: every resource deployed under the
|
|
51
|
+
* tag (tags may repeat across deployments), or — untagged — every distinct
|
|
52
|
+
* one the config's deployments mention ({@link dedupeResources}). */
|
|
50
53
|
export declare function resolveReadResources(config: WorkflowConfig, tag: string | undefined): WorkflowResource[];
|
|
51
|
-
/** The single resource
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* {@link
|
|
54
|
+
/** The single resource an instance-keyed command reads from when it isn't
|
|
55
|
+
* disambiguated interactively: the sole resource, the `--tag`-narrowed one, or
|
|
56
|
+
* a `fail` asking for `--deployment`/`--tag` when the config spans several. The
|
|
57
|
+
* interactive picker lives in {@link resolveInstanceResource}; listings fan out
|
|
58
|
+
* via {@link resolveReadResources} instead. */
|
|
55
59
|
export declare function resolveReadResource(config: WorkflowConfig, tag: string | undefined): WorkflowResource;
|
|
56
60
|
/**
|
|
57
61
|
* The resolution an instance-id-targeted command shares, read or write: an
|
|
@@ -60,15 +64,34 @@ export declare function resolveReadResource(config: WorkflowConfig, tag: string
|
|
|
60
64
|
* config's declared deployments. An instance id is globally unique and carries
|
|
61
65
|
* its own `tag`, so a command that names one acts on that instance regardless
|
|
62
66
|
* of which tags the config happens to deploy; the config only locates the
|
|
63
|
-
* resource (via {@link
|
|
67
|
+
* resource (via {@link resolveInstanceResource}, no tag filter).
|
|
64
68
|
*
|
|
65
69
|
* Contrast {@link resolveContext}: the deploy/diff/delete path IS scoped to a
|
|
66
70
|
* declared deployment because it acts on the authored definition set (or a
|
|
67
71
|
* definition name, which — unlike an instance id — isn't unique across tags).
|
|
68
72
|
*/
|
|
69
73
|
export declare function resolveInstanceContext(flags: {
|
|
74
|
+
deployment?: string | undefined;
|
|
70
75
|
tag?: string | undefined;
|
|
71
76
|
}, instanceId: string): Promise<InstanceContext>;
|
|
77
|
+
/**
|
|
78
|
+
* Which resource an instance-keyed command reads from: the one `--deployment`
|
|
79
|
+
* names (resolved by its unique deployment name); otherwise, when the config
|
|
80
|
+
* spans several resources, an interactive terminal is prompted to pick a
|
|
81
|
+
* deployment ({@link canPromptOnStderr}) — its resource is the read source, the
|
|
82
|
+
* interactive counterpart to `--deployment`. A run that can't prompt falls to
|
|
83
|
+
* the sole or `--tag`-narrowed resource, or the ambiguity error
|
|
84
|
+
* ({@link resolveReadResource}). The instance id is globally unique, so this
|
|
85
|
+
* only locates the resource to look in — never the instance's `tag` partition,
|
|
86
|
+
* which the caller takes from the loaded instance. The shared path behind all
|
|
87
|
+
* four instance-keyed commands.
|
|
88
|
+
*/
|
|
89
|
+
export declare function resolveInstanceResource(config: WorkflowConfig, { deployment, tag, interactive, chooseDeployment, }: {
|
|
90
|
+
deployment?: string | undefined;
|
|
91
|
+
tag?: string | undefined;
|
|
92
|
+
interactive?: boolean | undefined;
|
|
93
|
+
chooseDeployment?: ChooseDeploymentName | undefined;
|
|
94
|
+
}): Promise<WorkflowResource>;
|
|
72
95
|
/** Fetch an instance by id, exiting cleanly when the resource has no such
|
|
73
96
|
* document — the diagnostic an operator sees on a mistyped id. Split out from
|
|
74
97
|
* {@link resolveInstanceContext} so the not-found path is unit-testable
|