Este repositório descreve um roteiro prático para configuração e uso de um Servidor de Integração Contínua. O objetivo é proporcionar ao aluno um primeiro contato real com essa prática de desenvolvimento de software.
Se você ainda não sabe o que é Integração Contínua e também não entende o papel desempenhado por servidores de CI, recomendamos antes ler o Capítulo 10 do nosso livro texto (Engenharia de Software Moderna).
Apesar de existirem diversos servidores de integração contínua, neste roteiro iremos usar um recurso nativo do GitHub, chamado GitHub Actions, para configurar um servidor de CI.
O Github Actions permite executar programas externos assim que determinados eventos forem detectados em um repositório GitHub. Como nosso intuito é configurar um servidor CI, iremos usar o GitHub Actions para compilar todo o código (build) do projeto e rodar seus testes de unidade quando um Pull Request (PR) for aberto no repositório, conforme ilustrado a seguir.
Para ilustrar o uso do servidor de CI, vamos usar um programa Java muito simples, que já foi criado e está disponível neste mesmo repositório (Calculadora.java):
public class Calculadora {
public int soma(int x, int y) {
return x + y;
}
public int subtrai(int x, int y) {
return x - y;
}
}
Quando chegar um PR no repositório, o servidor de CI vai automaticamente realizar um build desse programa e rodar o seguinte teste de unidade (também já disponível no repositório, veja em CalculadoraTest.java):
public class CalculadoraTest {
@Test
public void testeSoma1() {
Calculadora calc = new Calculadora();
int resultadoEsperado = 5;
int resultadoRetornado = calc.soma(2,3);
assertEquals(resultadoEsperado, resultadoRetornado);
}
@Test
public void testeSoma2() {
Calculadora calc = new Calculadora();
assertEquals(10, calc.soma(4,6));
}
}
Antes de mais nada realize um fork deste repositório. Para isso, basta clicar no botão Fork no canto superior direito desta página.
Ou seja, você irá configurar um servidor de CI na sua própria cópia do repositório.
Clone o repositório para sua máquina local, usando o seguinte comando (onde <USER>
deve ser substituído pelo seu usuário no GitHub):
git clone https://github.com/<USER>/demo-ci.git
Em seguida, copie o código a seguir para um arquivo com o seguinte nome: .github/workflows/actions.yaml
. Isto é, crie diretórios .github
e depois workflows
e salve o código abaixo no arquivo actions.yaml
.
name: Github CI
on:
# Configura servidor de CI para executar o pipeline de tarefas abaixo (jobs) quando
# um push ou pull request for realizado tendo como alvo a branch main
push:
branches:
- main
pull_request:
branches:
- main
jobs:
pipeline:
runs-on: ubuntu-latest # Os comandos serão executados em um sistema operacional Linux
steps:
- name: Git Checkout
uses: actions/checkout@v2 # Faz o checkout do código recebido
- name: Set up JDK 1.8
uses: actions/setup-java@v1 # Configura o Java 1.8
with:
java-version: 1.8
- name: Build
run: mvn package -Dmaven.test.skip=true # Compila o código fonte
- name: Unit Test
run: mvn test # Executada os testes de unidade
Esse arquivo ativa e configura o GitHub Actions para -- toda vez que ocorrer um evento push
ou pull_request
tendo como alvo a branch principal do repositório -- realizar três tarefas (jobs):
- realizar o checkout do código;
- realizar um build;
- rodar os testes de unidade.
Realize um commit
e um git push
, isto é:
git add --all
git commit -m "Configurando GitHub Actions"
git push origin main
Quando o push
chegar no repositório principal, o GitHub Actions iniciará automaticamente o fluxo de tarefas configurado no arquivo actions.yaml
(isto é, build + testes).
Você pode acompanhar o status dessa execução clicando na aba Actions do seu repositório.
Para finalizar, vamos introduzir um pequeno bug no programa de exemplo e enviar um PR, para mostrar que ele será "barrado" pelo processo de integração (isto, o nosso teste vai "detectar" o bug e falhar).
Introduza um pequeno bug na função soma
do arquivo src/main/java/br/ufmg/dcc/Calculadora.java. Por exemplo, basta alterar a linha 6, alterando o retorno da função para x + y + 1
, como apresentado abaixo.
--- a/src/main/java/br/ufmg/dcc/Calculadora.java
+++ b/src/main/java/br/ufmg/dcc/Calculadora.java
@@ -3,7 +3,7 @@ package br.ufmg.dcc;
public class Calculadora {
public int soma(int x, int y) {
- return x + y;
+ return x + y + 1;
}
public int subtrai(int x, int y) {
Após modificar o código, você deve criar um novo branch, realizar um commit
e push
:
git checkout -b bug
git add --all
git commit -m "Incluindo alterações na função soma"
git push origin bug
Em seguida, crie um Pull Request (PR) com sua modificação. Para isso, basta acessar a seguinte URL em seu navegador: https://github.com/<USER>/demo-ci/compare/main...bug
, onde <USER>
deve ser substituido pelo seu usuário no GitHub. Nessa janela, você pode conferir as modificações feitas e incluir uma pequena descrição no PR.
Após finalizar a criação do Pull Request, será iniciada nossa pipeline, ou seja, o próprio GitHub vai fazer o build do sistema e rodar seus testes (como na tarefa #1). Porém, dessa vez os testes não vão passar, como mostrado abaixo:
RESUMINDO: O Servidor de CI conseguiu alertar, de forma automática, tanto o autor do PR como o integrador de que existe um problema no código submetido, o que impede que ele seja integrado no branch principal do repositório.
Este roteiro foi elaborado por Rodrigo Brito, aluno de mestrado do DCC/UFMG, como parte das suas atividades na disciplina Estágio em Docência, cursada em 2020/2, sob orientação do Prof. Marco Tulio Valente.