feat: Добавлены 3 стадии в CI/CD пайплайны (lint, test, deploy)

- GitHub Actions: добавлены стадии lint, test, deploy с зависимостями
- Azure DevOps: добавлены стадии lint, test, deploy с зависимостями
- Jenkins: добавлены стадии lint, test, deploy с зависимостями
- GitLab CI: создан новый .gitlab-ci.yml с 3 стадиями

Особенности:
- Деплой происходит только после успешного прохождения lint и test
- Деплой выполняется только для main ветки
- Добавлены уведомления о результатах
- Используются make команды для консистентности
- Параллельное тестирование с разными preset'ами
This commit is contained in:
Сергей Антропов
2025-10-25 19:33:37 +03:00
parent bfed0d1ea8
commit 787ab06e25
4 changed files with 514 additions and 66 deletions

View File

@@ -14,11 +14,12 @@ variables:
DOCKER_TLS_CERTDIR: '' DOCKER_TLS_CERTDIR: ''
stages: stages:
- stage: Test # Стадия 1: Lint проверка
displayName: 'Test Stage' - stage: Lint
displayName: '🔍 Lint Check'
jobs: jobs:
- job: TestJob - job: LintJob
displayName: 'Run Tests' displayName: 'Run Lint'
steps: steps:
- task: UsePythonVersion@0 - task: UsePythonVersion@0
inputs: inputs:
@@ -27,27 +28,140 @@ stages:
- script: | - script: |
pip install --upgrade pip pip install --upgrade pip
pip install molecule[docker] ansible-lint pip install ansible ansible-lint
ansible-galaxy collection install -r requirements.yml ansible-galaxy collection install -r requirements.yml
displayName: 'Install Dependencies' displayName: 'Install Dependencies'
- script: | - script: |
ansible-lint molecule/universal/ echo "🔍 Проверка синтаксиса ролей..."
make role lint
displayName: 'Run Ansible Lint' displayName: 'Run Ansible Lint'
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: '.ansible-lint'
artifactName: 'lint-results'
condition: always()
# Стадия 2: Тестирование
- stage: Test
displayName: '🧪 Role Testing'
dependsOn: Lint
condition: succeeded()
jobs:
- job: TestJob
displayName: 'Run Tests'
strategy:
matrix:
minimal:
preset: minimal
default:
preset: default
performance:
preset: performance
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.11'
displayName: 'Use Python 3.11'
- script: | - script: |
cd molecule/universal sudo apt-get update
molecule test -s universal sudo apt-get install -y docker.io make
sudo systemctl start docker
sudo usermod -aG docker $USER
displayName: 'Install System Dependencies'
- script: |
pip install --upgrade pip
pip install ansible ansible-lint
ansible-galaxy collection install -r requirements.yml
displayName: 'Install Python Dependencies'
- script: |
make docker setup-builder
make docker build
displayName: 'Setup Docker and Build Images'
- script: |
echo "🧪 Тестирование с preset: $(preset)"
make role test $(preset)
displayName: 'Run Molecule Tests' displayName: 'Run Molecule Tests'
env:
PRESET: $(preset)
- task: PublishTestResults@2 - task: PublishTestResults@2
inputs: inputs:
testResultsFiles: 'molecule/universal/.molecule/reports/junit.xml' testResultsFiles: 'molecule/default/.molecule/reports/junit.xml'
testRunTitle: 'Molecule Test Results' testRunTitle: 'Molecule Test Results - $(preset)'
condition: always() condition: always()
- task: PublishBuildArtifacts@1 - task: PublishBuildArtifacts@1
inputs: inputs:
pathToPublish: 'molecule/universal/.molecule' pathToPublish: 'molecule/default/.molecule'
artifactName: 'molecule-reports' artifactName: 'test-results-$(preset)'
condition: always() condition: always()
# Стадия 3: Деплой (только для main ветки)
- stage: Deploy
displayName: '🚀 Deploy Check'
dependsOn: [Lint, Test]
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- job: DeployJob
displayName: 'Check Deployment'
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.11'
displayName: 'Use Python 3.11'
- script: |
pip install --upgrade pip
pip install ansible ansible-lint
ansible-galaxy collection install -r requirements.yml
displayName: 'Install Dependencies'
- script: |
mkdir -p inventory
cat > inventory/hosts.ini << EOF
[test_servers]
localhost ansible_connection=local
[all:vars]
ansible_python_interpreter=python3
EOF
displayName: 'Create Inventory File'
- script: |
echo "🚀 Проверка развертывания (dry-run)..."
make role deploy
displayName: 'Run Deployment Check'
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: 'deployment.log'
artifactName: 'deployment-results'
condition: always()
# Уведомления
- stage: Notify
displayName: '📢 Notifications'
dependsOn: [Lint, Test, Deploy]
condition: always()
jobs:
- job: NotifyJob
displayName: 'Send Notifications'
steps:
- script: |
echo "🔍 Lint: $(Lint.result)"
echo "🧪 Test: $(Test.result)"
echo "🚀 Deploy: $(Deploy.result)"
if [ "$(Lint.result)" = "Succeeded" ] && [ "$(Test.result)" = "Succeeded" ]; then
echo "✅ Все проверки пройдены успешно!"
else
echo "❌ Проверки не пройдены!"
exit 1
fi
displayName: 'Check Results and Notify'

