task-pipeliner 0.3.5 → 0.3.7
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.ko.md +30 -1276
- package/README.md +31 -1278
- package/dist/index.cjs +181 -169
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> A powerful workflow orchestration tool with condition-based execution and beautiful CLI output
|
|
4
4
|
|
|
5
|
-
**Version:** 0.3.
|
|
5
|
+
**Version:** 0.3.7
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
|
@@ -13,11 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
**README-Language-Map** [KR [한국어 버전]](https://github.com/racgoo/task-pipeliner/blob/main/README.ko.md) / [EN [English Version]](https://github.com/racgoo/task-pipeliner)
|
|
15
15
|
|
|
16
|
+
> **📖 For detailed documentation, please refer to the [official documentation](https://task-pipeliner.racgoo.com/)!**
|
|
17
|
+
> This README provides a quick start and basic usage. For DSL syntax, advanced features, examples, and more, please visit the documentation site.
|
|
18
|
+
|
|
16
19
|
## 🔗 Resources
|
|
17
20
|
|
|
18
21
|
### Documentation & Tools
|
|
19
22
|
|
|
20
|
-
-
|
|
23
|
+
- **[📖 Official Documentation](https://task-pipeliner.racgoo.com/)** - **Complete DSL reference, guides, examples, and all feature descriptions** ⭐
|
|
21
24
|
- 🎨 **[Visual Generator](https://task-pipeliner-generator.racgoo.com/)** - Create workflows visually in your browser
|
|
22
25
|
|
|
23
26
|
### Repositories & Package Managers
|
|
@@ -29,6 +32,8 @@
|
|
|
29
32
|
|
|
30
33
|
### CLI Commands
|
|
31
34
|
|
|
35
|
+
> 💡 **For detailed CLI command descriptions, see the [CLI Reference documentation](https://task-pipeliner.racgoo.com/docs/cli-reference).**
|
|
36
|
+
|
|
32
37
|
**Project setup (recommended for new projects):**
|
|
33
38
|
```bash
|
|
34
39
|
tp setup # Create tp/, tp/workflows, tp/schedules and add 2 example workflows + 2 example schedules (echo-based; includes choose, when, profiles, prompt)
|
|
@@ -75,6 +80,11 @@ tp schedule status # Check daemon status (real-time mode; Ctrl+C exits the view
|
|
|
75
80
|
```
|
|
76
81
|
After `tp schedule add`, `toggle`, or `remove`, the affected schedule(s) are displayed in the same card layout as `tp schedule list` (cron expression, human-readable “when” description, next run, enabled state). Toggle result emphasizes ENABLED or DISABLED so the new state is obvious.
|
|
77
82
|
|
|
83
|
+
**Schedule status (live view)** — `tp schedule status` shows the daemon and all schedules in a scrollable, auto-updating view. Cron times include timezone (UTC or local). Use ↑/↓ or PgUp/PgDn to scroll when there are many schedules.
|
|
84
|
+
|
|
85
|
+
<p align="center"><img src="https://github.com/user-attachments/assets/348325d3-d184-4c1e-bc78-040da13e7e7d" width="720" alt="tp schedule status live view" /></p>
|
|
86
|
+
|
|
87
|
+
|
|
78
88
|
**Data & upgrades:**
|
|
79
89
|
```bash
|
|
80
90
|
tp clean # Remove all data in ~/.pipeliner (schedules, daemon state, workflow history)
|
|
@@ -83,6 +93,8 @@ After upgrading to a new version, if you see compatibility issues (e.g. schedule
|
|
|
83
93
|
|
|
84
94
|
## ✨ Features
|
|
85
95
|
|
|
96
|
+
> 💡 **For detailed descriptions and examples of each feature, see the [DSL Reference documentation](https://task-pipeliner.racgoo.com/docs/dsl-reference/workflow-structure).**
|
|
97
|
+
|
|
86
98
|
- **Condition-based execution** - Run steps based on file existence, user choices, environment variables, and more
|
|
87
99
|
|
|
88
100
|
- **Parallel execution** - Run multiple tasks simultaneously
|
|
@@ -216,6 +228,8 @@ npx tp run workflow.yaml
|
|
|
216
228
|
|
|
217
229
|
### Basic Usage
|
|
218
230
|
|
|
231
|
+
> 💡 **For more examples and advanced usage, see the [Getting Started guide](https://task-pipeliner.racgoo.com/docs/getting-started) and [Examples documentation](https://task-pipeliner.racgoo.com/docs/examples).**
|
|
232
|
+
|
|
219
233
|
Create a `workflow.yaml` or `workflow.json` file:
|
|
220
234
|
|
|
221
235
|
**YAML Format (`workflow.yaml`):**
|
|
@@ -343,1282 +357,21 @@ The `--silent` (or `-s`) flag suppresses all console output during workflow exec
|
|
|
343
357
|
|
|
344
358
|
Note: Silent mode suppresses all output including command output, step headers, and error messages. The workflow still executes normally and returns appropriate exit codes.
|
|
345
359
|
|
|
346
|
-
##
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
- bash # - First element: shell program (bash, zsh, sh, etc.)
|
|
362
|
-
- -lc # - Rest: shell arguments (-c, -lc, etc.)
|
|
363
|
-
# - If omitted: uses platform default shell
|
|
364
|
-
profiles: # Optional: Pre-set variables for tp run --profile <name>
|
|
365
|
-
- name: Test # - name: profile name
|
|
366
|
-
var: # - var: key-value map (used for {{variable}} and to skip choose/prompt)
|
|
367
|
-
mode: "dev"
|
|
368
|
-
label: "test-label"
|
|
369
|
-
|
|
370
|
-
steps: # Required: Array of steps to execute
|
|
371
|
-
- some-step-1
|
|
372
|
-
- some-step-2
|
|
373
|
-
# ...
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
**JSON Format:**
|
|
377
|
-
|
|
378
|
-
```json
|
|
379
|
-
{
|
|
380
|
-
"name": "Workflow Name", // Optional: Display name for the workflow
|
|
381
|
-
"baseDir": "./", // Optional: Base directory for command execution
|
|
382
|
-
// - Relative path: resolved from JSON file location
|
|
383
|
-
// - Absolute path: used as-is
|
|
384
|
-
// - If omitted: uses current working directory
|
|
385
|
-
"shell": ["bash", "-lc"], // Optional: Global shell configuration for all run commands
|
|
386
|
-
// - First element: shell program
|
|
387
|
-
// - Rest: shell arguments
|
|
388
|
-
// - If omitted: uses platform default shell
|
|
389
|
-
"profiles": [ // Optional: Pre-set variables for tp run --profile <name>
|
|
390
|
-
{ "name": "Test", "var": { "mode": "dev", "label": "test-label" } }
|
|
391
|
-
],
|
|
392
|
-
"steps": [ // Required: Array of steps to execute
|
|
393
|
-
{ /* some-step-1 */ },
|
|
394
|
-
{ /* some-step-2 */ }
|
|
395
|
-
]
|
|
396
|
-
}
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
#### `name` (optional)
|
|
400
|
-
- **Type**: `string`
|
|
401
|
-
- **Description**: Display name for the workflow
|
|
402
|
-
- **Example**: `name: "Build and Deploy"`
|
|
403
|
-
|
|
404
|
-
#### `baseDir` (optional)
|
|
405
|
-
- **Type**: `string` (relative or absolute path)
|
|
406
|
-
- **Description**: Base directory for all command executions
|
|
407
|
-
- **Resolution**:
|
|
408
|
-
- **Relative path** (e.g., `./`, `../frontend`): Resolved relative to the workflow file's directory
|
|
409
|
-
- **Absolute path** (e.g., `/home/user/project`): Used as-is
|
|
410
|
-
- **If omitted**: Uses `process.cwd()` (current working directory)
|
|
411
|
-
- **Example**:
|
|
412
|
-
```yaml
|
|
413
|
-
baseDir: ./frontend # Relative to workflow file
|
|
414
|
-
baseDir: /app/frontend # Absolute path
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
#### `shell` (optional)
|
|
418
|
-
- **Type**: `array` of `string`
|
|
419
|
-
- **Description**: Global shell configuration for all `run` commands in the workflow
|
|
420
|
-
- **Format**: `[program, ...args]` - First element is the shell program, rest are arguments
|
|
421
|
-
- **Priority**: Step-level `shell` > Workflow-level `shell` > User's current shell
|
|
422
|
-
- **User's current shell** (when omitted):
|
|
423
|
-
- **Linux/macOS**: Uses `$SHELL` environment variable (e.g., `/bin/zsh`, `/bin/bash`)
|
|
424
|
-
- **Windows**: Uses `%COMSPEC%` (typically `cmd.exe`)
|
|
425
|
-
- **Behavior**: Commands run in the same shell environment as where you execute `tp run`
|
|
426
|
-
- **Example**:
|
|
427
|
-
```yaml
|
|
428
|
-
# Unix/Linux/macOS
|
|
429
|
-
shell: [bash, -lc] # Use bash login shell
|
|
430
|
-
shell: [zsh, -c] # Use zsh
|
|
431
|
-
shell: [sh, -c] # Use sh (POSIX)
|
|
432
|
-
|
|
433
|
-
# Windows
|
|
434
|
-
shell: [cmd, /c] # Command Prompt
|
|
435
|
-
shell: [powershell, -Command] # Windows PowerShell
|
|
436
|
-
shell: [pwsh, -Command] # PowerShell Core
|
|
437
|
-
```
|
|
438
|
-
- **Cross-platform examples**:
|
|
439
|
-
- **Linux/macOS**: `[bash, -lc]`, `[zsh, -c]`, `[/bin/bash, -c]`
|
|
440
|
-
- **Windows**: `[cmd, /c]`, `[powershell, -Command]`, `[pwsh, -Command]`
|
|
441
|
-
- **Git Bash (Windows)**: `[bash, -c]`
|
|
442
|
-
- **WSL**: `[wsl, bash, -c]` or use `wsl` command directly
|
|
443
|
-
|
|
444
|
-
#### `profiles` (optional)
|
|
445
|
-
- **Type**: `array` of `{ name: string, var: Record<string, string> }`
|
|
446
|
-
- **Description**: Named sets of variables for non-interactive runs. Use with `tp run --profile <name>`.
|
|
447
|
-
- **Behavior**: When a profile is used, any **choose** or **prompt** step that stores into a variable already set in the profile is skipped; the profile value is used for `{{variable}}` substitution and conditions.
|
|
448
|
-
- **Example**:
|
|
449
|
-
```yaml
|
|
450
|
-
profiles:
|
|
451
|
-
- name: Test
|
|
452
|
-
var:
|
|
453
|
-
mode: "dev"
|
|
454
|
-
label: "test-label"
|
|
455
|
-
- name: Prod
|
|
456
|
-
var:
|
|
457
|
-
mode: "prod"
|
|
458
|
-
label: "prod-label"
|
|
459
|
-
```
|
|
460
|
-
```bash
|
|
461
|
-
tp run workflow.yaml --profile Test # Uses Test profile variables; choose/prompt for mode, label are skipped
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
#### `steps` (required)
|
|
465
|
-
- **Type**: `array` of `Step` objects
|
|
466
|
-
- **Description**: List of steps to execute sequentially
|
|
467
|
-
- **Execution**: Steps run in order, one after another (unless parallel)
|
|
468
|
-
|
|
469
|
-
---
|
|
470
|
-
|
|
471
|
-
### Step Types
|
|
472
|
-
|
|
473
|
-
Each step in the `steps` array can be one of the following types:
|
|
474
|
-
|
|
475
|
-
#### 1. `run` - Execute Command
|
|
476
|
-
|
|
477
|
-
Execute a shell command.
|
|
478
|
-
|
|
479
|
-
**Syntax:**
|
|
480
|
-
```yaml
|
|
481
|
-
- run: <command>
|
|
482
|
-
when?: <condition> # Optional: Execute only if condition is met
|
|
483
|
-
timeout?: <number> # Optional: Timeout in seconds
|
|
484
|
-
retry?: <number> | "Infinity" # Optional: Number of retries on failure (default: 0). Use "Infinity" for infinite retries
|
|
485
|
-
shell?: <array> # Optional: Shell configuration (overrides workflow.shell)
|
|
486
|
-
continue?: <bool> # Optional: Continue to next step after this step completes (regardless of success/failure)
|
|
487
|
-
onError?: # Optional: Error handling behavior
|
|
488
|
-
run: <command> # Fallback command when main run command fails (side effect)
|
|
489
|
-
timeout?: <number> # Optional: Timeout for this fallback command
|
|
490
|
-
retry?: <number> | "Infinity" # Optional: Retry count for this fallback command. Use "Infinity" for infinite retries
|
|
491
|
-
onError?: ... # Optional: Nested fallback (recursive onError chain)
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
**Properties:**
|
|
495
|
-
- `run` (required): `string` - Shell command to execute
|
|
496
|
-
- `when` (optional): `Condition` - Condition to check before execution
|
|
497
|
-
- `timeout` (optional): `number` - Maximum execution time in seconds. Command will be killed if it exceeds this time.
|
|
498
|
-
- `retry` (optional): `number | "Infinity"` - Number of retry attempts if command fails (default: 0, meaning no retry). Use `"Infinity"` for infinite retries until success
|
|
499
|
-
- `shell` (optional): `array` of `string` - Shell configuration for this step. Overrides workflow's global `shell`. Format: `[program, ...args]`. Example: `[bash, -lc]`, `[zsh, -c]`.
|
|
500
|
-
- `continue` (optional): `boolean` - Controls whether to proceed to the next step after this step completes, regardless of success or failure.
|
|
501
|
-
- `continue: true` - Always proceed to the next step (even if this step fails)
|
|
502
|
-
- `continue: false` - Always stop the workflow after this step (even if this step succeeds)
|
|
503
|
-
- `continue` not set (default) - Proceed on success, stop on failure
|
|
504
|
-
- `onError.run` (optional): `string` - Fallback command executed when the main `run` command (after its retries) fails. **onError only performs side effects (e.g., cleanup, rollback) and does not affect the step's success/failure status.** If the main `run` fails, this step is considered failed regardless of onError execution.
|
|
505
|
-
- `onError.timeout` (optional): `number` - Timeout for this fallback command.
|
|
506
|
-
- `onError.retry` (optional): `number | "Infinity"` - Retry count for this fallback command. Use `"Infinity"` for infinite retries.
|
|
507
|
-
|
|
508
|
-
**Examples:**
|
|
509
|
-
```yaml
|
|
510
|
-
# Simple command
|
|
511
|
-
steps:
|
|
512
|
-
- run: 'npm install'
|
|
513
|
-
|
|
514
|
-
# Command with condition
|
|
515
|
-
- when:
|
|
516
|
-
file: ./package.json
|
|
517
|
-
run: 'npm install'
|
|
518
|
-
|
|
519
|
-
# Variable input
|
|
520
|
-
- choose:
|
|
521
|
-
message: Select execution mode.
|
|
522
|
-
options:
|
|
523
|
-
- id: 1.1.1
|
|
524
|
-
label: Version 1.1.1 (string displayed in display area)
|
|
525
|
-
- id: 1.1.2
|
|
526
|
-
label: Version 1.1.2 (string displayed in display area)
|
|
527
|
-
- id: 1.1.3
|
|
528
|
-
label: Version 1.1.3 (string displayed in display area)
|
|
529
|
-
as: version
|
|
530
|
-
|
|
531
|
-
# Command with variable substitution
|
|
532
|
-
- run: 'echo "Building {{version}}"'
|
|
533
|
-
|
|
534
|
-
# Command with timeout (30 seconds)
|
|
535
|
-
- run: 'npm install'
|
|
536
|
-
timeout: 30
|
|
537
|
-
|
|
538
|
-
# Command with retry (retry up to 3 times)
|
|
539
|
-
- run: 'npm install'
|
|
540
|
-
retry: 3
|
|
541
|
-
|
|
542
|
-
# Command with infinite retry (retry until success)
|
|
543
|
-
- run: 'npm install'
|
|
544
|
-
retry: Infinity
|
|
545
|
-
|
|
546
|
-
# PM2-like process manager: auto-restart crashed server
|
|
547
|
-
- run: 'node server.js'
|
|
548
|
-
retry: Infinity
|
|
549
|
-
|
|
550
|
-
# Using both timeout and retry
|
|
551
|
-
- run: 'npm install'
|
|
552
|
-
timeout: 60
|
|
553
|
-
retry: 2
|
|
554
|
-
|
|
555
|
-
# Command with fallback on error
|
|
556
|
-
- run: 'pnpm lint'
|
|
557
|
-
onError:
|
|
558
|
-
run: 'pnpm lint:fix'
|
|
559
|
-
|
|
560
|
-
# Command with multi-level fallback on error
|
|
561
|
-
- run: 'step1'
|
|
562
|
-
onError:
|
|
563
|
-
run: 'step2'
|
|
564
|
-
onError:
|
|
565
|
-
run: 'step3'
|
|
566
|
-
|
|
567
|
-
# Command that records failure but continues workflow
|
|
568
|
-
- run: 'pnpm typecheck'
|
|
569
|
-
continue: true
|
|
570
|
-
onError:
|
|
571
|
-
run: 'echo "Type check failed, but continuing..."'
|
|
572
|
-
|
|
573
|
-
# Command with custom shell (step-level)
|
|
574
|
-
- run: 'echo $SHELL'
|
|
575
|
-
shell:
|
|
576
|
-
- zsh
|
|
577
|
-
- -c
|
|
578
|
-
|
|
579
|
-
# Command with bash login shell
|
|
580
|
-
- run: 'source ~/.bashrc && echo "Loaded profile"'
|
|
581
|
-
shell:
|
|
582
|
-
- bash
|
|
583
|
-
- -lc
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
**Behavior:**
|
|
587
|
-
- Command runs in the `baseDir` (if specified) or current working directory
|
|
588
|
-
- The main `run` command's success/failure determines the final step result. `onError` only performs additional actions (cleanup, rollback, etc.) on failure and does not change the step's success status.
|
|
589
|
-
- The `continue` flag controls workflow execution after this step completes:
|
|
590
|
-
- `continue: true` - Always proceed to the next step (regardless of success/failure)
|
|
591
|
-
- `continue: false` - Always stop the workflow (regardless of success/failure)
|
|
592
|
-
- `continue` not set - Default behavior: proceed on success, stop on failure
|
|
593
|
-
- Output is displayed in real-time with CLI formatting
|
|
594
|
-
- If `timeout` is specified and command exceeds the time limit, it will be killed and the step will fail
|
|
595
|
-
- If `retry` is specified, the command will be retried up to the retry value until it succeeds
|
|
596
|
-
|
|
597
|
-
---
|
|
598
|
-
|
|
599
|
-
#### 2. `choose` - User Choice
|
|
600
|
-
|
|
601
|
-
Prompt user to select from a list of options. The choice menu includes a **real-time search feature** that allows you to filter options by typing.
|
|
602
|
-
|
|
603
|
-
**Syntax:**
|
|
604
|
-
```yaml
|
|
605
|
-
steps:
|
|
606
|
-
- choose:
|
|
607
|
-
message: <string> # Required: Question to display
|
|
608
|
-
options: # Required: Array of options
|
|
609
|
-
- id: <string> # Required: Unique identifier (stored as value)
|
|
610
|
-
label: <string> # Required: Display text
|
|
611
|
-
- id: <string>
|
|
612
|
-
label: <string>
|
|
613
|
-
as: <variable-name> # Optional: Variable name to store result
|
|
614
|
-
when: <condition> # Condition for providing choice prompt
|
|
615
|
-
```
|
|
616
|
-
|
|
617
|
-
**Properties:**
|
|
618
|
-
- `choose.message` (required): `string` - Question text displayed to user
|
|
619
|
-
- `choose.options` (required): `array` of objects with:
|
|
620
|
-
- `id` (required): `string` - Unique identifier (this value is stored)
|
|
621
|
-
- `label` (required): `string` - Display text shown to user
|
|
622
|
-
- `choose.as` (optional): `string` - Variable name to store the selected `id`
|
|
623
|
-
- If omitted: choice is stored by its `id` (for backward compatibility)
|
|
624
|
-
- If provided: selected `id` is stored in this variable name
|
|
625
|
-
- `when` (optional): `Condition` - Show choice prompt only if condition is met
|
|
626
|
-
|
|
627
|
-
**Interactive Features:**
|
|
628
|
-
- **Real-time search**: Type to filter options instantly - only matching options are shown
|
|
629
|
-
- **Arrow key navigation**: Use ↑↓ keys to navigate through options
|
|
630
|
-
- **Enter to select**: Press Enter to confirm your choice
|
|
631
|
-
- **Backspace**: Remove characters from search term
|
|
632
|
-
- **Escape**: Clear search term and show all options
|
|
633
|
-
|
|
634
|
-
**Examples:**
|
|
635
|
-
```yaml
|
|
636
|
-
# Basic choice
|
|
637
|
-
- choose:
|
|
638
|
-
message: "Select environment:"
|
|
639
|
-
options:
|
|
640
|
-
- id: dev
|
|
641
|
-
label: "Development"
|
|
642
|
-
- id: staging
|
|
643
|
-
label: "Staging"
|
|
644
|
-
- id: prod
|
|
645
|
-
label: "Production"
|
|
646
|
-
|
|
647
|
-
# Choice with variable storage
|
|
648
|
-
- choose:
|
|
649
|
-
message: "Select environment:"
|
|
650
|
-
options:
|
|
651
|
-
- id: dev
|
|
652
|
-
label: "Development"
|
|
653
|
-
- id: prod
|
|
654
|
-
label: "Production"
|
|
655
|
-
as: env # Selected id stored in 'env' variable
|
|
656
|
-
|
|
657
|
-
# Conditional choice
|
|
658
|
-
- when:
|
|
659
|
-
file: ./package.json
|
|
660
|
-
choose:
|
|
661
|
-
message: "Run tests?"
|
|
662
|
-
options:
|
|
663
|
-
- id: yes
|
|
664
|
-
label: "Yes"
|
|
665
|
-
- id: no
|
|
666
|
-
label: "No"
|
|
667
|
-
as: runTests
|
|
668
|
-
```
|
|
669
|
-
|
|
670
|
-
**Storage:**
|
|
671
|
-
- Selected option's `id` is stored as:
|
|
672
|
-
1. A choice (accessible via `hasChoice(id)`)
|
|
673
|
-
2. A variable with the `id` name (for backward compatibility)
|
|
674
|
-
3. If `as` is provided: also stored as a variable with the `as` name
|
|
675
|
-
|
|
676
|
-
**Usage in conditions:**
|
|
677
|
-
```yaml
|
|
678
|
-
# After choice with 'as: env'
|
|
679
|
-
- when:
|
|
680
|
-
var: # Definition that uses a variable
|
|
681
|
-
env: prod # Check if 'env' variable equals 'prod'
|
|
682
|
-
run: 'echo "Deploying to production"'
|
|
683
|
-
```
|
|
684
|
-
|
|
685
|
-
---
|
|
686
|
-
|
|
687
|
-
#### 3. `prompt` - Text Input
|
|
688
|
-
|
|
689
|
-
Ask user for text input.
|
|
690
|
-
|
|
691
|
-
**Syntax:**
|
|
692
|
-
```yaml
|
|
693
|
-
- prompt:
|
|
694
|
-
message: <string> # Required: Question to display
|
|
695
|
-
as: <variable-name> # Required: Variable name to store result
|
|
696
|
-
default: <string> # Optional: Default value
|
|
697
|
-
when: <condition> # Optional: Show prompt only if condition is met
|
|
698
|
-
```
|
|
699
|
-
|
|
700
|
-
**Properties:**
|
|
701
|
-
- `prompt.message` (required): `string` - Question text displayed to user
|
|
702
|
-
- `prompt.as` (required): `string` - Variable name to store the input value
|
|
703
|
-
- `prompt.default` (optional): `string` - Default value if user presses Enter without input
|
|
704
|
-
- `when` (optional): `Condition` - Show prompt only if condition is met
|
|
705
|
-
|
|
706
|
-
**Examples:**
|
|
707
|
-
```yaml
|
|
708
|
-
# Basic prompt
|
|
709
|
-
- prompt:
|
|
710
|
-
message: "Enter version number:"
|
|
711
|
-
as: version
|
|
712
|
-
|
|
713
|
-
# Prompt with default value
|
|
714
|
-
- prompt:
|
|
715
|
-
message: "Enter version number:"
|
|
716
|
-
as: version
|
|
717
|
-
default: "1.0.0"
|
|
718
|
-
|
|
719
|
-
# Conditional prompt
|
|
720
|
-
- when:
|
|
721
|
-
var:
|
|
722
|
-
env: prod
|
|
723
|
-
prompt:
|
|
724
|
-
message: "Enter production deployment reason:"
|
|
725
|
-
as: deployReason
|
|
726
|
-
```
|
|
727
|
-
|
|
728
|
-
**Storage:**
|
|
729
|
-
- User input is stored as a variable with the name specified in `as`
|
|
730
|
-
- Can be used in commands with `{{variable}}` syntax
|
|
731
|
-
- Can be checked in conditions with `var` conditions
|
|
732
|
-
|
|
733
|
-
**Usage:**
|
|
734
|
-
```yaml
|
|
735
|
-
# Use in command
|
|
736
|
-
- run: 'echo "Building version {{version}}"'
|
|
737
|
-
|
|
738
|
-
# Check in condition
|
|
739
|
-
- when:
|
|
740
|
-
var:
|
|
741
|
-
version: "1.0.0"
|
|
742
|
-
run: 'echo "Deploying stable version"'
|
|
743
|
-
```
|
|
744
|
-
|
|
745
|
-
---
|
|
746
|
-
|
|
747
|
-
#### 4. `parallel` - Parallel Execution
|
|
748
|
-
|
|
749
|
-
Execute multiple steps simultaneously. Like `steps`, `parallel` contains an array of steps, each starting with `-`. All these steps execute at the same time.
|
|
750
|
-
|
|
751
|
-
**Syntax:**
|
|
752
|
-
```yaml
|
|
753
|
-
- parallel:
|
|
754
|
-
- <step1> # Each step starts with `-`, same format as `steps`
|
|
755
|
-
- <step2>
|
|
756
|
-
- <step3>
|
|
757
|
-
when?: <condition> # Optional: Execute parallel block only if condition is met
|
|
758
|
-
```
|
|
759
|
-
|
|
760
|
-
**Properties:**
|
|
761
|
-
- `parallel` (required): `array` of steps - Steps to execute in parallel. **Only `run`, nested `parallel`, and `fail` steps are allowed.** `choose` and `prompt` (user input steps) are **not allowed** inside `parallel`—user input cannot run in parallel.
|
|
762
|
-
- `when` (optional): `Condition` - Execute parallel block only if condition is met
|
|
763
|
-
|
|
764
|
-
**Restriction:** Steps inside `parallel` may only be `run`, nested `parallel`, or `fail`. Do **not** use `choose` or `prompt` inside `parallel`; the workflow validator will reject it and report an error (e.g. `'choose' step is not allowed inside 'parallel' block`).
|
|
765
|
-
|
|
766
|
-
**Examples:**
|
|
767
|
-
```yaml
|
|
768
|
-
# Basic parallel execution
|
|
769
|
-
# Each step inside parallel starts with `-`, same format as `steps`
|
|
770
|
-
- parallel:
|
|
771
|
-
- run: 'npm run test:unit'
|
|
772
|
-
- run: 'npm run test:integration'
|
|
773
|
-
- run: 'npm run lint'
|
|
774
|
-
|
|
775
|
-
# Parallel with conditions
|
|
776
|
-
# Each step can have its own `when` condition
|
|
777
|
-
- parallel:
|
|
778
|
-
- when:
|
|
779
|
-
file: ./src
|
|
780
|
-
run: 'echo "Building frontend..."'
|
|
781
|
-
- when:
|
|
782
|
-
file: ./api
|
|
783
|
-
run: 'echo "Building backend..."'
|
|
784
|
-
|
|
785
|
-
# Conditional parallel block
|
|
786
|
-
# The entire parallel block can have a `when` condition
|
|
787
|
-
- when:
|
|
788
|
-
var:
|
|
789
|
-
env: staging
|
|
790
|
-
parallel:
|
|
791
|
-
- run: 'npm run test'
|
|
792
|
-
- run: 'npm run lint'
|
|
793
|
-
|
|
794
|
-
# Nested parallel (allowed); only run / parallel / fail inside parallel
|
|
795
|
-
- parallel:
|
|
796
|
-
- run: 'npm run test'
|
|
797
|
-
- parallel:
|
|
798
|
-
- run: 'npm run lint'
|
|
799
|
-
- run: 'npm run typecheck'
|
|
800
|
-
```
|
|
801
|
-
|
|
802
|
-
**Behavior:**
|
|
803
|
-
- All steps in the `parallel` array start executing at the same time
|
|
804
|
-
- Workflow waits for all parallel steps to complete before continuing
|
|
805
|
-
- If any step fails, the workflow stops
|
|
806
|
-
- Each parallel branch has its own isolated workspace state (cloned)
|
|
807
|
-
- **`choose` and `prompt` are not allowed inside `parallel`** (user input cannot run in parallel; use them in sequential steps before or after a `parallel` block)
|
|
808
|
-
|
|
809
|
-
---
|
|
810
|
-
|
|
811
|
-
#### 5. `fail` - Fail Workflow
|
|
812
|
-
|
|
813
|
-
Stop the workflow with an error message.
|
|
814
|
-
|
|
815
|
-
**Syntax:**
|
|
816
|
-
```yaml
|
|
817
|
-
- fail:
|
|
818
|
-
message: <string>
|
|
819
|
-
when?: <condition> # Optional: Fail only if condition is met
|
|
820
|
-
```
|
|
821
|
-
|
|
822
|
-
**Properties:**
|
|
823
|
-
- `fail.message` (required): `string` - Error message to display
|
|
824
|
-
- `when` (optional): `Condition` - Fail only if condition is met
|
|
825
|
-
|
|
826
|
-
**Examples:**
|
|
827
|
-
```yaml
|
|
828
|
-
# Fail if file doesn't exist
|
|
829
|
-
- when:
|
|
830
|
-
not:
|
|
831
|
-
file: ./dist
|
|
832
|
-
fail:
|
|
833
|
-
message: "Build output not found"
|
|
834
|
-
|
|
835
|
-
# Fail based on variable
|
|
836
|
-
- when:
|
|
837
|
-
var:
|
|
838
|
-
env: prod
|
|
839
|
-
fail:
|
|
840
|
-
message: "Cannot deploy to production without approval"
|
|
841
|
-
```
|
|
842
|
-
|
|
843
|
-
**Behavior:**
|
|
844
|
-
- Immediately stops workflow execution
|
|
845
|
-
- Displays the error message
|
|
846
|
-
- Exits with non-zero status code
|
|
847
|
-
|
|
848
|
-
---
|
|
849
|
-
|
|
850
|
-
### Conditions (`when` clause)
|
|
851
|
-
|
|
852
|
-
Conditions control when steps execute. All conditions are evaluated as questions about the workspace state.
|
|
853
|
-
|
|
854
|
-
#### Condition Types
|
|
855
|
-
|
|
856
|
-
##### 1. File Existence (`file`)
|
|
857
|
-
|
|
858
|
-
Check if a file or directory exists.
|
|
859
|
-
|
|
860
|
-
**Syntax:**
|
|
861
|
-
```yaml
|
|
862
|
-
when:
|
|
863
|
-
file: <path>
|
|
864
|
-
```
|
|
865
|
-
|
|
866
|
-
**Properties:**
|
|
867
|
-
- `file`: `string` - File or directory path (relative to current working directory)
|
|
868
|
-
|
|
869
|
-
**Examples:**
|
|
870
|
-
```yaml
|
|
871
|
-
- when:
|
|
872
|
-
file: ./dist
|
|
873
|
-
run: 'echo "Build exists"'
|
|
874
|
-
|
|
875
|
-
- when:
|
|
876
|
-
file: ./package.json
|
|
877
|
-
run: 'npm install'
|
|
878
|
-
|
|
879
|
-
- when:
|
|
880
|
-
not:
|
|
881
|
-
file: ./node_modules
|
|
882
|
-
run: 'npm install'
|
|
883
|
-
```
|
|
884
|
-
|
|
885
|
-
**Behavior:**
|
|
886
|
-
- Paths are resolved relative to `process.cwd()` (current working directory)
|
|
887
|
-
- Returns `true` if file or directory exists, `false` otherwise
|
|
888
|
-
|
|
889
|
-
---
|
|
890
|
-
|
|
891
|
-
##### 2. Variable Value Comparison (`var` object)
|
|
892
|
-
|
|
893
|
-
Check if a variable equals a specific value.
|
|
894
|
-
|
|
895
|
-
**Syntax:**
|
|
896
|
-
```yaml
|
|
897
|
-
when:
|
|
898
|
-
var:
|
|
899
|
-
<variable-name>: <expected-value>
|
|
900
|
-
```
|
|
901
|
-
|
|
902
|
-
**Properties:**
|
|
903
|
-
- `var`: `object` - Object with variable name as key and expected value as value
|
|
904
|
-
- Keys: Variable names (from `prompt.as` or `choose.as`)
|
|
905
|
-
- Values: Expected string values to compare
|
|
906
|
-
|
|
907
|
-
**Examples:**
|
|
908
|
-
```yaml
|
|
909
|
-
# Check if env variable equals 'prod'
|
|
910
|
-
- when:
|
|
911
|
-
var:
|
|
912
|
-
env: prod
|
|
913
|
-
run: 'echo "Deploying to production"'
|
|
914
|
-
|
|
915
|
-
# Check if version equals specific value
|
|
916
|
-
- when:
|
|
917
|
-
var:
|
|
918
|
-
version: "1.0.0"
|
|
919
|
-
run: 'echo "Deploying stable version"'
|
|
920
|
-
|
|
921
|
-
# Multiple variable checks (all must match)
|
|
922
|
-
- when:
|
|
923
|
-
var:
|
|
924
|
-
env: staging
|
|
925
|
-
version: "2.0.0"
|
|
926
|
-
run: 'echo "Deploying v2.0.0 to staging"'
|
|
927
|
-
```
|
|
928
|
-
|
|
929
|
-
**Behavior:**
|
|
930
|
-
- Compares variable value (as string) with expected value
|
|
931
|
-
- Returns `true` if values match exactly (case-sensitive)
|
|
932
|
-
- Returns `false` if variable doesn't exist or values don't match
|
|
933
|
-
- All key-value pairs in the object must match (AND logic)
|
|
934
|
-
|
|
935
|
-
---
|
|
936
|
-
|
|
937
|
-
##### 3. Variable Existence (`var` string)
|
|
938
|
-
|
|
939
|
-
Check if a variable exists (regardless of value).
|
|
940
|
-
|
|
941
|
-
**Syntax:**
|
|
942
|
-
```yaml
|
|
943
|
-
when:
|
|
944
|
-
var: <variable-name>
|
|
945
|
-
# or
|
|
946
|
-
when:
|
|
947
|
-
has: <variable-name> # Alias for var
|
|
948
|
-
```
|
|
949
|
-
|
|
950
|
-
**Properties:**
|
|
951
|
-
- `var` or `has`: `string` - Variable name to check
|
|
952
|
-
|
|
953
|
-
**Examples:**
|
|
954
|
-
```yaml
|
|
955
|
-
# Check if variable exists
|
|
956
|
-
- when:
|
|
957
|
-
var: version
|
|
958
|
-
run: 'echo "Version: {{version}}"'
|
|
959
|
-
|
|
960
|
-
# Use 'has' alias
|
|
961
|
-
- when:
|
|
962
|
-
has: projectName
|
|
963
|
-
run: 'echo "Project: {{projectName}}"'
|
|
964
|
-
```
|
|
965
|
-
|
|
966
|
-
**Behavior:**
|
|
967
|
-
- Returns `true` if variable exists (from `prompt.as` or `choose.as`)
|
|
968
|
-
- Returns `false` if variable doesn't exist
|
|
969
|
-
- Only checks existence, not value
|
|
970
|
-
|
|
971
|
-
---
|
|
972
|
-
|
|
973
|
-
##### 4. Combined Conditions
|
|
974
|
-
|
|
975
|
-
Combine multiple conditions using `all`, `any`, and `not`.
|
|
976
|
-
|
|
977
|
-
###### `all` - AND Logic
|
|
978
|
-
|
|
979
|
-
All conditions must be true.
|
|
980
|
-
|
|
981
|
-
**Syntax:**
|
|
982
|
-
```yaml
|
|
983
|
-
when:
|
|
984
|
-
all:
|
|
985
|
-
- <condition1>
|
|
986
|
-
- <condition2>
|
|
987
|
-
- <condition3>
|
|
988
|
-
```
|
|
989
|
-
|
|
990
|
-
**Examples:**
|
|
991
|
-
```yaml
|
|
992
|
-
- when:
|
|
993
|
-
all:
|
|
994
|
-
- file: ./dist
|
|
995
|
-
- var:
|
|
996
|
-
env: production
|
|
997
|
-
run: 'echo "Production build ready"'
|
|
998
|
-
|
|
999
|
-
- when:
|
|
1000
|
-
all:
|
|
1001
|
-
- var:
|
|
1002
|
-
env: staging
|
|
1003
|
-
- var:
|
|
1004
|
-
version: "2.0.0"
|
|
1005
|
-
- file: ./dist
|
|
1006
|
-
run: 'echo "Deploying v2.0.0 to staging"'
|
|
1007
|
-
```
|
|
1008
|
-
|
|
1009
|
-
**Behavior:**
|
|
1010
|
-
- Returns `true` only if ALL conditions in the array are `true`
|
|
1011
|
-
- Returns `false` if ANY condition is `false`
|
|
1012
|
-
- Short-circuit evaluation: stops checking after first `false`
|
|
1013
|
-
|
|
1014
|
-
---
|
|
1015
|
-
|
|
1016
|
-
###### `any` - OR Logic
|
|
1017
|
-
|
|
1018
|
-
Any condition can be true.
|
|
1019
|
-
|
|
1020
|
-
**Syntax:**
|
|
1021
|
-
```yaml
|
|
1022
|
-
when:
|
|
1023
|
-
any:
|
|
1024
|
-
- <condition1>
|
|
1025
|
-
- <condition2>
|
|
1026
|
-
- <condition3>
|
|
1027
|
-
```
|
|
1028
|
-
|
|
1029
|
-
**Examples:**
|
|
1030
|
-
```yaml
|
|
1031
|
-
- when:
|
|
1032
|
-
any:
|
|
1033
|
-
- var:
|
|
1034
|
-
env: staging
|
|
1035
|
-
- var:
|
|
1036
|
-
env: production
|
|
1037
|
-
run: 'echo "Deploying to server"'
|
|
1038
|
-
|
|
1039
|
-
- when:
|
|
1040
|
-
any:
|
|
1041
|
-
- file: ./dist
|
|
1042
|
-
- file: ./build
|
|
1043
|
-
run: 'echo "Build output found"'
|
|
1044
|
-
```
|
|
1045
|
-
|
|
1046
|
-
**Behavior:**
|
|
1047
|
-
- Returns `true` if ANY condition in the array is `true`
|
|
1048
|
-
- Returns `false` only if ALL conditions are `false`
|
|
1049
|
-
- Short-circuit evaluation: stops checking after first `true`
|
|
1050
|
-
|
|
1051
|
-
---
|
|
1052
|
-
|
|
1053
|
-
###### `not` - Negation
|
|
1054
|
-
|
|
1055
|
-
Negate a condition.
|
|
1056
|
-
|
|
1057
|
-
**Syntax:**
|
|
1058
|
-
```yaml
|
|
1059
|
-
when:
|
|
1060
|
-
not:
|
|
1061
|
-
<condition>
|
|
1062
|
-
```
|
|
1063
|
-
|
|
1064
|
-
**Examples:**
|
|
1065
|
-
```yaml
|
|
1066
|
-
# Fail if file doesn't exist
|
|
1067
|
-
- when:
|
|
1068
|
-
not:
|
|
1069
|
-
file: ./dist
|
|
1070
|
-
fail:
|
|
1071
|
-
message: "Build output not found"
|
|
1072
|
-
|
|
1073
|
-
# Execute if variable doesn't equal value
|
|
1074
|
-
- when:
|
|
1075
|
-
not:
|
|
1076
|
-
var:
|
|
1077
|
-
env: prod
|
|
1078
|
-
run: 'echo "Not production environment"'
|
|
1079
|
-
|
|
1080
|
-
# Complex negation
|
|
1081
|
-
- when:
|
|
1082
|
-
not:
|
|
1083
|
-
all:
|
|
1084
|
-
- file: ./dist
|
|
1085
|
-
- var:
|
|
1086
|
-
env: prod
|
|
1087
|
-
run: 'echo "Production not ready"'
|
|
1088
|
-
```
|
|
1089
|
-
|
|
1090
|
-
**Behavior:**
|
|
1091
|
-
- Returns `true` if inner condition is `false`
|
|
1092
|
-
- Returns `false` if inner condition is `true`
|
|
1093
|
-
- Can negate any condition type
|
|
1094
|
-
|
|
1095
|
-
---
|
|
1096
|
-
|
|
1097
|
-
##### 5. Nested Conditions
|
|
1098
|
-
|
|
1099
|
-
Nest conditions to create complex logic.
|
|
1100
|
-
|
|
1101
|
-
**Examples:**
|
|
1102
|
-
```yaml
|
|
1103
|
-
# Complex nested condition
|
|
1104
|
-
- when:
|
|
1105
|
-
all:
|
|
1106
|
-
- file: ./dist
|
|
1107
|
-
- any:
|
|
1108
|
-
- var:
|
|
1109
|
-
env: staging
|
|
1110
|
-
- var:
|
|
1111
|
-
env: production
|
|
1112
|
-
- not:
|
|
1113
|
-
var:
|
|
1114
|
-
version: "0.0.0"
|
|
1115
|
-
run: 'echo "Ready to deploy"'
|
|
1116
|
-
|
|
1117
|
-
# Multiple levels of nesting
|
|
1118
|
-
- when:
|
|
1119
|
-
any:
|
|
1120
|
-
- all:
|
|
1121
|
-
- var:
|
|
1122
|
-
env: prod
|
|
1123
|
-
- file: ./dist
|
|
1124
|
-
- all:
|
|
1125
|
-
- var:
|
|
1126
|
-
env: staging
|
|
1127
|
-
- not:
|
|
1128
|
-
file: ./test-results
|
|
1129
|
-
run: 'echo "Conditional deployment"'
|
|
1130
|
-
```
|
|
1131
|
-
|
|
1132
|
-
---
|
|
1133
|
-
|
|
1134
|
-
### Variable Substitution
|
|
1135
|
-
|
|
1136
|
-
Variables can be used in commands using the `{{variable}}` syntax. Optional whitespace is supported: `{{var}}`, `{{ var }}`, `{{ var }}` all work.
|
|
1137
|
-
|
|
1138
|
-
**Syntax:**
|
|
1139
|
-
```yaml
|
|
1140
|
-
run: 'echo "{{variableName}}"'
|
|
1141
|
-
# or with optional spaces
|
|
1142
|
-
run: 'echo "{{ variableName }}"'
|
|
1143
|
-
```
|
|
1144
|
-
|
|
1145
|
-
**⚠️ Important YAML Syntax Rules:**
|
|
1146
|
-
|
|
1147
|
-
When using `{{variable}}` in commands, follow these rules to avoid parsing errors:
|
|
1148
|
-
|
|
1149
|
-
✅ **Safe patterns:**
|
|
1150
|
-
```yaml
|
|
1151
|
-
# Wrap in single quotes (recommended)
|
|
1152
|
-
- run: 'echo "Building {{version}}..."'
|
|
1153
|
-
- run: 'npm run build --version={{version}}'
|
|
1154
|
-
|
|
1155
|
-
# Wrap entire command in single quotes
|
|
1156
|
-
- run: 'echo "Selected: {{mode}}"'
|
|
1157
|
-
```
|
|
1158
|
-
|
|
1159
|
-
❌ **Problematic patterns:**
|
|
1160
|
-
```yaml
|
|
1161
|
-
# DO NOT: unquoted value with colons before variables
|
|
1162
|
-
- run: echo "mode: {{mode}}" # ❌ YAML parsing error!
|
|
1163
|
-
|
|
1164
|
-
# FIX: Wrap entire command in single quotes
|
|
1165
|
-
- run: 'echo "mode: {{mode}}"' # ✅ Works correctly
|
|
1166
|
-
```
|
|
1167
|
-
|
|
1168
|
-
**Examples:**
|
|
1169
|
-
```yaml
|
|
1170
|
-
# Use prompt variable
|
|
1171
|
-
- prompt:
|
|
1172
|
-
message: "Enter project name:"
|
|
1173
|
-
as: projectName
|
|
1174
|
-
- run: 'echo "Building {{projectName}}..."'
|
|
1175
|
-
|
|
1176
|
-
# Use choice variable
|
|
1177
|
-
- choose:
|
|
1178
|
-
message: "Select environment:"
|
|
1179
|
-
options:
|
|
1180
|
-
- id: dev
|
|
1181
|
-
label: "Development"
|
|
1182
|
-
as: env
|
|
1183
|
-
- run: 'echo "Deploying to {{env}}"'
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
# Multiple variables
|
|
1187
|
-
- run: 'echo "Building {{projectName}} version {{version}} for {{env}}"'
|
|
1188
|
-
```
|
|
1189
|
-
|
|
1190
|
-
**Behavior:**
|
|
1191
|
-
- Variables are replaced with their string values
|
|
1192
|
-
- If variable doesn't exist, it's replaced with empty string
|
|
1193
|
-
- Variables are resolved at execution time
|
|
1194
|
-
|
|
1195
|
-
---
|
|
1196
|
-
|
|
1197
|
-
### Complete Example
|
|
1198
|
-
|
|
1199
|
-
A complete example demonstrating all features:
|
|
1200
|
-
|
|
1201
|
-
```yaml
|
|
1202
|
-
name: Complete Workflow Example
|
|
1203
|
-
baseDir: ./
|
|
1204
|
-
shell: [bash, -c] # Optional: Use bash for all steps (default: user's current shell)
|
|
1205
|
-
|
|
1206
|
-
steps:
|
|
1207
|
-
# 1. Simple command
|
|
1208
|
-
- run: 'echo "Starting workflow..."'
|
|
1209
|
-
|
|
1210
|
-
# 2. User choice with variable storage
|
|
1211
|
-
- choose:
|
|
1212
|
-
message: "Select deployment environment:"
|
|
1213
|
-
options:
|
|
1214
|
-
- id: dev
|
|
1215
|
-
label: "Development"
|
|
1216
|
-
- id: staging
|
|
1217
|
-
label: "Staging"
|
|
1218
|
-
- id: prod
|
|
1219
|
-
label: "Production"
|
|
1220
|
-
as: env
|
|
1221
|
-
|
|
1222
|
-
# 3. Conditional step based on variable value
|
|
1223
|
-
- when:
|
|
1224
|
-
var:
|
|
1225
|
-
env: prod
|
|
1226
|
-
prompt:
|
|
1227
|
-
message: "Enter production deployment reason:"
|
|
1228
|
-
as: deployReason
|
|
1229
|
-
|
|
1230
|
-
# 4. Variable value comparison
|
|
1231
|
-
- when:
|
|
1232
|
-
var:
|
|
1233
|
-
env: dev
|
|
1234
|
-
run: 'echo "Deploying to development..."'
|
|
1235
|
-
|
|
1236
|
-
- when:
|
|
1237
|
-
var:
|
|
1238
|
-
env: staging
|
|
1239
|
-
run: 'echo "Deploying to staging..."'
|
|
1240
|
-
|
|
1241
|
-
# 5. Complex condition (all)
|
|
1242
|
-
- when:
|
|
1243
|
-
all:
|
|
1244
|
-
- var:
|
|
1245
|
-
env: prod
|
|
1246
|
-
- var: deployReason
|
|
1247
|
-
- file: ./dist
|
|
1248
|
-
run: 'echo "Production deployment approved"'
|
|
1249
|
-
|
|
1250
|
-
# 6. Parallel execution
|
|
1251
|
-
- parallel:
|
|
1252
|
-
- run: 'npm run test:unit'
|
|
1253
|
-
- run: 'npm run test:integration'
|
|
1254
|
-
- run: 'npm run lint'
|
|
1255
|
-
|
|
1256
|
-
# 6.5. Step-level shell override
|
|
1257
|
-
- run: 'echo "Running with zsh"'
|
|
1258
|
-
shell: [zsh, -c] # Override workflow shell for this step only
|
|
1259
|
-
|
|
1260
|
-
# 7. File existence check
|
|
1261
|
-
- when:
|
|
1262
|
-
file: ./test-results
|
|
1263
|
-
run: 'echo "Tests completed"'
|
|
1264
|
-
|
|
1265
|
-
# 8. Combined condition (any)
|
|
1266
|
-
- when:
|
|
1267
|
-
any:
|
|
1268
|
-
- var:
|
|
1269
|
-
env: staging
|
|
1270
|
-
- var:
|
|
1271
|
-
env: prod
|
|
1272
|
-
run: 'echo "Deploying to server..."'
|
|
1273
|
-
|
|
1274
|
-
# 9. Negation
|
|
1275
|
-
- when:
|
|
1276
|
-
not:
|
|
1277
|
-
file: ./dist
|
|
1278
|
-
fail:
|
|
1279
|
-
message: "Build output not found"
|
|
1280
|
-
|
|
1281
|
-
# 10. Variable substitution
|
|
1282
|
-
- run: 'echo "Deploying {{projectName}} version {{version}} to {{env}}"'
|
|
1283
|
-
```
|
|
1284
|
-
|
|
1285
|
-
---
|
|
1286
|
-
|
|
1287
|
-
## 📜 History Management
|
|
1288
|
-
|
|
1289
|
-
task-pipeliner automatically records workflow execution history, allowing you to review past executions, debug issues, and track performance.
|
|
1290
|
-
|
|
1291
|
-
### Viewing History
|
|
1292
|
-
|
|
1293
|
-
All workflow executions are automatically saved to `~/.pipeliner/workflow-history/` with timestamped filenames.
|
|
1294
|
-
|
|
1295
|
-
**Interactive Menu:**
|
|
1296
|
-
```bash
|
|
1297
|
-
tp history
|
|
1298
|
-
```
|
|
1299
|
-
|
|
1300
|
-
This opens an interactive menu where you can:
|
|
1301
|
-
- **Show** - View and select a history to view
|
|
1302
|
-
- **Remove** - Delete a specific history file
|
|
1303
|
-
- **Remove All** - Delete all history files
|
|
1304
|
-
|
|
1305
|
-
**View Specific History:**
|
|
1306
|
-
```bash
|
|
1307
|
-
tp history show
|
|
1308
|
-
```
|
|
1309
|
-
|
|
1310
|
-
This command:
|
|
1311
|
-
1. Lists all available history files
|
|
1312
|
-
2. Lets you select one to view
|
|
1313
|
-
3. Displays detailed execution information including:
|
|
1314
|
-
- Execution timestamp
|
|
1315
|
-
- Total duration
|
|
1316
|
-
- Step-by-step results (success/failure)
|
|
1317
|
-
- Command output (stdout/stderr)
|
|
1318
|
-
- Step durations
|
|
1319
|
-
|
|
1320
|
-
**Example Output:**
|
|
1321
|
-
```
|
|
1322
|
-
┌─────────────────────────────────────────┐
|
|
1323
|
-
│ Workflow Execution History │
|
|
1324
|
-
│ │
|
|
1325
|
-
│ File: workflow-2026-01-26_21-51-17... │
|
|
1326
|
-
│ Started: 2026-01-26 21:51:17 │
|
|
1327
|
-
│ Total Duration: 5.23s │
|
|
1328
|
-
│ Total Steps: 3 │
|
|
1329
|
-
│ ✓ Successful: 2 │
|
|
1330
|
-
│ ✗ Failed: 1 │
|
|
1331
|
-
└─────────────────────────────────────────┘
|
|
1332
|
-
|
|
1333
|
-
┌─────────────────────────────────────────┐
|
|
1334
|
-
│ ✓ Step 1/3 - Run │
|
|
1335
|
-
│ Duration: 1.23s | Status: Success │
|
|
1336
|
-
│ │
|
|
1337
|
-
│ Command: npm install │
|
|
1338
|
-
└─────────────────────────────────────────┘
|
|
1339
|
-
```
|
|
1340
|
-
|
|
1341
|
-
### Removing History
|
|
1342
|
-
|
|
1343
|
-
**Remove Specific History:**
|
|
1344
|
-
```bash
|
|
1345
|
-
tp history remove
|
|
1346
|
-
```
|
|
1347
|
-
|
|
1348
|
-
Opens an interactive menu to select which history file to delete.
|
|
1349
|
-
|
|
1350
|
-
**Remove All Histories:**
|
|
1351
|
-
```bash
|
|
1352
|
-
tp history remove-all
|
|
1353
|
-
```
|
|
1354
|
-
|
|
1355
|
-
Removes all stored workflow execution histories. You'll be prompted for confirmation unless you use the `-y` flag:
|
|
1356
|
-
|
|
1357
|
-
```bash
|
|
1358
|
-
tp history remove-all -y # Skip confirmation
|
|
1359
|
-
```
|
|
1360
|
-
|
|
1361
|
-
### History File Format
|
|
1362
|
-
|
|
1363
|
-
History files are stored as JSON in `~/.pipeliner/workflow-history/` with the following structure:
|
|
1364
|
-
|
|
1365
|
-
```json
|
|
1366
|
-
{
|
|
1367
|
-
"initialTimestamp": 1706281877000,
|
|
1368
|
-
"records": [
|
|
1369
|
-
{
|
|
1370
|
-
"step": { "run": "npm install" },
|
|
1371
|
-
"output": {
|
|
1372
|
-
"success": true,
|
|
1373
|
-
"stdout": ["...", "..."],
|
|
1374
|
-
"stderr": []
|
|
1375
|
-
},
|
|
1376
|
-
"duration": 1234,
|
|
1377
|
-
"status": "success"
|
|
1378
|
-
}
|
|
1379
|
-
]
|
|
1380
|
-
}
|
|
1381
|
-
```
|
|
1382
|
-
|
|
1383
|
-
Each record contains:
|
|
1384
|
-
- **step**: The step definition that was executed
|
|
1385
|
-
- **output**: Command output (stdout/stderr) and success status
|
|
1386
|
-
- **duration**: Execution time in milliseconds
|
|
1387
|
-
- **status**: `"success"` or `"failure"`
|
|
1388
|
-
|
|
1389
|
-
---
|
|
1390
|
-
|
|
1391
|
-
## ⏰ Workflow Scheduling
|
|
1392
|
-
|
|
1393
|
-
Schedule workflows to run automatically at specified times using cron expressions.
|
|
1394
|
-
|
|
1395
|
-
### Adding Schedules
|
|
1396
|
-
|
|
1397
|
-
Create a schedule file (YAML or JSON) defining your schedules:
|
|
1398
|
-
|
|
1399
|
-
**YAML (`schedules.yaml`):**
|
|
1400
|
-
```yaml
|
|
1401
|
-
schedules:
|
|
1402
|
-
- name: Daily Build # Schedule alias (for identification)
|
|
1403
|
-
cron: "0 9 * * *" # Cron expression
|
|
1404
|
-
workflow: ./build.yaml # Path relative to schedule file
|
|
1405
|
-
|
|
1406
|
-
- name: Nightly Test
|
|
1407
|
-
cron: "0 2 * * *"
|
|
1408
|
-
workflow: ./test.yaml
|
|
1409
|
-
silent: true # Optional: run in silent mode
|
|
1410
|
-
|
|
1411
|
-
- name: Production Deploy
|
|
1412
|
-
cron: "0 18 * * 5" # Every Friday at 6 PM
|
|
1413
|
-
workflow: ./deploy.yaml
|
|
1414
|
-
profile: Production # Optional: use specific profile
|
|
1415
|
-
|
|
1416
|
-
- name: Hourly Check
|
|
1417
|
-
cron: "0 * * * *"
|
|
1418
|
-
workflow: simple.yaml
|
|
1419
|
-
baseDir: /path/to/workflows # Optional: base directory for workflow path
|
|
1420
|
-
|
|
1421
|
-
- name: Daily UTC
|
|
1422
|
-
cron: "0 9 * * *"
|
|
1423
|
-
workflow: ./daily.yaml
|
|
1424
|
-
timezone: 0 # Optional: UTC offset (hours). +9, -5, 0. Omit = system local
|
|
1425
|
-
```
|
|
1426
|
-
|
|
1427
|
-
**Field Descriptions:**
|
|
1428
|
-
- `name`: Alias to identify the schedule
|
|
1429
|
-
- `cron`: Execution time (cron expression)
|
|
1430
|
-
- `workflow`: Path to workflow file (relative to schedule file or `baseDir`, or absolute)
|
|
1431
|
-
- `baseDir`: (Optional) Base directory for workflow path (defaults to schedule file's directory)
|
|
1432
|
-
- `timezone`: (Optional) UTC offset in hours: number or string (e.g. `+9`, `-5`, `0`). Omit = system local
|
|
1433
|
-
- `silent`: (Optional) Run in silent mode, suppressing console output
|
|
1434
|
-
- `profile`: (Optional) Profile name to use (for workflows with profiles)
|
|
1435
|
-
|
|
1436
|
-
**Path Resolution:**
|
|
1437
|
-
By default, relative workflow paths are resolved from the schedule file's directory. This means if your schedule file and workflow are in the same folder, you can simply use `./workflow.yaml`. Use `baseDir` to specify a different base directory if needed.
|
|
1438
|
-
|
|
1439
|
-
**JSON (`schedules.json`):**
|
|
1440
|
-
```json
|
|
1441
|
-
{
|
|
1442
|
-
"schedules": [
|
|
1443
|
-
{
|
|
1444
|
-
"name": "Daily Build",
|
|
1445
|
-
"cron": "0 9 * * *",
|
|
1446
|
-
"workflow": "./build.yaml"
|
|
1447
|
-
},
|
|
1448
|
-
{
|
|
1449
|
-
"name": "Nightly Test",
|
|
1450
|
-
"cron": "0 2 * * *",
|
|
1451
|
-
"workflow": "./test.yaml",
|
|
1452
|
-
"silent": true
|
|
1453
|
-
},
|
|
1454
|
-
{
|
|
1455
|
-
"name": "Production Deploy",
|
|
1456
|
-
"cron": "0 18 * * 5",
|
|
1457
|
-
"workflow": "./deploy.yaml",
|
|
1458
|
-
"profile": "Production"
|
|
1459
|
-
}
|
|
1460
|
-
]
|
|
1461
|
-
}
|
|
1462
|
-
```
|
|
1463
|
-
|
|
1464
|
-
Then add all schedules from the file:
|
|
1465
|
-
|
|
1466
|
-
```bash
|
|
1467
|
-
tp schedule add schedules.yaml
|
|
1468
|
-
# Or, with no path: select a file from the nearest tp/schedules/ directory
|
|
1469
|
-
tp schedule add
|
|
1470
|
-
```
|
|
1471
|
-
|
|
1472
|
-
You'll be prompted to confirm or override the alias for each schedule. After adding, each added schedule is shown in the same card format as `tp schedule list` (cron, human-readable “when” description, next run, enabled state).
|
|
1473
|
-
|
|
1474
|
-
**Cron Expression Format:**
|
|
1475
|
-
|
|
1476
|
-
5 fields (standard) or **6 fields with seconds** (node-cron extension):
|
|
1477
|
-
|
|
1478
|
-
```
|
|
1479
|
-
# 6 fields (optional seconds)
|
|
1480
|
-
# ┌────────────── second (0-59, optional)
|
|
1481
|
-
# │ ┌──────────── minute (0-59)
|
|
1482
|
-
# │ │ ┌────────── hour (0-23)
|
|
1483
|
-
# │ │ │ ┌──────── day of month (1-31)
|
|
1484
|
-
# │ │ │ │ ┌────── month (1-12)
|
|
1485
|
-
# │ │ │ │ │ ┌──── day of week (0-7)
|
|
1486
|
-
# │ │ │ │ │ │
|
|
1487
|
-
# * * * * * *
|
|
1488
|
-
```
|
|
1489
|
-
|
|
1490
|
-
**Common Examples (5 fields):**
|
|
1491
|
-
- `0 9 * * *` - Daily at 9:00 AM
|
|
1492
|
-
- `0 0 * * 1` - Weekly on Monday at midnight
|
|
1493
|
-
- `*/15 * * * *` - Every 15 minutes
|
|
1494
|
-
- `0 */2 * * *` - Every 2 hours
|
|
1495
|
-
- `0 9 * * 1-5` - Weekdays at 9:00 AM
|
|
1496
|
-
|
|
1497
|
-
**With seconds (6 fields):**
|
|
1498
|
-
- `* * * * * *` - Every second
|
|
1499
|
-
- `*/5 * * * * *` - Every 5 seconds
|
|
1500
|
-
- `0 * * * * *` - Every minute (same as `* * * * *`)
|
|
1501
|
-
|
|
1502
|
-
### Managing Schedules
|
|
1503
|
-
|
|
1504
|
-
```bash
|
|
1505
|
-
# List all schedules (card layout: cron, "when" description, next run, etc.)
|
|
1506
|
-
tp schedule list
|
|
1507
|
-
|
|
1508
|
-
# Remove a schedule (after removal, the removed schedule is shown in the same card format)
|
|
1509
|
-
tp schedule remove
|
|
1510
|
-
|
|
1511
|
-
# Remove all schedules
|
|
1512
|
-
tp schedule remove-all
|
|
1513
|
-
|
|
1514
|
-
# Enable/disable a schedule (after toggle, ENABLED/DISABLED is shown clearly in bold/color and the schedule card is displayed)
|
|
1515
|
-
tp schedule toggle
|
|
1516
|
-
```
|
|
1517
|
-
|
|
1518
|
-
**Unified schedule UI:** List, add, toggle, and remove all use the same schedule card layout. Each card shows the cron expression, a human-readable description of when it runs (e.g. “Every minute”), timezone, workflow path, profile if set, last run, and next run. After `tp schedule toggle`, the new state is emphasized (ENABLED in green or DISABLED in gray) so it’s obvious at a glance.
|
|
1519
|
-
|
|
1520
|
-
### Running the Scheduler
|
|
1521
|
-
|
|
1522
|
-
Start the scheduler to run workflows at their scheduled times. You can run it in two modes:
|
|
1523
|
-
|
|
1524
|
-
**Foreground Mode:**
|
|
1525
|
-
```bash
|
|
1526
|
-
tp schedule start
|
|
1527
|
-
```
|
|
1528
|
-
- Runs in the foreground (attached to your terminal)
|
|
1529
|
-
- Press `Ctrl+C` to stop the scheduler
|
|
1530
|
-
- Useful for testing or temporary scheduling
|
|
1531
|
-
|
|
1532
|
-
**Daemon Mode (Background):**
|
|
1533
|
-
```bash
|
|
1534
|
-
tp schedule start -d
|
|
1535
|
-
```
|
|
1536
|
-
- Runs as a background daemon process
|
|
1537
|
-
- Continues running even after closing the terminal
|
|
1538
|
-
- Only one daemon instance can run at a time (duplicate execution is prevented)
|
|
1539
|
-
- Use `tp schedule stop` to stop the daemon
|
|
1540
|
-
|
|
1541
|
-
**Checking Daemon Status:**
|
|
1542
|
-
```bash
|
|
1543
|
-
tp schedule status # Live view (updates every second); Ctrl+C exits the view only, daemon keeps running
|
|
1544
|
-
tp schedule status -n # Show status once and exit (no live refresh)
|
|
1545
|
-
```
|
|
1546
|
-
- Shows daemon and schedule status in a unified card layout (same as `tp schedule list` and `tp schedule start`)
|
|
1547
|
-
- Displays: daemon state (active/inactive), PID, start time and uptime, all schedules with Enabled/Cron/Timezone/Workflow/Profile/Last run/Next run
|
|
1548
|
-
- Press `Ctrl+C` to exit the status view (daemon continues running if it was started with `tp schedule start -d`)
|
|
1549
|
-
|
|
1550
|
-
The scheduler will:
|
|
1551
|
-
- Execute workflows at their scheduled times
|
|
1552
|
-
- Log all executions to `~/.pipeliner/workflow-history/`
|
|
1553
|
-
- Prevent duplicate daemon instances (only one can run at a time)
|
|
1554
|
-
|
|
1555
|
-
### Schedule Storage
|
|
1556
|
-
|
|
1557
|
-
Schedules are stored in `~/.pipeliner/schedules/schedules.json`. Each schedule includes:
|
|
1558
|
-
- Unique ID
|
|
1559
|
-
- Workflow path
|
|
1560
|
-
- Cron expression
|
|
1561
|
-
- Enabled/disabled status
|
|
1562
|
-
- Last execution time
|
|
1563
|
-
|
|
1564
|
-
All scheduled workflow executions are logged to the same history directory as manual runs (`~/.pipeliner/workflow-history/`), so you can review them using `tp history`.
|
|
1565
|
-
|
|
1566
|
-
---
|
|
1567
|
-
|
|
1568
|
-
## 📚 Examples
|
|
1569
|
-
|
|
1570
|
-
### Project Examples
|
|
1571
|
-
|
|
1572
|
-
Check out the `examples/` directory for complete project examples:
|
|
1573
|
-
|
|
1574
|
-
- **`tp setup`** – Run `tp setup` in your project root to generate `tp/workflows/` and `tp/schedules/` with two example workflows (choose, when, profiles, prompt) and two example schedule files (including profile usage). All steps use `echo` so you can run them safely and then replace with real commands.
|
|
1575
|
-
- **`monorepo-example/`** - Monorepo workflow with multiple projects
|
|
1576
|
-
- **`simple-project/`** - Simple single-project workflow
|
|
1577
|
-
- **`react-app/`** - React application build and deployment
|
|
1578
|
-
|
|
1579
|
-
### YAML Examples
|
|
1580
|
-
|
|
1581
|
-
Check out `examples/yaml-examples/` for YAML workflow examples:
|
|
1582
|
-
|
|
1583
|
-
- **`basic.yaml`** - Basic workflow with choices and conditions
|
|
1584
|
-
- **`simple.yaml`** - Minimal workflow example
|
|
1585
|
-
- **`parallel.yaml`** - Parallel execution example
|
|
1586
|
-
- **`conditions.yaml`** - Various condition types
|
|
1587
|
-
- **`file-checks.yaml`** - File existence checks
|
|
1588
|
-
- **`prompt.yaml`** - User input prompts
|
|
1589
|
-
- **`variables.yaml`** - Variable substitution examples
|
|
1590
|
-
- **`profiles-example.yaml`** - Profiles for non-interactive runs (`tp run --profile <name>`)
|
|
1591
|
-
|
|
1592
|
-
### JSON Examples
|
|
1593
|
-
|
|
1594
|
-
Check out `examples/json-examples/` for JSON workflow examples (equivalent to YAML examples):
|
|
1595
|
-
|
|
1596
|
-
- **`basic.json`** - Basic workflow with choices and conditions
|
|
1597
|
-
- **`simple.json`** - Minimal workflow example
|
|
1598
|
-
- **`parallel.json`** - Parallel execution example
|
|
1599
|
-
- **`conditions.json`** - Condition evaluation examples
|
|
1600
|
-
- **`prompt.json`** - User input prompts
|
|
1601
|
-
- **`variables.json`** - Variable substitution examples
|
|
1602
|
-
- **`profiles-example.json`** - Profiles for non-interactive runs (`tp run --profile <name>`)
|
|
1603
|
-
|
|
1604
|
-
**Note:** Both YAML and JSON formats are fully supported. Choose the format that fits your preference - YAML for readability, JSON for programmatic generation.
|
|
1605
|
-
- **`variables.yaml`** - Variable usage examples
|
|
1606
|
-
- **`prompt.yaml`** - Text prompt examples
|
|
1607
|
-
- **`var-value-example.yaml`** - Variable value comparison examples
|
|
1608
|
-
- **`choice-as-example.yaml`** - Using `as` keyword in choices
|
|
1609
|
-
- **`base-dir-example.yaml`** - baseDir configuration example
|
|
1610
|
-
- **`timeout-retry-example.yaml`** - Timeout and retry features
|
|
1611
|
-
- **`cicd.yaml`** - CI/CD pipeline example
|
|
1612
|
-
- **`advanced.yaml`** - Advanced workflow patterns
|
|
1613
|
-
- **`multi-choice.yaml`** - Multiple sequential choices
|
|
1614
|
-
- **`react.yaml`** - React-specific workflow
|
|
1615
|
-
|
|
1616
|
-
## 🏗️ Architecture
|
|
1617
|
-
|
|
1618
|
-
- **CLI**: Node.js + TypeScript with Commander.js
|
|
1619
|
-
- **Task Execution**: Node.js child processes with streaming output
|
|
1620
|
-
- **UI**: Boxen and Chalk for beautiful terminal output
|
|
1621
|
-
- **Prompts**: Inquirer.js for interactive prompts
|
|
360
|
+
## 📚 Learn More
|
|
361
|
+
|
|
362
|
+
This README covers only the basics. For more detailed information, see the following documentation:
|
|
363
|
+
|
|
364
|
+
- **[Getting Started](https://task-pipeliner.racgoo.com/docs/getting-started)** - From installation to your first workflow
|
|
365
|
+
- **[DSL Reference](https://task-pipeliner.racgoo.com/docs/dsl-reference/workflow-structure)** - Complete syntax guide
|
|
366
|
+
- [Workflow Structure](https://task-pipeliner.racgoo.com/docs/dsl-reference/workflow-structure)
|
|
367
|
+
- [Step Types](https://task-pipeliner.racgoo.com/docs/dsl-reference/step-types)
|
|
368
|
+
- [Conditions](https://task-pipeliner.racgoo.com/docs/dsl-reference/conditions)
|
|
369
|
+
- [Variables](https://task-pipeliner.racgoo.com/docs/dsl-reference/variables)
|
|
370
|
+
- [Profiles](https://task-pipeliner.racgoo.com/docs/dsl-reference/profiles)
|
|
371
|
+
- **[CLI Reference](https://task-pipeliner.racgoo.com/docs/cli-reference)** - Detailed descriptions of all CLI commands
|
|
372
|
+
- **[Examples](https://task-pipeliner.racgoo.com/docs/examples)** - Real-world use cases and examples
|
|
373
|
+
- **[Execution History](https://task-pipeliner.racgoo.com/docs/history)** - Managing past execution records
|
|
374
|
+
- **[Workflow Scheduling](https://task-pipeliner.racgoo.com/docs/schedule)** - Automatic execution with cron
|
|
1622
375
|
|
|
1623
376
|
## 🤝 Contributing
|
|
1624
377
|
|