Tópicos:
- Contexto do Problema
- Objetivo do Experimento
- Ferramentas, Tecnologias e Premissas
- Procedimento / Metodologia
- Resultados Observados
- Aprendizados e Implicações
- Próximos Passos / Melhorias
1. Contexto do Problema
Onde tudo começou
Decidi criar um site utilizando um gerador de sites estáticos (Hugo + PaperMod) para agilizar o processo. O foco inicial estava em criar uma visualização melhor para os projetos que estão no meu GitHub, pois a gestão de README de repositórios e sua leitura podem ser cansativas.
Estruturando a ideia
A partir da criação do site, vi que seria viável e de baixo custo de desenvolvimento criar seções de P&D que comportariam repositórios menos expressivos e completos (aqueles que armazenam experimentos), Projetos (para projetos funcionais e que agrupam conhecimento prático em suas funcionalidades) e Insights (para conteúdos que representem resumos, indicações de materiais técnicos interessantes, curiosidades etc.).
E agora? Onde hospedar?
Por fim, veio a pergunta: onde posso hospedar de forma simples e gratuita? Surge então o GitHub Pages e, com ele, dois repositórios: um para o projeto e outro para a publicação do site.
Simples porém melhor: Não perder o foco.
Ao longo do desenvolvimento e dos experimentos, percebi o quão repetitivo e monótono é o processo de deploy utilizando dois repositórios, pois em um é gerado o conteúdo em uma pasta public e esta deve ser publicada no outro repositório, que será o site.
Oportunidade de aprendizado durante o processo de criação
Vejo então a oportunidade: criar uma rotina com o GitHub Actions para realizar o deploy do site.
Resumo
- Criei meu site pessoal usando Hugo + PaperMod.
- Mantenho o código-fonte em um repositório separado.
- Mas o deploy no GitHub Pages acontece em outro repositório (
rafael-o-cunha.github.io). - Toda vez que gera o site com
hugo, preciso:- copiar o
/public - abrir outro repo
- commitar
- enviar
- copiar o
- Repetitivo, suscetível a erro, quebra fluxo e interrompe foco.
- Decidi buscar uma forma de automatizar — iniciando um pequeno P&D.
2. Objetivo do Experimento
Este seria meu primeiro contato de forma prática com o Github Actions pois no dia a dia de desenvolvimento focamos sempre no negócio, nas funcionaliades, enquanto o deploy automatizado foi preparado e está lá apenas sendo utilizado.
Sigo então na missão de entender como funciona este recurso no Github e desenvolver experimentos para aprender e praticar.
O objetivo do primeiro experimento com o Actions:
- Automação total do fluxo de build + deploy.
- Verificar se é possível:
- Build do Hugo automaticamente em cada push
- Fazer deploy para um repositório externo
- Garantir que o GitHub Actions possa realizar commit e push no repo do Pages
- Objetivo intermediário: Realizar build e publicação manual no repositório principal e o Actions apenas copiar a pasta
public/para o repositório do site. - Objetivo final: zerar esforço manual e manter o site sempre atualizado com um push no repo principal do projeto, onde o build e publicação serão automáticos.
- Job to be Done: Eliminar atrito/passos e tempo no processo criativo de conteúdo.
3. Ferramentas, Tecnologias e Premissas
Ferramentas e Tecnologias
- Hugo (hugo:latest)
- Tema PaperMod
- Docker (Hugo é executado em container)
- Makefile (para simplificar comandos)
- GitHub Actions
- Personal Access Token (PAT) com permissões adequadas
- Repositório rafael-hub (desenvolvimento)
- Repositório rafael-o-cunha.github.io (produção)
Premissas do Experimento
- O Hugo será executado dentro de um container Docker.
- Haverá duas Base URLs (dev e prod), e isso deve ser considerado no processo de build.
- O Makefile será usado como interface principal para build e automação local.
- O foco do experimento é automatização, portanto a solução deve manter o fluxo simples para permitir foco em conteúdo.
- Cada experimento no projeto será registrado previamente como uma issue.
- A automação deve usar Action oficial ou workflow customizado para fazer deploy em repositório externo.
4. Procedimento / Metodologia
Abordagem adotada
A Abordagem seguiu um ciclo incremental de experimentação avançando no processo por três etapas macro em formato de perguntas e com isso foi realizado a pesquisa e experimentação de:
- O que é preciso ter no repositório base?
- O que é preciso ter no repositório de destino?
- O que precisa ser feito no GitHub e/ou repositórios para que ambos repositórios que originalmente são independentes tivessem este fluxo de movimentação de arquivos?
Preparação do ambiente
- VS Code
- Git
- Github
- Docker
- Hugo (Gerador de sites estáticos)
- HTML, CSS, Javascript e Markdown
- Makefile
Execução passo a passo
O Fluxo inicial era realizado de forma manual e portanto consistia em:
Etapa 1 - Deploy manual