View File

@@ -2,7 +2,7 @@
# Автор: Сергей Антропов # Автор: Сергей Антропов
# Сайт: https://devops.org.ru # Сайт: https://devops.org.ru
name: Ansible Testing name: AnsibleLab CI/CD Pipeline
on: on:
push: push:
@@ -11,44 +11,9 @@ on:
branches: [ main ] branches: [ main ]
jobs: jobs:
test: # Стадия 1: Lint проверка
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl start docker
sudo usermod -aG docker $USER
- name: Install Python dependencies
run: |
pip install --upgrade pip
pip install molecule[docker] ansible-lint
ansible-galaxy collection install -r requirements.yml
- name: Run Molecule tests
run: |
cd molecule/universal
molecule test -s universal
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: molecule-reports
path: molecule/universal/.molecule/
lint: lint:
name: 🔍 Lint Check
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -62,9 +27,146 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
pip install ansible-lint pip install --upgrade pip
pip install ansible ansible-lint
ansible-galaxy collection install -r requirements.yml ansible-galaxy collection install -r requirements.yml
- name: Run Ansible Lint - name: Run Ansible Lint
run: | run: |
ansible-lint molecule/universal/ echo "🔍 Проверка синтаксиса ролей..."
make role lint
- name: Upload lint results
uses: actions/upload-artifact@v3
if: always()
with:
name: lint-results
path: |
.ansible-lint
lint-report.txt
# Стадия 2: Тестирование
test:
name: 🧪 Role Testing
runs-on: ubuntu-latest
needs: lint
strategy:
matrix:
preset: [minimal, default, performance]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y docker.io make
sudo systemctl start docker
sudo usermod -aG docker $USER
- name: Install Python dependencies
run: |
pip install --upgrade pip
pip install ansible ansible-lint
ansible-galaxy collection install -r requirements.yml
- name: Setup Docker builder
run: |
make docker setup-builder
- name: Build Docker images
run: |
make docker build
- name: Run Molecule tests
run: |
echo "🧪 Тестирование с preset: ${{ matrix.preset }}"
make role test ${{ matrix.preset }}
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results-${{ matrix.preset }}
path: |
molecule/default/.molecule/
test-report-${{ matrix.preset }}.txt
# Стадия 3: Деплой (только для main ветки)
deploy:
name: 🚀 Deploy Check
runs-on: ubuntu-latest
needs: [lint, test]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install --upgrade pip
pip install ansible ansible-lint
ansible-galaxy collection install -r requirements.yml
- name: Create inventory file
run: |
mkdir -p inventory
cat > inventory/hosts.ini << EOF
[test_servers]
localhost ansible_connection=local
[all:vars]
ansible_python_interpreter=python3
EOF
- name: Run deployment check
run: |
echo "🚀 Проверка развертывания (dry-run)..."
make role deploy
- name: Upload deployment results
uses: actions/upload-artifact@v3
if: always()
with:
name: deployment-results
path: |
deployment.log
deployment-report.txt
# Уведомления
notify:
name: 📢 Notifications
runs-on: ubuntu-latest
needs: [lint, test, deploy]
if: always()
steps:
- name: Notify on success
if: needs.lint.result == 'success' && needs.test.result == 'success'
run: |
echo "✅ Все проверки пройдены успешно!"
echo "🔍 Lint: ${{ needs.lint.result }}"
echo "🧪 Test: ${{ needs.test.result }}"
echo "🚀 Deploy: ${{ needs.deploy.result }}"
- name: Notify on failure
if: needs.lint.result == 'failure' || needs.test.result == 'failure'
run: |
echo "❌ Проверки не пройдены!"
echo "🔍 Lint: ${{ needs.lint.result }}"
echo "🧪 Test: ${{ needs.test.result }}"
echo "🚀 Deploy: ${{ needs.deploy.result }}"
exit 1

