Ir para o conteúdo principal

GitLab CI/CD

Introdução

O GitLab CI/CD é uma ferramenta integrada ao GitLab onde é possível descrever todos os passos de integração e implantação contínua em um arquivo dentro do repositório. Na SETIC é utilizado para automatizar os processos de integração, inspeção de código e publicação no OpenShift.

Orientações

Pré-requisitos

Docker

A esteira de automação da SETIC, que utiliza o Gitlab CI/CD, é baseada na adoção de Containers, com isso, dentre as opções disponíveis no mercado, foi escolhido a ferramenta Docker.

Todo projeto deverá possuir um arquivo "Dockerfile" ou "Containerfile" funcional.

Certificados

Alguns certificados são necessários para que o projeto possa ser publicado no OpenShift.

Abaixo segue o exemplo, baseado em uma imagem Linux (Alpine, Debian, Ubuntu e distribuições derivadas)

RUN curl -fsSL https://gitlab.setic.ro.gov.br/publico/ca-trust/-/raw/master/openshift_ca.crt -o /usr/local/share/ca-certificates/openshift_ca.crt
RUN curl -fsSL https://gitlab.setic.ro.gov.br/publico/ca-trust/-/raw/master/portainer_ca.crt -o /usr/local/share/ca-certificates/portainer_ca.crt
RUN update-ca-certificates

Abaixo segue o exemplo, baseado em uma imagem Windows

Em andamento...

Estrutura de branches padrão

Para utilizar a esteira de automação da SETIC, as seguintes branches devem ser utilizadas:

  • development - A branch development é a branch onde o time de desenvolvimento mantêm as novas features desenvolvidas.
  • staging - A branch staging representa o ambiente de treinamento/review do produto.
  • production - A branch production deve ser tratada como the single source of truth, ou seja, ela representa exatamento o que está em produção.

O objetivo das branches não necessariamente precisa ser igual ao sugerido, entretanto, é necessário que essa estrutura exista.

É obrigatório que as branches citadas sejam protegidas, aceitando apenas merge requests para alteração. A imagem abaixo ilustra o que deve ser configurado para atender a obrigatoriedade.

image-1652802149709.png
Fig. 1


 

Estrutura de branches padrão
Nossos ambientes GIT possuem 3 branches com nomes fixados: production, staging e development.
Branchs fixadas são protegidas, aceitando apenas merge requests para alteração.

HotFix
Correções urgentes podem ser mescladas a branchs principais, como staging e production, mas devem seguir algumas regras para isso:
✔ Branchs hotfix devem iniciar com o prefixo 'hotfix-', seguindo esse padrão de nomenclatura, podemos controlar melhor nossa estrutura de esteira, permitindo que o passo do SonarQube seja executado no momento do Merge Request.
❌ Branchs que não seguem esse padrão, automaticamente serão recusadas pela esteira.

O que não fazer
❌ Desenvolver direto em development. Vai estar bloqueado mesmo!
❌ Subir código quebrado para as branchs padrão. Lembre-se que outros utilizarão!
❌ Alterar a nomenclatura das branchs padrão!
❌ Alterar a configuração de branchs do GIT para permitir PUSH direto!
❌ Aceitar o próprio merge requests. Eu sei que é difícil, mas vamos deixar os outros darem uma olhada no nosso código!

O que dá pra fazer, mas não é o ideal
⚠ Enviar alterações por merge requests direto para production. Que tal testar primeiro? (Não esqueça que essas alterações devem ir para development e staging depois!)
⚠ Fazer REVERT na branch padrão. Já deu muita dor de cabeça!

Instalação

Crie um arquivo "gitlab-ci.yml" na raiz do projeto, com a estrutura básica abaixo.

include:
  - project: ci-cd/templates
    ref: production
    file:
      - deploy.openshift.yml
      - variables.yml

stages:
  - deploy

