add ci/cd test
This commit is contained in:
240
.template/ci-cd/gitea-cicd.yml
Normal file
240
.template/ci-cd/gitea-cicd.yml
Normal file
@@ -0,0 +1,240 @@
|
||||
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 "✅ Изменения применены"
|
||||
|
||||
Reference in New Issue
Block a user