Repository navigation
builds
Esta página descreve como empacotar o Codis para distribuição.
O Codis inclui o script package_codis.py na raiz do projeto para gerar distribuições.
python package_codis.pyO setup.py na raiz define os metadados do pacote Python. A versão não é hardcoded - é extraída dinamicamente de APP_VERSION em src/constants.py via regex, para nunca ficar dessincronizada:
# setup.py (resumido)
import re
from pathlib import Path
from setuptools import setup, find_packages
def _find_version() -> str:
"""Extrai APP_VERSION de src/constants.py."""
m = re.search(r'^APP_VERSION\s*=\s*["\']([^"\']+)["\']',
Path("src/constants.py").read_text(encoding="utf-8"), re.MULTILINE)
return m.group(1)
setup(
name="codis",
version=_find_version(),
python_requires=">=3.12",
packages=find_packages(exclude=["tests*", "docs*", "wiki*", "build*", "dist*"]),
install_requires=[], # sem dependências obrigatórias
extras_require={
"recommended": ["send2trash>=1.8.0", "Pillow>=9.0.0", "markdown>=3.4.0"],
"full": ["send2trash>=1.8.0", "Pillow>=9.0.0", "markdown>=3.4.0",
"py7zr>=0.20.0", "rarfile>=4.0"],
"dev": ["pyinstaller", "pytest", "pytest-cov", "flake8", "pylint"],
},
entry_points={
"console_scripts": ["codis = run:main"],
"gui_scripts": ["codis-gui = run:main"],
},
)
pip install .[dev]instala as ferramentas de desenvolvimento (PyInstaller, pytest, flake8, pylint) de uma vez.
pip install -e .Após isso, o comando codis fica disponível globalmente.
O requirements.txt lista pacotes opcionais que habilitam funcionalidades extras:
send2trash>=1.8.0 # lixeira nativa (fallback: pseudo-lixeira interna)
Pillow>=9.0.0 # imagens no K-UI
markdown>=3.4.0 # preview Markdown
py7zr>=0.20.0 # suporte a .7z
rarfile>=4.0 # suporte a .rar
Nenhum deles é obrigatório. O Codis executa com zero dependências externas.
O Codis inclui um modo dedicado em package_codis.py que monta automaticamente todos os parâmetros corretos do PyInstaller - é a forma recomendada de gerar um executável, em vez de chamar pyinstaller manualmente:
pip install pyinstaller
python package_codis.py pyinstaller # gera em modo --onedir (padrão)
python package_codis.py pyinstaller --onefile # executável único em vez de pasta
python package_codis.py pyinstaller --debug # mantém console para depuraçãoO padrão é um executável único (--onefile, mesmo modo do CI); use --onedir para gerar uma pasta (inicia mais rápido, pois não auto-extrai a cada execução).
Por baixo dos panos, o script monta automaticamente:
-
Dados incluídos: os
src/locales/<idioma>.json(14 idiomas; o.translate_manifest.jsonde desenvolvimento não entra),wiki/erequirements.txt -
Tcl/Tk: coletado pelo hook oficial do PyInstaller. Não adicione
--add-datade Tcl/Tk manualmente (duplica os dados e, semDISPLAY, pode embutir o prefixo inteiro do Python) -
Imports ocultos: todos os submódulos de
tkinter, maissrc.plugins,src.ia,src.lsp,src.lint,src.syntax,src.diff,xmlrpc.client/servereemail.mime.* -
Módulos excluídos (reduzem o tamanho do bundle):
matplotlib,numpy,pandas,scipy,cv2,PyQt5/6,PySide2/6,wx, entre outros nunca usados pelo Codis
Para nunca usar UPX (como no CI): python package_codis.py pyinstaller --no-upx ou CODIS_NO_UPX=1. O PyInstaller já ignora o UPX fora do Windows, e no executável --onefile final ele não reduz nada.
Tamanho de referência do executável Linux x64: ~32 MB. O CI falha se passar de 60 MB.
Se
send2trashestiver instalado no ambiente de build, ele é incluído automaticamente no bundle. Sem ele, o executável final usa a lixeira do projeto (.codis_trash/) normalmente.
Diferente do PyInstaller, o Nuitka não faz parte do pipeline oficial do Codis (não há workflow de CI usando-o, nem script dedicado em
package_codis.py). O comando abaixo é um ponto de partida não usado pelo projeto, caso prefira essa alternativa por conta própria.
pip install nuitka
python -m nuitka --onefile --enable-plugin=tk-inter \
--include-data-dir=src/locales=src/locales \
--include-data-dir=wiki=wiki \
run.pyO repositório inclui 10 workflows em .github/workflows/. A regra de ouro: cada commit passa por um único pipeline (pipeline.yml), que valida, compila e publica a release uma só vez - os arquivos compilados são os mesmos do artefato e da release, e nada é refeito quando você lança uma versão.
push / tag / PR
│
plan ─────────────┬──► quality (testes, lint, i18n) ──┐
(decide tudo │ ├──► release ──► summary
uma única vez) └──► build (executáveis + ZIP) ──┘
| Job | O que faz |
|---|---|
plan |
Roda .github/scripts/plan.py: lê APP_VERSION, descobre o canal de release, o que mudou desde o último build publicado e monta a matriz de plataformas |
quality |
Chama _quality.yml: sintaxe (Python 3.12/3.13), imports em Linux/Windows/macOS, Flake8 e Pylint (informativos), pytest com cobertura, i18n e consistência de locales |
build |
Chama _build.yml: executáveis PyInstaller de cada plataforma (com smoke test no Linux e limite de 60 MB) + ZIP do código-fonte. Roda em paralelo com quality
|
release |
Só roda se quality e build passaram. Baixa os arquivos já compilados, gera SHA256SUMS.txt e as notas e publica a release. Não recompila nada
|
summary |
Resumo da execução; falha o pipeline se alguma etapa obrigatória falhou |
O canal é decidido pelo plan, sem nenhuma ação manual:
| Canal | Quando | Resultado |
|---|---|---|
stable |
Push em main/master quando APP_VERSION ainda não tem tag; ou push de tag vX.Y.Z
|
Release oficial vX.Y.Z (marcada como Latest; -beta.N etc. viram pre-release), com notas do CHANGELOG.md e notas automáticas por label
|
nightly |
Push em main/master quando a versão já foi lançada
|
Uma única pré-release móvel chamada nightly, atualizada a cada commit com mudança de código (não acumula releases) |
dev |
Push em develop
|
Pré-release móvel dev (somente as 3 plataformas principais) |
none |
Pull request | Só valida e compila (3 plataformas principais); não publica |
Cada release traz, de uma vez: os executáveis (Windows x64, Linux x64, macOS Apple Silicon e, em main/tag, também Linux ARM64, Windows ARM64/x86 e macOS Intel, que são experimentais e nunca derrubam o pipeline), o ZIP do código-fonte (Codis-vX.Y.Z-source.zip), o SHA256SUMS.txt (usado pelo atualizador do app para conferir a integridade), as notas e o comparativo com a versão anterior.
Releases oficiais são criadas como rascunho, recebem todos os arquivos e só então são publicadas: nem usuários nem o atualizador enxergam uma release pela metade. Pré-releases nightly/dev não afetam o atualizador (ele lê apenas a última release oficial).
Commits só de documentação (
*.md,wiki/,docs/,tools/...) não compilam nem publicam release: oplancompara o commit com o último build publicado e só segue se algo que entra no binário mudou (src/**,run.py,requirements.txt,package_codis.py,setup.py,pyproject.tomlou os scripts/workflows de build).
| Arquivo | Trigger | O que faz |
|---|---|---|
pipeline.yml |
Push em main/master/develop, tag v*.*.*, PR para main/master, workflow_dispatch (inputs release e extended) |
Porta de entrada única: plan → quality ∥ build → release → summary
|
_quality.yml |
Chamado pelo pipeline.yml
|
Verificações de código (reutilizável, sem triggers próprios) |
_build.yml |
Chamado pelo pipeline.yml
|
Executáveis multiplataforma + ZIP de código-fonte (reutilizável, não publica) |
docs.yml |
PR com mudanças em docs/código (check); push em main com mudanças em docs/**, wiki/**, *.md, tools/** ou src/constants.py (site + deploy + wiki); workflow_dispatch
|
PR: confere tools/docs_facts.py --check e tools/build_site.py --check. Push: gera docs/ e publica no GitHub Pages; sincroniza wiki/ com a GitHub Wiki somente se wiki/ mudou
|
codeql.yml |
Push/PR em main/master/develop com mudanças de código, e semanalmente (segunda 08:00 UTC) |
Análise estática de segurança CodeQL (independente do pipeline; não bloqueia releases) |
dependency-review.yml |
PR com mudanças em requirements.txt ou .github/dependabot.yml
|
Bloqueia PRs com dependências de CVE alto/crítico e comenta o resumo no PR |
label.yml |
Abertura/edição/sync de PR, abertura/edição de issue | Rotulagem automática (as labels alimentam as notas de release por categoria) |
locale-sync.yml |
Somente workflow_dispatch (flag apply) |
Ferramenta manual: sincroniza as chaves dos 14 locales e commita. A verificação automática já roda em quality
|
artifact-cleanup.yml |
Semanalmente (segunda 07:00 UTC), ou workflow_dispatch (dry_run, min_age_days, keep_last_builds) |
Remove artifacts antigos do Actions, protegendo as execuções mais recentes de pipeline.yml
|
stale.yml |
Diariamente (06:00 UTC), ou workflow_dispatch
|
Marca issues/PRs inativos como stale |
As categorias das notas automáticas ficam em .github/release.yml (por label: bug, melhoria, segurança, documentação, i18n, dependencies etc.).
Em Actions → Pipeline → Run workflow:
-
release = auto(padrão): comporta-se como um push no branch escolhido, ignorando o filtro de "o que mudou". -
release = none: valida e compila sem publicar (útil para testar o build). -
extended = false: só as 3 plataformas principais. - Rodar a partir de uma tag (
Use workflow from: Tag: vX.Y.Z) recompila e atualiza os arquivos da release dessa tag (reexecução segura, sem duplicar).
| Tarefa | Onde roda | Onde não roda mais |
|---|---|---|
| Checagem de sintaxe |
quality (uma vez) |
no build (antes havia outra) |
| ZIP do código-fonte |
build (uma vez) |
package.yml (removido) |
| Compilar executáveis |
build (uma vez por commit) |
release.yml (recompilava ao criar a tag) |
| Verificar locales | quality |
locale-sync.yml em push/PR |
| Site, wiki e conferência de docs | docs.yml |
três workflows separados |
Mapa do que mudou:
ci.yml→_quality.yml;build.yml+package.yml+release.yml→_build.yml+pipeline.yml;docs-check.yml+pages.yml+wiki-sync.yml→docs.yml. O badge de CI do README aponta parapipeline.yml.
Os testes ficam em tests/ - 70 arquivos, 1683 casos no total, rodando 100% headless (sem display gráfico):
tests/
├── conftest.py ← Fixtures compartilhadas + stub de Tkinter
├── test_config.py ← Testes do ConfigManager
├── test_diff_engine.py ← Testes do DiffEngine
├── test_lsp_protocol.py ← Testes do protocolo LSP
├── test_syntax_patterns.py ← Testes de highlight (8 linguagens)
└── ... (mais 13 arquivos)
Executar todos os testes:
pytest tests/ -v
pytest tests/ --cov=src --cov-report=term-missing # com cobertura→ Veja Testes para a cobertura completa por módulo, fixtures disponíveis e convenções.
O Codis pode ser distribuído como um ZIP portátil (sem instalação):
- Clone o repositório.
- Compacte o diretório:
zip -r Codis.zip . - O usuário extrai e executa
python run.py- sem nenhum pip install.
Para funcionalidades extras (lixeira nativa, imagens, etc.):
pip install send2trash Pillow markdownO Codis usa Semantic Versioning (SemVer):
-
MAJOR.MINOR.PATCH- ex:1.0.0 - A versão é definida em
src/constants.py(APP_VERSION) - O codinome de cada versão é definido em
APP_CODENAME(ex:"Aether")
Para lançar uma versão não é preciso criar tag nem rodar nada manualmente:
- Atualize
CHANGELOG.md(seção## [X.Y.Z]) eAPP_VERSIONemsrc/constants.py. - Faça o commit/merge em
main.
O pipeline.yml percebe que vX.Y.Z ainda não existe, valida, compila todas as plataformas, gera o ZIP do código-fonte e os checksums e publica a release oficial - tudo na mesma execução. Os commits seguintes (sem mudar a versão) apenas atualizam a pré-release nightly.
Também continua válido criar a tag manualmente (git tag vX.Y.Z && git push origin vX.Y.Z): ela precisa ser igual a APP_VERSION, e se a release já tiver sido publicada o pipeline não faz nada.
O binário gerado por package_codis.py pyinstaller não embute Python para rodar
pip, venv, servidores LSP baseados em Python (pylsp, pyright...) nem o
code runner de Python: eles usam o Python do sistema (ver Troubleshooting). Ao
adicionar código que lança subprocessos Python, use src/pyexec.py
(python_cmd(), child_env(), script_command()) - nunca sys.executable,
que no executável compilado é o próprio Codis.
Começando
Editando
- Editor
- Inteligência do Editor
- KDocs
- Linting & LSP
- Debug
- Git
- Terminal
- Workspace & Produtividade
- Utilitários de Desenvolvimento
Assistente e conectividade
Ferramentas e extras
- Recursos Avançados
- Recursos Exclusivos
- K-UI
- Sistema & Performance
- Backups, Lixeira & Arquivos
- Painel de Saída
- Acessibilidade
- Editor de Imagens (Paint)
- Utilitários Pessoais
- Incorporar Programas e Preview Web
- DOOM Embutido
Para quem desenvolve
Projeto