fixes
This commit is contained in:
parent
167abca134
commit
8a42e77563
6 changed files with 71 additions and 214 deletions
|
|
@ -1,203 +0,0 @@
|
||||||
# Исправление ошибки "Flutter directory is not a clone of the GitHub project"
|
|
||||||
|
|
||||||
**Дата**: 19 ноября 2025
|
|
||||||
**Статус**: ✅ Исправлено
|
|
||||||
|
|
||||||
## Проблема
|
|
||||||
|
|
||||||
При выполнении CI/CD workflow для web app получали ошибку:
|
|
||||||
|
|
||||||
```
|
|
||||||
Error: The Flutter directory is not a clone of the GitHub project.
|
|
||||||
The flutter tool requires Git in order to operate properly;
|
|
||||||
to install Flutter, see the instructions at:
|
|
||||||
https://flutter.dev/get-started
|
|
||||||
```
|
|
||||||
|
|
||||||
## Причина
|
|
||||||
|
|
||||||
Flutter SDK требует наличия Git для своей работы, так как:
|
|
||||||
1. Flutter проверяет целостность своего SDK через Git
|
|
||||||
2. Flutter использует Git для управления своими компонентами
|
|
||||||
3. В некоторых runner'ах Git может не быть установлен по умолчанию
|
|
||||||
|
|
||||||
## Решение
|
|
||||||
|
|
||||||
Добавлены следующие изменения во все Flutter workflow:
|
|
||||||
|
|
||||||
### 1. Полный checkout репозитория
|
|
||||||
|
|
||||||
**Было**:
|
|
||||||
```yaml
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
```
|
|
||||||
|
|
||||||
**Стало**:
|
|
||||||
```yaml
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0 # Полная история Git
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Явная установка Git
|
|
||||||
|
|
||||||
Добавлен новый шаг перед Setup Flutter:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Install Git
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y git
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Включение кеширования Flutter
|
|
||||||
|
|
||||||
**Было**:
|
|
||||||
```yaml
|
|
||||||
- name: Setup Flutter
|
|
||||||
uses: subosito/flutter-action@v2
|
|
||||||
with:
|
|
||||||
flutter-version: '3.35.5'
|
|
||||||
channel: 'stable'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Стало**:
|
|
||||||
```yaml
|
|
||||||
- name: Setup Flutter
|
|
||||||
uses: subosito/flutter-action@v2
|
|
||||||
with:
|
|
||||||
flutter-version: '3.35.5'
|
|
||||||
channel: 'stable'
|
|
||||||
cache: true # Включено кеширование
|
|
||||||
```
|
|
||||||
|
|
||||||
## Обновленные файлы
|
|
||||||
|
|
||||||
1. ✅ `.forgejo/workflows/ci-web.yml` - Web App CI
|
|
||||||
- Job: `test` - обновлен
|
|
||||||
- Job: `build` - обновлен
|
|
||||||
|
|
||||||
2. ✅ `.forgejo/workflows/ci-mobile.yml` - Mobile App CI
|
|
||||||
- Все jobs обновлены (3 job'а)
|
|
||||||
|
|
||||||
3. ✅ `.forgejo/workflows/code-quality.yml` - Code Quality
|
|
||||||
- Job обновлен
|
|
||||||
|
|
||||||
## Преимущества изменений
|
|
||||||
|
|
||||||
### 1. Полная история Git (fetch-depth: 0)
|
|
||||||
- Позволяет Git командам работать корректно
|
|
||||||
- Необходимо для некоторых Flutter операций
|
|
||||||
- Полезно для анализа изменений
|
|
||||||
|
|
||||||
### 2. Явная установка Git
|
|
||||||
- Гарантирует наличие Git в runner
|
|
||||||
- Избегает зависимости от базового образа
|
|
||||||
- Работает на разных платформах (GitHub Actions, Forgejo Actions)
|
|
||||||
|
|
||||||
### 3. Кеширование Flutter (cache: true)
|
|
||||||
- Ускоряет установку Flutter SDK
|
|
||||||
- Экономит время на повторных запусках
|
|
||||||
- Уменьшает нагрузку на сеть
|
|
||||||
|
|
||||||
## Проверка
|
|
||||||
|
|
||||||
После применения изменений:
|
|
||||||
|
|
||||||
1. **Commit изменения**:
|
|
||||||
```bash
|
|
||||||
git add .forgejo/workflows/
|
|
||||||
git commit -m "fix: Add Git installation for Flutter workflows"
|
|
||||||
git push origin master
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Запустить workflow вручную** через Forgejo UI:
|
|
||||||
- Перейти в Actions
|
|
||||||
- Выбрать workflow (например, Web App CI)
|
|
||||||
- Нажать "Run workflow"
|
|
||||||
|
|
||||||
3. **Проверить логи**:
|
|
||||||
- Шаг "Install Git" должен выполниться успешно
|
|
||||||
- Шаг "Setup Flutter" должен пройти без ошибок
|
|
||||||
- Шаг "Build web app" должен завершиться успешно
|
|
||||||
|
|
||||||
## Альтернативные решения
|
|
||||||
|
|
||||||
Если проблема сохраняется, можно попробовать:
|
|
||||||
|
|
||||||
### 1. Использовать Docker образ с предустановленным Flutter
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container:
|
|
||||||
image: ghcr.io/cirruslabs/flutter:3.35.5
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Установить Flutter вручную
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Install Flutter manually
|
|
||||||
run: |
|
|
||||||
git clone https://github.com/flutter/flutter.git -b stable
|
|
||||||
echo "$PWD/flutter/bin" >> $GITHUB_PATH
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Использовать flutter-action с git-path
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Setup Flutter
|
|
||||||
uses: subosito/flutter-action@v2
|
|
||||||
with:
|
|
||||||
flutter-version: '3.35.5'
|
|
||||||
channel: 'stable'
|
|
||||||
cache: true
|
|
||||||
git-path: /usr/bin/git
|
|
||||||
```
|
|
||||||
|
|
||||||
## Версия Flutter
|
|
||||||
|
|
||||||
Во всех workflow используется **Flutter 3.35.5 stable**, как указано в требованиях.
|
|
||||||
|
|
||||||
## Дополнительные настройки
|
|
||||||
|
|
||||||
### Если используется self-hosted runner
|
|
||||||
|
|
||||||
На self-hosted runner нужно убедиться что Git установлен:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# На сервере runner'а
|
|
||||||
ssh root@147.45.152.129
|
|
||||||
|
|
||||||
# Проверить Git
|
|
||||||
git --version
|
|
||||||
|
|
||||||
# Если не установлен
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y git
|
|
||||||
```
|
|
||||||
|
|
||||||
### Если нужно обновить Flutter на сервере
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# На сервере
|
|
||||||
cd /path/to/flutter
|
|
||||||
git fetch
|
|
||||||
git checkout stable
|
|
||||||
git pull
|
|
||||||
flutter doctor
|
|
||||||
```
|
|
||||||
|
|
||||||
## Статус
|
|
||||||
|
|
||||||
🟢 **ИСПРАВЛЕНО**
|
|
||||||
|
|
||||||
Все Flutter workflow обновлены и должны работать корректно.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Примечание**: Изменения применены ко всем workflow файлам, использующим Flutter, чтобы обеспечить единообразие и избежать подобных проблем в будущем.
|
|
||||||
|
|
||||||
|
|
@ -11,6 +11,8 @@ on:
|
||||||
- web_v2
|
- web_v2
|
||||||
- backend
|
- backend
|
||||||
- common
|
- common
|
||||||
|
schedule:
|
||||||
|
- cron: '0 */4 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
planning:
|
planning:
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ This is a language learning application with multiple components:
|
||||||
## Input Sources
|
## Input Sources
|
||||||
|
|
||||||
Review these files to understand current state:
|
Review these files to understand current state:
|
||||||
- `tasks.md` - Human-defined tasks and priorities
|
- `ai_docs/agent/tasks.md` - Human-defined tasks and priorities in component directories
|
||||||
- `workflow_state.md` - Current development state and progress
|
- `workflow_state.md` - Current development state and progress in component directories
|
||||||
- `ai_docs/agent/{component}/task_list.json` - Current task list
|
- `ai_docs/agent/{component}/task_list.json` - Current task list
|
||||||
- `ai_docs/agent/{component}/agent_state.json` - Agent execution state
|
- `ai_docs/agent/{component}/agent_state.json` - Agent execution state
|
||||||
- Recent commits - What has been completed recently
|
- Recent commits - What has been completed recently
|
||||||
|
|
@ -62,10 +62,10 @@ Each task should have:
|
||||||
|
|
||||||
- **Small tasks** (1-3 hours): Single feature or bug fix - **PREFERRED SIZE**
|
- **Small tasks** (1-3 hours): Single feature or bug fix - **PREFERRED SIZE**
|
||||||
- **Medium tasks** (4-5 hours): Feature with multiple files - **ACCEPTABLE, but prefer smaller**
|
- **Medium tasks** (4-5 hours): Feature with multiple files - **ACCEPTABLE, but prefer smaller**
|
||||||
- **Large tasks** (6+ hours): **MUST be broken down** into smaller subtasks before adding to task list
|
- **Large tasks** (3+ hours): **MUST be broken down** into smaller subtasks before adding to task list
|
||||||
|
|
||||||
**Task Decomposition Rules:**
|
**Task Decomposition Rules:**
|
||||||
- If a task exceeds 6 hours, it MUST be split into multiple smaller tasks
|
- If a task exceeds 3 hours, it MUST be split into multiple smaller tasks
|
||||||
- Each subtask should be independently testable and completable
|
- Each subtask should be independently testable and completable
|
||||||
- Subtasks should have clear dependencies between them
|
- Subtasks should have clear dependencies between them
|
||||||
- Aim for tasks that can be completed in 2-4 hours whenever possible
|
- Aim for tasks that can be completed in 2-4 hours whenever possible
|
||||||
|
|
@ -170,7 +170,7 @@ When a task in one component depends on another:
|
||||||
- Identify dependencies between tasks
|
- Identify dependencies between tasks
|
||||||
- Determine component ownership
|
- Determine component ownership
|
||||||
- Estimate effort for each task
|
- Estimate effort for each task
|
||||||
- **Break down large tasks** (6+ hours) into smaller subtasks before proceeding
|
- **Break down large tasks** (3+ hours) into smaller subtasks before proceeding
|
||||||
|
|
||||||
### 3. Prioritization Phase
|
### 3. Prioritization Phase
|
||||||
|
|
||||||
|
|
@ -204,7 +204,7 @@ Generate `task_list.json` for each component:
|
||||||
"title": "Implement Subscription Service",
|
"title": "Implement Subscription Service",
|
||||||
"priority": "high",
|
"priority": "high",
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"estimated_hours": 6,
|
"estimated_hours": 2,
|
||||||
"description": "Create SubscriptionService to handle subscription operations using HttpRepositoryV2. Include methods for fetching plans, purchasing, checking status, and cancelling subscriptions.",
|
"description": "Create SubscriptionService to handle subscription operations using HttpRepositoryV2. Include methods for fetching plans, purchasing, checking status, and cancelling subscriptions.",
|
||||||
"acceptance_criteria": [
|
"acceptance_criteria": [
|
||||||
"SubscriptionService created with all CRUD methods",
|
"SubscriptionService created with all CRUD methods",
|
||||||
|
|
@ -260,8 +260,8 @@ Before finalizing task list:
|
||||||
1. ✅ All tasks have unique IDs
|
1. ✅ All tasks have unique IDs
|
||||||
2. ✅ Dependencies are valid (tasks exist)
|
2. ✅ Dependencies are valid (tasks exist)
|
||||||
3. ✅ Priorities are balanced (not all high)
|
3. ✅ Priorities are balanced (not all high)
|
||||||
4. ✅ **All tasks are small (2-6 hours max)** - large tasks have been broken down
|
4. ✅ **All tasks are small (1-3 hours max)** - large tasks have been broken down
|
||||||
5. ✅ Estimates are reasonable (2-6 hours preferred, 6-8 hours acceptable only if cannot be split)
|
5. ✅ Estimates are reasonable (2-3 hours preferred, 3-5 hours acceptable only if cannot be split)
|
||||||
6. ✅ Acceptance criteria are specific
|
6. ✅ Acceptance criteria are specific
|
||||||
7. ✅ Files to modify are listed
|
7. ✅ Files to modify are listed
|
||||||
8. ✅ No circular dependencies
|
8. ✅ No circular dependencies
|
||||||
|
|
|
||||||
0
ai_docs/agent/tasks.md
Normal file
0
ai_docs/agent/tasks.md
Normal file
|
|
@ -50,6 +50,9 @@ class AgentOrchestrator:
|
||||||
try:
|
try:
|
||||||
state = self.task_manager.load_state()
|
state = self.task_manager.load_state()
|
||||||
|
|
||||||
|
# Reset stale in_progress tasks (tasks that were left in_progress from previous runs)
|
||||||
|
self.task_manager.reset_stale_in_progress_tasks(state.current_task_id)
|
||||||
|
|
||||||
# Check iteration limit
|
# Check iteration limit
|
||||||
if state.iteration_count >= self.config.max_iterations:
|
if state.iteration_count >= self.config.max_iterations:
|
||||||
print(f"\n⏹️ Reached maximum iterations ({self.config.max_iterations})")
|
print(f"\n⏹️ Reached maximum iterations ({self.config.max_iterations})")
|
||||||
|
|
@ -59,10 +62,37 @@ class AgentOrchestrator:
|
||||||
next_task = self.task_manager.get_next_task()
|
next_task = self.task_manager.get_next_task()
|
||||||
|
|
||||||
if not next_task:
|
if not next_task:
|
||||||
print("\n✅ All tasks completed!")
|
print("\n✅ All tasks completed or no pending tasks!")
|
||||||
self.task_manager.reset_state()
|
|
||||||
return 0
|
# Trigger planning agent to generate new tasks
|
||||||
|
print("\n🎯 No tasks available, triggering planning agent...")
|
||||||
|
planning_agent = PlanningAgent(self.config)
|
||||||
|
planning_result = planning_agent.run()
|
||||||
|
|
||||||
|
if planning_result == 0:
|
||||||
|
print("\n✅ Planning agent completed successfully")
|
||||||
|
print(" New tasks have been generated. Checking for available tasks...")
|
||||||
|
|
||||||
|
# Try to get next task again after planning
|
||||||
|
next_task = self.task_manager.get_next_task()
|
||||||
|
|
||||||
|
if next_task:
|
||||||
|
print(f"\n📋 Found new task: {next_task.id} - {next_task.title}")
|
||||||
|
print(" Proceeding to execute the new task...")
|
||||||
|
# Continue with task execution (don't return, fall through to task execution)
|
||||||
|
else:
|
||||||
|
print("\n⚠️ Planning agent completed but no new tasks were generated")
|
||||||
|
print(" Agent will exit. You may need to manually create tasks.")
|
||||||
|
self.task_manager.reset_state()
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
print("\n⚠️ Planning agent failed")
|
||||||
|
print(" Agent will exit. You may need to manually trigger planning or create tasks")
|
||||||
|
self.task_manager.reset_state()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# At this point we should have a task to execute
|
||||||
|
# Continue with task execution
|
||||||
print(f"\n{'='*80}")
|
print(f"\n{'='*80}")
|
||||||
print(f"📋 Task: {next_task.id}")
|
print(f"📋 Task: {next_task.id}")
|
||||||
print(f"📝 {next_task.title}")
|
print(f"📝 {next_task.title}")
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ class TaskManager:
|
||||||
if task_id not in state.completed_tasks:
|
if task_id not in state.completed_tasks:
|
||||||
state.completed_tasks.append(task_id)
|
state.completed_tasks.append(task_id)
|
||||||
state.current_task_id = None
|
state.current_task_id = None
|
||||||
|
state.status = "idle" # Reset status to allow agent to continue or finish
|
||||||
state.retry_count = 0
|
state.retry_count = 0
|
||||||
self.save_state(state)
|
self.save_state(state)
|
||||||
|
|
||||||
|
|
@ -243,6 +244,33 @@ class TaskManager:
|
||||||
"""Check if all tasks are completed."""
|
"""Check if all tasks are completed."""
|
||||||
tasks = self.load_tasks()
|
tasks = self.load_tasks()
|
||||||
return all(task.status in ["completed", "skipped"] for task in tasks)
|
return all(task.status in ["completed", "skipped"] for task in tasks)
|
||||||
|
|
||||||
|
def reset_stale_in_progress_tasks(self, current_task_id: Optional[str] = None) -> None:
|
||||||
|
"""
|
||||||
|
Reset tasks that are stuck in 'in_progress' status.
|
||||||
|
These are tasks that were started but never completed (e.g., agent crashed).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
current_task_id: ID of the task that is currently being worked on (don't reset this one)
|
||||||
|
"""
|
||||||
|
tasks = self.load_tasks()
|
||||||
|
state = self.load_state()
|
||||||
|
|
||||||
|
reset_count = 0
|
||||||
|
for task in tasks:
|
||||||
|
if task.status == "in_progress":
|
||||||
|
# Don't reset the current task if it's actually being worked on
|
||||||
|
if task.id == current_task_id and state.status == "in_progress":
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Reset stale in_progress task to pending
|
||||||
|
task.status = "pending"
|
||||||
|
reset_count += 1
|
||||||
|
print(f"⚠️ Resetting stale task {task.id} from 'in_progress' to 'pending'")
|
||||||
|
|
||||||
|
if reset_count > 0:
|
||||||
|
self.save_tasks(tasks)
|
||||||
|
print(f"✅ Reset {reset_count} stale task(s) to 'pending' status")
|
||||||
|
|
||||||
|
|
||||||
class GlobalLock:
|
class GlobalLock:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue