Ответ
В CI/CD пайплайнах я настраиваю условное выполнение на основе измененных файлов, чтобы оптимизировать время сборки и запускать только релевантные этапы. Вот как я это реализовывал в разных системах:
В GitLab CI/CD:
Использую правило changes в секции rules задания (job).
build_backend:
script:
- ./build-backend.sh
rules:
- changes:
- backend/**/*
- go.mod
- go.sum
when: on_success
- when: never # Не запускать, если изменения не в backend
deploy_infrastructure:
script:
- terraform apply -auto-approve
rules:
- changes:
- terraform/**/*
when: on_success
- when: never
В GitHub Actions:
Использую действие dorny/paths-filter для создания выходных переменных, которые затем используются в условиях if.
jobs:
changes:
runs-on: ubuntu-latest
outputs:
backend: ${{ steps.filter.outputs.backend }}
frontend: ${{ steps.filter.outputs.frontend }}
steps:
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
backend:
- 'src/backend/**'
- 'package-lock.json'
frontend:
- 'src/frontend/**'
- 'package.json'
build_backend:
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.backend == 'true' }}
steps:
- run: echo "Building backend..."
build_frontend:
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.frontend == 'true' }}
steps:
- run: echo "Building frontend..."
В Jenkins с использованием Jenkinsfile (Declarative Pipeline):
Использую директиву when с условием changeset.
pipeline {
agent any
stages {
stage('Build Docker Image') {
when {
changeset 'Dockerfile,**/package*.json'
}
steps {
sh 'docker build -t myapp .'
}
}
stage('Terraform Plan') {
when {
changeset 'terraform/**'
}
steps {
dir('terraform') {
sh 'terraform plan'
}
}
}
}
}
Общий подход с помощью скрипта:
Иногда, для более сложной логики, я пишу скрипт, который анализирует git diff.
#!/bin/bash
# В шаге пайплайна
CHANGED_FILES=$(git diff --name-only HEAD~1)
if echo "$CHANGED_FILES" | grep -q "^infrastructure/kubernetes/.*.yaml$"; then
echo "K8s manifests changed. Running helm upgrade..."
helm upgrade myapp ./charts/myapp
fi
if echo "$CHANGED_FILES" | grep -q "^src/.*.go$"; then
echo "Go source changed. Running tests..."
go test ./...
fi
Такой подход позволяет избежать ненужных запусков полного пайплайна и значительно ускоряет процесс CI/CD.