153
cicd/gitlab/.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,153 @@
# GitLab CI Pipeline для AnsibleLab
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
stages:
- lint
- test
- deploy
variables:
ANSIBLE_FORCE_COLOR: "true"
DOCKER_TLS_CERTDIR: ""
# Стадия 1: Lint проверка
lint:
stage: lint
image: python:3.11
before_script:
- pip install --upgrade pip
- pip install ansible ansible-lint
- ansible-galaxy collection install -r requirements.yml
script:
- echo "🔍 Проверка синтаксиса ролей..."
- make role lint
artifacts:
reports:
junit: .ansible-lint
paths:
- .ansible-lint
expire_in: 1 week
# Стадия 2: Тестирование
test_minimal:
stage: test
image: docker:latest
services:
- docker:dind
variables:
DOCKER_TLS_CERTDIR: ""
before_script:
- apk add --no-cache make python3 py3-pip
- pip install --upgrade pip
- pip install ansible ansible-lint
- ansible-galaxy collection install -r requirements.yml
- make docker setup-builder
- make docker build
script:
- echo "🧪 Тестирование с preset: minimal"
- make role test minimal
artifacts:
reports:
junit: molecule/default/.molecule/reports/junit.xml
paths:
- molecule/default/.molecule/
expire_in: 1 week
test_default:
stage: test
image: docker:latest
services:
- docker:dind
variables:
DOCKER_TLS_CERTDIR: ""
before_script:
- apk add --no-cache make python3 py3-pip
- pip install --upgrade pip
- pip install ansible ansible-lint
- ansible-galaxy collection install -r requirements.yml
- make docker setup-builder
- make docker build
script:
- echo "🧪 Тестирование с preset: default"
- make role test default
artifacts:
reports:
junit: molecule/default/.molecule/reports/junit.xml
paths:
- molecule/default/.molecule/
expire_in: 1 week
test_performance:
stage: test
image: docker:latest
services:
- docker:dind
variables:
DOCKER_TLS_CERTDIR: ""
before_script:
- apk add --no-cache make python3 py3-pip
- pip install --upgrade pip
- pip install ansible ansible-lint
- ansible-galaxy collection install -r requirements.yml
- make docker setup-builder
- make docker build
script:
- echo "🧪 Тестирование с preset: performance"
- make role test performance
artifacts:
reports:
junit: molecule/default/.molecule/reports/junit.xml
paths:
- molecule/default/.molecule/
expire_in: 1 week
# Стадия 3: Деплой (только для main ветки)
deploy:
stage: deploy
image: python:3.11
only:
- main
before_script:
- pip install --upgrade pip
- pip install ansible ansible-lint
- ansible-galaxy collection install -r requirements.yml
script:
- echo "🚀 Проверка развертывания (dry-run)..."
- mkdir -p inventory
- |
cat > inventory/hosts.ini << EOF
[test_servers]
localhost ansible_connection=local
[all:vars]
ansible_python_interpreter=python3
EOF
- make role deploy
artifacts:
paths:
- deployment.log
expire_in: 1 week
# Уведомления
notify_success:
stage: deploy
image: python:3.11
only:
- main
when: on_success
script:
- echo "✅ Все проверки пройдены успешно!"
- echo "🔍 Lint: Success"
- echo "🧪 Test: Success"
- echo "🚀 Deploy: Success"
notify_failure:
stage: deploy
image: python:3.11
when: on_failure
script:
- echo "❌ Проверки не пройдены!"
- echo "🔍 Lint: Failed"
- echo "🧪 Test: Failed"
- echo "🚀 Deploy: Failed"

