diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..77ba316 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,99 @@ +name: CI + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.12'] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e .[test] + # Install frontend dependencies for potential frontend tests (optional) + cd frontend && npm ci && cd .. + + # 统一配置生成,用于后端测试(与前端构建共享相同配置) + - name: Create config.yml for CI + run: | + cat > config.yml << 'EOF' + backend_port: 3000 + frontend_port: 4000 + max_iterations: 5 + sub_agent: + max_iterations: 3 + max_tokens: 4096 + max_agents: 5 + max_concurrency: 3 + models: + - id: dummy + name: Dummy + api_url: https://api.example.com + api_key: dummy-key + default_model: dummy + db_type: sqlite + db_sqlite_file: ":memory:" + workspace_root: ./workspaces + EOF + + - name: Run tests with pytest + run: | + python -m pytest tests/ -v + + - name: Upload coverage to Codecov (optional) + uses: codecov/codecov-action@v3 + if: matrix.python-version == '3.10' && github.event_name == 'push' + with: + file: ./coverage.xml + fail_ci_if_error: false + build-frontend: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + - name: Install frontend dependencies + run: | + cd frontend && npm ci + # 统一配置生成,用于前端构建(与后端测试共享相同配置) + - name: Create config.yml for frontend build + run: | + cat > config.yml << 'EOF' + backend_port: 3000 + frontend_port: 4000 + max_iterations: 5 + sub_agent: + max_iterations: 3 + max_tokens: 4096 + max_agents: 5 + max_concurrency: 3 + models: + - id: dummy + name: Dummy + api_url: https://api.example.com + api_key: dummy-key + default_model: dummy + db_type: sqlite + db_sqlite_file: ":memory:" + workspace_root: ./workspaces + EOF + - name: Build frontend + run: | + cd frontend && npm run build \ No newline at end of file diff --git a/.gitignore b/.gitignore index fcd3615..ca493b7 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,7 @@ !frontend/src/**/*.vue !frontend/src/**/*.css !frontend/public/ -!frontend/public/** \ No newline at end of file +!frontend/public/** + +# CI / CD +!.github/workflows/* diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 4483a15..77cb2d4 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -8,17 +8,25 @@ import { dirname, resolve } from 'path' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) -const config = yaml.load( - fs.readFileSync(resolve(__dirname, '..', 'config.yml'), 'utf-8') -) +const configPath = resolve(__dirname, '..', 'config.yml'); +let config = {}; +try { + config = yaml.load(fs.readFileSync(configPath, 'utf-8')); +} catch (e) { + console.warn(`Config file not found at ${configPath}, using defaults.`); + config = {}; +} + +const frontend_port = process.env.VITE_FRONTEND_PORT || config.frontend_port || 4000; +const backend_port = process.env.VITE_BACKEND_PORT || config.backend_port || 3000; export default defineConfig({ plugins: [vue()], server: { - port: config.frontend_port, + port: frontend_port, proxy: { '/api': { - target: `http://localhost:${config.backend_port}`, + target: `http://localhost:${backend_port}`, changeOrigin: true, }, },