@dynamicweb/cli 1.1.1 → 2.0.0-beta.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/README.md CHANGED
@@ -1,256 +1,477 @@
1
1
  # DynamicWeb CLI
2
2
 
3
- ## What is it?
4
- DynamicWeb CLI is a powerful command line tool designed to help developers quickly and efficiently manage any given DynamicWeb 10 solution they may have access to. These tools include an easy setup and handling of different environments, access to the Management API and an easy way to update a Swift solution.
3
+ DynamicWeb CLI is the command-line interface for working with DynamicWeb 10 solutions. It helps you manage environments, authenticate against the admin API, run queries and commands, move files in and out of a solution, install add-ins, export databases, and pull Swift solutions.
5
4
 
6
- Logging into a DynamicWeb 10 solution through the DynamicWeb CLI will create an API Key for the given user, which in turn lets you use any Queries and Commands the solution had, meaning you can control everything you can do in the backend, from your command line.
7
- With this, you can hook it up to your own build pipelines and processes, if certain requests needs to happen before or after deployments or changes.
5
+ This branch now targets `2.0.0-beta.0`.
8
6
 
9
- The DynamicWeb CLI can also help with active development of custom addins to solutions. With a simple `dw install` command it will upload and install your custom code to a solution.
7
+ ## Requirements
10
8
 
11
- Extracting files from solutions is just as easy as well, with the DynamicWeb CLI you can list out the structure of a solution and get full exports of the files structure and the database. Importing files into a solution is just as easy as well, as long as you have access to the files and the solution, they can be imported with a simple command using the DynamicWeb CLI.
9
+ - Node.js `>=20.12.0`
12
10
 
13
- ## Get started
14
- ### Install from npm
15
- Install the published CLI globally:
16
- > $ npm install -g @dynamicweb/cli
11
+ ## Install
17
12
 
18
- Then verify the command is available:
19
- > $ dw --help
13
+ Install from npm:
20
14
 
21
- ### Install from source
22
- If you're working on the CLI locally, clone the repository, move into the project directory, and run:
23
- > $ npm install
24
- >
25
- > $ npm install -g .
15
+ ```sh
16
+ npm install -g @dynamicweb/cli
17
+ dw --help
18
+ ```
26
19
 
27
- This installs dependencies for development and links the current checkout as the global `dw` command.
20
+ Install from source:
28
21
 
29
- ### Publish a new version
30
- Before publishing, make sure the version in `package.json` has been bumped:
31
- > $ npm version patch
22
+ ```sh
23
+ npm install
24
+ npm install -g .
25
+ ```
32
26
 
33
- Log in to npm and publish the scoped package publicly:
34
- > $ npm login
35
- >
36
- > $ npm publish --access public
27
+ ## What Changed
37
28
 
38
- ## Commands
39
- All commands and options can be viewed by running
40
- > $ dw --help
41
- >
42
- > $ dw \<command\> --help
29
+ The `2.0` beta is a substantial overhaul focused on automation and modern authentication.
30
+
31
+ - Automation-first command output: `env`, `login`, `files`, `query`, `command`, and `install` now support `--output json` so scripts and pipelines can consume structured results instead of plain console logs.
32
+ - OAuth client credentials support: the CLI can now authenticate with OAuth 2.0 `client_credentials`, which makes headless and CI/CD usage much easier.
33
+ - Better environment handling: protocol, host, and auth details are stored more cleanly in `~/.dwc`, while one-off runs can still override host and credentials directly.
34
+ - Improved file workflows: file import, export, recursive sync, raw archive export, progress reporting, and source-type override flags make file operations more predictable.
35
+ - Clearer error reporting: commands can now return structured failures in JSON mode, which is much easier to handle in automation.
36
+
37
+ ## Quick Start
38
+
39
+ View all available commands:
43
40
 
44
- ### Global options
45
- Most commands support the following global options:
46
- - `-v` `--verbose` Run with verbose logging
47
- - `--host` Set the host directly, bypassing environment config (requires `--apiKey`)
48
- - `--apiKey` Set the API key for an environmentless execution
49
- - `--protocol` Set the protocol used (only with `--host`, defaults to `https`)
41
+ ```sh
42
+ dw --help
43
+ dw <command> --help
44
+ ```
45
+
46
+ Set up an environment and log in with a user:
47
+
48
+ ```sh
49
+ dw env dev
50
+ dw login
51
+ dw # shows current environment, user, protocol, and host
52
+ ```
53
+
54
+ Run a query:
50
55
 