- Criar o Post com toda estrutura do conteúdo e formatação desejada.
- Realizar Commit para salvar as alterações.
- Realizar o Build do Hugo para gerar a pasta
/Publicpara que o post criado seja convertido em conteúdo publicável. - Realizar push para o repositório remoto(Github - repositório de desenvolvimento)
Etapa 2 - Deploy manual

- Abrir o repositório de destino na ferramenta de desenvolvimento.
- Copiar os arquivos da pasta
/Publicpara o repositório de destino. - Realizar Commit para salvar as alterações.
- Realizar push para o repositório remoto(Github - Pages)
Observa-se que este fluxo de criação não é prático, ainda há um volume considerável de atividades técnicas envolvidas na criação de conteúdo, portanto visando aprimorar a experiência da criação de conteúdo foi realizado a mudança para que o GitHub Actions fosse responvável por realizar o deploy para produção. A mudança proposta deve eliminar o processo de publicação do site.
Etapa 3 - Analisando o processo, suas etapas e melhoria esperada
Com uma visão clara e experimentada do processo de criação e publicação do conteúdo pode-se observar a divisão entre três etapas para mudar o processo levando-o do estado A ao estado B para que na sequência seja viável alcançar o estado C, desta forma alacançando melhoria considerável no processo reduzindo quantidade de passos manuais e tempo.
- A) Criação + build manuais e Publicação manual.
- B) Criação + build manuais e Publicação automática.
- C) Criação + build automáticos e Publicação automática.
Etapa 3.1 - Configurando o Repositório de origem para/com o GitHub Actions:
O que é preciso ter no repositório base?
- Workflow do GitHub Actions configurado
- Um Personal Access Token (PAT) ou GitHub Token Fine-grained
- Um secret configurado no repositório base
- Identificar quais arquivos/pastas serão copiados
O que é preciso ter no repositório de destino?
- Permissão de escrita para o PAT criado
- Um branch destino para receber os arquivos
- (Opcional) Um diretório específico para receber os arquivos
O que precisa ser feito no GitHub e/ou repositórios para que ambos repositórios que originalmente são independentes tivessem este fluxo de movimentação de arquivos?
⭐ Etapa 3.1.1 - Criar um Personal Access Token (PAT):
↘️ Por que criar um Personal Access Token (PAT)?
Porque o GitHub Actions roda dentro do repositório base, e por padrão ele só tem permissão para escrever no próprio repositório, através do token automático GITHUB_TOKEN.
O GITHUB_TOKEN não pode fazer push em outros repositórios.
Ele só funciona dentro do repositório onde o workflow está rodando.
↘️ O que o PAT resolve?
O PAT funciona como uma credencial criada por você, com permissão explícita para escrever no repositório de destino.
Ele permite que o GitHub Actions:
- clone o repositório de destino
- modifique os arquivos
- faça commit
- realize push
- Como se fosse você próprio executando isso localmente.
↘️ Sem o PAT, qualquer tentativa de push resultaria em erro de autenticação:
“Authentication failed – You do not have permission to access this repository.”
Criando Token
- Vá até o GitHub, clique no perfil(canto direito superior), clique em Settings

- Na tela de configurações vá até Developer settings

- Na tela de Developer settings vá até Personal access tokens e então acesse: Fine-Grained tokens

- Clique no botão que foi exibido: Generate new token

