Pular para o conteúdo principal

Extends

Olhando para a nossa pipeline podemos observar que o build nem foi utilizado para fazer os testes que queremos. Quanto mais cedo pegarmos o erro, melhor é. Estamos perdendo tempo com esse build antes. Como poderíamos melhorar isso? Vamos criar um stage antes chamado check, mas poderíamos usa o default .pre.

before_script, script e after_script

A ordem de execução em um job do GitLab CI é:

  1. before_script (global ou do job)
  2. script
  3. after_script (se existir)

Depois disso, se o job for bem-sucedido, ele salva os artifacts (se definidos)

before_script e after_script podem ser definidos, mas não é obrigatório. Se for definido...

  • No default: → afeta todos os jobs
  • Ou individualmente por job

Se o before_script falhar, o script não é executado, porém se o script falhar o after_script ainda é executado (pra limpeza, logs, notificações, etc).

Sabendo disso e com as informações que temos já podemos melhorar nossa pipeline. Vamos aplicar o conceito de extends e templates para enxugar isso.

default:
tags:
- general
# Os jobs agora terão essa imagem por default eliminando uma linha em cada um deles
# Também é uma imagem menor.
image: node:22-alpine

stages:
- check # Novo stage anterior
- build
- test # Esta aqui mas não será usado, só para mostrar que não bloquei a pipeline se um stage é definido, mas não utilizado

.check: # Template para stage check só com o que será padrão para todos
stage: check
before_script:
- npm ci
artifacts:
when: always
expire_in: "3 months"

unit-test:
extends: .check
script:
- npm test
artifacts: # Agora só colocamos o reports e eliminamos outras coisas
reports:
junit: reports/junit.xml

lint-test:
extends: .check
script:
- npm run lint
artifacts:
reports:
codequality: gl-codequality.json

vulnerability-test:
extends: .check
script:
- npm audit --audit-level=high --json > vulnerability-report.json
artifacts:
paths:
- vulnerability-report.json

build:
stage: build
script:
- node --version
- npm --version
- npm ci
- npm run build
artifacts:
when: on_success
expire_in: "1 hour"
paths:
- build/

Antes com a imagem slim tínhamos esse tempo e esta sequência.

alt text

Agora temos esse tempos e esta sequência. Extends e templates só melhoram a visibilidade do código não a performance. O que melhorou o tempo foi a imagem menor.

alt text

Um detalhe importante. Extends na verdade é uma lista. Podemos extender mais de um template como se fosse uma combinação entre eles.

jobx:
extends: [.check, .other]

Se .check e .other definem a mesma coisa, .other irá prevalecer pois foi o último a escrever. É uma lista ordenada.

Agora está na hora de definir quando essa pipeline será executada pois está sendo executada sempre. Se uma pessoa estiver desenvolvendo, o código ainda nem terminou direito e ela precisa fazer um push para a sua branch, não precisamos que a pipeline seja executada. Vamos iniciar esse conceito, mas entenderemos melhor depois sobre isso.

Em um dos jobs podemos ter uma rule que irá definir quando um job deve ou não deve ser executado.

ex:

jobX:
...
script:
...
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"'
when: always

Vamos introduzir sobre variáveis e rules jajá. Essa variável CI_MERGE_REQUEST_TARGET_BRANCH_NAME é uma variável do GitLab e existem várias. A regra acima diz que o pipeline deve ser executado sempre quando for um merge request direcionado para a main. Poderíamos colocar isso em todos os nossos jobs, mas vamos aproveitar e fazer um extends de dois templates ao mesmo tempo.

default:
tags:
- general
image: node:22-alpine

stages:
- check
- build

.check: # Template para stage check
stage: check
before_script:
- npm ci
artifacts:
when: always
expire_in: "3 months"

.rules-only-main-mr: # Template para rules geral
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"'
when: always

unit-test:
extends: # Podemos definir assim
- .check
- .rules-only-main-mr
script:
- npm test
artifacts:
reports:
junit: reports/junit.xml

lint-test:
extends: [.check,.rules-only-main-mr] # Ou assim
script:
- npm run lint
artifacts:
reports:
codequality: gl-codequality.json

vulnerability-test:
extends: [.check,.rules-only-main-mr]
script:
- npm audit --audit-level=high --json > vulnerability-report.json
artifacts:
paths:
- vulnerability-report.json

build:
stage: build
extends: [.rules-only-main-mr] # Ou assim ou como vimos antes em caso de um só extends: .rules-only-main-mr
script:
- node --version
- npm --version
- npm ci
- npm run build
artifacts:
when: on_success
expire_in: "1 hour"
paths:
- build/

Agora ao subir esse código não irá disparar a pipeline. Faça o teste.

Porém ao criar um merge request teremos a pipeline disparada e se seguiu as recomendações somente se a pipeline passar é que poderemos mergear na main.

O resultado...

alt text