@ciromaciel/extension-publisher
v0.2.1
Published
Publishes a browser extension to the Chrome Web Store and Microsoft Edge Add-ons, and a VS Code extension to the VS Code Marketplace and Open VSX, from the terminal or CI: credentials, package, upload, publish, status.
Readme
@ciromaciel/extension-publisher
Publica uma extensão de navegador na Chrome Web Store e no Microsoft Edge Add-ons, e uma extensão de VS Code no VS Code Marketplace e no Open VSX, pelo terminal ou no CI: salva as credenciais, empacota, envia, publica e acompanha o status.
bun add -g @ciromaciel/extension-publisher # o comando extension-publish fica no PATHO caminho, do zero
1. A primeira publicação é pelo painel de cada loja. Nenhuma das duas APIs
cria o item nem mexe na ficha (textos, imagens, formulário de privacidade).
Publique a primeira versão à mão, com o zip de extension-publish package, e
anote os IDs:
| Loja | ID | Onde está |
|---|---|---|
| Chrome | publisherId | no endereço do painel: chrome.google.com/webstore/devconsole/<publisherId> |
| Chrome | itemId | o ID da extensão, na página dela no painel |
| Edge | productId | Partner Center → a extensão → "Extension identity" |
Os IDs vão no extension-publish.json da extensão. Eles não são segredo, porque
aparecem nas URLs públicas das lojas, então o arquivo entra no git:
{
"name": "history-extension",
"build": "bun run build",
"dist": "dist",
"release": "release",
"forbidden": ["localhost", "127.0.0.1"],
"chrome": { "publisherId": "…", "itemId": "…" },
"edge": { "productId": "…" }
}2. As credenciais, uma vez por máquina. Cada comando abre as páginas certas no navegador e guia o resto:
extension-publish credentials google # conta de serviço do Google (Chrome Web Store API V2)
extension-publish credentials microsoft # Client ID e API key do Partner Center (Publish API v1.1)
extension-publish credentials # o que está salvo, sem mostrar os segredosElas ficam em ~/.ciromacielos/extension-publisher/credentials.json, que só o
seu usuário lê (0600), e nunca num repositório. A chave do Google é testada
com o Google antes de ser salva. A API key da Microsoft não aparece enquanto
você digita e vence: o Partner Center mostra a data, e o comando a guarda para
lembrar você.
3. Publicar uma versão: suba o version da extensão e, na pasta dela, rode:
extension-publish publish --dry-run # o pacote e o que impediria o envio, sem falar com as lojas
extension-publish publish # as duas lojas
extension-publish publish chrome --percent 10 # Chrome para 10% dos usuários primeiro
extension-publish publish edge --notes "Corrige a busca"O comando faz, nesta ordem:
- o build de produção;
- as verificações;
- o zip em
release/; - em cada loja, o envio, a espera até a loja aceitar o pacote e a publicação.
Uma loja que falhe não impede a outra, e o comando termina com erro dizendo em qual falhou.
4. Acompanhar:
extension-publish status # as duas
extension-publish status chrome # em revisão · publicada · recusada · versão · % dos usuáriosO Edge só acompanha operações, não a extensão, então o status mostra os últimos
envios feitos por esta máquina (~/.ciromacielos/extension-publisher/state.json).
Extensões de VS Code
Uma extensão de VS Code não precisa de IDs: o publisher e o name do
package.json já dizem quem ela é nas duas lojas. O extension-publish.json
só marca o tipo e, se houver, o que roda antes do vsce package (que já roda o
vscode:prepublish da extensão):
{
"kind": "vscode",
"build": "bun run --cwd ../../packages/shared build"
}Para o CI, um comando só configura tudo: abre cada página no lugar certo,
confere cada valor com a loja e grava os secrets direto no repositório do
GitHub (OVSX_PAT, AZURE_CLIENT_ID, AZURE_TENANT_ID), sem mostrar nenhum:
brew install gh azure-cli # se faltar
extension-publish setup vscode # da raiz do repositório das extensões
extension-publish setup vscode --only openvsxO Marketplace publica pelo Microsoft Entra ID, não por token: o Azure DevOps parou de emitir os tokens globais que ele aceitava em março de 2026, e os que restam vencem em 01/12/2026. Quem publica é uma managed identity numa assinatura do Azure (a gratuita serve; a identidade não tem custo). Um app registration entra no Azure, mas o Marketplace recusa. E uma conta Microsoft pessoal não entra no Azure CLI pelo login comum, só pelo diretório dela — por isso o setup pede o ID do locatário e entra com código.
O setup cria o grupo e a identidade, deixa a branch main do repositório
entrar como ela (OIDC, sem segredo guardado), grava os secrets e roda o
workflow uma vez para ler o ID da identidade no Azure DevOps (só ela consegue).
O ID vai para a área de transferência, e a tela de membros do publisher abre
para você colar. No CI, VSCE_AZURE_CREDENTIAL=1 faz o vsce publicar como ela.
Na sua máquina, também dá para usar tokens:
extension-publish credentials marketplace # token do Azure DevOps (Marketplace → Manage)
extension-publish credentials openvsx # token do Open VSX (assine antes o Publisher Agreement)
extension-publish status # a versão do package.json e a de cada loja
extension-publish publish --dry-run # o .vsix e o que impediria o envio
extension-publish publish # as duas lojas
extension-publish publish openvsx # só umaO publish pergunta a cada loja qual versão ela tem e só envia para a que não
tem a do package.json. Sem subir a versão, ele não faz nada e termina bem, e
por isso pode rodar em todo push: é assim que o CI publica. Uma loja que falhou
é tentada de novo no próximo push, e só ela.
O .vsix é feito e enviado pelas ferramentas das próprias lojas (vsce e
ovsx, via bunx), que acompanham as regras e a autenticação de cada uma.
O mesmo arquivo vai para as duas. Os tokens chegam a elas por variável de
ambiente, nunca na linha de comando. No Open VSX, o namespace (o publisher)
é criado na primeira publicação.
Antes de publicar, confere:
- o
package.jsontempublisher,name,engines.vscodee uma versãox.y.z; - o
main(e obrowser, se houver) está dentro do.vsix.
CI: as credenciais num comando só
setup cria o que dá para criar, confere cada credencial com a loja e grava
os secrets direto no repositório do GitHub (via gh, pela entrada padrão,
sem mostrar nenhum). Rode da pasta da extensão; sem nome de loja, ele faz as
do extension-publish.json dali. Pode rodar de novo: o que existe é
reaproveitado.
brew install gh # sempre
brew install --cask google-cloud-sdk # para o Chrome
brew install azure-cli # para o VS Code Marketplace
extension-publish setup # as lojas da extensão daqui
extension-publish setup chrome # → CHROME_SERVICE_ACCOUNT
extension-publish setup edge # → EDGE_CLIENT_ID, EDGE_API_KEY
extension-publish setup vscode # → OVSX_PAT, AZURE_CLIENT_ID, AZURE_TENANT_ID| Loja | O que o setup faz sozinho | O que fica com você |
|---|---|---|
| Chrome | projeto no Google Cloud, API ligada, conta de serviço, chave testada com o Google | colar o e-mail da conta (já copiado) em Conta, no painel |
| Edge | testa o Client ID e a API key contra a extensão | criar as credenciais na página da Publish API, que ele abre |
| Open VSX | confere o token, cria o namespace | assinar o acordo da Eclipse e gerar o token |
| Marketplace | grupo e managed identity, entrada da main por OIDC, o ID da identidade (já copiado) | ter uma assinatura do Azure (gratuita); colar o ID em Members, no publisher |
Com as credenciais no CI, publish pula a loja que já tem a versão: no
Chrome, publicada ou em revisão; no VS Code, publicada. O Edge não tem como
perguntar a versão pela API, então, sem subir a versão, o envio para ele falha.
O que é verificado antes de enviar
Um pacote com algum destes problemas nunca sai daqui:
- Manifesto: não há
manifest.jsonna raiz, o manifesto não é Manifest V3, ou a versão é inválida. - Endereços: aparece qualquer palavra da lista
forbidden, por padrãolocalhoste127.0.0.1. Isso pega um build que falaria com a máquina de quem desenvolve. evalounew Function: código gerado em tempo de execução, que a revisão das lojas recusa.- Mapas de código (
.map).
Em CI
As variáveis de ambiente valem mais que o arquivo de credenciais:
| Variável | O quê |
|---|---|
| CHROME_SERVICE_ACCOUNT | o JSON da chave da conta de serviço, como texto |
| EDGE_CLIENT_ID | Client ID do Partner Center |
| EDGE_API_KEY | API key do Partner Center |
| VSCE_PAT | token do Azure DevOps para o VS Code Marketplace |
| OVSX_PAT | token do Open VSX |
Testes
bun test tests/Os testes simulam as quatro lojas e as ferramentas vsce e ovsx, e cobrem:
- os endereços e cabeçalhos de cada API;
- a assinatura da conta de serviço, conferida com a chave pública;
- a espera até cada envio terminar;
- as verificações do pacote;
- as credenciais com permissão 0600 e sem o segredo no terminal;
- no VS Code, pular a loja que já tem a versão, e o token só no ambiente.
