9 pontos por GN⁺ 2025-09-18 | 2 comentários | Compartilhar no WhatsApp
  • O Homebrew é um gerenciador de pacotes que facilita a instalação e o gerenciamento de ferramentas de CLI no macOS, permitindo que desenvolvedores configurem o ambiente do sistema de forma eficiente com ferramentas usadas com frequência
  • Este guia explica o processo de distribuir scripts pessoais de CLI usando o Homebrew e mostra como simplificar a manutenção com integração com GitHub e fluxos de trabalho automatizados
  • O processo de distribuição segue criação da CLI → release no GitHub → criação de Tap → criação e atualização da Formula e, no fim, permite a instalação apenas com os comandos brew tap e brew install
  • Entender a terminologia e as boas práticas do Homebrew permite fazer uma distribuição estável com mais reprodutibilidade e segurança da cadeia de suprimentos
  • Também é possível automatizar com GitHub Actions e, depois de configurar uma vez, a principal vantagem é que distribuir outras CLIs fica muito mais simples

Contexto e motivação

  • O Homebrew é o gerenciador de pacotes preferido para instalar ferramentas de CLI no macOS e é usado por muitos desenvolvedores
  • Porém, ao distribuir uma CLI criada por você, é comum usar npm ou RubyGems, e o processo de distribuição via Homebrew pode parecer pouco familiar
  • O repositório core oficial do Homebrew evita registrar ferramentas autorais, então desenvolvedores em geral distribuem por meio de um tap e uma formula separados
  • Este guia se baseia em uma experiência simples de distribuição de uma CLI em Ruby

Explicação dos termos

  • O Homebrew usa uma terminologia própria inspirada no tema de fabricação de cerveja, e entendê-la ajuda a compreender a estrutura do sistema
    • Formula é o arquivo de definição do pacote, contendo instruções para instalar código-fonte ou binários
    • Tap é um repositório Git de Formulas, usado para gerenciar pacotes customizados por usuário ou organização
    • Cask é um manifesto de instalação para apps com GUI ou binários grandes; é parecido com Formula, mas lida com arquivos pré-compilados
    • Bottle é um pacote binário pré-compilado copiado em vez de compilado do código-fonte, acelerando a instalação
    • Cellar é o diretório onde ficam as Formulas instaladas, por exemplo em /opt/homebrew/Cellar
    • Keg é o diretório de uma instância instalada de uma Formula, organizado por versão dentro do Cellar

Visão geral

  • Como o repositório core do Homebrew não aceita conteúdos de nicho ou enviados por indivíduos, os usuários precisam criar um repositório tap separado para distribuir sua CLI
    • 1. Criar a CLI, enviar ao GitHub e fazer um release com tag
    • 2. Criar um Tap com brew tap-new e fazer push para o GitHub
    • 3. Criar a Formula com brew create (incluindo URL do tarball e SHA256)
    • 4. A cada nova versão, atualizar a Formula para que os usuários possam instalar facilmente com brew install
  • Depois da distribuição, o usuário pode instalar a CLI com dois comandos: brew tap your_github_handle/tap e brew install your_cool_cli
    • Este guia não aborda o desenvolvimento da CLI em si; o foco está na criação do tap, na criação da Formula e no processo de atualização
    • Como exemplo, é usada a CLI imsg, que cria um arquivo web interativo a partir de um banco de dados do iMessage

Criação do tap

  • Siga o guia de criação de tap do Homebrew, substituindo pelo seu nome de usuário ou organização no GitHub
    • Para reunir todas as CLIs futuras em um único tap, recomenda-se o nome homebrew-tap; o prefixo homebrew recebe tratamento especial na CLI e o sufixo tap é convencional
  • Execute o comando de criação do tap: brew tap-new searlsco/homebrew-tap
    • Isso cria o scaffold em /opt/homebrew/Library/Taps/searlsco/homebrew-tap
    • Crie o repositório correspondente no GitHub e faça push do conteúdo gerado: cd /opt/homebrew/Library/Taps/searlsco/homebrew-tap, git remote add origin git@github.com:searlsco/homebrew-tap.git, git push -u origin main
  • Depois que o tap estiver sob seu controle, outros usuários poderão clonar o repositório com brew tap searlsco/tap para colocá-lo em /opt/homebrew/Library/Taps
    • No início, ele ainda não terá nada útil, mas já permite verificar o funcionamento básico

Criação da Formula

  • O Homebrew pode apontar diretamente para um repositório GitHub, mas recomenda usar um tarball versionado com checksum, aumentando a reprodutibilidade e a segurança da cadeia de suprimentos de open source
  • Comando para criar a Formula: brew create https://github.com/searlsco/imsg/archive/refs/tags/v0.0.5.tar.gz --tap searlsco/homebrew-tap --set-name imsg --ruby
    • A flag --tap especifica o tap customizado e coloca a Formula em /opt/homebrew/Library/Taps/searlsco/homebrew-tap/Formula
    • --set-name imsg define explicitamente o nome da Formula; escolha um nome único para evitar duplicações (por exemplo, cuidado com conflitos com a CLI TLDR ou standard já existentes)
    • --ruby é um preset de template para CLIs em Ruby e é uma das várias opções que simplificam a customização
  • A Formula gerada pode não funcionar de início, então vale usar um LLM para ajustar: execute brew install --verbose imsg, envie os erros ao ChatGPT e repita a atualização da Formula
    • O arquivo final Formula/imsg.rb pode ser copiado como ponto de partida para distribuir CLIs em Ruby
    • Distribuir via Homebrew, em vez de usar um gerenciador de pacotes específico de linguagem, permite trocar a linguagem de implementação sem atrito para os usuários na hora de atualizar

Principais destaques da Formula

  • Todas as Formulas são escritas em Ruby, já que muitas ferramentas de desenvolvimento populares antes da era do JavaScript ou da IA eram baseadas em Ruby
    • É possível especificar um repositório Git com o método head, embora o efeito real seja incerto
    • Adicionar livecheck vale a pena porque facilita a atualização de versão da Formula
    • O teste de execução do binário pode ser implementado de forma simples verificando a saída de ajuda; não se intimide com os comentários gerados automaticamente
    • Use o comando brew style searlsco/tap para verificar erros de estilo
    • O padrão uses_from_macos "ruby" do template --ruby usa a versão 2.6.10 (um release anterior à COVID e com EOL há 3 anos), então é recomendável depender da Formula mais atual com depends_on "ruby@3"
  • Quando a Formula estiver satisfatória, faça git push para publicá-la; então os usuários poderão instalar com brew tap searlsco/tap e brew install imsg

Atualização da Formula a cada release da CLI

  • Atualizar manualmente a url e o hash sha256 no topo da Formula a cada release é trabalhoso, e o texto observa que até criar tags ou releases no GitHub acaba sendo cansativo
    • É possível usar o comando bump-formula-pr do Homebrew ou GitHub Actions para gerar um PR, mas o processo de fork e PR é desnecessariamente complexo
    • Se você é dono do tap, o ideal é um método simples que faça commit direto na branch main
  • Para evitar isso, recomenda-se adicionar um workflow do GitHub ao repositório da Formula para atualizar o tap automaticamente no momento do release
    • Você pode copiar o exemplo de workflow
    • Configuração necessária: ao criar um token de acesso pessoal (PAT) do GitHub, conceda permissão ContentWrite ao repositório homebrew-tap e salve-o como HOMEBREW_TAP_TOKEN nos Secrets do repositório da Formula
    • Defina o tap e a Formula com variáveis de ambiente (por exemplo, nas linhas 13–15)
    • Recomenda-se usar a conta de bot do GitHub para as atualizações: GH_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com, GH_NAME: github-actions[bot]
  • Depois de criar um release e executar git push --tags, a atualização acontece automaticamente em poucos segundos, e os usuários podem atualizar com brew update e brew upgrade imsg

A melhor parte

  • O processo parece complexo, mas depois de configurar o tap e concluir um exemplo de Formula, distribuir CLIs adicionais se torna quase trivial
    • É conveniente poder publicar uma nova Formula em apenas alguns minutos
  • O processo oficial do Homebrew é um pouco complicado, mas a automação o torna muito mais confortável
    • Isso reduz o atrito entre o release da ferramenta e sua distribuição, além de permitir expandir o suporte para CLIs em várias linguagens
  • Não se sabe se outra Formula será publicada de fato, mas é satisfatório ter essa possibilidade aberta

2 comentários

 
lamanus 2025-09-18

É possível criar PRs com o comando bump-formula-pr do Homebrew ou com GitHub Actions, mas o processo de fork e PR é desnecessariamente complexo

Existe a opção --no-fork, que permite fazer push direto para a branch e realizar o merge, além de oferecer um recurso de atualização automática.

 
GN⁺ 2025-09-18
Comentários do Hacker News
  • Às vezes acho as convenções de nomenclatura do Homebrew um pouco confusas, mas continuo sentindo que, no geral, é uma ferramenta realmente útil
    Também não imaginava que o processo de criar seu próprio tap para distribuir ferramentas fosse tão simples
    Fico curioso sobre em que aspectos isso é melhor em comparação com gerenciadores de pacotes específicos por linguagem, como o uv
    Queria saber especialmente se isso é mais fácil para quem não está dentro de um ecossistema específico, ou seja, se leva vantagem do ponto de vista da generalidade

    • Agradeço por mencionar isso; outras ferramentas que usam registros de pacotes geralmente exigem criação de conta, autenticação em dois fatores, processo de assinatura etc.
      O Homebrew é muito mais simplificado no geral porque os Termos de Serviço (ToS) do GitHub funcionam como base de confiança
      A equipe do Homebrew consegue reduzir bastante a complexidade graças a esse modelo

    • Falando em pacotes Python, tentativas como o uv, de empacotar tudo de uma vez, são difíceis na prática
      Por isso, em geral, usa-se a abordagem de instalar apenas dependências fixadas em um ambiente venv
      Como exemplo concreto, dá para consultar esta fórmula
      Sobre o uv, tentei usar as ferramentas oficiais (brew update-python-resources, homebrew-pypi-poet) para dar suporte a pacotes privados, mas não funcionou direito,
      então acabei criando o uvbrew para ajudar na geração de recursos
      Há também a documentação oficial para consultar ao escrever fórmulas Python no Homebrew

  • Se você é desenvolvedor Go, recomendo a ferramenta Goreleaser
    Ela facilita muito a distribuição de binários em um tap pessoal (esse método é proibido no core oficial)

    • Descobri recentemente que o Goreleaser agora oferece suporte não só a Go, mas também a Rust, TypeScript, Python, Zig e várias outras linguagens
      Tem bastante utilidade na gestão de projetos de diferentes linguagens
  • Pessoalmente, acho mais ideal gerenciar as atualizações diretamente do lado do tap
    Em geral, é parecido com a forma como se atualiza no upstream
    Consultando este workflow, dá para atualizar facilmente fórmulas/casks que você nem possui
    Com o comando brew bump, é possível escanear tudo, abrir PRs e até automatizar os testes com brew test-bot
    Um exemplo real de PR pode ser visto aqui

    • Acho uma ótima ideia
      Normalmente eu nem considerava isso porque achava ruim gastar tempo de uso do GitHub Actions, mas como em open source é grátis, esse tipo de uso parece bem válido
  • Cheguei a escrever meu próprio workflow automático de bump de versão para tap do Homebrew, o homebrew-bump-revision
    Tenho usado isso bem em vários projetos pessoais

    • Parece muito legal
      Eu não tentei por pura preguiça, mas é uma boa ferramenta
  • Houve um episódio do podcast Ruby Rogues que cobriu várias dicas para distribuir CLIs com Homebrew
    Dá para ouvir mais no link do episódio relacionado

  • Descobri um ponto interessante sobre empacotamento de ferramentas Python
    Alguns pacotes Python acabam criando ciclos de dependência durante o processo de build, o que os torna incompatíveis com o Homebrew
    O pip não sofre com isso porque baixa releases binárias, mas o Homebrew compila diretamente até as dependências, então esse processo leva bem mais tempo
    Por isso, até um projeto Python de porte médio pode levar mais de uma hora para gerar uma "bottle"

  • Desde que comecei a usar nix para administração do sistema, nunca me arrependi nem uma vez
    A única coisa de que sinto falta é que ainda preciso depender do Windows por causa de jogos multiplayer