variables:
  PROJECT_NAME: "nomedoprojeto"
  PROJECT_DISPLAY_NAME: "Nome do Projeto"

  DOCKERFILE_PATH: "Dockerfile"
  DOCKERFILE_CONTEXT: "/"

  ROUTER_PORT: "8080"
  ROUTER_PATH: "/"
  ROUTER_TERMINATION: "reencrypt"

  CERTIFICATE_SECRET_NAME: "openshift-tls"
  CERTIFICATE_MOUNT_PATH: "/var/run/secrets/service-cert"

  ROUTER_HOSTNAME_DEVELOPMENT: ""

  ROUTER_HOSTNAME_STAGING: >
    "rotaexternaqa.exemplo.com"

  ROUTER_HOSTNAME_PRODUCTION: >
    "rotaexternaproducao.exemplo.com"

  DEPLOY_ENVIRONMENT: >
    "TZ=America/Porto_Velho"

Trecho Include

Este trecho referencia os arquivos de configuração da esteira de automação. Por padrão é incluído o arquivo de configuração de deploy junto com arquivo de variáveis necessárias para o funcionamento da esteira.

Trecho Stages

Este trecho especifica quais estágios do arquivo serão utilizados no processo de execução da esteira.

Trecho Variables

Este trecho é responsável por incluir variáveis pertinentes ao projeto para a execução da esteira, sendo customizável para cada projeto.

PROJECT_NAME

Essa variável configura  o nome do projeto que será criado no OpenShift, também será utilizada internamente por operações do OpenShift, como por exemplo, para criação de rotas internas.

O valor da variável deve possuir apenas letras minúsculas, sem acento ou espaço.

 PROJECT_DISPLAY_NAME

 Essa variável será o nome "amigável" do projeto no OpenShift.

É permitido qualquer valor alfanumérico, incluindo espaço, símbolos e acentos.


DOCKERFILE_PATH

Variável que indica onde está localizado o arquivo Dockerfile do projeto.

É suportado arquivo "Dockerfile", "Containerfile" ou qualquer outro arquivo que seja suportado pela Docker Engine.

DOCKERFILE_CONTEXT: "/"

## ROTA
  ROUTER_PORT: "8080"
  ROUTER_PATH: "/"
  ROUTER_TERMINATION: "reencrypt"

  ## CERTIFICADOS
  CERTIFICATE_SECRET_NAME: "openshift-tls"
  CERTIFICATE_MOUNT_PATH: "/var/run/secrets/service-cert"

 Explica aí, Jão.  


ROUTER_HOSTNAME_DEVELOPMENT, ROUTER_HOSTNAME_STAGING, ROUTER_HOSTNAME_PRODUCTION 

Representação das rotas externas do projeto, caso possuam. São separadas por ambientes, sendo eles: Development, Staging e Production.

Essa variável suporta uma lista de URLs, caso seu projeto possua mais de uma.

As URLs inseridas devem ser apenas externas. As URLs internas, são criadas automaticamente pela esteira de automação, sem a necessidade de especifica-las.

Não devem possuir protocolo e devem conter apenas a URL base, sem diretórios.

  
DEPLOY_ENVIRONMENT

Nessa variável é possível especificar variáveis que serão utilizadas no Deployment do container.

Atualmente utilizamos para inserir variáveis de configurações do Container, como por exemplo, configurar a timezone do container.

Instalação em Multiprojetos

Essa configuração é referente a um repositório que contenha mais de um projeto.

Atualmente, a esteira de automação não suporta deploy baseado em docker-compose. Assim, foi criado uma extensão na própria esteira para suportar deploy de vários projetos do mesmo repositório.

Crie um arquivo "gitlab-ci.yml" na raiz do projeto, com a estrutura básica abaixo.

include:
  - project: ci-cd/templates
    ref: production
    file:
      - deploy.openshift.yml
      - variables.yml

stages:
  - deploy

variables:
  PROJECT_NAME: "nomedosistema"
  PROJECT_DISPLAY_NAME: "Nome do Sistema"

  PROJECT_DEPLOY: "multi-deploy"

sistema-web:
  extends: .multi_deploy
  variables:
    PROJECT_NAME: "sistemaweb"
    PROJECT_DISPLAY_NAME: "Sistema Web"

    DOCKERFILE_PATH: "Dockerfile"

    ROUTER_PORT: "8080"
    ROUTER_TERMINATION: "reencrypt"

    CERTIFICATE_SECRET_NAME: "openshift-tls"
    CERTIFICATE_MOUNT_PATH: "/var/run/secrets/service-cert"

    ROUTER_HOSTNAME_DEVELOPMENT: ""

    ROUTER_HOSTNAME_STAGING: >
      "sistemawebstaging.exemplo.com"

    ROUTER_HOSTNAME_PRODUCTION: >
      "sistemaweb.exemplo.com"

    DEPLOY_ENVIRONMENT: >
      "TZ=America/Porto_Velho"