51
- ### Users and environments
52
- As most commands are pulling or pushing data from the DW admin API, the necessary authorization is required.
56
+ ```sh
57
+ dw query HealthCheck
58
+ ```
53
59
 
54
- To generate an Api-key that the CLI will use, login to your environment
55
- > $ dw login
60
+ ## Authentication
56
61
 
57
- This will start an interactive session asking for username and password, as well as the name of the environment, so it's possible to switch between different environments easily.
58
- It will also ask for a host, if you're running a local environment, set this to the host it starts up with, i.e `localhost:6001`.
62
+ ### Interactive User Login
59
63
 
60
- Each environment has its own users, and each user has its own Api-key assigned to it, swap between environments by using
61
- > $ dw env \<env\>
64
+ The default login flow uses a DynamicWeb user account. The CLI logs in, creates an API key, and stores it in `~/.dwc`.
62
65
 
63
- and swap between users by simply supplying the name of the user in the login command
64
- > $ dw login \<username\>
66
+ ```sh
67
+ dw login
68
+ dw login <saved-user>
69
+ dw env <environment>
70
+ ```
65
71
 
66
- You can view the current environment and user being used by simply typing
67
- > $ dw
72
+ A user-authenticated config typically looks like this:
68
73
 
69
- The configuration will automatically be created when setting up your first environment, but if you already have an Api-key you want to use for a user, you can modify the config directly in the file located in `~/.dwc`. The structure should look like the following
70
74
  ```json
71
75
  {
72
- "env": {
73
- "dev": {
74
- "host": "localhost:6001",
75
- "users": {
76
- "DemoUser": {
77
- "apiKey": "<keyPrefix>.<key>"
78
- }
79
- },
80
- "current": {
81
- "user": "DemoUser"
82
- }
76
+ "env": {
77
+ "dev": {
78
+ "host": "localhost:6001",
79
+ "protocol": "https",
80
+ "users": {
81
+ "DemoUser": {
82
+ "apiKey": "<keyPrefix>.<key>"
83
83
  }
84
- },
85
- "current": {
86
- "env": "dev"
84
+ },
85
+ "current": {
86
+ "user": "DemoUser",
87
+ "authType": "user"
88
+ }
87
89
  }
90
+ },
91
+ "current": {
92
+ "env": "dev"
93
+ }
88
94
  }
89
95
  ```
90
96
 
91
- ### Files
92
- > $ dw files \<dirPath\> \<outPath\>
97
+ ### OAuth Client Credentials
98
+
99
+ For service accounts, automation, and headless usage, the CLI also supports OAuth 2.0 `client_credentials`.
100
+
101
+ Configure an environment for OAuth:
102
+
103
+ ```sh
104
+ export DW_CLIENT_ID=my-client-id
105
+ export DW_CLIENT_SECRET=my-client-secret
106
+
107
+ dw login --oauth
108
+ ```
109
+
110
+ Run a one-off command with OAuth flags instead of saved config:
111
+
112
+ ```sh
113
+ dw query HealthCheck \
114
+ --host your-solution.example.com \
115
+ --auth oauth \
116
+ --clientIdEnv DW_CLIENT_ID \
117
+ --clientSecretEnv DW_CLIENT_SECRET \
118
+ --output json
119
+ ```
120
+
121
+ An OAuth-enabled environment in `~/.dwc` looks like this:
122
+
123
+ ```json
124
+ {
125
+ "env": {
126
+ "dev": {
127
+ "host": "localhost:6001",
128
+ "protocol": "https",
129
+ "auth": {
130
+ "type": "oauth_client_credentials",
131
+ "clientIdEnv": "DW_CLIENT_ID",
132
+ "clientSecretEnv": "DW_CLIENT_SECRET"
133
+ },
134
+ "current": {
135
+ "authType": "oauth_client_credentials"
136
+ }
137
+ }
138
+ },
139
+ "current": {
140
+ "env": "dev"
141
+ }
142
+ }
143
+ ```
144
+
145
+ ## Global Options
146
+
147
+ Most API-driven commands support these global options:
148
+
149
+ - `-v`, `--verbose`: enable verbose logging
150
+ - `--host`: use a host directly instead of the saved environment
151
+ - `--protocol`: set the protocol used with `--host` and default to `https`
152
+ - `--apiKey`: use an API key for environmentless execution
153
+ - `--auth`: override authentication mode with `user` or `oauth`
154
+ - `--clientId`: pass an OAuth client ID directly
155
+ - `--clientSecret`: pass an OAuth client secret directly
156
+ - `--clientIdEnv`: read the OAuth client ID from an environment variable
157
+ - `--clientSecretEnv`: read the OAuth client secret from an environment variable
158
+
159
+ ## JSON Output for Automation
160
+
161
+ Commands that support `--output json` return a machine-readable envelope with `ok`, `status`, `data`, `errors`, and `meta` fields.
162
+
163
+ Examples:
164
+
165
+ ```sh
166
+ dw env --list --output json
167
+ dw login --output json
168
+ dw query FileByName --name DefaultMail.html --output json
169
+ ```
170
+
171
+ Representative output:
172
+
173
+ ```json
174
+ {
175
+ "ok": true,
176
+ "command": "env",
177
+ "operation": "list",
178
+ "status": 200,
179
+ "data": [
180
+ {
181
+ "environments": ["dev", "staging"]
182
+ }
183
+ ],
184
+ "errors": [],
185
+ "meta": {}
186
+ }
187
+ ```
188
+
189
+ ## Commands
190
+
191
+ ### `dw env [env]`
192
+
193
+ Create, select, or inspect saved environments.
194
+
195
+ ```sh
196
+ dw env dev
197
+ dw env --list
198
+ dw env --users
199
+ dw env --list --output json
200
+ ```
201
+
202
+ Example JSON output:
93
203
 
