---
name: devops
description: CI/CD pipelines para o AcidaOS via Gitea Actions — build, test, deploy para acidaos-core (Rust) e acidaos-dashboard (Next.js). Usar quando "pipeline acidaos", "gitea actions acidaos", "ci cd acidaos", "deploy acidaos", "workflow acidaos".
allowed-tools: Read, Write, Edit, Bash, mcp__gitea__list_repo_action_workflows, mcp__gitea__get_repo_action_workflow, mcp__gitea__create_file, mcp__gitea__update_file, mcp__memory-supabase__search_memories
---

# AcidaOS DevOps — Gitea Actions

Skill para criar e gerir pipelines CI/CD do AcidaOS via **Gitea Actions**.

> **Atenção:** O AcidaOS usa **Gitea Actions**, não GitHub Actions. A sintaxe é compatível mas o runner é self-hosted em `gateway.descomplicar.pt`.

## Contexto

```
Repositórios Gitea:
  acidaos-core      → Rust Core
  acidaos-dashboard → Next.js Dashboard

Runners:
  self-hosted @ gateway.descomplicar.pt
  Labels: [self-hosted, linux, rust, node]

Deploy target:
  EasyPanel (projectName: "descomplicar")
  acidaos-core    → serviceName: "acidaos-core"
  acidaos-dashboard → serviceName: "acidaos-dashboard"
```

## Protocolo Inicial

```
mcp__memory-supabase__search_memories "acidaos devops pipeline"
mcp__gitea__list_repo_action_workflows <repo>  # ver workflows existentes
```

---

## Pipelines Disponíveis

### 1. Core Rust — CI Pipeline

**Ficheiro:** `.gitea/workflows/ci.yml`

```yaml
name: AcidaOS Core CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  check:
    name: Verificar código
    runs-on: [self-hosted, linux, rust]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Cache Cargo
        uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target/
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

      - name: Cargo check
        run: cargo check --all-features

      - name: Clippy
        run: cargo clippy --all-features -- -D warnings

      - name: Formatação
        run: cargo fmt --all -- --check

  test:
    name: Testes
    needs: check
    runs-on: [self-hosted, linux, rust]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Cache Cargo
        uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target/
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

      - name: Testes unitários
        run: cargo test --all-features

      - name: Testes de integração
        run: cargo test --test '*' --all-features
        env:
          ACIDAOS_ENV: test
          DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}

  security:
    name: Auditoria de segurança
    runs-on: [self-hosted, linux, rust]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: cargo-audit
        run: |
          cargo install cargo-audit --quiet
          cargo audit
```

---

### 2. Core Rust — Deploy Pipeline

**Ficheiro:** `.gitea/workflows/deploy.yml`

```yaml
name: AcidaOS Core Deploy

on:
  push:
    branches: [main]
    tags: ['v*']

jobs:
  deploy:
    name: Deploy para EasyPanel
    runs-on: [self-hosted, linux, rust]
    environment: production
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Build release
        run: cargo build --release

      - name: Build Docker image
        run: |
          docker build \
            -t acidaos-core:${{ gitea.sha }} \
            -t acidaos-core:latest \
            .

      - name: Push para registry
        run: |
          docker tag acidaos-core:latest \
            registry.descomplicar.pt/acidaos/core:latest
          docker push registry.descomplicar.pt/acidaos/core:latest
        env:
          DOCKER_REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}

      - name: Deploy via EasyPanel API
        run: |
          curl -X POST \
            "https://easypanel.descomplicar.pt/api/deploy" \
            -H "Authorization: Bearer ${{ secrets.EASYPANEL_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d '{
              "projectName": "descomplicar",
              "serviceName": "acidaos-core",
              "image": "registry.descomplicar.pt/acidaos/core:latest"
            }'

      - name: Verificar health
        run: |
          sleep 10
          curl -f http://acidaos-core.descomplicar.pt/health || exit 1
```

---

### 3. Dashboard Next.js — CI Pipeline

**Ficheiro:** `.gitea/workflows/ci.yml` (no repo acidaos-dashboard)

```yaml
name: AcidaOS Dashboard CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  lint-typecheck:
    name: Lint e TypeCheck
    runs-on: [self-hosted, linux, node]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'

      - name: Instalar dependências
        run: pnpm install --frozen-lockfile

      - name: TypeScript check
        run: pnpm tsc --noEmit

      - name: ESLint
        run: pnpm lint

  test:
    name: Testes
    needs: lint-typecheck
    runs-on: [self-hosted, linux, node]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'

      - name: Instalar dependências
        run: pnpm install --frozen-lockfile

      - name: Testes unitários
        run: pnpm test

      - name: Build de verificação
        run: pnpm build
        env:
          ACIDAOS_CORE_URL: http://localhost:3001

  e2e:
    name: Testes E2E
    needs: test
    runs-on: [self-hosted, linux, node]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'

      - name: Instalar dependências
        run: pnpm install --frozen-lockfile

      - name: Instalar Playwright
        run: pnpm exec playwright install --with-deps chromium

      - name: Testes E2E
        run: pnpm test:e2e
        env:
          BASE_URL: http://localhost:3000
          ACIDAOS_CORE_URL: http://localhost:3001

      - name: Upload relatório E2E
        if: failure()
        uses: actions/upload-artifact@v3
        with:
          name: playwright-report
          path: playwright-report/
```

---

## Gestão via MCP Gitea

```javascript
// Listar workflows de um repo
mcp__gitea__list_repo_action_workflows({ owner: "descomplicar", repo: "acidaos-core" })

// Ver runs recentes
mcp__gitea__list_repo_action_runs({ owner: "descomplicar", repo: "acidaos-core" })

// Desencadear workflow manualmente
mcp__gitea__dispatch_repo_action_workflow({
  owner: "descomplicar",
  repo: "acidaos-core",
  workflow_id: "deploy.yml",
  ref: "main"
})

// Ver logs de uma job
mcp__gitea__get_repo_action_job_log_preview({ owner: "descomplicar", repo: "acidaos-core", job_id: <id> })
```

## Segredos necessários (Gitea Secrets)

| Segredo | Usado em | Descrição |
|---------|----------|-----------|
| `TEST_DATABASE_URL` | Core CI | PostgreSQL de teste |
| `REGISTRY_TOKEN` | Core Deploy | Token registry Docker |
| `EASYPANEL_TOKEN` | Core/Dashboard Deploy | Token API EasyPanel |

## Checklist Pipeline Nova

- [ ] Workflow criado em `.gitea/workflows/`
- [ ] Runner labels correctas (`self-hosted, linux, rust` ou `node`)
- [ ] Cache Cargo/pnpm configurado
- [ ] Segredos referenciados (não hardcoded)
- [ ] Health check no deploy
- [ ] Tested com `mcp__gitea__dispatch_repo_action_workflow`

---
**Versão**: 1.0.0 | **Autor**: Descomplicar® | **Plugin**: acidaos

---

## Healing Log

Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.

```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```

*Adicionar nova linha após cada erro corrigido.*
