Configurando pipeline com github actions para um projeto React
Fazia tempo que não configurava um serviço de ci/cd e esses dias fui fazer isso no github usando o github actions e percebi ser bem simples, e podemos fazer várias rotinas, é bem legal, mesmo se você estiver trabalhando sozinho, pois consegue que todo commit seja verificado para saber se não quebrou nada.
Vou mostrar uma configuração simples e você pode adaptar para o que você vai precisar no seu dia-a-dia
Primeiro passo, dentro da raiz do seu projeto, crie uma pasta .github
dentro dessa pasta crie outra pasta chamada workflows
e dentro crie o seu arquivo para rodar sempre que um commit entrar na sua branch main ou sempre que abrir Pull Request. Vou chamar o arquivo de build.yaml
para o exemplo:
name: Build and Deploy
on:
push:
branches: 'main'
pull_request:
branches: 'main'
jobs:
tests:
name: Run Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Use Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 20.x
cache: 'yarn'
- name: Install Dependencies
run: yarn install
- name: Run Tests
run: yarn test
deploy:
name: Build and Deploy
needs: [tests]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Use Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 20.x
cache: 'yarn'
- name: Install Dependencies
run: yarn install
- name: Run Build
run: yarn build
Bora para uma simples explicação
1 On nessa propriedade dizemos quando a action deve rodar, no caso, quando acontecer um commit ou um PR para a branch main.
2 Jobs nessa rotina dizemos quais scripts que queremos que nosso action execute no meu caso só tem dois o de tests e deploy o primeiro argumento é nome da tarefa no meu caso são Run Tests e Build and Deploy, depois temos runs-on que vai ser o ambiente que vamos querer que o nossa pipe rode, ou seja, vamos querer uma máquina virtual ubuntu na última versão, antes de entrar nos steps nosso job de build tem uma instrução chamada needs passando o argumento [tests], ou seja, para o nosso deploy rodar, precisa rodar os testes antes sem que nada quebre.
3 Steps temos algumas rotinas aqui dentro, no primeiro name e uses as actions fazem checkout do seu código e “pedem autorização” para seguir com as próximas rotinas:
- name: Checkout code
uses: actions/checkout@v3
Depois podemos declarar qual versão do node ele vai usar para rodar os scripts do nosso projeto:
- name: Use Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 20.x
cache: 'yarn'
Normalmente você vai ver essa propriedade cache com npm, mas eu preferi usar o yarn, pois estava usando ele localmente também.
Por último pedimos para de fato ele rodar o script de instalação e logo em seguida o de testes:
- name: Install Dependencies
run: yarn install
- name: Run Tests
run: yarn test
O de build é o mesmo, porém só muda de yarn test para yarn build.
Bem é isso, é algo bem simples de se construir, é legal implementar em ambientes diferentes e fazer vários testes. Espero que tenham gostado e qualquer feedback será muito bem-vindo, muito obrigado.
Cuidado com os custos escondidos
Se você verificar nesta página os custos do github actions é cobrado por MINUTO
Ok, mas o que acontece se a action demorar 5 segundos para executar? Vai ser cobrado um minuto inteiro
Lendo o seu workflow vemos que tem diversos passos que se repetem entre os jobs:
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Use Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 20.x
cache: 'yarn'
- name: Install Dependencies
run: yarn install
essas ações vão consumir tempo desnecessário!
Otimizando essa action
Porquê não fazer em um único job o teste e o deploy?
name: Build and Deploy
on:
push:
branches: 'main'
pull_request:
branches: 'main'
jobs:
tests:
name: Run Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Use Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 20.x
cache: 'yarn'
- name: Install Dependencies
run: yarn install
- name: Run Tests
run: yarn test
- name: Run Build
run: yarn build
Isso irá diminuir MUITO o tempo para rodar o flow, se ocorrer em uma organização grande pode ter certeza que fará diferença no orçamento mensal
Erro 1: O que está sendo feito com o build?
No último passo é executado o build:
- name: Run Build
run: yarn build
mas cadê o commit?
Esse build simplesmente será descartado assim que a action terminar de executar.
Erro 2: O mesmo fluxo ocorrendo em 2 momentos diferentes
Ok, não chega a ser um erro, mais uma sugestão pessoal
on:
push:
branches: 'main'
pull_request:
branches: 'main'
Porque o mesmo fluxo ocorre nesses 2 momentos? se o teste passou no Pull request não precisa testar novamente na main! Assim como buildar no pull request pode remover uma build de uma main mais atualizada.
Vou tentar exclarecer melhor:
Main Branch A Branch B
|
|-------------+----------------+
| | |
| | Commit 1 |
| | |
| <-----------+ PR 1 |
| | Commit 2
| |
| <----------------------------+ PR 2
|
No momento que é solicitado o PR 2
vai gerar uma nova build. Se esse PR for aceito vai acontecer uma das situações:
- A build do
PR 2
vai apagar totalmente oPR 1
por um momento - Vai dar conflito de merge
- Vai ficar inconsistente com arquivos de cada build misturados
Solução que utilizo
Deploy apenas quando foi aprovado o PR
# DEPLOY
on:
push:
branches: 'main'
Testes apenas no pull request
# TESTES
on:
pull_request:
branches: 'main'
Muito obrigado por esse artigo, graças a ele eu tive a curiosidade de descobrir o que é pipeline.
Eu sou novo no ramo e fico meio perdido com alguns termos, e ver as pessoas usando me da curiosidade pra saber o que... Valeu mesmo!!