94
- The files command is used to list out and export the structure in your Dynamicweb files archive, as such is has multiple options;
95
- - `-l` `--list` This will list the directory given in \<dirPath\>
96
- - `-f` `--includeFiles` The list will now also show all files in the directories
97
- - `-r` `--recursive` By default it only handles the \<dirPath\>, but with this option it will handle all directories under this recursively
98
- - `-e` `--export` It will export \<dirPath\> into \<outPath\> on your local machine, unzipped by default
99
- - `--raw` This will keep the content zipped
100
- - `--iamstupid` This will include the export of the /files/system/log and /files/.cache folders
101
- - `--json` This will output a single JSON object for automation-friendly parsing
204
+ ```json
205
+ {
206
+ "ok": true,
207
+ "command": "env",
208
+ "operation": "select",
209
+ "status": 200,
210
+ "data": [
211
+ {
212
+ "environment": "dev",
213
+ "current": "dev"
214
+ }
215
+ ],
216
+ "errors": [],
217
+ "meta": {}
218
+ }
219
+ ```
102
220
 
103
- #### Examples
104
- Exporting all templates from current environment to local solution
105
- > $ cd DynamicWebSolution/Files
106
- >
107
- > $ dw files templates ./templates -fre
221
+ ### `dw login [user]`
108
222
 
109
- Listing the system files structure of the current environment
110
- > $ dw files system -lr
223
+ Log in interactively, configure OAuth, or switch between saved users for the current environment.
111
224
 
112
- Uploading files with JSON output for automation
113
- > $ dw files ./Files templates -i -r --json
225
+ ```sh
226
+ dw login
227
+ dw login DemoUser
228
+ dw login --oauth
229
+ dw login --output json
230
+ ```
114
231
 
115
- ### Files Source Type Detection
116
- By default, the `dw files` command automatically detects the source type based on the \<dirPath\>:
117
- If the path contains a file extension (e.g., 'templates/Translations.xml'), it is treated as a file.
118
- Otherwise, it is treated as a directory.
119
- In cases where this detection is incorrect, you can force the type using these flags:
232
+ Example JSON output:
120
233
 
121
- - `-ad` `--asDirectory` Forces the command to treat the path as a directory, even if its name contains a dot.
122
- - `-af` `--asFile` Forces the command to treat the path as a single file, even if it has no extension.
234
+ ```json
235
+ {
236
+ "ok": true,
237
+ "command": "login",
238
+ "operation": "oauth-login",
239
+ "status": 200,
240
+ "data": [
241
+ {
242
+ "environment": "dev",
243
+ "authType": "oauth_client_credentials",
244
+ "clientIdEnv": "DW_CLIENT_ID",
245
+ "clientSecretEnv": "DW_CLIENT_SECRET",
246
+ "expires": "2026-04-13T14:22:31Z"
247
+ }
248
+ ],
249
+ "errors": [],
250
+ "meta": {}
251
+ }
252
+ ```
123
253
 
124
- #### Examples
254
+ ### `dw files [dirPath] [outPath]`
125
255
 
126
- Exporting single file from current environment to local solution
127
- > $ dw files templates/Translations.xml ./templates -e
256
+ List, export, and import files from the DynamicWeb file archive.
128
257
 
129
- Exporting a directory that looks like a file
130
- > $ dw files templates/templates.v1 ./templates -e -ad
258
+ Useful flags:
131
259
 
132
- Exporting a file that has no extension
133
- > $ dw files templates/testfile ./templates -e -af
260
+ - `-l`, `--list`: list directories
261
+ - `-f`, `--includeFiles`: include files in listings
262
+ - `-e`, `--export`: export from the environment to disk
263
+ - `-i`, `--import`: import from disk to the environment
264
+ - `-r`, `--recursive`: recurse through subdirectories
265
+ - `--raw`: keep downloaded archives zipped
266
+ - `--dangerouslyIncludeLogsAndCache`: include log and cache folders during export, which is risky and usually not recommended
267
+ - `-af`, `--asFile`: force the source path to be treated as a file
268
+ - `-ad`, `--asDirectory`: force the source path to be treated as a directory
134
269
 
135
- ### Swift
136
- > $ dw swift \<outPath\>
270
+ Examples:
137
271
 
138
- The swift command is used to easily get your local environment up to date with the latest swift release. It will override all existing directories and content in those, which can then be adjusted in your source control afterwards. It has multiple options to specify which tag or branch to pull;
139
- - `-t` `--tag <tag>` The tag/branch/release to pull
140
- - `-l` `--list` Will list all the release versions
141
- - `-n` `--nightly` Will pull #HEAD, as default is latest release
142
- - `--force` Used if \<outPath\> is not an empty folder, to override all the content
272
+ ```sh
273
+ dw files templates ./templates -fre
274
+ dw files system -lr
275
+ dw files templates/Translations.xml ./templates -e
276
+ dw files templates/templates.v1 ./templates -e -ad
277
+ dw files ./Files templates -i -r --output json
278
+ ```
143
279
 
144
- #### Examples
145
- Getting all the available releases
146
- > $ dw swift -l
280
+ Example JSON output:
147
281
 
148
- Pulling and overriding local solution with latest nightly build
149
- > $ cd DynamicWebSolution/Swift
150
- >
151
- > $ dw swift . -n --force
282
+ ```json
283
+ {
284
+ "ok": true,
285
+ "command": "files",
286
+ "operation": "import",
287
+ "status": 200,
288
+ "data": [
289
+ {
290
+ "type": "upload",
291
+ "destinationPath": "templates",
292
+ "files": [
293
+ "/workspace/Files/Templates/DefaultMail.html"
294
+ ],
295
+ "response": {
296
+ "message": "Upload completed"
297
+ }
298
+ }
299
+ ],
300
+ "errors": [],
301
+ "meta": {
302
+ "filesProcessed": 1,
303
+ "chunks": 1
304
+ }
305
+ }
306
+ ```
152
307
 
153
- ### Query
154
- > $ dw query \<query\>
308
+ ### `dw query [query]`
155
309
 
156
- The query command will fire any query towards the admin Api with the given query parameters. This means any query parameter that's necessary for the given query, is required as an option in this command. It's also possible to list which parameters is necessary for the given query through the options;
157
- - `-l` `--list` Will list all the properties for the given \<query\>
158
- - `-i` `--interactive` Will perform the \<query\> but without any parameters, as they will be asked for one by one in interactive mode
159
- - `--output json` Will output a single JSON object for automation-friendly parsing
160
- - `--<queryParam>` Any parameter the query needs will be sent by '--key value'
310
+ Run admin API queries, inspect available parameters, or prompt for them interactively.
161
311
 
162
- #### Examples
163
- Getting all properties for a query
164
- > $ dw query FileByName -l
312
+ ```sh
313
+ dw query FileByName -l
314
+ dw query FileByName --name DefaultMail.html --directorypath /Templates/Forms/Mail
315
+ dw query FileByName --interactive
316
+ dw query FileByName --name DefaultMail.html --output json
317
+ ```
165
318
 
166
- Getting file information on a specific file by name
167
- > $ dw query FileByName --name DefaultMail.html --directorypath /Templates/Forms/Mail
319
+ Example JSON output:
168
320
 