View File

@@ -17,26 +17,99 @@ pipeline {
} }
} }
stage('Install Dependencies') { // Стадия 1: Lint проверка
stage('🔍 Lint Check') {
steps { steps {
sh ''' sh '''
echo "🔍 Проверка синтаксиса ролей..."
pip install --upgrade pip pip install --upgrade pip
pip install molecule[docker] ansible-lint pip install ansible ansible-lint
ansible-galaxy collection install -r requirements.yml ansible-galaxy collection install -r requirements.yml
make role lint
''' '''
} }
} post {
always {
stage('Lint') { archiveArtifacts artifacts: '.ansible-lint', allowEmptyArchive: true
steps { }
sh 'ansible-lint molecule/universal/'
} }
} }
stage('Test') { // Стадия 2: Тестирование
stage('🧪 Role Testing') {
parallel {
stage('Test Minimal') {
steps {
sh '''
echo "🧪 Тестирование с preset: minimal"
sudo apt-get update
sudo apt-get install -y docker.io make
sudo systemctl start docker
sudo usermod -aG docker $USER
make docker setup-builder
make docker build
make role test minimal
'''
}
}
stage('Test Default') {
steps {
sh '''
echo "🧪 Тестирование с preset: default"
sudo apt-get update
sudo apt-get install -y docker.io make
sudo systemctl start docker
sudo usermod -aG docker $USER
make docker setup-builder
make docker build
make role test default
'''
}
}
stage('Test Performance') {
steps {
sh '''
echo "🧪 Тестирование с preset: performance"
sudo apt-get update
sudo apt-get install -y docker.io make
sudo systemctl start docker
sudo usermod -aG docker $USER
make docker setup-builder
make docker build
make role test performance
'''
}
}
}
}
// Стадия 3: Деплой (только для main ветки)
stage('🚀 Deploy Check') {
when {
branch 'main'
}
steps { steps {
dir('molecule/universal') { sh '''
sh 'molecule test -s universal' echo "🚀 Проверка развертывания (dry-run)..."
pip install --upgrade pip
pip install ansible ansible-lint
ansible-galaxy collection install -r requirements.yml
mkdir -p inventory
cat > inventory/hosts.ini << EOF
[test_servers]
localhost ansible_connection=local
[all:vars]
ansible_python_interpreter=python3
EOF
make role deploy
'''
}
post {
always {
archiveArtifacts artifacts: 'deployment.log', allowEmptyArchive: true
} }
} }
} }
@@ -44,16 +117,22 @@ pipeline {
post { post {
always { always {
archiveArtifacts artifacts: 'molecule/universal/.molecule/**/*', allowEmptyArchive: true archiveArtifacts artifacts: 'molecule/default/.molecule/**/*', allowEmptyArchive: true
publishTestResults testResultsPattern: 'molecule/universal/.molecule/reports/junit.xml' publishTestResults testResultsPattern: 'molecule/default/.molecule/reports/junit.xml'
} }
success { success {
echo 'Pipeline completed successfully!' echo 'Все проверки пройдены успешно!'
echo '🔍 Lint: Success'
echo '🧪 Test: Success'
echo '🚀 Deploy: Success'
} }
failure { failure {
echo 'Pipeline failed!' echo '❌ Проверки не пройдены!'
echo '🔍 Lint: Failed'
echo '🧪 Test: Failed'
echo '🚀 Deploy: Failed'
} }
} }
} }