Workflow
Até agora controlamos os jobs dos pipelines usando as rules em cada job, porém é possível definir quando o pipeline inteiro deve rodar através do workflow
.
Ele fica no topo do .gitlab-ci.yml e é útil pra evitar que o GitLab gaste recurso rodando pipelines desnecessários.
Exemplo básico.
workflow:
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: always
- when: never
Esse exemplo diz: só roda pipeline se a branch for main, senão não faz nada. Não confundir com rules: dos jobs. workflow.rules controla o pipeline inteiro, enquanto rules: nos jobs controla os jobs individuais.
As rules do workflow tem preferência às rules dos jobs.
Se o workflow bloquear o pipeline, nenhum job vai rodar, mesmo que as rules do job deixem ele rodar.
No GitLab, a execução do pipeline segue duas camadas de decisão:
-
Workflow (workflow.rules):
- Decide se o pipeline inteiro deve ser criado.
- Se nenhuma regra for satisfeita → o pipeline nem nasce.
-
Jobs (rules, only, except):
- Uma vez que o pipeline foi criado, essas regras definem quais jobs vão rodar dentro dele.
Ou seja, se fossêmos fazer um workflow para o nosso projeto de forma que não atrapalhasse as rules dos nossos jobs precisaríamos abranger tudo.
Se tivermos isso no nosso .gitlab-ci.yml
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: always # Liberado para qualquer merge request
- if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop"' # Liberado para commit nessas branches
when: always
- when: never
A primeira regra libera o pipeline em merge requests, mas os jobs dos stages de pre-check e check não irão disparar, pois apesar de ser um evento de merge, uma as regras dos jobs garante que somente deve ter como destino as branches develop ou main.
.rules-only-mr-main-develop:
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"'
when: always
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"'
when: always
O uso do workflow ajuda:
- Evitar pipelines desnecessários. Esquecer de colocar um rule em um job faria que ele disparasse por qualquer motivo.
- Definir a intenção do pipeline. Só de bater o olho já sabe que é para merge requests e branchs específicas e não para tags, ou vice versa.