169
- Running a query with JSON output
170
- > $ dw query FileByName --name DefaultMail.html --output json
321
+ ```json
322
+ {
323
+ "ok": true,
324
+ "command": "query",
325
+ "operation": "run",
326
+ "status": 200,
327
+ "data": [
328
+ {
329
+ "name": "DefaultMail.html",
330
+ "path": "/Templates/Forms/Mail/DefaultMail.html"
331
+ }
332
+ ],
333
+ "errors": [],
334
+ "meta": {
335
+ "query": "FileByName"
336
+ }
337
+ }
338
+ ```
171
339
 
172
- ### Command
173
- > $ dw command \<command\>
340
+ ### `dw command [command]`
174
341
 
175
- Using command will, like query, fire any given command in the solution. It works like query, given the query parameters necessary, however if a `DataModel` is required for the command, it is given in a json-format, either through a path to a .json file or a literal json-string in the command.
176
- - `-l` `--list` Lists all the properties for the command, as well as the json model required
177
- - `--json` Takes a path to a .json file or a literal json, i.e --json '{ abc: "123" }'
178
- - `--output json` Outputs a single JSON object for automation-friendly parsing
342
+ Run admin API commands and pass a JSON payload either inline or by file path.
179
343
 
180
- #### Examples
181
- Creating a copy of a page using a json-string
182
- > $ dw command PageCopy --json '{ "model": { "SourcePageId": 1189, "DestinationParentPageId": 1129 } }'
344
+ ```sh
345
+ dw command PageCopy --json '{ "model": { "SourcePageId": 1189, "DestinationParentPageId": 1129 } }'
346
+ dw command PageMove --json ./PageMove.json
347
+ dw command PageDelete --json '{ "id": "1383" }' --output json
348
+ ```
183
349
 
184
- Removing a page using a json file
185
- > $ dw command PageMove --json ./PageMove.json
350
+ Example JSON output:
186
351
 
187
- Where PageMove.json contains
188
352
  ```json
189
- { "model": { "SourcePageId": 1383, "DestinationParentPageId": 1376 } }
353
+ {
354
+ "ok": true,
355
+ "command": "command",
356
+ "operation": "run",
357
+ "status": 200,
358
+ "data": [
359
+ {
360
+ "success": true,
361
+ "message": "Command executed"
362
+ }
363
+ ],
364
+ "errors": [],
365
+ "meta": {
366
+ "commandName": "PageDelete"
367
+ }
368
+ }
190
369
  ```
191
370
 
192
- Deleting a page
193
- > $ dw command PageDelete --json '{ "id": "1383" }'
371
+ `dw command --list` is reserved for command metadata, but it is not fully implemented yet.
194
372
 
195
- Running a command with JSON output
196
- > $ dw command PageDelete --json '{ "id": "1383" }' --output json
373
+ ### `dw install [filePath]`
197
374
 
198
- ### Install
199
- > $ dw install \<filePath\>
375
+ Upload and install a `.dll` or `.nupkg` add-in into the current environment.
200
376
 
201
- Install is somewhat of a shorthand for a few commands. It will upload and install a given .dll or .nupkg addin to your current environment.
377
+ ```sh
378
+ dw install ./bin/Release/net10.0/CustomProject.dll
379
+ dw install ./bin/Release/net10.0/CustomProject.dll --queue --output json
380
+ ```
202
381
 
203
- It's meant to be used to easily apply custom dlls to a given project, it being local or otherwise, so after having a dotnet library built locally, this command can be run, pointing to the built .dll and it will handle the rest with all the addin installation, and it will be available in the DynamicWeb solution as soon as the command finishes.
382
+ Example JSON output:
204
383
 
205
- #### Examples
206
- > $ dw install ./bin/Release/net10.0/CustomProject.dll
384
+ ```json
385
+ {
386
+ "ok": true,
387
+ "command": "install",
388
+ "operation": "queue",
389
+ "status": 200,
390
+ "data": [
391
+ {
392
+ "type": "upload",
393
+ "destinationPath": "System/AddIns/Local",
394
+ "files": [
395
+ "/workspace/bin/Release/net10.0/CustomProject.dll"
396
+ ],
397
+ "response": {
398
+ "message": "Upload completed"
399
+ }
400
+ },
401
+ {
402
+ "type": "install",
403
+ "filePath": "/workspace/bin/Release/net10.0/CustomProject.dll",
404
+ "filename": "CustomProject.dll",
405
+ "queued": true,
406
+ "response": {
407
+ "success": true,
408
+ "message": "Addin installed"
409
+ }
410
+ }
411
+ ],
412
+ "errors": [],
413
+ "meta": {
414
+ "filePath": "./bin/Release/net10.0/CustomProject.dll",
415
+ "filesProcessed": 1,
416
+ "chunks": 1
417
+ }
418
+ }
419
+ ```
207
420
 
