feat: добавлена пометка типа операции (Build/Push) в истории сборок Dockerfile

- Добавлена колонка 'Тип' во все таблицы истории сборок
- Для push операций отображается registry вместо платформ
- Сохранение пользователя при создании push лога
- Исправлена ошибка с logger в push_docker_image endpoint
- Улучшено отображение истории сборок с визуальными индикаторами
This commit is contained in:
Сергей Антропов
2026-02-15 22:59:02 +03:00
parent 23e1a6037b
commit 1fbf9185a2
232 changed files with 38075 additions and 5 deletions

View File

@@ -0,0 +1,163 @@
{% extends "base.html" %}
{% block title %}Экспорт {{ role_name }} - DevOpsLab{% endblock %}
{% block page_title %}Экспорт роли: {{ role_name }}{% endblock %}
{% block content %}
<div class="card mb-3">
<div class="card-header">
<h5 class="mb-0">Настройки экспорта</h5>
</div>
<div class="card-body">
<form
hx-post="/api/v1/roles/{{ role_name }}/export"
hx-target="#export-result"
hx-swap="innerHTML"
class="space-y-4"
>
<!-- URL репозитория -->
<div class="mb-3">
<label class="form-label">URL Git репозитория *</label>
<input
type="url"
name="repo_url"
class="form-control"
placeholder="https://github.com/username/ansible-role-{{ role_name }}.git"
required
>
<div class="form-text">
Поддерживаются HTTPS и SSH URL (git@github.com:user/repo.git)
</div>
</div>
<!-- Ветка -->
<div class="mb-3">
<label class="form-label">Ветка</label>
<input
type="text"
name="branch"
value="main"
class="form-control"
placeholder="main"
>
</div>
<!-- Версия -->
<div class="mb-3">
<label class="form-label">Версия (для создания тега)</label>
<input
type="text"
name="version"
class="form-control"
placeholder="1.0.0"
pattern="^[0-9]+\.[0-9]+\.[0-9]+$"
>
<div class="form-text">
Формат: X.Y.Z (например, 1.0.0). Будет создан тег v{version}
</div>
</div>
<!-- Компоненты -->
<div class="mb-3">
<label class="form-label">Компоненты для экспорта</label>
<div class="row g-2">
{% for component in components %}
<div class="col-12 col-md-6 col-lg-4">
<div class="form-check">
<input
class="form-check-input"
type="checkbox"
value="{{ component }}"
id="component-{{ component }}"
name="components"
checked
>
<label class="form-check-label" for="component-{{ component }}">
{{ component }}
</label>
</div>
</div>
{% endfor %}
</div>
</div>
<!-- Секреты -->
<div class="mb-3">
<div class="form-check form-switch">
<input
class="form-check-input"
type="checkbox"
id="include-secrets"
name="include_secrets"
>
<label class="form-check-label" for="include-secrets">
Включать секреты из vars/ (не рекомендуется)
</label>
</div>
<div class="form-text text-warning">
⚠️ Если включено, секреты будут экспортированы. Используйте с осторожностью!
</div>
</div>
<!-- Сообщение коммита -->
<div class="mb-3">
<label class="form-label">Сообщение коммита</label>
<textarea
name="commit_message"
class="form-control"
rows="2"
placeholder="Автоматически сгенерируется, если не указано"
></textarea>
</div>
<!-- Скрытое поле для компонентов -->
<input
type="hidden"
name="components"
id="components-json"
value="[]"
>
<!-- Результат -->
<div id="export-result" class="mt-4"></div>
<!-- Кнопки -->
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">
<i class="fas fa-upload me-2"></i>
Экспортировать роль
</button>
<a href="/roles/{{ role_name }}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>
Отмена
</a>
</div>
</form>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.querySelector('form');
const componentsInput = document.getElementById('components-json');
const checkboxes = document.querySelectorAll('input[name="components"]');
function updateComponents() {
const selected = Array.from(checkboxes)
.filter(cb => cb.checked)
.map(cb => cb.value);
componentsInput.value = JSON.stringify(selected);
}
checkboxes.forEach(cb => {
cb.addEventListener('change', updateComponents);
});
updateComponents();
form.addEventListener('submit', function(e) {
updateComponents();
});
});
</script>
{% endblock %}