task-pipeliner 0.1.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.
Files changed (161) hide show
  1. package/LICENSE +21 -0
  2. package/README.ko.md +1034 -0
  3. package/README.md +1031 -0
  4. package/dist/cli/index.d.ts +19 -0
  5. package/dist/cli/index.d.ts.map +1 -0
  6. package/dist/cli/index.js +147 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/cli/prompts.d.ts +48 -0
  9. package/dist/cli/prompts.d.ts.map +1 -0
  10. package/dist/cli/prompts.js +75 -0
  11. package/dist/cli/prompts.js.map +1 -0
  12. package/dist/cli/ui.d.ts +39 -0
  13. package/dist/cli/ui.d.ts.map +1 -0
  14. package/dist/cli/ui.js +84 -0
  15. package/dist/cli/ui.js.map +1 -0
  16. package/dist/core/__tests__/actual-execution.test.d.ts +2 -0
  17. package/dist/core/__tests__/actual-execution.test.d.ts.map +1 -0
  18. package/dist/core/__tests__/actual-execution.test.js +140 -0
  19. package/dist/core/__tests__/actual-execution.test.js.map +1 -0
  20. package/dist/core/__tests__/base-dir.test.d.ts +2 -0
  21. package/dist/core/__tests__/base-dir.test.d.ts.map +1 -0
  22. package/dist/core/__tests__/base-dir.test.js +146 -0
  23. package/dist/core/__tests__/base-dir.test.js.map +1 -0
  24. package/dist/core/__tests__/built-code-execution.test.d.ts +2 -0
  25. package/dist/core/__tests__/built-code-execution.test.d.ts.map +1 -0
  26. package/dist/core/__tests__/built-code-execution.test.js +48 -0
  27. package/dist/core/__tests__/built-code-execution.test.js.map +1 -0
  28. package/dist/core/__tests__/choose-as-var-condition.test.d.ts +2 -0
  29. package/dist/core/__tests__/choose-as-var-condition.test.d.ts.map +1 -0
  30. package/dist/core/__tests__/choose-as-var-condition.test.js +308 -0
  31. package/dist/core/__tests__/choose-as-var-condition.test.js.map +1 -0
  32. package/dist/core/__tests__/cli-integration.test.d.ts +2 -0
  33. package/dist/core/__tests__/cli-integration.test.d.ts.map +1 -0
  34. package/dist/core/__tests__/cli-integration.test.js +83 -0
  35. package/dist/core/__tests__/cli-integration.test.js.map +1 -0
  36. package/dist/core/__tests__/comprehensive-basic-yaml.test.d.ts +2 -0
  37. package/dist/core/__tests__/comprehensive-basic-yaml.test.d.ts.map +1 -0
  38. package/dist/core/__tests__/comprehensive-basic-yaml.test.js +111 -0
  39. package/dist/core/__tests__/comprehensive-basic-yaml.test.js.map +1 -0
  40. package/dist/core/__tests__/condition-evaluator.test.d.ts +2 -0
  41. package/dist/core/__tests__/condition-evaluator.test.d.ts.map +1 -0
  42. package/dist/core/__tests__/condition-evaluator.test.js +170 -0
  43. package/dist/core/__tests__/condition-evaluator.test.js.map +1 -0
  44. package/dist/core/__tests__/debug-basic-yaml.test.d.ts +2 -0
  45. package/dist/core/__tests__/debug-basic-yaml.test.d.ts.map +1 -0
  46. package/dist/core/__tests__/debug-basic-yaml.test.js +128 -0
  47. package/dist/core/__tests__/debug-basic-yaml.test.js.map +1 -0
  48. package/dist/core/__tests__/example-files.test.d.ts +2 -0
  49. package/dist/core/__tests__/example-files.test.d.ts.map +1 -0
  50. package/dist/core/__tests__/example-files.test.js +200 -0
  51. package/dist/core/__tests__/example-files.test.js.map +1 -0
  52. package/dist/core/__tests__/executor-choice-integration.test.d.ts +2 -0
  53. package/dist/core/__tests__/executor-choice-integration.test.d.ts.map +1 -0
  54. package/dist/core/__tests__/executor-choice-integration.test.js +171 -0
  55. package/dist/core/__tests__/executor-choice-integration.test.js.map +1 -0
  56. package/dist/core/__tests__/executor-choice.test.d.ts +2 -0
  57. package/dist/core/__tests__/executor-choice.test.d.ts.map +1 -0
  58. package/dist/core/__tests__/executor-choice.test.js +174 -0
  59. package/dist/core/__tests__/executor-choice.test.js.map +1 -0
  60. package/dist/core/__tests__/executor-parallel.test.d.ts +2 -0
  61. package/dist/core/__tests__/executor-parallel.test.d.ts.map +1 -0
  62. package/dist/core/__tests__/executor-parallel.test.js +136 -0
  63. package/dist/core/__tests__/executor-parallel.test.js.map +1 -0
  64. package/dist/core/__tests__/executor-prompt.test.d.ts +2 -0
  65. package/dist/core/__tests__/executor-prompt.test.d.ts.map +1 -0
  66. package/dist/core/__tests__/executor-prompt.test.js +149 -0
  67. package/dist/core/__tests__/executor-prompt.test.js.map +1 -0
  68. package/dist/core/__tests__/executor-real-scenario.test.d.ts +2 -0
  69. package/dist/core/__tests__/executor-real-scenario.test.d.ts.map +1 -0
  70. package/dist/core/__tests__/executor-real-scenario.test.js +169 -0
  71. package/dist/core/__tests__/executor-real-scenario.test.js.map +1 -0
  72. package/dist/core/__tests__/file-condition.test.d.ts +2 -0
  73. package/dist/core/__tests__/file-condition.test.d.ts.map +1 -0
  74. package/dist/core/__tests__/file-condition.test.js +182 -0
  75. package/dist/core/__tests__/file-condition.test.js.map +1 -0
  76. package/dist/core/__tests__/final-verification.test.d.ts +2 -0
  77. package/dist/core/__tests__/final-verification.test.d.ts.map +1 -0
  78. package/dist/core/__tests__/final-verification.test.js +59 -0
  79. package/dist/core/__tests__/final-verification.test.js.map +1 -0
  80. package/dist/core/__tests__/parallel-when-condition.test.d.ts +2 -0
  81. package/dist/core/__tests__/parallel-when-condition.test.d.ts.map +1 -0
  82. package/dist/core/__tests__/parallel-when-condition.test.js +155 -0
  83. package/dist/core/__tests__/parallel-when-condition.test.js.map +1 -0
  84. package/dist/core/__tests__/parser.test.d.ts +2 -0
  85. package/dist/core/__tests__/parser.test.d.ts.map +1 -0
  86. package/dist/core/__tests__/parser.test.js +94 -0
  87. package/dist/core/__tests__/parser.test.js.map +1 -0
  88. package/dist/core/__tests__/real-inquirer-test.test.d.ts +2 -0
  89. package/dist/core/__tests__/real-inquirer-test.test.d.ts.map +1 -0
  90. package/dist/core/__tests__/real-inquirer-test.test.js +20 -0
  91. package/dist/core/__tests__/real-inquirer-test.test.js.map +1 -0
  92. package/dist/core/__tests__/reproduce-bug.test.d.ts +2 -0
  93. package/dist/core/__tests__/reproduce-bug.test.d.ts.map +1 -0
  94. package/dist/core/__tests__/reproduce-bug.test.js +84 -0
  95. package/dist/core/__tests__/reproduce-bug.test.js.map +1 -0
  96. package/dist/core/__tests__/timeout-retry.test.d.ts +2 -0
  97. package/dist/core/__tests__/timeout-retry.test.d.ts.map +1 -0
  98. package/dist/core/__tests__/timeout-retry.test.js +184 -0
  99. package/dist/core/__tests__/timeout-retry.test.js.map +1 -0
  100. package/dist/core/__tests__/workflow-validation.test.d.ts +2 -0
  101. package/dist/core/__tests__/workflow-validation.test.d.ts.map +1 -0
  102. package/dist/core/__tests__/workflow-validation.test.js +120 -0
  103. package/dist/core/__tests__/workflow-validation.test.js.map +1 -0
  104. package/dist/core/__tests__/workspace.test.d.ts +2 -0
  105. package/dist/core/__tests__/workspace.test.d.ts.map +1 -0
  106. package/dist/core/__tests__/workspace.test.js +29 -0
  107. package/dist/core/__tests__/workspace.test.js.map +1 -0
  108. package/dist/core/__tests__/yaml-integration.test.d.ts +2 -0
  109. package/dist/core/__tests__/yaml-integration.test.d.ts.map +1 -0
  110. package/dist/core/__tests__/yaml-integration.test.js +114 -0
  111. package/dist/core/__tests__/yaml-integration.test.js.map +1 -0
  112. package/dist/core/__tests__/yaml-scenarios.test.d.ts +2 -0
  113. package/dist/core/__tests__/yaml-scenarios.test.d.ts.map +1 -0
  114. package/dist/core/__tests__/yaml-scenarios.test.js +199 -0
  115. package/dist/core/__tests__/yaml-scenarios.test.js.map +1 -0
  116. package/dist/core/condition-evaluator.d.ts +44 -0
  117. package/dist/core/condition-evaluator.d.ts.map +1 -0
  118. package/dist/core/condition-evaluator.js +121 -0
  119. package/dist/core/condition-evaluator.js.map +1 -0
  120. package/dist/core/executor.d.ts +172 -0
  121. package/dist/core/executor.d.ts.map +1 -0
  122. package/dist/core/executor.js +579 -0
  123. package/dist/core/executor.js.map +1 -0
  124. package/dist/core/parser.d.ts +41 -0
  125. package/dist/core/parser.d.ts.map +1 -0
  126. package/dist/core/parser.js +202 -0
  127. package/dist/core/parser.js.map +1 -0
  128. package/dist/core/rust-task-runner.d.ts +14 -0
  129. package/dist/core/rust-task-runner.d.ts.map +1 -0
  130. package/dist/core/rust-task-runner.js +34 -0
  131. package/dist/core/rust-task-runner.js.map +1 -0
  132. package/dist/core/task-runner.d.ts +63 -0
  133. package/dist/core/task-runner.d.ts.map +1 -0
  134. package/dist/core/task-runner.js +252 -0
  135. package/dist/core/task-runner.js.map +1 -0
  136. package/dist/core/template.d.ts +11 -0
  137. package/dist/core/template.d.ts.map +1 -0
  138. package/dist/core/template.js +36 -0
  139. package/dist/core/template.js.map +1 -0
  140. package/dist/core/workflow-schema.d.ts +31 -0
  141. package/dist/core/workflow-schema.d.ts.map +1 -0
  142. package/dist/core/workflow-schema.js +125 -0
  143. package/dist/core/workflow-schema.js.map +1 -0
  144. package/dist/core/workspace.d.ts +90 -0
  145. package/dist/core/workspace.d.ts.map +1 -0
  146. package/dist/core/workspace.js +143 -0
  147. package/dist/core/workspace.js.map +1 -0
  148. package/dist/index.d.ts +10 -0
  149. package/dist/index.d.ts.map +1 -0
  150. package/dist/index.js +10 -0
  151. package/dist/index.js.map +1 -0
  152. package/dist/task-pipeliner-rs.node +0 -0
  153. package/dist/types/condition.d.ts +62 -0
  154. package/dist/types/condition.d.ts.map +1 -0
  155. package/dist/types/condition.js +6 -0
  156. package/dist/types/condition.js.map +1 -0
  157. package/dist/types/workflow.d.ts +69 -0
  158. package/dist/types/workflow.d.ts.map +1 -0
  159. package/dist/types/workflow.js +2 -0
  160. package/dist/types/workflow.js.map +1 -0
  161. package/package.json +67 -0
