--- id: KB-PLUGIN-031 title: "Runbook — Processo oficial de desenvolvimento de plugins GLPI (DEV → homologação → PROD)" domain: plugin-dev tags: - runbook - workflow - dev - deploy - forgejo - scaffold - validation - console - processo-oficial status: active severity: high created_at: 2026-06-11 updated_at: 2026-06-11 applies_to: - GLPI 11.x no ambiente dev (CT 100 docker, stack GLPI11) - qualquer plugin novo desenvolvido internamente related_records: - KB-INFRA-001 - KB-INFRA-002 - KB-PLUGIN-001 - KB-PLUGIN-004 - KB-PLUGIN-013 - KB-PLUGIN-018 - KB-PLUGIN-027 --- # Runbook — Processo oficial de desenvolvimento de plugins GLPI Processo padrão em 5 passos, do nascimento do plugin até a produção: ``` 1. Acessar o ambiente DEV (CT 100) 2. Criar o diretório do plugin direto em .../plugins/ ← dev e validação acontecem juntos, pela interface do GLPI dev 3. Push para o Forgejo DEV (origin) 4. Homologar (testes funcionais + E2E validados) 5. Deploy: push para o Forgejo de PROD (remote production) ``` A publicação completa em PROD (Mindplace, licenciamento, release ZIP) é detalhada em [KB-PLUGIN-013](KB-PLUGIN-013-mindplace-plugin-publication-runbook.md) e [KB-PLUGIN-027](KB-PLUGIN-027-mcprotocol-dev-prod-release-flow.md). Primeiro plugin a seguir este fluxo de ponta a ponta: `assetinherit` (2026-06-11). ## ⭐ Regra de ouro — protocolo de conhecimento Durante TODO o processo de desenvolvimento: 1. **Knowledge-base é a fonte primária.** Antes de implementar ou diagnosticar qualquer coisa, consultar `index.json` e os records relevantes desta base. 2. **Na ausência de dado relevante, estudar o core do GLPI** (código-fonte em `/var/www/glpi/src/` no container, ou clone do branch `11.0/bugfixes`). Não confiar em memória/suposição sobre comportamento do GLPI — ler o código. 3. **Após o teste validado, escrever um novo KB** com o que foi aprendido, para que o próximo desenvolvimento seja mais fácil. Rodar `make kb-fix` e `make kb-check`, commitar e push. ## Mapa do ambiente | Componente | Onde | |---|---| | Servidor dev (docker) | CT 100 — `root@192.168.100.49` (SSH key do Mac já cadastrada) | | Diretório de plugins | `/home/glpi/glpi_dev/plugins/` (bind → `/var/www/glpi/plugins`, ver [KB-INFRA-001]) | | Container GLPI | `devportal_glpi` (GLPI dev em `http://localhost`) | | Knowledge-base | `/opt/projects/GLPI11/knowledge-base/` (repo no Forgejo dev) | | Forgejo DEV | `git@192.168.100.101:administrador/.git` (remote `origin`) — web `http://192.168.100.101:3000` / `https://forgejo.lab.coretoai.com`, usuário `administrador` | | Forgejo PROD | `servicedesk.mindtek.com.br/git/rodolpho.lopes/` (remote `production`) | | Credencial Forgejo DEV | **PAT** em `/opt/projects/GLPI11/bin/.forgejo-dev.token` (gitignored — NUNCA versionar; padrão igual ao PROD, ver [KB-PLUGIN-027]). O segredo não fica na KB. | ## Passo 1 — Acessar o ambiente DEV ```bash ssh root@192.168.100.49 cd /home/glpi/glpi_dev/plugins/ ``` Ou via IDE no Mac: Remote SSH em `root@192.168.100.49`, abrir a pasta do plugin. O bind mount entrega qualquer mudança ao container na hora — GLPI é PHP, lê do disco a cada request: salvar arquivo + refresh no browser, sem recriar container. ## Passo 2 — Criar o plugin direto em plugins/ O diretório nasce no servidor dev, assim humano e agente trabalham e validam juntos pela interface do GLPI dev desde o primeiro minuto. ```bash mkdir && cd git init && git branch -M main ``` Estrutura mínima obrigatória (a chave/diretório define TUDO — funções, hooks, constantes): ``` / ├── setup.php # plugin_init_, plugin_version_ + 4 callbacks ├── hook.php # install/uninstall e demais hooks ├── logo.png # PNG 128x128 na raiz — obrigatório [KB-INFRA-002] ├── README.md # dor que resolve, como funciona, instalação, CONFIGURAÇÃO passo a passo ├── CHANGELOG.md # Keep a Changelog ├── LICENSE # GPL-3.0-or-later (compatível com o GLPI) └── .gitignore # padrão de plugins [KB-PLUGIN-013] ``` Checklist de armadilhas conhecidas: - [ ] `setup.php` com os **4 callbacks**: `check_prerequisites`, `check_config`, `install`, `uninstall` — sem eles a instalação falha genericamente ([KB-PLUGIN-001]). - [ ] Toda chave em `$PLUGIN_HOOKS[...]['']` é o **plugin key exato** (= nome do diretório). Variações falham em silêncio ([KB-PLUGIN-004]). - [ ] `logo.png` é PNG real (SVG renomeado não funciona) ([KB-INFRA-002]). - [ ] `version` no `setup.php` em SemVer — o release de produção lê de lá. - [ ] Ownership: `chown -R www-data:www-data ` + `git config --global --add safe.directory ` (git roda como root, arquivos são www-data). Instalação e ativação **sempre via console** (erros legíveis; a UI só mostra falha genérica): ```bash docker exec devportal_glpi sh -c ' php -l /var/www/glpi/plugins//setup.php && php -l /var/www/glpi/plugins//hook.php && php /var/www/glpi/bin/console plugin:install -n --username=glpi && php /var/www/glpi/bin/console plugin:activate -n && php /var/www/glpi/bin/console plugin:list | grep ' ``` ## Passo 3 — Push para o Forgejo DEV Criar o repo (API ou UI em `http://192.168.100.101:3000`). Via API, usar o **PAT** do arquivo gitignored (ver Mapa do ambiente) — não usar senha em texto: ```bash TOKEN=$(cat /opt/projects/GLPI11/bin/.forgejo-dev.token) curl -s -H "Authorization: token $TOKEN" -X POST \ http://192.168.100.101:3000/api/v1/user/repos \ -H 'Content-Type: application/json' \ -d '{"name":"","private":true,"default_branch":"main"}' ``` ⚠️ **Escopos do PAT:** criar repo via API exige `write:user` **e** `write:repository`. Sem `write:user`, a API retorna 403 (`token does not have ... write:user`) e só a senha (basic auth) cria o repo. Gerar o token com ambos os escopos para dispensar a senha. ⚠️ **Push-to-create está DESABILITADO** no Forgejo DEV — o repo precisa existir antes do push. ```bash git remote add origin git@192.168.100.101:administrador/.git git add -A && git commit -m " 0.1.0: scaffold" git push -u origin main ``` Durante o desenvolvimento, commit + push contínuos para `origin`. ## Passo 4 — Homologar Validação funcional pela interface do GLPI dev **e** teste E2E automatizado em CLI. ⚠️ **Gotcha do GLPI 11:** em CLI, `include 'inc/includes.php'` **não** carrega mais o core (classes como `RuleAsset` ficam indisponíveis). O bootstrap correto para scripts de teste é o do `bin/console`: ```php require '/var/www/glpi/vendor/autoload.php'; $kernel = new \Glpi\Kernel\Kernel(); $kernel->boot(); // carrega core + plugins ativos (plugin_init roda aqui) // sessão CLI mínima para CommonDBTM::add()/update() $_SESSION['glpiactiveentities'] = [0]; $_SESSION['glpiactive_entity'] = 0; $_SESSION['glpiactiveprofile']['interface'] = 'central'; ``` Padrão do teste: criar massa de dados com prefixo `TEST` → exercitar os cenários → **deletar tudo com purge no final**. Executar: ```bash docker cp test_.php devportal_glpi:/tmp/ docker exec devportal_glpi php /tmp/test_.php ``` Exemplo real: teste E2E do `assetinherit` (6 cenários; a homologação revelou comportamento que virou documentação — `PATTERN_EXISTS` não casa com `users_id = 0`, exigindo regra complementar de desvínculo). Homologado = todos os cenários OK + README com passo a passo de configuração conferido contra o comportamento real. **→ É aqui que se cumpre o item 3 da Regra de ouro: escrever o(s) novo(s) KB(s) com o que o desenvolvimento ensinou.** ## Passo 5 — Deploy para o Forgejo de PROD Somente após homologação: ```bash git remote add production https://servicedesk.mindtek.com.br/git/rodolpho.lopes/.git git push production main ``` Publicação no marketplace (release ZIP com wrapper [KB-PLUGIN-018], catálogo Mindplace, kill switch de licença, serial do cliente): seguir [KB-PLUGIN-013]. Topologia dev→prod detalhada: [KB-PLUGIN-027]. ## Regra para agentes Ao criar/depurar plugin, seguir os 5 passos na ordem e a Regra de ouro sempre: KB primeiro, core do GLPI na ausência de KB, novo KB após validação. Antes de diagnosticar erro funcional, validar mount/ownership/instalação via console (Passo 2). Para testes E2E em CLI, usar SEMPRE o bootstrap do Kernel (Passo 4), nunca `inc/includes.php`. ## Classificação - Tipo: Runbook operacional — processo oficial de desenvolvimento. - Reutilização: obrigatória para todo plugin novo.