Skip to content

Release v0.2.0 - #4

Merged
blackfoxsoftware merged 6 commits into
mainfrom
dev
Sep 2, 2026
Merged

Release v0.2.0#4
blackfoxsoftware merged 6 commits into
mainfrom
dev

Conversation

@blackfoxsoftware

Copy link
Copy Markdown
Owner

Merge da dev na main. Ao entrar, o workflow Release vai:

  1. validar o patchnotes.json e ler 0.2.0 do package.json;
  2. rodar o CI inteiro no estado que vira tag;
  3. empacotar o instalador NSIS e o portátil, e abrir o .exe num teste de fumaça;
  4. criar a tag anotada v0.2.0 e publicar a release com os dois binários anexados.

Empacotar vem antes da tag de propósito: config quebrada não pode deixar uma tag publicada sem binário.

Os .exe não são assinados — o SmartScreen vai avisar "editor desconhecido" e exigir Mais informações → Executar assim mesmo.


Notas que vão sair na release

O app agora tem instalador, e leva o SDK do WSL consigo.

Adicionado

  • Instalador (NSIS) e versão portátil para Windows x64, publicados como assets da release. Não são assinados: o SmartScreen avisa 'editor desconhecido'.
  • A wslcsdk.dll vai empacotada com o app — duas versões, 2.9.3 e 2.9.9, com a escolha feita em tempo de execução pela versão do WSL instalado.
  • Seletor de wslcsdk.dll na aba Sistema, para apontar uma DLL própria. O arquivo é sondado antes de ser aceito: versão, ABI e SHA-256 são lidos na hora, e o que não serve é recusado ali.
  • A aba Sistema passa a mostrar a origem da DLL em uso (empacotada, escolhida, do WSL ou de variável de ambiente), a ABI detectada e o tamanho do binário.
  • Ícone próprio do app.

Alterado

  • Containers nativos SOBREVIVEM ao fechamento do app quando o SDK é 2.9.9+: eles param e são reabertos por nome na execução seguinte, em vez de serem apagados na saída.
  • O campo que a aba Sistema chamava de 'SDK' virou 'WSL (pelo SDK)': medindo, WslcGetVersion devolve a versão do WSL instalado, não a da DLL — binários diferentes respondem o mesmo número.
  • O app ficou ~100 MB menor: tudo o que só o renderer usa saiu de dependencies, onde viajava duas vezes (embutido no bundle e de novo em node_modules).

Corrigido

  • Login em registry e instalação guiada não corrompem mais a chamada quando a DLL é 2.9.9: as duas funções mudaram de assinatura sem mudar o header de forma detectável, e o app agora identifica a ABI e se adapta.

O app passa a levar a wslcsdk.dll consigo — o pacote Microsoft.WSL.Containers
é MIT, então redistribuir é permitido, e LICENSE.txt e NOTICE.txt vão junto.

São DUAS DLLs, 2.9.3 e 2.9.9, e a escolha é em tempo de execução, porque a
versão do SDK precisa acompanhar a do WSL. Isso foi medido, não suposto: com
WSL 2.9.4, o SDK 2.9.9 carrega, cria a sessão, lista imagens e então dá
segmentation fault em WslcGetSessionTerminationEvent. Nada no header denuncia
o problema — a declaração daquela função é byte a byte idêntica nas duas
versões, e os 18 structs também. A regra ficou conservadora: a DLL mais nova
que não passe da versão do WSL instalado; sem saber a versão, a mais antiga.
Errar para baixo custa recurso, errar para cima custa o processo.

A 2.9.9 também mudou duas assinaturas sem mudar nada visível
(WslcSessionAuthenticate ganhou tokenType, WslcInstallWithDependencies ganhou
components e options), o que corromperia login em registry e instalação
guiada em silêncio. O bindings.ts agora detecta a ABI pela presença do símbolo
WslcOpenContainer e adapta as duas chamadas.

Com isso a aba Sistema pode oferecer o seletor de DLL: o arquivo escolhido é
sondado na hora — carregado num binding próprio, lido e descarregado, sem
tocar na sessão viva — e só então gravado. Um arquivo errado é recusado ali,
em vez de virar um motor nativo quebrado na próxima abertura. A troca vale ao
reabrir o app, porque a sessão nativa segura handles da DLL atual.

No caminho, dois acertos: o registro de tipos koffi saiu de dentro do load
(era por nome, num namespace global, e impedia carregar uma segunda DLL), e o
campo sdkVersion virou wslVersion — a medição mostrou que WslcGetVersion
devolve a versão do WSL instalado, não a da DLL, e a UI dizia "SDK".

