# galaxis-agent Gitea Actions CI/CD Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** galaxis-agent 리포에 Gitea Actions CI/CD를 구성한다 (PR 테스트 + main 배포). **Architecture:** 2개 워크플로우 파일로 구성. `ci.yml`은 PR에서 pytest를 실행하고, `deploy.yml`은 main push 시 테스트 → Docker Compose 배포 → health check를 수행한다. galaxis-po의 기존 deploy.yml 패턴을 따른다. **Tech Stack:** Gitea Actions, Docker Compose, uv, pytest **Spec:** `docs/superpowers/specs/2026-03-20-galaxis-agent-cicd-design.md` **Working Directory:** `~/workspace/quant/galaxis-agent/` **전제조건 (수동):** Gitea 리포 Settings > Secrets에 8개 시크릿 등록 필요 — `ANTHROPIC_API_KEY`, `GITEA_TOKEN`, `GITEA_WEBHOOK_SECRET`, `DISCORD_TOKEN`, `DISCORD_CHANNEL_ID`, `DISCORD_BOT_USER_ID`, `FERNET_KEY`, `AGENT_API_KEY` --- ## File Structure ### 신규 생성 파일 ``` .gitea/workflows/ci.yml # PR 검증 워크플로우 (테스트만) .gitea/workflows/deploy.yml # main push → 테스트 + 배포 ``` --- **Task 의존성:** 2개 Task 모두 독립적 → 병렬 dispatch 가능 (sonnet 충분) --- ## Task 1: ci.yml 작성 PR 생성/업데이트 시 테스트를 실행하는 워크플로우. **Files:** - Create: `.gitea/workflows/ci.yml` ### Step 1a: ci.yml 작성 - [ ] **ci.yml 작성** ```yaml name: CI on: pull_request: branches: [main] jobs: test: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install uv run: | curl -LsSf https://astral.sh/uv/install.sh | sh echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Install dependencies run: uv sync --frozen - name: Run tests run: uv run python -m pytest --tb=short -q ``` - [ ] **커밋** ```bash mkdir -p .gitea/workflows git add .gitea/workflows/ci.yml git commit -m "ci: add PR test workflow" ``` --- ## Task 2: deploy.yml 작성 main push 시 테스트 → Docker Compose 배포 → health check를 수행하는 워크플로우. **Files:** - Create: `.gitea/workflows/deploy.yml` **참고:** galaxis-po의 `.gitea/workflows/deploy.yml` 패턴을 따른다. ### Step 2a: deploy.yml 작성 - [ ] **deploy.yml 작성** ```yaml name: Deploy to Production on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install uv run: | curl -LsSf https://astral.sh/uv/install.sh | sh echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Install dependencies run: uv sync --frozen - name: Run tests run: uv run python -m pytest --tb=short -q - name: Setup Docker CLI run: | apt-get update -qq && apt-get install -y -qq docker.io >/dev/null 2>&1 mkdir -p ~/.docker/cli-plugins curl -fsSL "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" \ -o ~/.docker/cli-plugins/docker-compose chmod +x ~/.docker/cli-plugins/docker-compose docker compose version - name: Create .env from secrets run: | cat < .env ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }} GITEA_URL=http://gitea:3000 GITEA_EXTERNAL_URL=https://ayuriel.duckdns.org GITEA_TOKEN=${{ secrets.GITEA_TOKEN }} GITEA_WEBHOOK_SECRET=${{ secrets.GITEA_WEBHOOK_SECRET }} DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }} DISCORD_CHANNEL_ID=${{ secrets.DISCORD_CHANNEL_ID }} DISCORD_BOT_USER_ID=${{ secrets.DISCORD_BOT_USER_ID }} LANGGRAPH_URL=http://langgraph-server:8123 AUTONOMY_LEVEL=conservative DEFAULT_REPO_OWNER=quant DEFAULT_REPO_NAME=galaxis-po AGENT_API_KEY=${{ secrets.AGENT_API_KEY }} SANDBOX_IMAGE=galaxis-sandbox:latest SANDBOX_MEM_LIMIT=4g SANDBOX_CPU_COUNT=2 SANDBOX_TIMEOUT=600 FERNET_KEY=${{ secrets.FERNET_KEY }} LOG_FORMAT=json DAILY_COST_LIMIT_USD=10.0 PER_TASK_COST_LIMIT_USD=3.0 EOF - name: Ensure galaxis-net network run: | docker network inspect galaxis-net >/dev/null 2>&1 || docker network create galaxis-net - name: Build sandbox image run: ./build-sandbox.sh - name: Deploy with Docker Compose run: | docker compose --project-name galaxis-agent down || true docker compose --project-name galaxis-agent build docker compose --project-name galaxis-agent up -d - name: Health check run: | echo "Waiting for galaxis-agent to become healthy..." for i in $(seq 1 12); do if curl -sf http://localhost:8100/health | grep -q '"status".*"ok"'; then echo "Main health check: OK" break fi if [ "$i" -eq 12 ]; then echo "Health check failed after 60 seconds" docker compose --project-name galaxis-agent logs exit 1 fi echo " Waiting... (${i}/12, 5s interval)" sleep 5 done for ep in /health/gitea /health/discord /health/queue /health/costs; do if curl -sf "http://localhost:8100${ep}" >/dev/null 2>&1; then echo " ${ep} ... OK" else echo " ${ep} ... WARN (non-critical)" fi done echo "Deploy complete!" ``` - [ ] **커밋** ```bash git add .gitea/workflows/deploy.yml git commit -m "ci: add production deploy workflow with health checks" ``` --- ## 완료 기준 - [ ] PR 생성 시 `ci.yml`이 테스트 139개를 실행한다 - [ ] `main` push 시 `deploy.yml`이 테스트 → 배포 → health check를 수행한다 - [ ] 모든 기존 테스트 통과 (139개)