Tópicos:

  1. Contexto do Problema
  2. Objetivo do Experimento
  3. Ferramentas, Tecnologias e Premissas
  4. Procedimento / Metodologia
  5. Resultados Observados
  6. Aprendizados e Implicações
  7. 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
  • 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

manual post 1

  • 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 /Public para 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

manual post 2

  • Abrir o repositório de destino na ferramenta de desenvolvimento.
  • Copiar os arquivos da pasta /Public para 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?

    • Criar um Personal Access Token (PAT) (3.1.1)
    • Registrar o token como secret no repositório base (3.1.2)
    • Criar workflow no repositório base para copiar os arquivos (3.1.3)

⭐ 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 pat1
  • Na tela de configurações vá até Developer settings pat2
  • Na tela de Developer settings vá até Personal access tokens e então acesse: Fine-Grained tokens pat3
  • Clique no botão que foi exibido: Generate new token pat4
  • 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) pat5
  • finalize a criação do PAT e copie-o para se editor de texto pois ele será usado mais tarde. pat6

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. token1
  • No menu que será exibido, vá até Secrets and variables e clique em Actions. token2
  • Na aba Secrets que aparecerá deverá clicar em New repository secret. token3
  • Dê um nome para a Secret e cole o PAT copiado na etapa anterior no campo secret e clique em Add secret. token4
  • A secret irá aparecer na lista de secrets disponíveis neste repositório para que possa ser utilizada no workflow. token5

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: workflow_diagram

↘️ 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 main daquele 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 brach main
  • 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 main o 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 .gitignore que estava configurado para não manter a pasta public/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

EstadoDescriçãoPassos de BuildPassos de PublicaçãoTempo de BuildTempo de Publicação
ACriação + build manuais e Publicação manual210~5–10 segundos~4:45–5 minutos
BCriação + build manuais e Publicação automática20~5–10 segundos~35–40 segundos
CCriação + build automáticos e Publicação automática0000

↘️ Estado B alcançado:

auto_post1

↘️ 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