A estrutura de um projeto (1): o padrão que não era padrão
Por Dorian Chávez · fundador e CEO da Hábil ·
O repo de estrutura de Go mais popular diz que não é oficial. O guia do Go pede cmd/ e internal/, e a ferramenta só vigia internal/. Com template.
A estrutura de um projeto · entrega 1 de 7 · Go
Cenário: os personagens e a história são inventados. Os dados técnicos e as citações levam a fonte no final.
Em 1 minuto
- O repositório de «estrutura padrão» de Go mais popular (56,7 mil estrelas em 22 de outubro de 2026) diz no README que não é um padrão oficial e que, para um projeto simples, é exagerado [2][3].
- O guia oficial do Go pede pouco para um servidor: os programas em
cmd/e a lógica eminternal/[1]. - Das pastas onde o código mora, só
internal/impõe uma fronteira que a ferramentagofaz cumprir: na prática, outro módulo não consegue importá-la [6][7]. - Fica um template que se clona e roda de primeira, com um script que demonstra essa fronteira ficando vermelho quando deve.
- Para segunda-feira: abra o repositório e pergunte a cada pasta que problema ela resolve hoje. A que não souber responder está sobrando.
Neste artigo
- O que aconteceu às 23:40?
- O que o guia do Go pede de verdade?
- Quais são os cinco erros mais comuns?
- Exercício: dá para deixar a fronteira vermelha?
- Para levar
- O que vem depois?
- O template e o curso
- O que a Hábil faz?
- Referências
O que aconteceu às 23:40?
Iván herdou um programa de 300 linhas espalhado em catorze pastas, e nenhuma dizia onde colocar uma função nova.
Segunda-feira, 23:40. Escritório vazio, terceiro andar.
Era o primeiro dia dele como estagiário. Sétimo semestre, o café frio desde as nove e uma única tarefa no quadro: «Fazer o verificador avisar quando um serviço demorar mais de um segundo».
O verificador era um programa em Go que consultava uma lista de serviços por HTTP e dizia quais respondiam. Quem tinha escrito era o Rodrigo, o estagiário anterior, que foi embora na sexta sem deixar nada além do repositório.
Iván clonou e ficou olhando para a tela.
api/ assets/ build/ cmd/ configs/ deployments/ docs/
examples/ init/ internal/ pkg/ scripts/ test/ web/Catorze pastas para umas 300 linhas de Go. api/: um README.md que dizia «aqui vai o contrato». web/: vazia. deployments/: um arquivo de 2019 sobre um servidor que já não existia. pkg/util: onze funções sem nada a ver umas com as outras.
A tarefa era pequena. Dez linhas, talvez. Mas onde? Em pkg/util, ao lado de uma função que formatava datas? Em internal/? Havia regras, ou era costume? O README do Rodrigo dizia: «Estrutura padrão de Go», com um link.
Ele seguiu: golang-standards/project-layout, mais de 56 mil estrelas. Iván respirou. Se tanta gente usava, tinha de ser o padrão. E no segundo parágrafo da introdução do README, em negrito, encontrou algo que não esperava:
«NOT an official standard defined by the core Go dev team» [2].
Não é um padrão oficial da equipe do Go. Quem diz é o próprio repositório.
Iván se recostou na cadeira. Se o padrão não era padrão, que parte daquelas catorze pastas importava de verdade?
Às 23:58 escreveu para a Lucía, a líder técnica. A resposta chegou em dois minutos:
— Dessas catorze, qual a ferramenta vigia? Qual muda o que o comando go deixa importar?
Iván olhou a lista de novo. Nenhuma tinha cara de vigiar nada.
— Não sei — escreveu.
— Uma. Amanhã eu mostro qual, e por que as outras treze são opinião.
O que o guia do Go pede de verdade?
Para um servidor, o guia oficial do Go cabe em duas pastas: o programa em cmd/ e todo o resto em internal/.
Ele se chama Organizing a Go module [1] e vai do menor ao maior, em sete casos: um pacote, um programa, um dos dois com pacotes de apoio, vários pacotes, vários programas, pacotes e programas juntos e, por fim, um servidor. Para esse último caso, diz duas coisas.
A primeira: um servidor normalmente não tem pacotes para outros importarem, então a lógica dele vai em internal/ [1]. A segunda: como costuma ter muitas pastas que não são de Go, convém juntar os programas em cmd/ [1].
É só isso. Não menciona pkg/; as pastas sem Go, como api/ ou web/, ficam a critério de quem programa [1].
Em 2021, numa discussão desse mesmo repositório, Russ Cox disse de forma mais curta: o padrão mínimo de um repositório de Go importável (um cujo código outros importam) é um LICENSE e um go.mod na raiz, e o código onde for mais cômodo. «That's it. That's the "standard"», escreveu [5]. E acrescentou que nem cmd/ é obrigatório [5].
O template desta entrega, estructura-go, segue o guia ao pé da letra:
estructura-go/
├── go.mod
├── README.md
├── LICENSE
├── LICENSE-CONTENIDO.md
├── cmd/
│ └── revisor/main.go el programa: lee la configuración, arma y arranca
├── internal/
│ ├── servicio/ el vocabulario: Servicio, Estado. Sin red ni archivos
│ ├── revisar/ consulta muchos servicios a la vez
│ ├── httpapi/ rutas, JSON y errores
│ └── config/ banderas, entorno y la lista de servicios
├── testdata/servicios.json
├── herramientas/probar-frontera.sh
└── .github/workflows/verificar.ymlVamos pasta por pasta, e em cada uma a pergunta é a mesma: que problema ela resolve hoje?
Por que o programa mora em cmd/?
main.go é magro de propósito: se algo ali merece um teste, já não pertence ali.
cmd/revisor/main.go lê a configuração, monta as peças de internal/ e sobe o servidor. Não decide o que é um serviço saudável nem como ele é consultado. Por que tão enxuto? Porque main encerra o processo com os.Exit e lê o ambiente real: o que fica ali fica sem teste. O template usa uma função ejecutar que devolve um erro, e o teste a chama com uma porta livre.
Um segundo programa, como uma tarefa noturna, iria em cmd/tarea-nocturna/ e compartilharia tudo o que está em internal/.
O que internal/ tem de especial?
internal/ é a única pasta da árvore com uma fronteira que a ferramenta go faz cumprir: o código que mora ali não pode ser importado de fora da árvore que a contém; na prática, de outro módulo.
Segundo a documentação do comando go, um pacote dentro de uma pasta internal só pode ser importado pelo código que compartilha o caminho acima dessa pasta [6]. Se o módulo for github.com/tu-usuario/revisor, todo esse módulo pode usar revisor/internal/servicio; um módulo alheio, não. Atenção: vale pelo caminho, não pelo módulo. Um módulo chamado github.com/tu-usuario/revisor/otro poderia, e o script da fronteira usa esse caso.
Quem faz cumprir não é a linguagem, e sim o comando go. As notas do Go 1.4 dizem assim: a linguagem não tem como impor essa distinção, e o comando go introduz um mecanismo para definir pacotes «internal» [7]. Desde o Go 1.5, vale para qualquer repositório [7][8].
E o que um servidor ganha com isso? O que ninguém de fora importa pode ser mudado sem quebrar nada de ninguém. Por isso o guia aconselha deixar em internal/ o máximo possível [1].
E as outras treze pastas do Iván? Nenhuma decide quem importa quem. O comando go trata de forma diferente outros dois nomes que não estão na lista dele. A testdata/, ele ignora [6].
Já a vendor/ fecha a passagem: se um módulo importa algo pelo caminho da vendor/ de outro, a ferramenta responde use of vendored package not allowed (medido com Go 1.27.1). Mas o código do projeto não vai ali: ela guarda cópias das dependências, e go mod vendor a apaga e a refaz toda vez [20]. Para o código do projeto, a fronteira é internal/.
Por que servicio/ não importa ninguém?
O pacote de que todos dependem não depende de nenhum, e por isso não pode fechar um ciclo.
internal/servicio/ define Servicio (nome, URL, tempo limite) e Estado (o que respondeu, quanto demorou, por que falhou). Não abre conexões, não lê arquivos, não sabe de JSON. Todos os pacotes de internal/ o importam, e ele não importa ninguém do projeto:
| Pacote | Importa |
|---|---|
cmd/revisor | config, httpapi, revisar |
httpapi | revisar, servicio |
revisar | servicio |
config | servicio |
servicio | ninguém do projeto |
Não é estética: a especificação proíbe que um pacote importe a si mesmo, direta ou indiretamente [11]. Como servicio não importa ninguém, não pode fazer parte de um ciclo. E como as demais setas vão num só sentido (cmd → httpapi → revisar → servicio), hoje não há nenhum.
O nome também conta: por convenção, os pacotes levam nomes em minúsculas e de uma só palavra [17]. servicio diz o que há dentro; models ou types diriam só de que tipo é.
Onde fica a interface?
A interface mora no pacote que a usa, não no que a implementa.
revisar consulta muitos serviços ao mesmo tempo, e para isso precisa de alguém que consulte um. Declara isso ali mesmo:
// Consultor es lo único que Todos necesita: alguien que consulte UN servicio y
// diga cómo lo encontró. Un método, y nada más.
type Consultor interface {
Consultar(ctx context.Context, s servicio.Servicio) servicio.Estado
}
func Todos(ctx context.Context, c Consultor, servicios []servicio.Servicio, paralelo int) []servicio.EstadoA consulta real é um tipo concreto, *revisar.HTTP, que cumpre essa interface sem declarar. O dublê para testes, consultorFalso, mora num _test.go e não viaja no programa.
É o que pede o Go Code Review Comments, o guia de revisão do próprio projeto: em geral, as interfaces ficam no pacote que usa os valores, não no que os implementa [10]. É o erro 4, logo abaixo.
E a porta HTTP?
httpapi só traduz: de requisição para chamada, e de resultado para JSON.
Tem três rotas: GET /salud, GET /servicios e GET /servicios/{nombre}, com o roteador da biblioteca padrão. Desde o Go 1.22, net/http entende o método e os curingas no padrão de rota, e a um POST responde 405 Method Not Allowed com os métodos válidos no cabeçalho Allow [12]. Medido no template: Allow: GET, HEAD.
Os erros que o template escreve saem no formato da RFC 9457, Problem Details [13]; os que o roteador responde por conta própria, como esse 405 ou uma rota que não existe, saem em texto puro (medido). Sem um tipo de erro próprio, usa-se about:blank e o título é a frase padrão do código, como «Not Found» [13]:
HTTP/1.1 404 Not Found
Content-Type: application/problem+json
{"type":"about:blank","title":"Not Found","status":404,"detail":"No hay ningún servicio llamado \"nomina\".","instance":"/servicios/nomina"}Mais uma coisa, porque um template também ensina maus hábitos: a URL de cada serviço sai sem usuário, senha nem parâmetros. https://usuario:clave@... ou ?token=... levam um segredo, e o que sai por uma API acaba em logs alheios. A configuração rejeita o primeiro caso e a porta limpa o segundo, cada um com um teste próprio. O caminho sai, sim, porque diz o que está sendo verificado: um token enfiado no caminho seria publicado inteiro.
O que é testdata/ e por que não atrapalha?
O comando go ignora as pastas chamadas testdata: são o lugar para os dados de apoio.
Assim ela fica disponível para os dados de que os testes precisam [6]. No template, guarda servicios.json, a lista do exemplo, e um teste a valida: se alguém a quebrar, fica sabendo antes do primeiro leitor.
E onde vão as dez linhas do Iván?
A regra vai no domínio; a porta só a publica.
«Avisar se um serviço demorar mais de um segundo» tem duas partes. Decidir o que é lento é vocabulário do programa, assim como decidir o que é saudável: vai em servicio, como um método de Estado ao lado de OK(), e o teste dele não precisa de rede. Comunicar isso para fora é trabalho de httpapi: um campo a mais no JSON. Se o segundo tiver de mudar sem recompilar, config o lê. Nenhuma pasta nova.
Na terça, Iván escreveu Lento() em servicio, o teste, e um campo em httpapi. Dez linhas, como ele pensava. Nenhuma em pkg/util.
Como saber que a fronteira existe?
Porque o CI a quebra de propósito a cada mudança e exige que a ferramenta a rejeite.
Uma regra que ninguém comprova é uma regra que ninguém sabe se continua viva. Por isso o template traz herramientas/probar-frontera.sh, com dois experimentos numa pasta temporária:
- Controle. Um módulo cujo caminho começa igual ao do template (
…/estructura-go/control) importainternal/servicio. A regra vale pelo caminho, então deixa passar: tem de compilar. Se não compilar, o experimento está mal montado e o script para no vermelho. - Violação. Um módulo com um caminho alheio (
ejemplo.com/intruso) importa o mesmo pacote, pela mesma via. Tem de falhar, e com a mensagem da regra.
Esta é a saída real:
1/2 control: github.com/HabilMX/estructura-go/control importa github.com/HabilMX/estructura-go/internal/servicio
✅ compiló: con la misma ruta de arriba, la regla lo deja pasar
2/2 violación: ejemplo.com/intruso importa github.com/HabilMX/estructura-go/internal/servicio
package ejemplo.com/intruso
main.go:3:8: use of internal package github.com/HabilMX/estructura-go/internal/servicio not allowed
✅ la herramienta go lo rechazó por la regla de internal/
✅ frontera: se sostienePor que o controle? Porque um experimento que só espera um vermelho fica «verde» também quando falha pelo motivo errado, como um caminho mal escrito. O controle busca o pacote pela mesma via que a violação, então uma montagem quebrada deixa o controle vermelho (comprovamos isso quebrando o caminho).
E a violação exige a mensagem exata da regra, não qualquer falha. Entre os dois passos, só muda quem importa: a regra fica demonstrada pelos dois lados.
O CI do GitHub roda esse script junto com gofmt, go vet, os testes com o detector de condições de corrida e a compilação de cmd/, a cada mudança, manualmente e toda segunda-feira, caso uma versão nova do Go quebre algo. Se o repositório passar 60 dias sem atividade, o GitHub desliga a execução das segundas e é preciso ligá-la de novo [21].
Quais são os cinco erros mais comuns?
Os três primeiros vêm de criar a pasta antes do problema que ela resolve; os dois últimos, de colocar o código do lado errado de uma seta.
1. Copiar golang-standards/project-layout num projeto pequeno
O próprio repositório desaconselha isso.
O README diz que, para quem está aprendendo Go ou fazendo uma prova de conceito ou um projeto simples, essa estrutura «is an overkill» [2]. E recomenda começar com um main.go e um go.mod [2]. O repositório tem 19 pastas na raiz [3]. Copiar todas é herdar dezenove perguntas sem resposta, como aconteceu com o Iván.
2. Criar pkg/ por costume
O guia oficial não o menciona, e Russ Cox apontou que a grande maioria do ecossistema não o usa.
Na issue #117 desse repositório, em 9 de abril de 2021, Russ Cox escreveu que «the vast majority of packages in the Go ecosystem do not put the importable packages in a pkg subdirectory» [4]. O guia oficial não usa pkg/ em nenhum exemplo [1]. E um servidor normalmente não tem nada para exportar, então a lógica dele vai em internal/ [1].
3. Pacotes util, common ou misc
Um nome que não diz o que há dentro vira uma gaveta onde cai de tudo.
O blog do Go explica em Package names: «Packages named util, common, or misc provide clients with no sense of what the package contains» [9]. Com o tempo, acumulam dependências e deixam a compilação mais lenta [9]. O Go Code Review Comments acrescenta api, types e interfaces [10]. A saída: dividir a gaveta e nomear cada parte pelo que ela faz (fecha, notificar).
4. Declarar a interface onde ela é implementada, «para os mocks»
A interface fica do lado de quem a usa; do lado que implementa, devolve-se um tipo concreto.
O Go Code Review Comments diz isso sem rodeios: «Do not define interfaces on the implementor side of an API “for mocking”» [10]. E pede não declará-la antes de usá-la: sem um uso real, não se sabe de quais métodos ela precisa [10]. No template, revisar declara Consultor porque a usa, e o dublê mora num _test.go.
5. Dividir por camadas até fechar um ciclo
Se models precisa de algo de services e services importa models, o programa deixa de compilar.
Acontece com as pastas por camada (handlers/, services/, models/): cedo ou tarde, a de baixo precisa de algo da de cima. A especificação proíbe isso [11], e go build diz assim (medido):
package ejemplo.com/capas/models
imports ejemplo.com/capas/services from models.go
imports ejemplo.com/capas/models from services.go: import cycle not allowedO extremo oposto também não ajuda: Andrew Gerrand advertia em 2012 que dividir em pacotes pequenos demais faz a pessoa empacar desenhando interfaces em vez de terminar o trabalho [16]. A saída do template: um pacote de domínio que não importa ninguém, e as setas apontando para ele.
| Erro | O que o denuncia | Fonte |
|---|---|---|
| 1. Copiar o layout completo | Pastas vazias ou com um só arquivo | [2] |
2. pkg/ por costume | Um servidor com pkg/ que ninguém importa | [1][4] |
3. util, common, misc | Funções que não têm nada a ver umas com as outras | [9][10] |
| 4. Interface do lado que implementa | Uma interface com uma só implementação e um Mock ao lado | [10] |
| 5. Camadas que se importam entre si | import cycle not allowed | [11] |
Exercício: dá para deixar a fronteira vermelha?
A ideia é quebrar a fronteira de propósito, e a ferramenta vai dizer, sozinha, se deu certo.
Requisitos: Go 1.27 ou mais novo (go version), Git e bash, uns 20 minutos. Se o sistema traz um Go mais antigo, como os repositórios do Linux Mint, instale-o a partir de go.dev [22]. Linux e macOS já trazem bash; no Windows, use WSL ou Git Bash.
Passo 1. Clone e confirme que está tudo verde.
git clone https://github.com/HabilMX/estructura-go
cd estructura-go
go test ./...
bash herramientas/probar-frontera.shO que deve aparecer: cinco linhas que começam com ok e, no final, ✅ frontera: se sostiene.
Passo 2. Preveja antes de mexer. Anote o que acontece ao renomear internal/ para interno/ e corrigir os imports. Compila? O que o script diz?
Passo 3. Renomeie e corrija os imports.
Copie só a linha de sed do sistema em uso: o do macOS pede um argumento vazio depois de -i.
mv internal interno
# En Linux:
grep -rl 'estructura-go/internal/' --include='*.go' . | xargs sed -i 's#estructura-go/internal/#estructura-go/interno/#'
# En macOS:
grep -rl 'estructura-go/internal/' --include='*.go' . | xargs sed -i '' 's#estructura-go/internal/#estructura-go/interno/#'
go build ./...Se go build não disser nada, compilou: o programa não precisa de internal/ para funcionar.
Passo 4. Rode o script.
bash herramientas/probar-frontera.shDeve sair vermelho, mas repare em qual:
❌ el control NO compiló; el experimento está mal montado:O script continua procurando internal/servicio, que já não existe, e se recusou a dar um verde. É o controle trabalhando.
Passo 5. Aponte o script para o pacote novo. Abra herramientas/probar-frontera.sh, procure a linha que começa com paquete= e troque internal por interno. Rode o script de novo:
❌ COMPILÓ: otro módulo pudo importar github.com/HabilMX/estructura-go/interno/servicio. La frontera no existe.Agora sim: um módulo alheio importou o código e ninguém o impediu. Com outro nome, a pasta é só uma pasta.
Passo 6. Desfaça tudo.
git checkout -- . && git clean -fd
bash herramientas/probar-frontera.shAtenção: git clean -fd também apaga os arquivos novos criados ali, como anotações.
Como saber que deu certo: apareceram três desfechos diferentes em quatro execuções, nesta ordem: verde no passo 1, vermelho «el control NO compiló» no 4, vermelho «COMPILÓ» no 5, e verde de novo no 6. Se no passo 5 se repetir «el control NO compiló», a linha paquete= não ficou com interno (ou o arquivo não foi salvo). Se sair verde, internal/ ainda existe: revise o passo 3.
Para ir além (opcional): acrescente a servicio uma função que use algo de revisar. Antes de compilar, preveja a mensagem. Depois compare com a do erro 5.
Para levar
Três perguntas para fazer ao repositório nesta semana.
- De cada pasta da raiz: que problema ela resolve hoje? Se a resposta for «para o caso de um dia», apague-a e anote isso no README.
- Se outra equipe importasse o código amanhã, que pacotes ela poderia usar? Todo o resto está em
internal/? - Qual é o pacote de que todos dependem? Ele importa algo do projeto? Se importa, ali está o próximo ciclo.
O que vem depois?
No Go, quem vigia a fronteira é a ferramenta. No Python, quem vigia é a instalação, e é fácil não perceber até que estoure.
Três dias depois, Iván já movia pastas sem medo. Então caiu com ele um projeto de Python. Os testes, verdes. A colega dele instalou o pacote: ModuleNotFoundError.
O arquivo existia. Estava na pasta. Os testes o encontravam. Mas nunca tinha entrado no pacote.
Como um teste passa sobre um código que não existe para quem o instala? Na entrega 2: uma pasta chamada src/, e por que ela muda tudo.
O template e o curso
- Template: github.com/HabilMX/estructura-go. Pode ser usado como template do GitHub ou clonado [19]. O README explica cada pasta, o que não traz, quando acrescentar cada coisa e como tirar o exemplo. O código é MIT; o texto e as explicações são CC BY-SA 4.0.
- Versões:
go.modpede Go 1.27, a versão lançada em agosto de 2026 [15]. Foi testado com Go 1.27.3, a estável mais recente em 22 de outubro [14], e só usa a biblioteca padrão. O CI pega a versão dogo.mode busca o patch mais recente da 1.27 [18]. - Curso de Go da Hábil: se
internal/, os pacotes ou os testes de tabela são novidade, a lição 5 explica tudo do zero: Curso de Go · Lição 5, Módulos e testes.
Escrevo a partir do que vemos todos os dias na Hábil, onde construímos sistemas para bancos, seguradoras e empresas no México. Se no trabalho ou na faculdade aparecer um repositório em que ninguém sabe onde mexer, vamos conversar: habil.mx
O que a Hábil faz?
Ensinamos a programar com o mesmo que usamos para construir: código testado, explicado e aberto.
Esta série nasce do mesmo lugar que os nossos cursos. O Curso de Go vai do zero até escrever um bom programa, e o publicamos aberto, com licença Creative Commons; a lição 5 explica os módulos, os pacotes e os testes que o template deste artigo usa. E no catálogo há mais cursos de programação, gratuitos e com código testado e explicado passo a passo.
Veja o Curso de Go e o catálogo de Cursos de programação.
Se a equipe herdar um sistema em que ninguém sabe onde mexer, ou precisar construir um que possa continuar sendo mantido, também fazemos isso: veja Construir um sistema sob medida. Peça a primeira conversa, sem custo. Nela avaliamos se convém configurar o que a equipe já tem, usar um produto ou construir, e o que ela receberia em cada caso. Escreva para nós pelo WhatsApp.
Fontes consultadas em 22 de outubro de 2026. As citações em inglês são reproduzidas tal como estão, sem os itálicos nem os negritos do original.
Referências
- Go Team, «Organizing a Go module», go.dev. https://go.dev/doc/modules/layout
- golang-standards, «Standard Go Project Layout» (README), GitHub. https://github.com/golang-standards/project-layout
- GitHub, dados do repositório
golang-standards/project-layout(56.702 estrelas; 19 pastas na raiz; primeiro lugar por estrelas na busca «go project layout», 812 resultados, o seguinte com 954), medidos em 22 de outubro de 2026. https://api.github.com/repos/golang-standards/project-layout - Russ Cox, «this is not a standard Go project layout», issue #117, 9 de abril de 2021. https://github.com/golang-standards/project-layout/issues/117
- Russ Cox, comentário na issue #117, 28 de abril de 2021. https://github.com/golang-standards/project-layout/issues/117#issuecomment-828503689
- Go Team, «Command go»: «Internal packages» e «Test packages», pkg.go.dev. https://pkg.go.dev/cmd/go
- Go Team, «Go 1.4 Release Notes»: «Internal packages», go.dev. https://go.dev/doc/go1.4
- Go Team, «Go 1.5 Release Notes», go.dev. https://go.dev/doc/go1.5
- Sameer Ajmani, «Package names», The Go Blog, 4 de fevereiro de 2015. https://go.dev/blog/package-names
- Go Team, «Go Code Review Comments»: «Interfaces» e «Package Names», go.dev. https://go.dev/wiki/CodeReviewComments
- Go Team, «The Go Programming Language Specification»: «Import declarations» (versão go1.27, 26 de maio de 2026). https://go.dev/ref/spec#Import_declarations
- Jonathan Amsterdam, «Routing Enhancements for Go 1.22», The Go Blog, 13 de fevereiro de 2024. https://go.dev/blog/routing-enhancements
- M. Nottingham, E. Wilde e S. Dalal, «RFC 9457: Problem Details for HTTP APIs», IETF, julho de 2023. https://www.rfc-editor.org/rfc/rfc9457
- Go Team, downloads do Go (estável vigente: go1.27.3). https://go.dev/dl/
- Go Team, «Go 1.27 Release Notes», go.dev. https://go.dev/doc/go1.27
- Andrew Gerrand, «Organizing Go code», The Go Blog, 16 de agosto de 2012. https://go.dev/blog/organizing-go-code
- Go Team, «Effective Go»: «Package names», go.dev. https://go.dev/doc/effective_go#package-names
- GitHub, «actions/setup-go» v5, README. https://github.com/actions/setup-go/blob/v5/README.md
- GitHub Docs, «Creating a template repository». https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository
- Go Team, «Go Modules Reference»: «Vendoring», go.dev. https://go.dev/ref/mod#vendoring
- GitHub Docs, «Disabling and enabling a workflow». https://docs.github.com/en/actions/how-tos/manage-workflow-runs/disable-and-enable-workflows
- Go Team, «Download and install», go.dev. https://go.dev/doc/install
A operação da empresa enfrenta esses desafios?
Prefere e-mail? Escreva para hola@habil.mx