- Dê um nome e descrição ao token e siga os passos abaixo:
- Selecione os repositórios que poderão usar o token (Repositório de origem que rodará o GitHub Actions e destino que receberá os arquivos copiados pelo Actions)
- Em Permissões adicione permissão de leitura e escrita para que o token permita o GitHub Actions realize alterações em abos repositórios escolhidos (isso permitirá posteriormente alterar arquivos, e portanto executar build que publica novos arquivos na pasta
/public)
- finalize a criação do PAT e copie-o para se editor de texto pois ele será usado mais tarde.

Resumo:
Settings → Developer settings → Personal access tokens → Fine-grained tokens
⭐ Etapa 3.1.2 - Registrar o token como secret no repositório base:
↘️ Por que registrar o token como secret no repositório base?
Porque o GitHub Actions precisa usar o PAT para acessar o repositório de destino, mas:
Não é seguro colocar o token direto no arquivo YAML
↘️ O que o secret resolve?
- Protege o token criptografado
- Permite que o workflow utilize o token sem expor o valor
- Mantém a segurança mesmo em pipelines públicos
Mesmo que o repositório base seja público, os secrets não são revelados em nenhuma condição.
Registrando o Token
- Navegue até o repositório base e clique em settings.

- No menu que será exibido, vá até Secrets and variables e clique em Actions.

- Na aba Secrets que aparecerá deverá clicar em New repository secret.

- Dê um nome para a Secret e cole o PAT copiado na etapa anterior no campo secret e clique em Add secret.

- A secret irá aparecer na lista de secrets disponíveis neste repositório para que possa ser utilizada no workflow.

Resumo:
Settings → Secrets → Actions → New secret
⭐ Etapa 3.1.3 - Criar workflow no repositório base para copiar os arquivos:
↘️ Qual propósito desta etapa?
O propósito desta etapa é criar um mecanismo automático que executará o todo o fluxo de copiar os arquivos necessários do repositório base para o repositório de destino sempre que for feito push para o branch maindo repositório base.
Em outras palavras:
O Workflow é em si a automação que realiza todo o processo.
↘️ Como é o Workflow deste experimento:

↘️ Como Um Workflow é materializado no GitHub Actions para ser executado?
No início a visão era de que seria necessário programar um script com alguma linguagem de programação ou .sh para realizar todo o processo, onde os comandos seriam executados passo a passo, porém durante a exploração deste recurso ficou claro que poderia ser mais simples e diferente o que torna o experimento mais atrativo pois utiliza-se uma maneira declarativa através de um arquivo .yaml para realizar o processo necessário neste experimento.
↘️ Então o que é um Workflow no GitHub Actions?
- Um workflow é um arquivo de instruções que o GitHub interpreta para automatizar tarefas.
- Ele não é um programa tradicional escrito em Java, Python ou Go.
- Ele é escrito em YAML, um formato de configuração.
Em outras palavras:
Você não programa um robô — você descreve o que quer que o GitHub Actions execute.
O GitHub cuida de:
- criar a máquina virtual
- instalar o ambiente
- executar os passos
- autenticar
- rodar seus comandos
↘️ Então como o workflow realmente executa coisas?
O Arquivo .yaml irá conter passos a serem realizados e nesta etapa pode-se criar comandos bash ou incluir a execução de arquivos de script, porém no caso do experimento que foi realizado foi necessário apenas executar ações prontas.
Ações prontas são como peças de lego já criadas pela comunidade e podem ser executadas diminuindo a necessidade de recriação de passos comuns entre muitos projetos.
Logo foi identificado que basta definir o fluxo de trabalho, por exemplo:
- Quando rodar (on)
- Onde rodar (runs-on)
- O que fazer (steps)
- Com quem fazer (actions)
↘️ Criando Workflow do experimento de deploy automático:
Para que o github actions realize o proceso de cópia foi criado no repositório base a sequência de diretórios com o arquivo do workflow:
.
└── .github
└── workflows
└── deploy.yml
O Arquivo ficou com a seguinte estrutura:
name: Deploy de arquivos estáticos para o GitHub Pages
on:
push:
branches:
- main
jobs:
deploy:
# Especifica o tipo de runner (máquina virtual) onde os steps vão rodar
runs-on: ubuntu-latest
steps:
- name: Checkout source repo
# Utiliza a action oficial checkout para clonar o repositório onde o workflow está sendo executado
uses: actions/checkout@v4
with:
# Realiza cópia raza, ou seja, apenas do último commit.
fetch-depth: 1
- name: Deploy public/ folder to GitHub Pages repo
# Utiliza uma action pronta que facilita publicar conteúdo em um repo de páginas.
uses: peaceiris/actions-gh-pages@v4
with:
# Apenas copia a pasta public - espera-se que build já tenha sido realizado.
publish_dir: ./public
# Repositório de destino (Pages)
external_repository: usuario_github/usuario_github.github.io
# Branch da publicação
publish_branch: main
# Token de deploy
personal_token: ${{ secrets.SECRET_TOKEN_LOREN_IPSUM }}
# Limpar repo antes de copiar
keep_files: false
Entendendo os passos realizados nas instruções do .yaml:
- É disparado a cada push na branch
main. - Clona o repositório atual.
- Usa a pasta
public/como conteúdo para publicar. - Conecta-se ao repositório usuario_github.github.io usando um token secreto.
- Apaga todo o conteúdo anterior do repositório Pages.
- Publica o novo conteúdo na branch
maindaquele repositório.
Resultado:
Seu site do GitHub Pages é atualizado automaticamente sempre que você der push no repositório base(branch main).
Validação e testes
↘️ Nesta etapa o objetivo foi confirmar se o workflow realmente:
- Executa no momento correto.
- Copia a pasta
public/para o repositório de pages. - Criar commit automaticamente no repositório de destino.
- Atualiza corretamente o conteúdo publicado no GitHub Pages.
- Mantém previsibilidade eliminando a necessidade de deploy manual.
📝 O primeiro passo foi garantir que o workflow disparasse corretamente para isso foi realizado o procedimento:
- Realizei um commit simples no repositório base contendo apenas uma alteração textual.
- Realizei
pushpara o repositório base (Remoto) na brachmain - Observei no menu “Actions” o Workflow sendo iniciado.
📊 Critérios de validação:
- O workflow apareceu na lista
- O status evoluiu para “in progress” e “sucess”
- Nenhum passo foi pulado.
Este teste validou que o gatilho estava configurado corretamente.
📝 Com o workflow disparado corretamente, a próxima verificação foi confirmar se cada etapa interna estava funcionando como esperado
- Os logs do GItHub Actions foram utilizados como fonte de dados para validação.
- Foi observado que o Checkout ocorreu com sucesso
- A opção de cópia raza fucionou corretamente.
- Verifiquei se a pasta
public/existia no workspace ⚠️ - Isso confirma que o build manual realizado no experimento ocorreu corretamente.
- Deploy com Action reconheceu o repositório externo.
- Autenticação com o token funcionou corretamente.
- O repositório de destino foi clonado corretamente.
- Todos os arquivos antigos foram removidos.
- Os arquivos da pasta
public/forma copiados. - Foi realizado um commit automático.
📊 Critérios de validação:
- Todos os steps apareceram com marcação verde
Este teste validou que o fluxo estava funcionando corretamente
📝 Testes de validação no repositório de destino
Após o workflow executar, o próximo passo foi validar o repositório que recebe o deploy.
- Um commit novo foi criado automaticamente.
- O conteúdo da branch main do Pages foi substituído pelo conteúdo da pasta
public/. - A árvore de diretórios estava consistente com o que havia sido gerado localmente.
📊 Critérios de validação:
- A árvore de diretórios estava consistente com o que havia sido gerado localmente.
Este teste validou que o personal token, permissões e secrets estavam configurados corretamente.
📝 Teste de validação no site publicado
Com tudo atualizado no repositório de Pages, a última validação foi diretamente no site.
- A URL do github pages foi acessada.
- Foi realizada limpeza de cache (CTRL + F5).
📊 Critérios de validação:
- Novo post publicado.
- Links funcionando.
- Assets (CSS/JS) carregando corretamente.
- Imagens e ícones renderizando.
- Ausência de erros no console do navegador.
O site refletiu exatamente o conteúdo da pasta public/, confirmando que o deploy foi concluído com sucesso.
Problemas encontrados e ajustes feitos
⚠️ Foi identificado um problema quando estava elevando o processo do estado A para o estado B (quando o build é manual e o deploy é automático)
- Durante o processo de push para a branch
maino GitHub Actions foi executado, porém ao realizar o deploy o site ficava em branco, e ao inspecionar o site foi observado que não haviam arquivos publicados. - O github actions está preparado para copiar a pasta public corretamente, o problema é que ele não identificava uma pasta public com conteúdo e portanto apenas limpava o repositório de destino.
- Analisando profundamente foi identificado que o problema não estava no deploy automático mas no
.gitignoreque estava configurado para não manter a pastapublic/no repositório remoto e portanto a mesma permanecia vazia. - O Problema foi solucionado permitidindo o versionamento da pasta para que fosse enviada para o repositório remoto.
O problema mencionado anteriormente foi solucionado e fez o processo de experimentação ser executado elevando o processo do estado A para o estado B, e para o estado C será necessário realizar os passos abaixo:
- Ignorar a pasta
public/ - A URL correta de produção deve estar visível para o embiente de build criado pelo GitHub Actions.
- O GitHub Actions deverá realizar os comandos de build do Hugo para gerar a pasta public considerando a URL correta de produção.
5. Resultados Observados
| Estado | Descrição | Passos de Build | Passos de Publicação | Tempo de Build | Tempo de Publicação |
|---|---|---|---|---|---|
| A | Criação + build manuais e Publicação manual | 2 | 10 | ~5–10 segundos | ~4:45–5 minutos |
| B | Criação + build manuais e Publicação automática | 2 | 0 | ~5–10 segundos | ~35–40 segundos |
| C | Criação + build automáticos e Publicação automática | 0 | 0 | 0 | 0 |
↘️ Estado B alcançado:

↘️ Observações:
📊 Foi observado uma melhora considerável na experiência de criação de conteúdo e sua publicação considerando que:
- O número de passos caiu em 83%.
- O tempo de publicação foi reduzido em ~86,7% e ~87,7%
📊 A chance de erros humanos acontecerem no processo caiu drásticamente pois:
- No estado A haviam cerca de 12 passos que poderiam ocorrer erro humano.
- No estado B não há mais passos a serem realizados para publicação.
6. Aprendizados e Implicações
💡 Aprendizados:
- Automação é mais sobre remover atrito do que sobre tecnologia.
- Pequenas automações geram impactos desproporcionais.
- Redução de variabilidade e riscos.
- Entender como a ferramenta de automação trabalha é mais importante do que o pipeline em si.
- Controle de segurança e permissões é essencial.
- A automação devolve a proposta de valor de “criar o conteúdo” ao elimintar passos que não contribuem diretamente para o objetivo final (Job to be done).
💡 Implicações
- A capacidade de produzir conteúdo aumenta.
- A automação pode se tornar replicável para outros projetos.
- Desenvolvimento de consciência sobre “fluxos de desenvolvimento”.
- A automação libera energia cognitiva.
- Base para criar expandir para CI/CD Completo.
🧠
O experimento não só automatizou o processo mas trouxe consigo um fator exponencial que é a replicação através do conhecimento obtido de forma que deste ponto em diante todo e qualquer projeto que eu desenvolva possa aplicar de maneira cada vez mais natural a automação e portanto aumentar a velocidade de criação de projetos, focando na proposta de valor.
Os testes, validações e métricas mostraram que antes o que parecia ter uma complexidade elevada para automatizar mostrou-se simples ao implementar um arquivo com as regras necessárias apenas, o que traz uma nova forma de ver o processo de desenvolvimento e entrega de valor por meio da tecnologia.
7. Próximos Passos / Melhorias
Para os próximos passos serão implementados conjuntos de regras no arquivo do workflow para viabilizar o terceiro estado(C) do procesos de criação de conteúdo.
- Criar conjunto de regras e configurações para build pelo GitHub Actions.
- Evitar novamente que a pasta
public/seja versionada e trafegada em rede. - Reduzir a quantidade de passos do processo de build para zero!
- Haverá apenas o processo de criação de conteúdo local que poderá ser aprimorado posteriormente com uso de novas ferramentas ou melhoria das ferramentas locais atuais.
#written_by_human