208
- ### Database
209
- > $ dw database \<outPath\>
421
+ ### `dw config`
210
422
 
211
- This command is used for various actions towards your current environments database.
212
- - `-e` `--export` Exports your current environments database to a .bacpac file at \<outPath\>
423
+ Write values directly into `~/.dwc` when you want to script config updates.
213
424
 
214
- #### Examples
215
- > $ dw database -e ./backup
425
+ ```sh
426
+ dw config --env.dev.host localhost:6001
427
+ ```
216
428
 
217
- ### Config
218
- > $ dw config
429
+ ### `dw database [path] --export`
219
430
 
220
- Config is used to manage the .dwc file through the CLI, given any prop it will create the key/value with the path to it.
221
- - `--<property>` The path and name of the property to set
431
+ Export the current environment database to a `.bacpac` file.
222
432
 
223
- #### Examples
224
- Changing the host for the dev environment
225
- > $ dw config --env.dev.host localhost:6001
433
+ ```sh
434
+ dw database ./backups --export
435
+ ```
226
436
 
227
- ## Using Git Bash
228
- If you're using Git Bash, you may encounter issues with path conversion that can interfere with relative paths used in commands.
437
+ ### `dw swift [outPath]`
229
438
 
230
- ### Path Conversion Issues
231
- Git Bash automatically converts relative paths to absolute paths, which can cause problems.
232
- You'll see a warning message if the conversion setting is not disabled:
439
+ Download the latest Swift release, a specific tag, or the nightly build.
233
440
 
234
- "You appear to have path conversion turned on in your shell.
235
- If you are using relative paths, this may interfere.
236
- Please see https://doc.dynamicweb.dev/documentation/fundamentals/code/CLI.html for more information."
441
+ ```sh
442
+ dw swift -l
443
+ dw swift . --tag v1.25.1 --force
444
+ dw swift . --nightly --force
445
+ ```
237
446
 
238
- ### Solution
239
- To resolve this issue, disable path conversion by setting the `MSYS_NO_PATHCONV` environment variable (current session only):
447
+ ## CI/CD
240
448
 
241
- > $ export MSYS_NO_PATHCONV=1
449
+ For CI/CD, prefer OAuth client credentials and JSON output.
242
450
 
243
- #### Examples
451
+ - Store `DW_CLIENT_ID` and `DW_CLIENT_SECRET` in your pipeline secret store.
452
+ - Use `--host` together with `--auth oauth` for ephemeral runners.
453
+ - Add `--output json` when you want reliable parsing in scripts.
244
454
 
245
- > $ export MSYS_NO_PATHCONV=1
246
- > $ dw files -iro ./ /TestFolder --host \<host\> --apiKey \<apiKey\>
455
+ Example:
247
456
 
248
- ### Alternative Solutions
249
- If you prefer not to disable path conversion globally, you can:
457
+ ```sh
458
+ dw query HealthCheck \
459
+ --host your-solution.example.com \
460
+ --auth oauth \
461
+ --clientIdEnv DW_CLIENT_ID \
462
+ --clientSecretEnv DW_CLIENT_SECRET \
463
+ --output json
464
+ ```
465
+
466
+ For longer-lived runners, you can configure a saved environment once with `dw login --oauth`. Full CI/CD guidance will be expanded in the documentation.
250
467
 
251
- 1. Prefix relative paths with `./` instead of just `/` to prevent conversion for specific commands.
252
- 2. Use PowerShell or CMD instead of Git Bash.
468
+ ## Using Git Bash
253
469
 
254
- #### Examples
470
+ Git Bash can rewrite relative paths in a way that interferes with CLI file operations. If you see the path-conversion warning, disable it for the session before running file commands:
471
+
472
+ ```sh
473
+ export MSYS_NO_PATHCONV=1
474
+ dw files -iro ./ ./TestFolder --host <host> --apiKey <apiKey>
475
+ ```
255
476
 
256
- > $ dw files -iro ./ ./TestFolder --host \<host\> --apiKey \<apiKey\>
477
+ If you do not want to change that setting, prefer `./`-prefixed paths or use PowerShell or CMD instead.