O ícone do app vem do icon.svg, rasterizado em .ico com 16/32/48/256.
…s antiga

Atualizar esta máquina para WSL 2.9.9 confirmou a hipótese do segfault — a
2.9.9 passou a funcionar inteira, com os 301 testes verdes, incluindo login em
registry e instalação guiada, que são justamente as duas rotas cujas
assinaturas mudaram.

E expôs um furo: a regra de compatibilidade é de mão dupla. SDK novo demais dá
segfault; SDK velho demais é recusado com WSLC_E_SDK_UPDATE_NEEDED em QUALQUER
chamada, inclusive no WslcGetVersion. Como o bootstrap perguntava a versão do
WSL à DLL mais antiga, num WSL 2.9.9 ele não obtinha resposta, caía na mais
antiga por precaução e deixava o app sem motor nativo.

Agora a sonda vai da mais nova para a mais antiga. A mais nova responde a
versão certa mesmo num WSL antigo (medido: a 2.9.9 respondeu 2.9.4 num WSL
2.9.4) — ela só quebra depois, ao mexer na sessão, que é do que a regra de
escolha protege.

O HRESULT de recusa também virou mensagem acionável, no status e na sonda do
seletor: em vez de "0x8004060B", diz que a DLL é antiga demais para o WSL e
aponta as duas saídas.
electron-builder gerando os dois alvos para x64, com as duas wslcsdk.dll em
extraResources (mais LICENSE e NOTICE, que a licença MIT do pacote exige levar
junto) e o koffi fora do asar, porque dlopen não enxerga arquivo dentro dele.

O app.asar caiu de 109 MB para 8,4 MB ao mover para devDependencies tudo o que
só o renderer usa. Estava tudo em dependencies, então viajava duas vezes: uma
embutida no bundle do Vite e outra em node_modules dentro do pacote. Só koffi
(nativo, carregado em tempo de execução) e zod (usado pelo main) precisam ficar.
Instalador e portátil saem com ~102 MB cada.

O release passou a empacotar ANTES de criar a tag: config de empacotamento
quebrada não pode deixar uma tag publicada sem binário. E ganhou um teste de
fumaça que abre o .exe de verdade e confere que o motor nativo achou a DLL em
resources/ — três coisas que só existem no app empacotado (asar, koffi
desempacotado, DLL fora de vendor/) e que o E2E, rodando contra out/, nunca
tocaria.

Verificado nesta máquina: o app instalado abre, escolhe a 2.9.9 pela regra de
versão, carrega o koffi do asar.unpacked e lista as imagens.
WslcOpenContainer levanta a limitação que o ROADMAP documentava: um container
criado numa execução pode ser reaberto por nome ou ID em outra. Medido: soltar
a sessão derruba o container para EXITED, mas o registro fica; reabrir devolve
um handle utilizável e o Start o põe de volta em RUNNING.

Então o app parou de apagar os containers na saída — o que só era necessário
porque, sem abrir por ID, eles virariam órfãos invisíveis no storage. Agora ele
lembra em disco (known.ts) os que criou e reabre na próxima listagem. O arquivo
mora dentro do storage da sessão, então o reset leva a memória junto, que é o
comportamento certo. Na ABI 2.9.3 nada muda: sem reabrir, apagar continua sendo
a única saída.

Continua não havendo enumeração de containers em nenhuma versão do SDK; é
justamente por isso que o app precisa lembrar os nomes.

Efeito colateral que só apareceu ao rodar a suíte: como fechar deixou de
apagar, sobras de execuções anteriores entravam na conta dos testes que
verificam quantidade. Os testes de integração agora limpam antes e depois.

Fecha a versão 0.2.0, com notas e bump.
…existe

Empacotar as DLLs no repositório quebrou o `describe.skipIf(locateWslcSdk() ===
null)`. Ele funcionava por acidente: como a DLL não era versionada, no CI ela
não existia e a suíte de integração pulava. Agora o arquivo existe em qualquer
runner — mas o WSL não, e 30 testes passaram a falhar no CI.

Presença de arquivo nunca foi a pergunta certa. `isNativeUsable()` carrega a
DLL e pede a versão, que é o que de fato determina se dá para testar contra o
SDK. Verificado apontando a 2.9.3 neste WSL 2.9.9, que a recusa: os 30 testes
pulam, em vez de falhar.
…mento

SDK empacotado, seletor de DLL e instalador (v0.2.0)
@blackfoxsoftware
blackfoxsoftware merged commit e315c2d into main Sep 2, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant