yakcloud CLI 추가(init/deploy/check) + install.sh + 공개용 README
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -16,6 +16,15 @@ YakCloud 콘솔 API로 **데이터소스 리컨실 + 워크로드 배포 + 바
|
|||||||
- "새 프로젝트 시작해서 배포까지" (→ `assets/starter/` 로 스캐폴딩)
|
- "새 프로젝트 시작해서 배포까지" (→ `assets/starter/` 로 스캐폴딩)
|
||||||
- "데이터소스(Postgres/Mongo/…) 연결/바인딩" / "커스텀 도메인으로 노출"
|
- "데이터소스(Postgres/Mongo/…) 연결/바인딩" / "커스텀 도메인으로 노출"
|
||||||
|
|
||||||
|
## CLI 가 있으면 우선 사용
|
||||||
|
`yakcloud` CLI 가 설치돼 있으면(명령 `command -v yakcloud`) 스캐폴딩/배포를 이걸로 처리한다:
|
||||||
|
- **"프로젝트 초기화"** → 빈 폴더에서 `yakcloud init [name]` (스타터+CI+매니페스트+이 스킬을 내려받음)
|
||||||
|
- **"yakcloud 에 배포"** → `yakcloud deploy vX.Y.Z` (커밋+태그 push → Gitea Actions)
|
||||||
|
- 사전 점검 → `yakcloud check` (dry-run)
|
||||||
|
|
||||||
|
설치: `curl -fsSL https://gitea.yakenator.io/yakenator/yakcloud-starter/raw/branch/main/install.sh | sh`
|
||||||
|
CLI 가 없거나 세밀 조정이 필요하면 아래 수동 절차를 따른다.
|
||||||
|
|
||||||
## 에이전트 실행 절차
|
## 에이전트 실행 절차
|
||||||
|
|
||||||
### 0) 상황 파악
|
### 0) 상황 파악
|
||||||
|
|||||||
76
.claude/skills/yakcloud-deploy/assets/bin/yakcloud
Normal file
76
.claude/skills/yakcloud-deploy/assets/bin/yakcloud
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# yakcloud — YakCloud 프로젝트 CLI. 빈 폴더 초기화(스타터+스킬) + 태그 push 자동배포.
|
||||||
|
# yakcloud init [name] 현재(빈) 폴더 또는 name/ 에 스타터 스캐폴딩(.claude 스킬 포함)
|
||||||
|
# yakcloud deploy [vX.Y.Z] 커밋 + 태그 push → Gitea Actions 자동 배포
|
||||||
|
# yakcloud check dry-run(직접 API, 계획만; YAKCLOUD_URL/TOKEN 필요)
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO="${YAKCLOUD_STARTER_REPO:-https://gitea.yakenator.io/yakenator/yakcloud-starter}"
|
||||||
|
BRANCH="${YAKCLOUD_STARTER_BRANCH:-main}"
|
||||||
|
VERSION="0.1.0"
|
||||||
|
|
||||||
|
die() { echo "✗ $*" >&2; exit 1; }
|
||||||
|
info() { echo "▸ $*"; }
|
||||||
|
|
||||||
|
cmd_init() {
|
||||||
|
local name="${1:-}"
|
||||||
|
if [ -n "$name" ]; then
|
||||||
|
mkdir -p "$name" && cd "$name"
|
||||||
|
fi
|
||||||
|
# 빈 폴더인지 확인(.git 은 허용)
|
||||||
|
if [ -n "$(ls -A . 2>/dev/null | grep -v '^\.git$' || true)" ]; then
|
||||||
|
die "폴더가 비어있지 않습니다. 빈 폴더에서 실행하거나 'yakcloud init <name>' 로 새 폴더에 생성하세요."
|
||||||
|
fi
|
||||||
|
info "yakcloud-starter 내려받는 중… ($REPO @ $BRANCH)"
|
||||||
|
curl -fsSL "$REPO/archive/$BRANCH.tar.gz" | tar xz --strip-components=1 \
|
||||||
|
|| die "스타터 다운로드 실패 — 네트워크/레포 공개 여부 확인"
|
||||||
|
# 프로젝트 이름 치환(선택)
|
||||||
|
if [ -n "$name" ] && [ -f yakcloud.yaml ]; then
|
||||||
|
sed -i.bak "s/^project: .*/project: $name/" yakcloud.yaml && rm -f yakcloud.yaml.bak
|
||||||
|
fi
|
||||||
|
git rev-parse --git-dir >/dev/null 2>&1 || git init -q
|
||||||
|
echo "✓ 초기화 완료 ($(pwd))"
|
||||||
|
echo " 다음:"
|
||||||
|
echo " 1) yakcloud.yaml 의 cluster / image(<GITEA_USER>) 수정, 필요하면 requires·binds 추가"
|
||||||
|
echo " 2) 앱 개발 (Claude Code 스킬: .claude/skills/yakcloud-deploy)"
|
||||||
|
echo " 3) Gitea 레포 연결 + Secrets(YAKCLOUD_URL/TOKEN/CLUSTER, REGISTRY_TOKEN) 설정"
|
||||||
|
echo " 4) yakcloud deploy v0.1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_deploy() {
|
||||||
|
[ -f yakcloud.yaml ] || die "yakcloud.yaml 없음 — 먼저 'yakcloud init'"
|
||||||
|
local ver="${1:-v0.1.0}"
|
||||||
|
case "$ver" in v*) : ;; *) ver="v$ver" ;; esac
|
||||||
|
git rev-parse --git-dir >/dev/null 2>&1 || git init -q
|
||||||
|
git remote get-url origin >/dev/null 2>&1 \
|
||||||
|
|| die "git 원격(origin) 없음 — Gitea 레포를 만들어 'git remote add origin <url>' 후, 레포 Secrets 설정 뒤 다시 실행"
|
||||||
|
info "커밋 + 태그 $ver push…"
|
||||||
|
git add -A
|
||||||
|
git commit -q -m "deploy $ver" 2>/dev/null || true
|
||||||
|
git push -q origin HEAD 2>/dev/null || true
|
||||||
|
git tag "$ver" 2>/dev/null || die "태그 $ver 이미 존재 — 다른 버전으로"
|
||||||
|
git push -q origin "$ver"
|
||||||
|
echo "✓ $ver push — Gitea Actions 에서 빌드·배포 진행. 콘솔 앱 탭/도메인에서 확인."
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_check() {
|
||||||
|
[ -f scripts/yakcloud_deploy.py ] || die "scripts/yakcloud_deploy.py 없음 — 'yakcloud init' 먼저"
|
||||||
|
: "${YAKCLOUD_URL:?YAKCLOUD_URL 필요}"
|
||||||
|
: "${YAKCLOUD_TOKEN:?YAKCLOUD_TOKEN(배포 토큰) 필요}"
|
||||||
|
python3 -c "import yaml" 2>/dev/null || pip3 install --quiet pyyaml
|
||||||
|
python3 scripts/yakcloud_deploy.py yakcloud.yaml --dry-run
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-help}" in
|
||||||
|
init) shift; cmd_init "$@" ;;
|
||||||
|
deploy) shift; cmd_deploy "$@" ;;
|
||||||
|
check|dry-run) shift; cmd_check "$@" ;;
|
||||||
|
version|-v|--version) echo "yakcloud $VERSION" ;;
|
||||||
|
*) cat <<EOF
|
||||||
|
yakcloud $VERSION — YakCloud 프로젝트 CLI
|
||||||
|
yakcloud init [name] 빈 폴더에 스타터 스캐폴딩(앱+CI+매니페스트+Claude 스킬)
|
||||||
|
yakcloud deploy [vX.Y.Z] 커밋 + 태그 push → Gitea Actions 자동 배포
|
||||||
|
yakcloud check dry-run(직접 API 계획만; YAKCLOUD_URL/TOKEN 필요)
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
esac
|
||||||
15
.claude/skills/yakcloud-deploy/assets/install.sh
Normal file
15
.claude/skills/yakcloud-deploy/assets/install.sh
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# yakcloud CLI 설치 — PATH 의 bin 디렉터리에 내려받는다.
|
||||||
|
# curl -fsSL https://gitea.yakenator.io/yakenator/yakcloud-starter/raw/branch/main/install.sh | sh
|
||||||
|
# 설치 위치 변경: DEST=/usr/local/bin sh install.sh
|
||||||
|
set -e
|
||||||
|
REPO="${YAKCLOUD_STARTER_REPO:-https://gitea.yakenator.io/yakenator/yakcloud-starter}"
|
||||||
|
BRANCH="${YAKCLOUD_STARTER_BRANCH:-main}"
|
||||||
|
DEST="${DEST:-$HOME/.local/bin}"
|
||||||
|
mkdir -p "$DEST"
|
||||||
|
echo "▸ yakcloud CLI 설치 → $DEST/yakcloud"
|
||||||
|
curl -fsSL "$REPO/raw/branch/$BRANCH/bin/yakcloud" -o "$DEST/yakcloud"
|
||||||
|
chmod +x "$DEST/yakcloud"
|
||||||
|
echo "✓ 완료. PATH 에 $DEST 가 있는지 확인하세요:"
|
||||||
|
echo ' export PATH="$HOME/.local/bin:$PATH"'
|
||||||
|
echo " 사용: yakcloud init my-app → 개발 → yakcloud deploy v0.1.0"
|
||||||
66
README.md
66
README.md
@ -1,41 +1,47 @@
|
|||||||
# yakcloud-starter — YakCloud 배포 기반(스타터) + Claude Code 스킬
|
# yakcloud-starter — YakCloud 프로젝트 기반 + CLI + Claude Code 스킬
|
||||||
|
|
||||||
새 프로젝트를 **YakCloud 선언적 CI/CD**(Gitea 태그 push → 자동 배포)로 시작하기 위한 **기반 레포**다.
|
빈 폴더에서 **한 명령으로 새 프로젝트를 초기화**하고, **태그 push로 YakCloud에 자동 배포**하기 위한 기반.
|
||||||
프레임워크 중립 최소 앱 + CI + 매니페스트 + **Claude Code 스킬**(`.claude/skills/yakcloud-deploy/`)이 들어 있어,
|
프레임워크 중립 스타터 앱 + CI + 매니페스트 + **`yakcloud` CLI** + **Claude Code 스킬**(`.claude/skills/yakcloud-deploy/`)이 들어 있다.
|
||||||
클론하면 바로 굴리거나, Claude Code에게 맡겨 원하는 대로 **추가/삭제**하며 확장할 수 있다.
|
|
||||||
|
|
||||||
|
## CLI 설치 (1회)
|
||||||
|
```sh
|
||||||
|
curl -fsSL https://gitea.yakenator.io/yakenator/yakcloud-starter/raw/branch/main/install.sh | sh
|
||||||
|
# PATH: export PATH="$HOME/.local/bin:$PATH"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 빈 폴더 → 배포까지
|
||||||
|
```sh
|
||||||
|
yakcloud init my-app # 빈 폴더에 스타터+CI+매니페스트+Claude 스킬 스캐폴딩
|
||||||
|
cd my-app
|
||||||
|
# (앱 개발 — Claude Code 로: "yakcloud 로 배포 붙여줘" / 앱 코드 작성)
|
||||||
|
# yakcloud.yaml 의 cluster / image(<GITEA_USER>) 수정, 필요하면 requires·binds 추가
|
||||||
|
yakcloud deploy v0.1.0 # 커밋 + 태그 push → Gitea Actions 자동 배포
|
||||||
|
```
|
||||||
|
> **Claude Code 흐름**: 빈 폴더에서 Claude Code를 열고 "프로젝트 초기화해줘" → Claude가 `yakcloud init` 실행 →
|
||||||
|
> 개발 → "yakcloud에 배포해줘" → Claude가 `yakcloud deploy` 실행. (CLI가 없으면 스킬의 수동 절차로 진행)
|
||||||
|
|
||||||
|
## 배포 전 1회 준비
|
||||||
|
1. 콘솔 → 설정 → **배포 토큰** 발급(`yakd_…`).
|
||||||
|
2. Gitea 레포 만들고 `git remote add origin …`. **Secrets**: `YAKCLOUD_URL`, `YAKCLOUD_TOKEN`, `YAKCLOUD_CLUSTER`, `REGISTRY_TOKEN`.
|
||||||
|
3. `yakcloud.yaml` 의 `cluster`·`image` 수정.
|
||||||
|
|
||||||
|
사전 점검(직접 API, 계획만):
|
||||||
|
```sh
|
||||||
|
YAKCLOUD_URL=https://console.yakenator.io YAKCLOUD_TOKEN=yakd_… yakcloud check
|
||||||
|
```
|
||||||
|
|
||||||
|
## 구성
|
||||||
|
```
|
||||||
|
bin/yakcloud # CLI(init/deploy/check)
|
||||||
|
install.sh # CLI 설치
|
||||||
.claude/skills/yakcloud-deploy/ # Claude Code 스킬(SKILL.md + assets) — 프로젝트에 그대로 따라감
|
.claude/skills/yakcloud-deploy/ # Claude Code 스킬(SKILL.md + assets) — 프로젝트에 그대로 따라감
|
||||||
app.py Dockerfile # 프레임워크 중립 스타터(표준 라이브러리, /healthz + PORT)
|
app.py Dockerfile # 프레임워크 중립 스타터(표준 라이브러리, /healthz + PORT)
|
||||||
yakcloud.yaml # 배포 매니페스트(대상 클러스터·소스·워크로드)
|
yakcloud.yaml # 배포 매니페스트
|
||||||
.gitea/workflows/deploy.yml # 태그 push CI(매니페스트 구동 — 수정 불필요)
|
.gitea/workflows/deploy.yml # 태그 push CI(매니페스트 구동 — 수정 불필요)
|
||||||
scripts/yakcloud_deploy.py # 리컨실 배포 CLI
|
scripts/yakcloud_deploy.py # 리컨실 배포 CLI
|
||||||
DATA-SOURCES.md # 소스별 주입 env 표
|
DATA-SOURCES.md # 소스별 주입 env 표
|
||||||
```
|
```
|
||||||
|
|
||||||
## 새 프로젝트 시작 (택1)
|
|
||||||
**A. 이 레포를 템플릿으로 클론**
|
|
||||||
```sh
|
|
||||||
git clone https://gitea.yakenator.io/yakenator/yakcloud-starter.git my-app
|
|
||||||
cd my-app && rm -rf .git && git init
|
|
||||||
```
|
|
||||||
**B. Claude Code로**: 새 프로젝트에서 `.claude/skills/yakcloud-deploy/` 만 복사해두면, Claude가 스킬을 참고해
|
|
||||||
앱·매니페스트·CI를 상황에 맞게 **추가/삭제**하며 스캐폴딩한다. (예: "yakcloud로 배포 붙여줘")
|
|
||||||
|
|
||||||
## 굴리기 (요약 — 상세는 SKILL.md §4~5)
|
|
||||||
1. 콘솔 → 설정 → **배포 토큰** 발급(`yakd_…`).
|
|
||||||
2. Gitea 레포 **Secrets**: `YAKCLOUD_URL`, `YAKCLOUD_TOKEN`, `YAKCLOUD_CLUSTER`, `REGISTRY_TOKEN`.
|
|
||||||
3. `yakcloud.yaml` 의 `cluster` / `image`(`<GITEA_USER>`) / (필요시) `requires`·`binds` 수정.
|
|
||||||
4. `git tag v0.1.0 && git push origin v0.1.0` → Actions 실행 → 콘솔 앱 탭/도메인 확인.
|
|
||||||
|
|
||||||
로컬 사전 점검:
|
|
||||||
```sh
|
|
||||||
YAKCLOUD_URL=https://console.yakenator.io YAKCLOUD_TOKEN=yakd_… \
|
|
||||||
python3 scripts/yakcloud_deploy.py yakcloud.yaml --dry-run
|
|
||||||
```
|
|
||||||
|
|
||||||
## 확장(추가/삭제)
|
## 확장(추가/삭제)
|
||||||
- **워크로드 추가**: `yakcloud.yaml` `workloads[]` 에 `{name, build, image, port, health, binds}` 추가(+ 그 build 컨텍스트에 Dockerfile).
|
- **워크로드/데이터소스/도메인 추가·삭제**는 `yakcloud.yaml` 을 편집하고 `yakcloud deploy` — 멱등 리컨실로 반영.
|
||||||
- **데이터 소스 추가**: `requires[]` 에 `{name,type,plan}` + 워크로드 `binds` 에 `{alias, source}`. 앱은 `<ALIAS>_URL` 로 접속.
|
- 상세: `.claude/skills/yakcloud-deploy/SKILL.md`.
|
||||||
- **도메인 노출**: 콘솔 설정→도메인 등록 후 `expose.host`(또는 `hosts: [...]`) 지정.
|
|
||||||
- **삭제**: 해당 워크로드/`requires` 항목 제거 후 태그 push(멱등 리컨실).
|
|
||||||
|
|||||||
76
bin/yakcloud
Executable file
76
bin/yakcloud
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# yakcloud — YakCloud 프로젝트 CLI. 빈 폴더 초기화(스타터+스킬) + 태그 push 자동배포.
|
||||||
|
# yakcloud init [name] 현재(빈) 폴더 또는 name/ 에 스타터 스캐폴딩(.claude 스킬 포함)
|
||||||
|
# yakcloud deploy [vX.Y.Z] 커밋 + 태그 push → Gitea Actions 자동 배포
|
||||||
|
# yakcloud check dry-run(직접 API, 계획만; YAKCLOUD_URL/TOKEN 필요)
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO="${YAKCLOUD_STARTER_REPO:-https://gitea.yakenator.io/yakenator/yakcloud-starter}"
|
||||||
|
BRANCH="${YAKCLOUD_STARTER_BRANCH:-main}"
|
||||||
|
VERSION="0.1.0"
|
||||||
|
|
||||||
|
die() { echo "✗ $*" >&2; exit 1; }
|
||||||
|
info() { echo "▸ $*"; }
|
||||||
|
|
||||||
|
cmd_init() {
|
||||||
|
local name="${1:-}"
|
||||||
|
if [ -n "$name" ]; then
|
||||||
|
mkdir -p "$name" && cd "$name"
|
||||||
|
fi
|
||||||
|
# 빈 폴더인지 확인(.git 은 허용)
|
||||||
|
if [ -n "$(ls -A . 2>/dev/null | grep -v '^\.git$' || true)" ]; then
|
||||||
|
die "폴더가 비어있지 않습니다. 빈 폴더에서 실행하거나 'yakcloud init <name>' 로 새 폴더에 생성하세요."
|
||||||
|
fi
|
||||||
|
info "yakcloud-starter 내려받는 중… ($REPO @ $BRANCH)"
|
||||||
|
curl -fsSL "$REPO/archive/$BRANCH.tar.gz" | tar xz --strip-components=1 \
|
||||||
|
|| die "스타터 다운로드 실패 — 네트워크/레포 공개 여부 확인"
|
||||||
|
# 프로젝트 이름 치환(선택)
|
||||||
|
if [ -n "$name" ] && [ -f yakcloud.yaml ]; then
|
||||||
|
sed -i.bak "s/^project: .*/project: $name/" yakcloud.yaml && rm -f yakcloud.yaml.bak
|
||||||
|
fi
|
||||||
|
git rev-parse --git-dir >/dev/null 2>&1 || git init -q
|
||||||
|
echo "✓ 초기화 완료 ($(pwd))"
|
||||||
|
echo " 다음:"
|
||||||
|
echo " 1) yakcloud.yaml 의 cluster / image(<GITEA_USER>) 수정, 필요하면 requires·binds 추가"
|
||||||
|
echo " 2) 앱 개발 (Claude Code 스킬: .claude/skills/yakcloud-deploy)"
|
||||||
|
echo " 3) Gitea 레포 연결 + Secrets(YAKCLOUD_URL/TOKEN/CLUSTER, REGISTRY_TOKEN) 설정"
|
||||||
|
echo " 4) yakcloud deploy v0.1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_deploy() {
|
||||||
|
[ -f yakcloud.yaml ] || die "yakcloud.yaml 없음 — 먼저 'yakcloud init'"
|
||||||
|
local ver="${1:-v0.1.0}"
|
||||||
|
case "$ver" in v*) : ;; *) ver="v$ver" ;; esac
|
||||||
|
git rev-parse --git-dir >/dev/null 2>&1 || git init -q
|
||||||
|
git remote get-url origin >/dev/null 2>&1 \
|
||||||
|
|| die "git 원격(origin) 없음 — Gitea 레포를 만들어 'git remote add origin <url>' 후, 레포 Secrets 설정 뒤 다시 실행"
|
||||||
|
info "커밋 + 태그 $ver push…"
|
||||||
|
git add -A
|
||||||
|
git commit -q -m "deploy $ver" 2>/dev/null || true
|
||||||
|
git push -q origin HEAD 2>/dev/null || true
|
||||||
|
git tag "$ver" 2>/dev/null || die "태그 $ver 이미 존재 — 다른 버전으로"
|
||||||
|
git push -q origin "$ver"
|
||||||
|
echo "✓ $ver push — Gitea Actions 에서 빌드·배포 진행. 콘솔 앱 탭/도메인에서 확인."
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_check() {
|
||||||
|
[ -f scripts/yakcloud_deploy.py ] || die "scripts/yakcloud_deploy.py 없음 — 'yakcloud init' 먼저"
|
||||||
|
: "${YAKCLOUD_URL:?YAKCLOUD_URL 필요}"
|
||||||
|
: "${YAKCLOUD_TOKEN:?YAKCLOUD_TOKEN(배포 토큰) 필요}"
|
||||||
|
python3 -c "import yaml" 2>/dev/null || pip3 install --quiet pyyaml
|
||||||
|
python3 scripts/yakcloud_deploy.py yakcloud.yaml --dry-run
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-help}" in
|
||||||
|
init) shift; cmd_init "$@" ;;
|
||||||
|
deploy) shift; cmd_deploy "$@" ;;
|
||||||
|
check|dry-run) shift; cmd_check "$@" ;;
|
||||||
|
version|-v|--version) echo "yakcloud $VERSION" ;;
|
||||||
|
*) cat <<EOF
|
||||||
|
yakcloud $VERSION — YakCloud 프로젝트 CLI
|
||||||
|
yakcloud init [name] 빈 폴더에 스타터 스캐폴딩(앱+CI+매니페스트+Claude 스킬)
|
||||||
|
yakcloud deploy [vX.Y.Z] 커밋 + 태그 push → Gitea Actions 자동 배포
|
||||||
|
yakcloud check dry-run(직접 API 계획만; YAKCLOUD_URL/TOKEN 필요)
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
esac
|
||||||
15
install.sh
Executable file
15
install.sh
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# yakcloud CLI 설치 — PATH 의 bin 디렉터리에 내려받는다.
|
||||||
|
# curl -fsSL https://gitea.yakenator.io/yakenator/yakcloud-starter/raw/branch/main/install.sh | sh
|
||||||
|
# 설치 위치 변경: DEST=/usr/local/bin sh install.sh
|
||||||
|
set -e
|
||||||
|
REPO="${YAKCLOUD_STARTER_REPO:-https://gitea.yakenator.io/yakenator/yakcloud-starter}"
|
||||||
|
BRANCH="${YAKCLOUD_STARTER_BRANCH:-main}"
|
||||||
|
DEST="${DEST:-$HOME/.local/bin}"
|
||||||
|
mkdir -p "$DEST"
|
||||||
|
echo "▸ yakcloud CLI 설치 → $DEST/yakcloud"
|
||||||
|
curl -fsSL "$REPO/raw/branch/$BRANCH/bin/yakcloud" -o "$DEST/yakcloud"
|
||||||
|
chmod +x "$DEST/yakcloud"
|
||||||
|
echo "✓ 완료. PATH 에 $DEST 가 있는지 확인하세요:"
|
||||||
|
echo ' export PATH="$HOME/.local/bin:$PATH"'
|
||||||
|
echo " 사용: yakcloud init my-app → 개발 → yakcloud deploy v0.1.0"
|
||||||
Reference in New Issue
Block a user