Files
IaC-pve-lxc/.template/ci-cd/gitea-cicd.yml
2026-02-19 23:04:04 +04:00

241 lines
10 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Gitea Actions - Terraform CI/CD
run-name: ${{ gitea.actor }} is running Terraform CI/CD 🚀
on:
pull_request:
types: [opened, synchronize, reopened]
branches:
- main # Проверка PRs В main
- dev # Проверка PRs В dev
push:
branches:
- dev # При push в dev создаем PR в main
- main # При push в main применяем изменения
permissions:
contents: write
pull-requests: write
jobs:
terraform-ci:
runs-on: code-runner00
env:
GITEA_URL: "http://code.hlc.lab" # ⚠️ ЗАМЕНИТЕ на ваш URL
GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
# Terraform переменные
TF_IN_AUTOMATION: "true"
TF_VAR_PVE_CLUSTER_API_ID: ${{ secrets.TF_VAR_PVE_CLUSTER_API_ID }}
TF_VAR_PVE_CLUSTER_API_TOKEN: ${{ secrets.TF_VAR_PVE_CLUSTER_API_TOKEN }}
TF_VAR_PVE_CLUSTER_URL: ${{ secrets.TF_VAR_PVE_CLUSTER_URL }}
TF_VAR_POWERDNS_API_URL: ${{ secrets.TF_VAR_POWERDNS_API_URL }}
TF_VAR_POWERDNS_API_TOKEN: ${{ secrets.TF_VAR_POWERDNS_API_TOKEN }}
# AWS переменные (если используете)
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Для корректной работы с ветками
- name: Create PR from dev to main
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
id: create-pr
run: |
echo "🔄 Создание Pull Request из dev в main..."
# Проверяем, существует ли уже открытый PR
EXISTING_PR=$(curl -s -H "Authorization: token $GITEA_TOKEN" \
"$GITEA_URL/api/v1/repos/${{ github.repository }}/pulls?state=open&base=main&head=dev" | jq length)
if [ "$EXISTING_PR" -eq "0" ]; then
# Создаем новый PR
RESPONSE=$(curl -s -X POST \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"title\": \"[Auto] Merge dev → main - $(date +'%Y-%m-%d %H:%M')\",
\"body\": \"Автоматически созданный PR из ветки dev.\\n\\n**Изменения:**\\n${{ github.event.head_commit.message }}\",
\"head\": \"dev\",
\"base\": \"main\",
\"draft\": false
}" \
"$GITEA_URL/api/v1/repos/${{ github.repository }}/pulls")
PR_NUMBER=$(echo "$RESPONSE" | jq -r '.number // empty')
if [ -n "$PR_NUMBER" ]; then
echo "✅ PR создан: #$PR_NUMBER"
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
else
echo "❌ Ошибка создания PR"
echo "$RESPONSE" | jq .
fi
else
echo "📝 PR уже существует, обновляем..."
echo "pr_number=existing" >> $GITHUB_OUTPUT
fi
- name: Setup Terraform
run: |
# Проверяем установку Terraform
terraform version
echo "Terraform готов к работе"
# 📋 Terraform проверки (выполняются всегда)
- name: Terraform Format Check
id: fmt
run: |
if terraform fmt -check -recursive; then
echo "✅ Форматирование корректно"
echo "fmt_status=passed" >> $GITHUB_OUTPUT
else
echo "⚠️ Найдены проблемы с форматированием"
echo "fmt_status=failed" >> $GITHUB_OUTPUT
fi
continue-on-error: true
- name: Terraform Init
id: init
run: terraform init
- name: Terraform Validate
id: validate
run: terraform validate -no-color
# 🗺️ Terraform Plan (для PR и push в dev)
- name: Terraform Plan
id: plan
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'push' && github.ref == 'refs/heads/dev')
run: |
echo "📋 Генерация Terraform плана..."
# Генерируем план
terraform plan -no-color -out=tfplan 2>&1 | tee plan_output.txt
# Проверяем наличие опасных изменений
if grep -q "destroy and then create replacement" plan_output.txt; then
echo "has_replace=true" >> $GITHUB_OUTPUT
echo "replace_count=$(grep -c 'destroy and then create replacement' plan_output.txt)" >> $GITHUB_OUTPUT
# Извлекаем имена ресурсов для замены
grep -B1 "destroy and then create replacement" plan_output.txt | grep "# " | sed 's/^[[:space:]]*#[[:space:]]*//' > replace_resources.txt
echo "replace_resources<<EOF" >> $GITHUB_OUTPUT
cat replace_resources.txt >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
fi
if grep -q "^[[:space:]]*\- destroy" plan_output.txt; then
echo "has_destroy=true" >> $GITHUB_OUTPUT
echo "destroy_count=$(grep -c '^[[:space:]]*\- destroy' plan_output.txt)" >> $GITHUB_OUTPUT
# Извлекаем имена ресурсов для удаления
grep "^[[:space:]]*\- destroy" plan_output.txt -B1 | grep "# " | sed 's/^[[:space:]]*#[[:space:]]*//' > destroy_resources.txt
echo "destroy_resources<<EOF" >> $GITHUB_OUTPUT
cat destroy_resources.txt >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
fi
# Сохраняем полный вывод плана
PLAN_CONTENT=$(cat plan_output.txt | jq -Rs .)
echo "plan_content=$PLAN_CONTENT" >> $GITHUB_OUTPUT
echo "✅ План сгенерирован"
- name: Create Gitea PR Comment
if: github.event_name == 'pull_request'
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO_OWNER: ${{ github.repository_owner }}
REPO_NAME: ${{ github.event.repository.name }}
run: |
echo "💬 Добавление комментария в PR #$PR_NUMBER..."
# Проверяем, сгенерирован ли план
if [ ! -f "plan_output.txt" ]; then
echo "⚠️ Файл плана не найден, пропускаем комментарий"
exit 0
fi
# Создаем Markdown комментарий
cat > comment.md << 'EOF'
## 🔧 Terraform Plan Report
### 📊 Проверки:
EOF
# Добавляем статусы
echo "- **Format Check:** ${{ steps.fmt.outputs.fmt_status == 'passed' && '✅ passed' || '⚠️ failed' }}" >> comment.md
echo "- **Validation:** ${{ steps.validate.outcome == 'success' && '✅ passed' || '❌ failed' }}" >> comment.md
echo "- **Plan:** ${{ steps.plan.outcome == 'success' && '✅ generated' || '⚠️ issues' }}" >> comment.md
# Предупреждения о деструктивных изменениях
if [ "${{ steps.plan.outputs.has_replace }}" = "true" ]; then
echo "" >> comment.md
echo "### ⚠️ REPLACE OPERATIONS DETECTED!" >> comment.md
echo "**${{ steps.plan.outputs.replace_count }}** ресурсов будут пересозданы:" >> comment.md
echo '```' >> comment.md
echo "${{ steps.plan.outputs.replace_resources }}" >> comment.md
echo '```' >> comment.md
fi
if [ "${{ steps.plan.outputs.has_destroy }}" = "true" ]; then
echo "" >> comment.md
echo "### 🗑️ DESTROY OPERATIONS DETECTED!" >> comment.md
echo "**${{ steps.plan.outputs.destroy_count }}** ресурсов будут удалены:" >> comment.md
echo '```' >> comment.md
echo "${{ steps.plan.outputs.destroy_resources }}" >> comment.md
echo '```' >> comment.md
fi
# Полный план
echo "" >> comment.md
echo "<details>" >> comment.md
echo "<summary>📄 Full Terraform Plan Output</summary>" >> comment.md
echo "" >> comment.md
echo '```terraform' >> comment.md
cat plan_output.txt >> comment.md
echo '```' >> comment.md
echo "</details>" >> comment.md
# Отправляем через Gitea API
COMMENT_BODY=$(jq -n --arg body "$(cat comment.md)" '{"body": $body}')
curl -X POST \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d "$COMMENT_BODY" \
"$GITEA_URL/api/v1/repos/${{ github.repository }}/issues/$PR_NUMBER/comments"
echo "✅ Комментарий добавлен"
- name: Block on Destructive Changes
if: |
github.event_name == 'pull_request' &&
(steps.plan.outputs.has_replace == 'true' || steps.plan.outputs.has_destroy == 'true')
run: |
echo "🚨 ОБНАРУЖЕНЫ ОПАСНЫЕ ИЗМЕНЕНИЯ!"
echo "Этот PR содержит destroy/replace операции."
echo "Требуется ручной review перед мержем."
exit 1
- name: Terraform Apply
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
echo "🚀 Применение изменений в main..."
if [ -f "tfplan" ]; then
terraform apply -auto-approve tfplan
else
terraform apply -auto-approve
fi
echo "✅ Изменения применены"