sistema-api:
  extends: .multi_deploy
  variables:
    ## PROJETO
    PROJECT_NAME: "sistema-api"
    PROJECT_DISPLAY_NAME: "Sistema API"

    DOCKERFILE_PATH: "Dockerfile"

    ROUTER_PORT: "8080"
    ROUTER_TERMINATION: "reencrypt"

    CERTIFICATE_SECRET_NAME: "openshift-tls"
    CERTIFICATE_MOUNT_PATH: "/var/run/secrets/service-cert"

    DEPLOY_ENVIRONMENT: >
      "TZ=America/Porto_Velho"

Trecho Variables

Este trecho é responsável por incluir variáveis pertinentes ao projeto para a execução da esteira, sendo customizável para cada projeto.

PROJECT_DEPLOY

Essa variável é a responsável por disponibilizar a configuração de multi-deploy na esteira de automação.

Trecho por Projeto

Para cada projeto que será publicado, deve existir um trecho com o nome do projeto.

extends

Essa variável especifica que o projeto fará uso da esteira de automação multi-deploy.

variables

Neste trecho serão adicionadas as configurações básicas de variáveis de cada projeto, similar a configuração padrão de projeto já demonstrada anteriormente.

Enriquecendo a configuração do CI

Trecho Include

Code-Quality

Além dos arquivos de deploy e variables, existe o "code-quality.{linguagem}.yml", que é o arquivo responsável pela configuração do pipeline de inspeção de código. Atualmente a ferramenta utilizada para inspeção de códigos é o SonarQube.

Exemplo de inserção:

include:
  - project: ci-cd/templates
    ref: production
    file:
      - code-quality.dotnet.yml
      - deploy.openshift.yml
      - variables.yml

Linguagens suportadas:
- .NET (dotnet)

Suporte a outras linguagens serão desenvolvidas conforme a necessidade.

Trecho Stage

Code-Quality

Além do stage de deploy, existe o code-quality, que é o estágio responsável por executar o processo de inspeção de código.

Exemplo de inserção:

stages:
  - code-quality
  - deploy

Trecho Variables

PROJECT_SDK (.NET)

Esta variável especifica a versão .NET utilizada no projeto, para ser utilizada no processo de inspeção de código.

Versões de SDKs .NET suportadas:
- 3.1
- 5.0
- 6.0

Esta variável é obrigatória para projetos .NET

Suporte a outros SDKs serão desenvolvidos conforme a necessidade.

PROJECT_SOLUTION (.NET)

Esta variável especifica o arquivo .SLN, sendo necessário para execução do comando build do .NET.

Esta variável é obrigatória para projetos .NET

BUILD_ENVIRONMENT

Nessa variável é possível especificar variáveis que serão utilizadas no Build do projeto.

Exemplo de inserção:

BUILD_ENVIRONMENT: >
  "DOTNET_RESTORE_DISABLE_PARALLEL=True"
  "DOTNET_INCREMENTAL=True"
  "DOTNET_VERBOSITY=diag"

Atualmente utilizamos para inserir variáveis de configurações do Container referentes a linguagem.

BUILD_ENVIRONMENT_FILE

Nessa variável é especificado o arquivo .ENV caso seu projeto possua um.

Para facilitar o uso dinâmico baseado em ambientes distintos, é possível utilizar a variável CI_COMMIT_REF_NAME do GitLab-CI para obter o nome da branch onde o estágio está sendo executado, como por examplo:
BUILD_ENVIRONMENT_FILE: "${CI_COMMIT_REF_NAME}.env"
Se for executado na branch development, será obtido o resultado: development.env.

Caso queira conhecer mais variáveis pré-definidas no GitLab-CI para utilizar na sua configuração do GitLab-CI, acesse: Variáveis pré-definidas do GitLab-CI