Windows Builds
Como produzir artefatos Windows por tipo de módulo da Koder Stack. Distingue o que funciona direto no Linux (Go cross-compile, MSI via wixl) do que exige delegar para máquina Windows via WinRM (Flutter desktop). Inclui receita pra k.win.
Windows Builds — Koder Stack
Guia de referência para produzir artefatos Windows a partir de diferentes tipos de módulo da Koder Stack. Distingue o que funciona diretamente no Linux do que requer delegar para uma máquina Windows via WinRM.
Regra: MSIX obrigatório para Flutter desktop com UI Windows
Todo módulo Koder que se enquadra em *ualquer*um dos critérios abaixo *eve*gerar .msix em cada release:
- Tem
app/desktop/com código Flutter - Tem
"windows"listado emplatformsnokoder.toml - É um produto com usuário final (app de consumo, SaaS, utilitário) mesmo que o diretório
app/desktop/ainda não exista — o MSIX deve ser incluído assim que o build Windows for adicionado
*ão pular*alegando ausência de máquina Windows — sempre delegar via WinRM para s.win.local (VM local) ou k.win (servidor remoto). Ver §2 abaixo para o fluxo completo.
Módulos Koder com Flutter desktop que precisam de MSIX (lista não exaustiva):
| Módulo | koder.toml platforms |
Diretório desktop |
|---|---|---|
dev/store (Koder Hub) |
android, linux, windows, macos, web | app/ (multi-plataforma) |
suite/kmail (Kmail) |
linux, windows, macos, android, ios | app/desktop/ |
suite/dek (Koder Dek) |
linux, windows, macos | app/desktop/ |
foundation/pass (Koder Pass) |
android, ios, linux, windows, macos | app/ |
Qualquer módulo novo com "windows" em platforms entra nessa lista automaticamente.
Sumário
| Tipo de módulo | A partir do Linux? | Ferramenta | Status |
|---|---|---|---|
| Go service / CLI | ✅ Cross-compile direto | GOOS=windows go build |
Produção |
| Flutter desktop app + MSIX | ✅ Via WinRM → s.win.local ou k.win | vmwinrm.py + build-msix.ps1 |
Produção |
| Installer MSI (para .exe Go) | ✅ Cross-compile direto | wixl (msitools) |
Produção |
| Installer EXE (PowerShell) | ✅ Via WinRM | vmwinrm.py + ps2exe na VM |
Produção |
| MSIX via kpkg | ⚠️ Stub | kpkg build --msix |
Não implementado |
| Koder Koda → .exe | ✅ Cross-compile direto | nasm + mingw + wine | Produção |
Máquinas Windows disponíveis
Há duas máquinas Windows acessíveis a partir do ambiente de desenvolvimento:
s.win.local — VM Win10 QEMU no notebook (preferida para builds interativos)
- OS: Windows 10 22H2 (10.0.19045.0)
- QCOW2:
/home/koder/temp/win10-vm/win10.qcow2 - WinRM:
http://localhost:5985/wsman(NTLM, port-forwarded pelo QEMU) - Usuário:
koder/koder123 - Controle Python:
/home/koder/temp/win10-vm/vmwinrm.py(WinRM) +vm.py(QMP+VNC) - Flutter + VS Build Tools: já instalados via
setup-flutter-env.ps1 - Iniciar VM:
bash /home/koder/temp/win10-vm/start-vm.sh
k.win — Windows Server 2019 remoto (para builds CI)
- OS: Windows Server 2019 (10.0.17763)
- WinRM:
http://187.108.204.239:5985/wsman(NTLM) - Usuário:
administrador/bKlPn0OkZ}N14\mA@`` - RDP:
187.108.204.239
Toolchain de WinRM (pywinrm)
O script vmwinrm.py faz a ponte Linux → Windows via pywinrm:
# Instalação (uma vez)
pip install --break-system-packages pywinrm
# Aguardar VM estar disponível
python3 ~/temp/win10-vm/vmwinrm.py wait
# Executar comando PowerShell
python3 ~/temp/win10-vm/vmwinrm.py run "Get-Date"
# Executar script .ps1 local (o script é enviado e executado na VM)
python3 ~/temp/win10-vm/vmwinrm.py script build-msix.ps1
# Upload de arquivo para a VM
python3 ~/temp/win10-vm/vmwinrm.py upload local.zip "C:\\dest.zip"Para k.win, editar HOST, USER, PASS em vmwinrm.py (ou criar cópia kwin.py):
HOST = "187.108.204.239"
USER = "administrador"
PASS = "bKlPn0OkZ}N14`mA@`"*roblema conhecido — upload de arquivos grandes:*A técnica de base64 embutido no comando falha para arquivos acima de ~1 MB. Solução: HTTP server no host Linux acessado pela VM em 10.0.2.2:
# Host Linux
python3 -m http.server 8877 --directory ~/temp/win10-vm/
# VM Windows (via vmwinrm.py run)
(New-Object Net.WebClient).DownloadFile('http://10.0.2.2:8877/kmail.zip', 'C:\kmail.zip')1. Go services e CLIs
Cross-compile 100% funcional a partir de Linux. Nenhuma VM necessária.
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 \
go build -o dist/meu-binario-windows-amd64.exe ./cmd/meu-binarioCGO_ENABLED=0é obrigatório para cross-compile.- Gera PE64 válido executável diretamente no Windows.
- Testado em: koder
signagent, koderwired, koderdrive, koderkmailserver.
2. Flutter desktop apps + MSIX (via WinRM)
flutter build windows --release requer MSVC — toolchain Windows-only. O mecanismo atual é delegar o build para s.win.local via WinRM.
Fluxo completo
# 1. Iniciar a VM (se não estiver rodando)
bash ~/temp/win10-vm/start-vm.sh
# 2. Aguardar WinRM ficar disponível
python3 ~/temp/win10-vm/vmwinrm.py wait
# 3. Copiar projeto para a VM via HTTP server temporário
cd ~/dev/koder/<area>/<produto>/app/desktop
zip -r /home/koder/temp/win10-vm/projeto.zip .
python3 -m http.server 8877 --directory ~/temp/win10-vm/ &
python3 ~/temp/win10-vm/vmwinrm.py run \
"(New-Object Net.WebClient).DownloadFile('http://10.0.2.2:8877/projeto.zip', 'C:\\projeto.zip')"
python3 ~/temp/win10-vm/vmwinrm.py run \
"Expand-Archive 'C:\\projeto.zip' 'C:\\projeto' -Force"
kill %1 # parar http.server
# 4. Executar build MSIX na VM
python3 ~/temp/win10-vm/vmwinrm.py script ~/temp/win10-vm/build-msix.ps1
# 5. Recuperar o MSIX gerado
MSIX_PATH=$(python3 ~/temp/win10-vm/vmwinrm.py run \
"Get-Content 'C:\\koder-msix-path.txt'")
python3 ~/temp/win10-vm/vmwinrm.py run \
"[Convert]::ToBase64String([IO.File]::ReadAllBytes('$MSIX_PATH'))" \
| base64 -d > produto.msixO script de referência para o build MSIX é ~/temp/win10-vm/build-msix.ps1:
- Gera certificado auto-assinado (
.pfx) para sideloading - Executa
flutter build windows --release - Executa
dart pub run msix:createcom as opções do produto - Salva o caminho do MSIX em
C:\koder-msix-path.txt
Configuração do pubspec.yaml (Flutter MSIX)
dependencies:
msix: ^3.16.7
msix_config:
display_name: Kmail
publisher_display_name: Koder Dev
identity_name: dev.koder.kmail
msix_version: 1.0.3.0
capabilities: internetClient,privateNetworkClientServer
languages: en-us3. Instaladores MSI (a partir de um .exe Go)
Funciona em Linux via wixl (parte do pacote msitools).
sudo apt-get install msitools wixl
# Script de referência (koder-sign-agent)
products/horizontal/sign/engine/cmd/koder-sign-agent/packaging/build-msi.sh \
<version> <caminho/para/binario.exe>Outros módulos com scripts MSI prontos:
infra/observe/wire/packaging/scripts/build-packages.sh(Koder Wired)products/horizontal/dek/app/windows/koder-dek.wxs(Koder Dek — manifest manual)
4. Installer EXE PowerShell via ps2exe (via WinRM)
O KoderHubSetup.exe é um script PowerShell compilado com ps2exe na VM Windows. ps2exe gera um executável PE32 Mono/.NET que encapsula o script.
# 1. Copiar script para a VM (via upload ou HTTP server)
python3 ~/temp/win10-vm/vmwinrm.py upload \
products/dev/store/installer/koder-hub-installer.ps1 \
"C:\\installer.ps1"
# 2. Compilar EXE na VM
python3 ~/temp/win10-vm/vmwinrm.py run \
"Invoke-ps2exe C:\\installer.ps1 C:\\KoderHubSetup.exe -requireAdmin -noConsole"
# 3. Baixar o EXE gerado
python3 ~/temp/win10-vm/vmwinrm.py run \
"[Convert]::ToBase64String([IO.File]::ReadAllBytes('C:\\KoderHubSetup.exe'))" \
| base64 -d > KoderHubSetup.exe*otcha ps2exe:*$PSScriptRoot e $MyInvocation.MyCommand.Path são null em executáveis compilados. Use try/catch com fallback $env:TEMP para caminhos de escrita.
5. MSIX via kpkg (não implementado)
kpkg build --msix é um stub — emite warning e sai sem gerar arquivo:
// products/dev/kpkg/internal/builder/builder.go linha ~117:
// TODO: implement MSIX export via makemsixPara implementar: ver meta/docs/stack/specs/kpkg/format.kmd (seção "export targets → msix").
6. Koder Koda → PE64 (executável Windows)
Cross-compile funcional a partir de Linux com nasm + MinGW:
sudo apt-get install nasm mingw-w64 wine-stable
engines/lang/lang/scripts/build-win64-prog.sh hello.kd -o hello.exe
wine hello.exe # valida o .exeReferências:
engines/lang/lang/scripts/build-win64-prog.shengines/lang/lang/self-hosted/lib/win64_syscall_shim.asm- Teste de regressão:
engines/lang/lang/tests/regression/018-win64-cross-compile.test.sh
7. Setup da VM Windows (one-time)
O ambiente Flutter na s.win.local já está instalado. Para reconfigurar do zero:
python3 ~/temp/win10-vm/vmwinrm.py script \
~/temp/win10-vm/setup-flutter-env.ps1O script instala: Chocolatey, Git, Flutter SDK estável, VS Build Tools 2022 (workloads: Desktop C++ + Windows 11 SDK), dart pub global activate msix.
8. Histórico de builds Windows realizados
| Produto | Versão | Tipo | Mecanismo |
|---|---|---|---|
| Koder Hub | v2.29.15–17 | MSIX | WinRM → s.win.local → build-msix.ps1 |
| Koder Hub | v2.29.17–18 | EXE installer | WinRM → s.win.local → ps2exe |
9. Registrar runner Windows no Flow (opcional — para CI/CD)
Para builds automáticos via Gitea Actions sem intervenção manual:
# .gitea/workflows/store-release.yml
store-publish-win:
runs-on: windows-latest
steps:
- uses: subosito/flutter-action@v2
- run: flutter pub get && flutter build windows --release
- run: dart run msix:createRegistrar runner:
# No Windows, após instalar Gitea Actions runner:
./act_runner register \
--instance https://flow.koder.dev \
--token <RUNNER_TOKEN> \
--labels windows-latest,windows,windows-amd64*tatus atual* runner windows-latest NÃO está registrado no Flow.