galaxis-po/docs/superpowers/plans/2026-03-20-galaxis-agent-cicd.md
2026-03-20 23:25:22 +09:00

5.9 KiB

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/


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 작성
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
  • 커밋
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 작성
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 <<EOF > .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!"
  • 커밋
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를 수행한다
  • Gitea secrets 8개가 리포에 등록되어 있다 (수동)
  • 모든 기존 테스트 통과 (139개)