package/README.ko.md ADDED
@@ -0,0 +1,1034 @@
1
+ # task-pipeliner
2
+
3
+ > 조건 기반 작업 파이프라인 실행기로 아름다운 CLI 출력을 제공합니다
4
+
5
+ **버전:** 0.1.0
6
+
7
+ ![task-pipeliner-banner](https://github.com/user-attachments/assets/282f3cfc-cd0d-4767-88dd-f3abb8e71bea)
8
+
9
+ [![npm version](https://img.shields.io/npm/v/task-pipeliner)](https://www.npmjs.com/package/task-pipeliner)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
11
+
12
+ **task-pipeliner**는 간단한 YAML 또는 JSON 파일로 복잡한 작업 파이프라인을 정의할 수 있는 현대적인 워크플로우 자동화 도구입니다. 조건부 실행, 병렬 작업, 대화형 프롬프트, 그리고 아름다운 터미널 출력을 제공하여 빌드 스크립트, 배포 워크플로우, CI/CD 파이프라인에 완벽합니다.
13
+
14
+ ## ✨ 주요 기능
15
+
16
+ - **조건 기반 실행** - 파일 존재 여부, 사용자 선택, 환경 변수 등을 기반으로 단계 실행
17
+
18
+ - **병렬 실행** - 여러 작업을 동시에 병렬로 실행
19
+
20
+ - **대화형 프롬프트** - 실행 중 사용자에게 입력과 선택을 요청
21
+
22
+ - **YAML & JSON 지원** - 선언적인 파이프라이닝을 YAML & JSON 형식으로 제공
23
+
24
+ - **변수 치환** - 워크플로우 전반에서 `{{variables}}` 사용
25
+
26
+ ## 리소스
27
+
28
+ - 📚 **[문서](https://task-pipeliner.racgoo.com/)** - 완전한 DSL 참조 및 가이드
29
+ - 🎨 **[시각적 생성기](https://task-pipeliner-generator.racgoo.com/)** - 브라우저에서 시각적으로 워크플로우 생성
30
+ > **CLI 명령어**:
31
+ ```bash
32
+ tp open generator # 시각적 생성기 열기
33
+ tp open docs # 문서 열기
34
+ ```
35
+
36
+ ## 🚀 빠른 시작
37
+
38
+ ### 설치
39
+
40
+ #### 전역 설치
41
+
42
+ 전역으로 설치하면 `task-pipeliner` 또는 `tp` 명령을 직접 사용할 수 있습니다:
43
+
44
+ ```bash
45
+ npm install -g task-pipeliner
46
+ # 또는
47
+ pnpm add -g task-pipeliner
48
+ ```
49
+
50
+ 전역 설치 후 다음 명령으로 실행할 수 있습니다:
51
+ ```bash
52
+ task-pipeliner run workflow.yaml
53
+ # 또는 짧은 별칭 사용
54
+ tp run workflow.yaml
55
+ ```
56
+
57
+ #### 프로젝트 설치 (개발 모드)
58
+
59
+ 프로젝트에 devDependency로 설치하면 `npx`로 사용할 수 있습니다:
60
+
61
+ ```bash
62
+ npm install -D task-pipeliner
63
+ # 또는
64
+ pnpm add -D task-pipeliner
65
+ ```
66
+
67
+ 프로젝트 설치 후 다음 명령으로 실행할 수 있습니다:
68
+ ```bash
69
+ npx task-pipeliner run workflow.yaml
70
+ # 또는 짧은 별칭 사용
71
+ npx tp run workflow.yaml
72
+ ```
73
+
74
+ ### 기본 사용법
75
+
76
+ `workflow.yaml` 또는 `workflow.json` 파일을 생성하세요:
77
+
78
+ **YAML 형식 (`workflow.yaml`):**
79
+
80
+ ```yaml
81
+ name: My Workflow
82
+
83
+ steps:
84
+ - run: echo "Hello, World!"
85
+
86
+ - choose:
87
+ message: "무엇을 하시겠습니까?"
88
+ options:
89
+ - id: build
90
+ label: "프로젝트 빌드"
91
+ - id: test
92
+ label: "테스트 실행"
93
+ as: action
94
+
95
+ - when:
96
+ var:
97
+ action: build
98
+ run: npm run build
99
+
100
+ - when:
101
+ var:
102
+ action: test
103
+ run: npm test
104
+ ```
105
+
106
+ **JSON 형식 (`workflow.json`):**
107
+
108
+ ```json
109
+ {
110
+ "name": "My Workflow",
111
+ "steps": [
112
+ {
113
+ "run": "echo \"Hello, World!\""
114
+ },
115
+ {
116
+ "choose": {
117
+ "message": "무엇을 하시겠습니까?",
118
+ "options": [
119
+ {
120
+ "id": "build",
121
+ "label": "프로젝트 빌드"
122
+ },
123
+ {
124
+ "id": "test",
125
+ "label": "테스트 실행"
126
+ }
127
+ ],
128
+ "as": "action"
129
+ }
130
+ },
131
+ {
132
+ "when": {
133
+ "var": {
134
+ "action": "build"
135
+ }
136
+ },
137
+ "run": "npm run build"
138
+ },
139
+ {
140
+ "when": {
141
+ "var": {
142
+ "action": "test"
143
+ }
144
+ },
145
+ "run": "npm test"
146
+ }
147
+ ]
148
+ }
149
+ ```
150
+
151
+ 실행:
152
+
153
+ ```bash
154
+ task-pipeliner run workflow.yaml
155
+ # 또는
156
+ task-pipeliner run workflow.json
157
+ # 또는 짧은 별칭 사용
158
+ tp run workflow.yaml
159
+ tp run workflow.json
160
+ ```
161
+
162
+ ## DSL 문법
163
+
164
+ ### 워크플로우 구조
165
+
166
+ 워크플로우 파일은 다음 구조를 가진 YAML 또는 JSON 문서입니다:
167
+
168
+ **YAML 형식:**
169
+
170
+ ```yaml
171
+ name: Workflow Name # 선택사항: 워크플로우 표시 이름
172
+ description: | # 선택사항: 여러 줄 설명
173
+ 이 워크플로우는...
174
+ baseDir: ./ # 선택사항: 명령 실행 기본 디렉토리
175
+ # - 상대 경로: YAML 파일 위치 기준으로 해석
176
+ # - 절대 경로: 그대로 사용
177
+ # - 생략 시: 현재 작업 디렉토리 사용
178
+
179
+ steps: # 필수: 실행할 단계 배열
180
+ - some-step-1
181
+ - some-step-2
182
+ # ...
183
+ ```
184
+
185
+ **JSON 형식:**
186
+
187
+ ```json
188
+ {
189
+ "name": "Workflow Name", // 선택사항: 워크플로우 표시 이름
190
+ "description": "이 워크플로우는...", // 선택사항: 설명
191
+ "baseDir": "./", // 선택사항: 명령 실행 기본 디렉토리
192
+ // - 상대 경로: JSON 파일 위치 기준으로 해석
193
+ // - 절대 경로: 그대로 사용
194
+ // - 생략 시: 현재 작업 디렉토리 사용
195
+ "steps": [ // 필수: 실행할 단계 배열
196
+ { /* some-step-1 */ },
197
+ { /* some-step-2 */ }
198
+ ]
199
+ }
200
+ ```
201
+
202
+ #### `name` (선택)
203
+ - **타입**: `string`
204
+ - **설명**: 워크플로우의 표시 이름
205
+ - **예제**: `name: "빌드 및 배포"`
206
+
207
+ #### `description` (선택)
208
+ - **타입**: `string` (`|`로 여러 줄 지원)
209
+ - **설명**: 워크플로우가 수행하는 작업에 대한 설명
210
+ - **예제**:
211
+ ```yaml
212
+ description: |
213
+ 이 워크플로우는 프로젝트를 빌드하고,
214
+ 테스트를 실행하며, 프로덕션에 배포합니다.
215
+ ```
216
+
217
+ #### `baseDir` (선택)
218
+ - **타입**: `string` (상대 또는 절대 경로)
219
+ - **설명**: 모든 명령 실행을 위한 기본 디렉토리
220
+ - **해석**:
221
+ - **상대 경로** (예: `./`, `../frontend`): YAML 파일의 디렉토리를 기준으로 해석
222
+ - **절대 경로** (예: `/home/user/project`): 그대로 사용
223
+ - **생략 시**: `process.cwd()` (현재 작업 디렉토리) 사용
224
+ - **예제**:
225
+ ```yaml
226
+ baseDir: ./frontend # YAML 파일 기준 상대 경로
227
+ baseDir: /app/frontend # 절대 경로
228
+ ```
229
+
230
+ #### `steps` (필수)
231
+ - **타입**: `Step` 객체의 `array`
232
+ - **설명**: 순차적으로 실행할 단계 목록
233
+ - **실행**: 단계는 순서대로 하나씩 실행됩니다 (병렬이 아닌 경우)
234
+
235
+ ---
236
+
237
+ ### 단계 타입
238
+
239
+ `steps` 배열의 각 단계는 다음 타입 중 하나일 수 있습니다:
240
+
241
+ #### 1. `run` - 명령 실행
242
+
243
+ 셸 명령을 실행합니다.
244
+
245
+ **문법:**
246
+ ```yaml
247
+ - run: <command>
248
+ when?: <condition> # 선택: 조건이 충족될 때만 실행
249
+ timeout?: <number> # 선택: 타임아웃 (초 단위)
250
+ retry?: <number> # 선택: 실패 시 재시도 횟수 (기본값: 0)
251
+ ```
252
+
253
+ **속성:**
254
+ - `run` (필수): `string` - 실행할 셸 명령
255
+ - `when` (선택): `Condition` - 실행 전 확인할 조건
256
+ - `timeout` (선택): `number` - 최대 실행 시간 (초 단위). 이 시간을 초과하면 명령이 종료됩니다.
257
+ - `retry` (선택): `number` - 실패 시 재시도 횟수 (기본값: 0, 재시도 없음)
258
+
259
+ **예제:**
260
+ ```yaml
261
+ # 간단한 명령
262
+ steps:
263
+ - run: npm install
264
+
265
+ # 조건이 있는 명령
266
+ - when:
267
+ file: ./package.json
268
+ run: npm install
269
+
270
+ # 변수 입력
271
+ - choose:
272
+ message: 실행알 모드를 선택하세요.
273
+ options:
274
+ - id: 1.1.1
275
+ label: 1.1.1 버전 (display 영역에 표시될 문자열)
276
+ - id: 1.1.2
277
+ label: 1.1.2 버전 (display 영역에 표시될 문자열)
278
+ - id: 1.1.3
279
+ label: 1.1.3 버전 (display 영역에 표시될 문자열)
280
+ as: version
281
+
282
+ # 변수 치환이 있는 명령
283
+ - run: echo "Building {{version}}"
284
+
285
+ # 타임아웃이 있는 명령 (30초)
286
+ - run: npm install
287
+ timeout: 30
288
+
289
+ # 재시도가 있는 명령 (최대 3번 재시도)
290
+ - run: npm install
291
+ retry: 3
292
+
293
+ # 타임아웃과 재시도 모두 사용
294
+ - run: npm install
295
+ timeout: 60
296
+ retry: 2
297
+ ```
298
+
299
+ **동작:**
300
+ - 명령은 `baseDir` (지정된 경우) 또는 현재 작업 디렉토리에서 실행됩니다
301
+ - 명령이 실패하면 워크플로우가 중지됩니다 (모든 재시도 후에도 실패한 경우)
302
+ - 출력은 CLI 포맷팅과 함께 실시간으로 표시됩니다
303
+ - `timeout`이 지정되면 명령이 시간 제한을 초과하면 종료되고 단계가 실패합니다
304
+ - `retry`가 지정되면 성공할때 까지 retry 값 만큼 재시도됩니다
305
+
306
+ ---
307
+
308
+ #### 2. `choose` - 사용자 선택
309
+
310
+ 옵션 목록에서 사용자가 선택하도록 프롬프트를 표시합니다.
311
+
312
+ **문법:**
313
+ ```yaml
314
+ steps:
315
+ - choose:
316
+ message: <string> # 필수: 표시할 질문
317
+ options: # 필수: 옵션 배열
318
+ - id: <string> # 필수: 고유 식별자 (값으로 저장됨)
319
+ label: <string> # 필수: 표시 텍스트
320
+ - id: <string>
321
+ label: <string>
322
+ as: <variable-name> # 선택: 결과를 저장할 변수 이름
323
+ when: <condition> # 초이스 프롬프트 제공 조건
324
+ ```
325
+
326
+ **속성:**
327
+ - `choose.message` (필수): `string` - 사용자에게 표시할 질문 텍스트
328
+ - `choose.options` (필수): 다음을 가진 객체의 `array`:
329
+ - `id` (필수): `string` - 고유 식별자 (이 값이 저장됨)
330
+ - `label` (필수): `string` - 사용자에게 표시할 텍스트
331
+ - `choose.as` (선택): `string` - 선택된 `id`를 저장할 변수 이름
332
+ - 생략 시: choice는 `id`로 저장됩니다 (하위 호환성을 위해)
333
+ - 제공 시: 선택된 `id`가 이 변수 이름으로 저장됩니다
334
+ - `when` (선택): `Condition` - 조건이 충족될 때만 선택 프롬프트 표시
335
+
336
+ **예제:**
337
+ ```yaml
338
+ # 기본 선택
339
+ - choose:
340
+ message: "환경을 선택하세요:"
341
+ options:
342
+ - id: dev
343
+ label: "개발"
344
+ - id: staging
345
+ label: "스테이징"
346
+ - id: prod
347
+ label: "프로덕션"
348
+
349
+ # 변수 저장이 있는 선택
350
+ - choose:
351
+ message: "환경을 선택하세요:"
352
+ options:
353
+ - id: dev
354
+ label: "개발"
355
+ - id: prod
356
+ label: "프로덕션"
357
+ as: env # 선택된 id가 'env' 변수에 저장됨
358
+
359
+ # 조건부 선택
360
+ - when:
361
+ file: ./package.json
362
+ choose:
363
+ message: "테스트를 실행하시겠습니까?"
364
+ options:
365
+ - id: yes
366
+ label: "예"
367
+ - id: no
368
+ label: "아니오"
369
+ as: runTests
370
+ ```
371
+
372
+ **저장:**
373
+ - 선택된 옵션의 `id`는 다음으로 저장됩니다:
374
+ 1. choice ( `hasChoice(id)`로 접근 가능)
375
+ 2. `id` 이름을 가진 변수 (하위 호환성을 위해)
376
+ 3. `as`가 제공된 경우: `as` 이름을 가진 변수로도 저장됨
377
+
378
+ **조건에서 사용:**
379
+ ```yaml
380
+ # 'as: env'가 있는 choice 후
381
+ - when:
382
+ var: # 변수를 사용한다는 정의
383
+ env: prod # 'env' 변수가 'prod'와 같은지 확인
384
+ run: echo "프로덕션에 배포 중"
385
+ ```
386
+
387
+ ---
388
+
389
+ #### 3. `prompt` - 텍스트 입력
390
+
391
+ 사용자에게 텍스트 입력을 요청합니다.
392
+
393
+ **문법:**
394
+ ```yaml
395
+ - prompt:
396
+ message: <string> # 필수: 표시할 질문
397
+ as: <variable-name> # 필수: 결과를 저장할 변수 이름
398
+ default: <string> # 선택: 기본값
399
+ when: <condition> # 선택: 조건이 충족될 때만 프롬프트 표시
400
+ ```
401
+
402
+ **속성:**
403
+ - `prompt.message` (필수): `string` - 사용자에게 표시할 질문 텍스트
404
+ - `prompt.as` (필수): `string` - 입력 값을 저장할 변수 이름
405
+ - `prompt.default` (선택): `string` - 사용자가 입력 없이 Enter를 누를 때의 기본값
406
+ - `when` (선택): `Condition` - 조건이 충족될 때만 프롬프트 표시
407
+
408
+ **예제:**
409
+ ```yaml
410
+ # 기본 프롬프트
411
+ - prompt:
412
+ message: "버전 번호를 입력하세요:"
413
+ as: version
414
+
415
+ # 기본값이 있는 프롬프트
416
+ - prompt:
417
+ message: "버전 번호를 입력하세요:"
418
+ as: version
419
+ default: "1.0.0"
420
+
421
+ # 조건부 프롬프트
422
+ - when:
423
+ var:
424
+ env: prod
425
+ prompt:
426
+ message: "프로덕션 배포 사유를 입력하세요:"
427
+ as: deployReason
428
+ ```
429
+
430
+ **저장:**
431
+ - 사용자 입력은 `as`에 지정된 이름의 변수로 저장됩니다
432
+ - `{{variable}}` 문법으로 명령에서 사용할 수 있습니다
433
+ - `var` 조건으로 조건에서 확인할 수 있습니다
434
+
435
+ **사용:**
436
+ ```yaml
437
+ # 명령에서 사용
438
+ - run: echo "Building version {{version}}"
439
+
440
+ # 조건에서 확인
441
+ - when:
442
+ var:
443
+ version: "1.0.0"
444
+ run: echo "안정 버전 배포 중"
445
+ ```
446
+
447
+ ---
448
+
449
+ #### 4. `parallel` - 병렬 실행
450
+
451
+ 여러 단계를 동시에 실행합니다. `steps`와 마찬가지로 `parallel`은 내부에 step 배열을 가지며, 각 step은 `-`로 시작합니다. 이 step들이 모두 동시에 실행됩니다.
452
+
453
+ **문법:**
454
+ ```yaml
455
+ - parallel:
456
+ - <step1> # 각 step은 `-`로 시작하며, `steps`와 동일한 형식
457
+ - <step2>
458
+ - <step3>
459
+ when?: <condition> # 선택: 조건이 충족될 때만 병렬 블록 실행
460
+ ```
461
+
462
+ **속성:**
463
+ - `parallel` (필수): `Step` 객체의 `array` - 병렬로 실행할 단계 (`steps`와 동일한 형식, 각 step은 `-`로 시작)
464
+ - `when` (선택): `Condition` - 조건이 충족될 때만 병렬 블록 실행
465
+
466
+ **예제:**
467
+ ```yaml
468
+ # 기본 병렬 실행
469
+ # parallel 내부의 각 step은 `-`로 시작하며, `steps`와 동일한 형식
470
+ - parallel:
471
+ - run: npm run test:unit
472
+ - run: npm run test:integration
473
+ - run: npm run lint
474
+
475
+ # 조건이 있는 병렬
476
+ # 각 step은 자신만의 `when` 조건을 가질 수 있습니다
477
+ - parallel:
478
+ - when:
479
+ file: ./src
480
+ run: echo "프론트엔드 빌드 중..."
481
+ - when:
482
+ file: ./api
483
+ run: echo "백엔드 빌드 중..."
484
+
485
+ # 조건부 병렬 블록
486
+ # 전체 parallel 블록에 `when` 조건을 적용할 수 있습니다
487
+ - when:
488
+ var:
489
+ env: staging
490
+ parallel:
491
+ - run: npm run test
492
+ - run: npm run lint
493
+
494
+ # parallel은 모든 step 타입을 포함할 수 있습니다 (run, choose, prompt 등)
495
+ - parallel:
496
+ - run: npm run test
497
+ - choose:
498
+ message: "린트를 실행하시겠습니까?"
499
+ options:
500
+ - id: yes
501
+ label: "예"
502
+ - id: no
503
+ label: "아니오"
504
+ as: runLint
505
+ - prompt:
506
+ message: "버전을 입력하세요:"
507
+ as: version
508
+ ```
509
+
510
+ **동작:**
511
+ - `parallel` 배열의 모든 단계가 동시에 실행을 시작합니다
512
+ - 워크플로우는 모든 병렬 단계가 완료될 때까지 기다립니다
513
+ - 어떤 단계라도 실패하면 워크플로우가 중지됩니다
514
+ - 각 병렬 브랜치는 자체 격리된 워크스페이스 상태를 가집니다 (복제됨)
515
+
516
+ ---
517
+
518
+ #### 5. `fail` - 워크플로우 실패
519
+
520
+ 오류 메시지와 함께 워크플로우를 중지합니다.
521
+
522
+ **문법:**
523
+ ```yaml
524
+ - fail:
525
+ message: <string>
526
+ when?: <condition> # 선택: 조건이 충족될 때만 실패
527
+ ```
528
+
529
+ **속성:**
530
+ - `fail.message` (필수): `string` - 표시할 오류 메시지
531
+ - `when` (선택): `Condition` - 조건이 충족될 때만 실패
532
+
533
+ **예제:**
534
+ ```yaml
535
+ # 파일이 없으면 실패
536
+ - when:
537
+ not:
538
+ file: ./dist
539
+ fail:
540
+ message: "빌드 출력을 찾을 수 없습니다"
541
+
542
+ # 변수 기반 실패
543
+ - when:
544
+ var:
545
+ env: prod
546
+ fail:
547
+ message: "승인 없이는 프로덕션에 배포할 수 없습니다"
548
+ ```
549
+
550
+ **동작:**
551
+ - 워크플로우 실행을 즉시 중지합니다
552
+ - 오류 메시지를 표시합니다
553
+ - 0이 아닌 상태 코드로 종료합니다
554
+
555
+ ---
556
+
557
+ ### 조건 (`when` 절)
558
+
559
+ 조건은 단계가 실행되는 시점을 제어합니다. 모든 조건은 워크스페이스 상태에 대한 질문으로 평가됩니다.
560
+
561
+ #### 조건 타입
562
+
563
+ ##### 1. 파일 존재 (`file`)
564
+
565
+ 파일 또는 디렉토리가 존재하는지 확인합니다.
566
+
567
+ **문법:**
568
+ ```yaml
569
+ when:
570
+ file: <path>
571
+ ```
572
+
573
+ **속성:**
574
+ - `file`: `string` - 파일 또는 디렉토리 경로 (현재 작업 디렉토리 기준)
575
+
576
+ **예제:**
577
+ ```yaml
578
+ - when:
579
+ file: ./dist
580
+ run: echo "빌드가 존재합니다"
581
+
582
+ - when:
583
+ file: ./package.json
584
+ run: npm install
585
+
586
+ - when:
587
+ not:
588
+ file: ./node_modules
589
+ run: npm install
590
+ ```
591
+
592
+ **동작:**
593
+ - 경로는 `process.cwd()` (현재 작업 디렉토리) 기준으로 해석됩니다
594
+ - 파일 또는 디렉토리가 존재하면 `true`, 그렇지 않으면 `false`를 반환합니다
595
+
596
+ ---
597
+
598
+ ##### 2. 변수 값 비교 (`var` 객체)
599
+
600
+ 변수가 특정 값과 같은지 확인합니다.
601
+
602
+ **문법:**
603
+ ```yaml
604
+ when:
605
+ var:
606
+ <variable-name>: <expected-value>
607
+ ```
608
+
609
+ **속성:**
610
+ - `var`: `object` - 변수 이름을 키로, 예상 값을 값으로 가진 객체
611
+ - 키: 변수 이름 (`prompt.as` 또는 `choose.as`에서)
612
+ - 값: 비교할 예상 문자열 값
613
+
614
+ **예제:**
615
+ ```yaml
616
+ # env 변수가 'prod'와 같은지 확인
617
+ - when:
618
+ var:
619
+ env: prod
620
+ run: echo "프로덕션에 배포 중"
621
+
622
+ # version이 특정 값과 같은지 확인
623
+ - when:
624
+ var:
625
+ version: "1.0.0"
626
+ run: echo "안정 버전 배포 중"
627
+
628
+ # 여러 변수 확인 (모두 일치해야 함)
629
+ - when:
630
+ var:
631
+ env: staging
632
+ version: "2.0.0"
633
+ run: echo "스테이징에 v2.0.0 배포 중"
634
+ ```
635
+
636
+ **동작:**
637
+ - 변수 값(문자열)을 예상 값과 비교합니다
638
+ - 값이 정확히 일치하면 `true`를 반환합니다 (대소문자 구분)
639
+ - 변수가 존재하지 않거나 값이 일치하지 않으면 `false`를 반환합니다
640
+ - 객체의 모든 키-값 쌍이 일치해야 합니다 (AND 논리)
641
+
642
+ ---
643
+
644
+ ##### 3. 변수 존재 (`var` 문자열)
645
+
646
+ 변수가 존재하는지 확인합니다 (값과 무관하게).
647
+
648
+ **문법:**
649
+ ```yaml
650
+ when:
651
+ var: <variable-name>
652
+ # 또는
653
+ when:
654
+ has: <variable-name> # var의 별칭
655
+ ```
656
+
657
+ **속성:**
658
+ - `var` 또는 `has`: `string` - 확인할 변수 이름
659
+
660
+ **예제:**
661
+ ```yaml
662
+ # 변수가 존재하는지 확인
663
+ - when:
664
+ var: version
665
+ run: echo "Version: {{version}}"
666
+
667
+ # 'has' 별칭 사용
668
+ - when:
669
+ has: projectName
670
+ run: echo "Project: {{projectName}}"
671
+ ```
672
+
673
+ **동작:**
674
+ - 변수가 존재하면 `true`를 반환합니다 (`prompt.as` 또는 `choose.as`에서)
675
+ - 변수가 존재하지 않으면 `false`를 반환합니다
676
+ - 값을 확인하지 않고 존재 여부만 확인합니다
677
+
678
+ ---
679
+
680
+ ##### 4. 결합된 조건
681
+
682
+ `all`, `any`, `not`을 사용하여 여러 조건을 결합합니다.
683
+
684
+ ###### `all` - AND 논리
685
+
686
+ 모든 조건이 참이어야 합니다.
687
+
688
+ **문법:**
689
+ ```yaml
690
+ when:
691
+ all:
692
+ - <condition1>
693
+ - <condition2>
694
+ - <condition3>
695
+ ```
696
+
697
+ **예제:**
698
+ ```yaml
699
+ - when:
700
+ all:
701
+ - file: ./dist
702
+ - var:
703
+ env: production
704
+ run: echo "프로덕션 빌드 준비 완료"
705
+
706
+ - when:
707
+ all:
708
+ - var:
709
+ env: staging
710
+ - var:
711
+ version: "2.0.0"
712
+ - file: ./dist
713
+ run: echo "스테이징에 v2.0.0 배포 중"
714
+ ```
715
+
716
+ **동작:**
717
+ - 배열의 모든 조건이 `true`일 때만 `true`를 반환합니다
718
+ - 어떤 조건이라도 `false`이면 `false`를 반환합니다
719
+ - 단락 평가: 첫 번째 `false` 후 확인을 중지합니다
720
+
721
+ ---
722
+
723
+ ###### `any` - OR 논리
724
+
725
+ 어떤 조건이라도 참일 수 있습니다.
726
+
727
+ **문법:**
728
+ ```yaml
729
+ when:
730
+ any:
731
+ - <condition1>
732
+ - <condition2>
733
+ - <condition3>
734
+ ```
735
+
736
+ **예제:**
737
+ ```yaml
738
+ - when:
739
+ any:
740
+ - var:
741
+ env: staging
742
+ - var:
743
+ env: production
744
+ run: echo "서버에 배포 중"
745
+
746
+ - when:
747
+ any:
748
+ - file: ./dist
749
+ - file: ./build
750
+ run: echo "빌드 출력을 찾았습니다"
751
+ ```
752
+
753
+ **동작:**
754
+ - 배열의 어떤 조건이라도 `true`이면 `true`를 반환합니다
755
+ - 모든 조건이 `false`일 때만 `false`를 반환합니다
756
+ - 단락 평가: 첫 번째 `true` 후 확인을 중지합니다
757
+
758
+ ---
759
+
760
+ ###### `not` - 부정
761
+
762
+ 조건을 부정합니다.
763
+
764
+ **문법:**
765
+ ```yaml
766
+ when:
767
+ not:
768
+ <condition>
769
+ ```
770
+
771
+ **예제:**
772
+ ```yaml
773
+ # 파일이 없으면 실패
774
+ - when:
775
+ not:
776
+ file: ./dist
777
+ fail:
778
+ message: "빌드 출력을 찾을 수 없습니다"
779
+
780
+ # 변수가 값과 같지 않으면 실행
781
+ - when:
782
+ not:
783
+ var:
784
+ env: prod
785
+ run: echo "프로덕션 환경이 아닙니다"
786
+
787
+ # 복잡한 부정
788
+ - when:
789
+ not:
790
+ all:
791
+ - file: ./dist
792
+ - var:
793
+ env: prod
794
+ run: echo "프로덕션 준비가 되지 않았습니다"
795
+ ```
796
+
797
+ **동작:**
798
+ - 내부 조건이 `false`이면 `true`를 반환합니다
799
+ - 내부 조건이 `true`이면 `false`를 반환합니다
800
+ - 모든 조건 타입을 부정할 수 있습니다
801
+
802
+ ---
803
+
804
+ ##### 5. 중첩된 조건
805
+
806
+ 조건을 중첩하여 복잡한 논리를 만들 수 있습니다.
807
+
808
+ **예제:**
809
+ ```yaml
810
+ # 복잡한 중첩 조건
811
+ - when:
812
+ all:
813
+ - file: ./dist
814
+ - any:
815
+ - var:
816
+ env: staging
817
+ - var:
818
+ env: production
819
+ - not:
820
+ var:
821
+ version: "0.0.0"
822
+ run: echo "배포 준비 완료"
823
+
824
+ # 여러 수준의 중첩
825
+ - when:
826
+ any:
827
+ - all:
828
+ - var:
829
+ env: prod
830
+ - file: ./dist
831
+ - all:
832
+ - var:
833
+ env: staging
834
+ - not:
835
+ file: ./test-results
836
+ run: echo "조건부 배포"
837
+ ```
838
+
839
+ ---
840
+
841
+ ### 변수 치환
842
+
843
+ 변수는 `{{variable}}` 문법을 사용하여 명령에서 사용할 수 있습니다.
844
+
845
+ **문법:**
846
+ ```yaml
847
+ run: echo "{{variableName}}"
848
+ ```
849
+
850
+ **예제:**
851
+ ```yaml
852
+ # 프롬프트 변수 사용
853
+ - prompt:
854
+ message: "프로젝트 이름을 입력하세요:"
855
+ as: projectName
856
+ - run: echo "Building {{projectName}}..."
857
+
858
+ # 선택 변수 사용
859
+ - choose:
860
+ message: "환경을 선택하세요:"
861
+ options:
862
+ - id: dev
863
+ label: "개발"
864
+ as: env
865
+ - run: echo "Deploying to {{env}}"
866
+
867
+ # 여러 변수
868
+ - run: echo "Building {{projectName}} version {{version}} for {{env}}"
869
+ ```
870
+
871
+ **동작:**
872
+ - 변수는 문자열 값으로 대체됩니다
873
+ - 변수가 존재하지 않으면 빈 문자열로 대체됩니다
874
+ - 변수는 실행 시점에 해석됩니다
875
+
876
+ ---
877
+
878
+ ### 완전한 예제
879
+
880
+ 모든 기능을 보여주는 완전한 예제입니다:
881
+
882
+ ```yaml
883
+ name: Complete Workflow Example
884
+ description: |
885
+ 이 워크플로우는 모든 DSL 기능을 보여줍니다:
886
+ - baseDir 설정
887
+ - 사용자 선택 및 프롬프트
888
+ - 변수 사용
889
+ - 조건부 실행
890
+ - 병렬 실행
891
+ - 파일 확인
892
+
893
+ baseDir: ./
894
+
895
+ steps:
896
+ # 1. 간단한 명령
897
+ - run: echo "워크플로우 시작 중..."
898
+
899
+ # 2. 변수 저장이 있는 사용자 선택
900
+ - choose:
901
+ message: "배포 환경을 선택하세요:"
902
+ options:
903
+ - id: dev
904
+ label: "개발"
905
+ - id: staging
906
+ label: "스테이징"
907
+ - id: prod
908
+ label: "프로덕션"
909
+ as: env
910
+
911
+ # 3. 변수 값 기반 조건부 단계
912
+ - when:
913
+ var:
914
+ env: prod
915
+ prompt:
916
+ message: "프로덕션 배포 사유를 입력하세요:"
917
+ as: deployReason
918
+
919
+ # 4. 변수 값 비교
920
+ - when:
921
+ var:
922
+ env: dev
923
+ run: echo "개발 환경에 배포 중..."
924
+
925
+ - when:
926
+ var:
927
+ env: staging
928
+ run: echo "스테이징에 배포 중..."
929
+
930
+ # 5. 복잡한 조건 (all)
931
+ - when:
932
+ all:
933
+ - var:
934
+ env: prod
935
+ - var: deployReason
936
+ - file: ./dist
937
+ run: echo "프로덕션 배포 승인됨"
938
+
939
+ # 6. 병렬 실행
940
+ - parallel:
941
+ - run: npm run test:unit
942
+ - run: npm run test:integration
943
+ - run: npm run lint
944
+
945
+ # 7. 파일 존재 확인
946
+ - when:
947
+ file: ./test-results
948
+ run: echo "테스트 완료"
949
+
950
+ # 8. 결합된 조건 (any)
951
+ - when:
952
+ any:
953
+ - var:
954
+ env: staging
955
+ - var:
956
+ env: prod
957
+ run: echo "서버에 배포 중..."
958
+
959
+ # 9. 부정
960
+ - when:
961
+ not:
962
+ file: ./dist
963
+ fail:
964
+ message: "빌드 출력을 찾을 수 없습니다"
965
+
966
+ # 10. 변수 치환
967
+ - run: echo "Deploying {{projectName}} version {{version}} to {{env}}"
968
+ ```
969
+
970
+ ---
971
+
972
+ ## 📚 예제
973
+
974
+ ### 프로젝트 예제
975
+
976
+ 완전한 프로젝트 예제는 `examples/` 디렉토리를 확인하세요:
977
+
978
+ - **`monorepo-example/`** - 여러 프로젝트가 있는 모노레포 워크플로우
979
+ - **`simple-project/`** - 간단한 단일 프로젝트 워크플로우
980
+ - **`react-app/`** - React 애플리케이션 빌드 및 배포
981
+
982
+ ### YAML 예제
983
+
984
+ `examples/yaml-examples/`에서 YAML 워크플로우 예제를 확인하세요:
985
+
986
+ - **`basic.yaml`** - 선택과 조건이 있는 기본 워크플로우
987
+ - **`simple.yaml`** - 최소한의 워크플로우 예제
988
+ - **`parallel.yaml`** - 병렬 실행 예제
989
+ - **`conditions.yaml`** - 다양한 조건 타입
990
+ - **`file-checks.yaml`** - 파일 존재 확인
991
+ - **`prompt.yaml`** - 사용자 입력 프롬프트
992
+ - **`variables.yaml`** - 변수 치환 예제
993
+
994
+ ### JSON 예제
995
+
996
+ `examples/json-examples/`에서 JSON 워크플로우 예제를 확인하세요 (YAML 예제와 동일):
997
+
998
+ - **`basic.json`** - 선택과 조건이 있는 기본 워크플로우
999
+ - **`simple.json`** - 최소한의 워크플로우 예제
1000
+ - **`parallel.json`** - 병렬 실행 예제
1001
+ - **`conditions.json`** - 조건 평가 예제
1002
+ - **`prompt.json`** - 사용자 입력 프롬프트
1003
+ - **`variables.json`** - 변수 치환 예제
1004
+
1005
+ **참고:** YAML과 JSON 형식 모두 완전히 지원됩니다. 선호하는 형식을 선택하세요 - 가독성을 위해 YAML, 프로그래밍 방식 생성을 위해 JSON.
1006
+ - **`variables.yaml`** - 변수 사용 예제
1007
+ - **`prompt.yaml`** - 텍스트 프롬프트 예제
1008
+ - **`var-value-example.yaml`** - 변수 값 비교 예제
1009
+ - **`choice-as-example.yaml`** - 선택에서 `as` 키워드 사용
1010
+ - **`base-dir-example.yaml`** - baseDir 설정 예제
1011
+ - **`timeout-retry-example.yaml`** - 타임아웃 및 재시도 기능
1012
+ - **`cicd.yaml`** - CI/CD 파이프라인 예제
1013
+ - **`advanced.yaml`** - 고급 워크플로우 패턴
1014
+ - **`multi-choice.yaml`** - 여러 순차적 선택
1015
+ - **`react.yaml`** - React 전용 워크플로우
1016
+
1017
+ ## 아키텍처
1018
+
1019
+ - **CLI**: Commander.js를 사용한 Node.js + TypeScript
1020
+ - **작업 실행**: 스트리밍 출력이 있는 Node.js 자식 프로세스
1021
+ - **UI**: 아름다운 터미널 출력을 위한 Boxen과 Chalk
1022
+ - **프롬프트**: 대화형 프롬프트를 위한 Inquirer.js
1023
+
1024
+ ## 기여하기
1025
+
1026
+ 기여를 환영합니다! ISSUE를 남겨주세요.
1027
+
1028
+ ## 라이선스
1029
+
1030
+ Copyright (c) 2024 racgoo
1031
+
1032
+ ## 문의 및 연락
1033
+
1034
+ 문의 사항은 lhsung98@naver.com 으로 메일 보내주세요!