From d4e02592a8cd03b76de941edeb8fceecdd7281d3 Mon Sep 17 00:00:00 2001 From: toki Date: Sun, 19 Apr 2026 14:42:26 +0900 Subject: [PATCH] update .claude/settings.json and README.md --- .claude/settings.json | 3 +- README.md | 374 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 374 insertions(+), 3 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index 6d8ce3a..c943410 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -3,7 +3,8 @@ "allow": [ "Read(**)", "Bash(bash agent-ops/bin/sync.sh agentic-framework)", - "Bash(git commit -m ' *)" + "Bash(git commit -m ' *)", + "Bash(grep \"\\\\.dart$\")" ] } } diff --git a/README.md b/README.md index 3816eca..ae6ec09 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,372 @@ -A sample command-line application with an entrypoint in `bin/`, library code -in `lib/`, and example unit test in `test/`. +# OTO CLI + +YAML로 정의된 CI/CD 파이프라인을 실행하는 Dart 기반 자동화 도구. +Jenkins, FTP, Git, Slack/Mattermost, iOS/Flutter/Android 빌드 등 다양한 작업을 커맨드로 추상화하고, 파이프라인 엔진이 순차 실행한다. + +--- + +## 설치 + +```bash +dart pub get +dart compile exe bin/main.dart -o oto +``` + +--- + +## 실행 모드 + +| 플래그 | 모드 | 설명 | +|--------|------|------| +| `-j` | `jenkins` | Jenkins 환경 변수에서 워크스페이스·YAML 읽기 | +| `-t` | `test` | 하드코딩된 테스트 데이터로 로컬 실행 | +| `-f ` | `file` | 지정한 YAML 파일 경로에서 파이프라인 실행 | +| (daemon) | `scheduler` | 스케줄러 데몬 모드 | + +```bash +oto -j # Jenkins CI 모드 +oto -t # 로컬 테스트 모드 +oto -f ./build.yaml # 파일 기반 실행 +``` + +--- + +## 실행 흐름 + +``` +bin/main.dart + └── Application (singleton) + └── DataComposer ← YAML + Jenkins env 파싱 + └── Pipeline + └── Command.byType(CommandType) → execute(DataCommand) +``` + +--- + +## YAML 파이프라인 구조 + +```yaml +property: + workspace: /path/to/project + version: 1.0.0 + env: prod + +commands: + - command: BuildiOS + id: buildApp + param: + workspacePath: /ios/Runner.xcworkspace + scheme: Runner + +pipeline: + workflow: + - exe: buildApp +``` + +### 태그 시스템 + +| 태그 | 방향 | 설명 | +|------|------|------| +| `` | 읽기 | property에서 값 치환 | +| `<@property.key>` | 쓰기 | 커맨드 결과를 property에 저장 | + +- 태그가 문자열 전체이면 원본 타입(List, Map 등) 유지 +- 태그가 문자열 일부이면 `toString()` 변환 +- 중첩 접근 지원: `` + +--- + +## 파이프라인 흐름 제어 + +### exe — 단순 실행 + +```yaml +- exe: buildApp +``` + +### exe-handle — 성공/실패 분기 + +```yaml +- exe-handle: + id: uploadArtifact + on-success: + - exe: notifySuccess + on-fail: + - exe: notifyError +``` + +### if — 조건 분기 + +```yaml +- if: + condition-string: " == prod" + type: string + on-true: + - exe: deployProd + on-false: + - exe: deployDev +``` + +**지원 연산자:** `==`, `!=`, `<`, `<=`, `>`, `>=` + +**지원 타입:** `string`, `int`, `float`, `bool`, `date`, `version`, `object` + +### foreach — 반복 + +```yaml +- foreach: + iterator: # List 또는 Map + setValue: <@property.target> + on-do: + - exe: buildTarget +``` + +### while — 조건 루프 + +```yaml +- while: + condition-string: " < 3" + type: int + on-do: + - exe: checkStatus +``` + +### switch — 멀티 케이스 + +```yaml +- switch: + value: + cases: + prod: + - exe: deployProd + dev: + - exe: deployDev +``` + +### wait-until — 대기 + +```yaml +- wait-until-true: + condition-string: " == complete" + interval: 10 +``` + +### async — 비동기 실행 + +```yaml +- async: notifyStart # 완료를 기다리지 않고 다음 단계 진행 +``` + +--- + +## 커맨드 목록 + +### 빌드 + +| 커맨드 | 설명 | +|--------|------| +| `BuildiOS` | xcodebuild로 iOS 앱 빌드 | +| `ArchiveiOS` | xcodebuild archive | +| `ExportiOS` | xcodebuild -exportArchive | +| `PublishiOS` | App Store Connect 배포 | +| `TestflightUpload` | TestFlight 업로드 | +| `TestflightStatusCheck` | TestFlight 처리 상태 확인 | +| `TestflightDistribute` | TestFlight 그룹 배포 | +| `BuildFlutter` | flutter build | +| `BuildDart` | dart build | +| `BuildDartCompile` | dart compile | +| `BuildMSBuild` | MSBuild (.NET) | +| `ProductBuild` | macOS productbuild | +| `Notarize` | macOS 공증 | + +### 파일 + +| 커맨드 | 설명 | +|--------|------| +| `Copy` | 파일/디렉토리 복사 (이동 포함) | +| `Delete` | 파일/디렉토리 삭제 | +| `Rename` | 이름 변경 | +| `FileRead` | 파일 읽기 → property 저장 | +| `FileWrite` | property 값 → 파일 쓰기 | +| `Files` | 파일 목록 조회 | +| `FileInfo` | 파일 메타데이터 조회 | +| `DirectoryCreate` | 디렉토리 생성 | +| `Zip` | 압축/해제 | + +### Git + +| 커맨드 | 설명 | +|--------|------| +| `Git` | 임의 git 명령 실행 | +| `GitCommit` | 변경사항 커밋 | +| `GitPull` | pull | +| `GitPush` | push | +| `GitCheckout` | 브랜치/파일 체크아웃 | +| `GitRev` | 리비전 해시 조회 | +| `GitCount` | 커밋 수 조회 | +| `GitReset` | reset | +| `GitStashPush` / `GitStashApply` | stash 관리 | +| `GitBranch` | 브랜치 목록/생성/삭제 | +| `GitHub` | GitHub API 호출 | +| `GitHubPullRequestCreate` / `List` / `Close` | PR 관리 | + +### 알림 + +| 커맨드 | 설명 | +|--------|------| +| `Slack` | Slack 메시지 전송 | +| `SlackFile` | Slack 파일 업로드 | +| `SlackBuild` | 빌드 결과 Slack 리포트 | +| `Mattermost` | Mattermost 메시지 전송 | +| `MattermostBuild` | 빌드 결과 Mattermost 리포트 | + +### 네트워크 / FTP + +| 커맨드 | 설명 | +|--------|------| +| `Upload` | FTP 업로드 | +| `Download` | FTP 다운로드 | +| `WebRequest` | HTTP 요청 | +| `WebFile` | HTTP 파일 다운로드 | +| `URLInfo` | URL 정보 파싱 | + +### 문자열 / 유틸 + +| 커맨드 | 설명 | +|--------|------| +| `Print` | 메시지 출력 | +| `SetValue` | property 값 직접 설정 | +| `Delay` | 지연 (초) | +| `Timer` | 경과 시간 측정 | +| `StringSub` | 문자열 자르기 | +| `StringReplace` | 문자열 치환 | +| `StringReplacePattern` | 정규식 치환 | +| `StringIndex` | 인덱스 검색 | +| `JsonReader` | JSON 값 읽기 | +| `JsonReaderFile` | JSON 파일 읽기 | +| `JsonWriterFile` | JSON 파일 쓰기 | + +### 셸 / 프로세스 + +| 커맨드 | 설명 | +|--------|------| +| `Shell` | 셸 명령 실행 | +| `ShellFile` | 셸 스크립트 파일 실행 | +| `ProcessRun` | 프로세스 실행 | +| `ProcessKill` | 프로세스 종료 | +| `ProcessPortUse` | 포트 사용 여부 확인 | + +### 외부 서비스 + +| 커맨드 | 설명 | +|--------|------| +| `Jira` | Jira 이슈 조회/수정 | +| `AwsCli` | AWS CLI 명령 실행 | +| `Docker` | Docker 명령 실행 | +| `Gradle` | Gradle 빌드 실행 | +| `Protobuf` | protoc 컴파일 | +| `JenkinsParameterModify` | Jenkins 파라미터 수정 | +| `SMBAuth` | SMB 인증 | + +--- + +## 데이터 모델 구조 + +모든 커맨드 파라미터는 `DataParam`을 상속한다. + +```dart +DataParam +├── workspace?: String // 기본 작업 디렉토리 +├── passExitCodes?: List // 성공으로 간주할 exit code +├── setResult?: String // 결과 저장 태그 +├── setExitCode?: String // exit code 저장 태그 +└── showPrint?: bool + +// 예시 +DataBuildiOS extends DataParam { + workspacePath: String + scheme: String + destination: String + ... +} +``` + +**워크스페이스 해석 우선순위:** +1. `param.workspace` +2. `property.workspace` +3. `DataCommon.workspace` (Jenkins env) + +--- + +## 새 커맨드 추가 + +``` +1. lib/oto/data/*.dart DataParam 상속 모델 정의 + @JsonSerializable +2. lib/oto/commands/command.dart CommandType enum에 값 추가 +3. lib/oto/commands/{category}/ Command 상속 클래스 구현 +4. lib/oto/commands/command_registry.dart registerAllCommands()에 등록 +5. dart run build_runner build *.g.dart 생성 +``` + +--- + +## 스케줄러 + +```bash +oto scheduler -r build.yaml # 스케줄러 등록 +oto scheduler -l # 목록 조회 +oto scheduler -e true # 활성화/비활성화 +oto scheduler -u # 해제 +``` + +**YAML 스케줄러 설정:** + +```yaml +scheduler: + alias: nightly-build + cron: "0 2 * * *" # cron 표현식 또는 + # interval: 3600 # 초 단위 interval + enableLog: true +``` + +**플랫폼별 실행 메커니즘:** +- **Linux:** cron +- **macOS:** LaunchAgent +- **Windows:** Task Scheduler + +--- + +## 프로젝트 구조 + +``` +lib/ +├── cli/ # CLI 인자 파싱, 스케줄러 관리 +├── framework/ # 플랫폼 추상화, ProcessExecutor, 로깅 +└── oto/ + ├── application.dart # 싱글턴 오케스트레이터 + ├── commands/ # 커맨드 구현체 (카테고리별) + ├── core/ # 태그 시스템, 데이터 합성, 정의 데이터 + ├── data/ # JSON 직렬화 데이터 모델 (*.g.dart 포함) + ├── pipeline/ # 파이프라인 흐름 제어 엔진 + └── utils/ # 공통 유틸리티 +``` + +--- + +## 기술 스택 + +- **언어:** Dart (SDK >=2.18.6 <4.0.0) +- **의존성:** dart_framework (커스텀), http, json_annotation, cron, xml +- **코드 생성:** json_serializable + build_runner + +```bash +dart run build_runner build # 데이터 모델 생성 +``` + +--- + +## 에러 처리 + +- `Application.build()`는 `catch (e, stacktrace)`로 Exception과 Error 모두 처리 +- 실패 시 `exit(10)` 으로 부모 프로세스에 실패 신호 전달 +- `passExitCodes`로 성공으로 간주할 exit code 지정 가능