| | @@ -1030,10 +1030,89 @@ |
| 1030 | 1030 | "result": result, |
| 1031 | 1031 | "active_tab": "sync", |
| 1032 | 1032 | }, |
| 1033 | 1033 | ) |
| 1034 | 1034 | |
| 1035 | + |
| 1036 | +# --- Git Mirror --- |
| 1037 | + |
| 1038 | + |
| 1039 | +@login_required |
| 1040 | +def git_mirror_config(request, slug): |
| 1041 | + """Configure Git mirror sync for a project.""" |
| 1042 | + project, fossil_repo, reader = _get_repo_and_reader(slug, request, "admin") |
| 1043 | + |
| 1044 | + from fossil.sync_models import GitMirror |
| 1045 | + |
| 1046 | + mirrors = GitMirror.objects.filter(repository=fossil_repo, deleted_at__isnull=True) |
| 1047 | + |
| 1048 | + if request.method == "POST": |
| 1049 | + action = request.POST.get("action", "") |
| 1050 | + if action == "create": |
| 1051 | + git_url = request.POST.get("git_remote_url", "").strip() |
| 1052 | + auth_method = request.POST.get("auth_method", "token") |
| 1053 | + auth_credential = request.POST.get("auth_credential", "").strip() |
| 1054 | + sync_mode = request.POST.get("sync_mode", "scheduled") |
| 1055 | + sync_schedule = request.POST.get("sync_schedule", "*/15 * * * *").strip() |
| 1056 | + git_branch = request.POST.get("git_branch", "main").strip() |
| 1057 | + |
| 1058 | + if git_url: |
| 1059 | + GitMirror.objects.create( |
| 1060 | + repository=fossil_repo, |
| 1061 | + git_remote_url=git_url, |
| 1062 | + auth_method=auth_method, |
| 1063 | + auth_credential=auth_credential, |
| 1064 | + sync_mode=sync_mode, |
| 1065 | + sync_schedule=sync_schedule, |
| 1066 | + git_branch=git_branch, |
| 1067 | + created_by=request.user, |
| 1068 | + ) |
| 1069 | + from django.contrib import messages |
| 1070 | + |
| 1071 | + messages.success(request, f"Git mirror configured: {git_url}") |
| 1072 | + from django.shortcuts import redirect |
| 1073 | + |
| 1074 | + return redirect("fossil:git_mirror", slug=slug) |
| 1075 | + |
| 1076 | + elif action == "delete": |
| 1077 | + mirror_id = request.POST.get("mirror_id") |
| 1078 | + mirror = GitMirror.objects.filter(pk=mirror_id, repository=fossil_repo).first() |
| 1079 | + if mirror: |
| 1080 | + mirror.soft_delete(user=request.user) |
| 1081 | + from django.contrib import messages |
| 1082 | + |
| 1083 | + messages.info(request, "Git mirror removed.") |
| 1084 | + |
| 1085 | + return render( |
| 1086 | + request, |
| 1087 | + "fossil/git_mirror.html", |
| 1088 | + { |
| 1089 | + "project": project, |
| 1090 | + "fossil_repo": fossil_repo, |
| 1091 | + "mirrors": mirrors, |
| 1092 | + "active_tab": "sync", |
| 1093 | + }, |
| 1094 | + ) |
| 1095 | + |
| 1096 | + |
| 1097 | +@login_required |
| 1098 | +def git_mirror_run(request, slug, mirror_id): |
| 1099 | + """Manually trigger a Git sync for a specific mirror.""" |
| 1100 | + project, fossil_repo, reader = _get_repo_and_reader(slug, request, "admin") |
| 1101 | + |
| 1102 | + if request.method == "POST": |
| 1103 | + from fossil.tasks import run_git_sync |
| 1104 | + |
| 1105 | + run_git_sync.delay(mirror_id) |
| 1106 | + from django.contrib import messages |
| 1107 | + |
| 1108 | + messages.info(request, "Git sync triggered. Check back shortly for results.") |
| 1109 | + |
| 1110 | + from django.shortcuts import redirect |
| 1111 | + |
| 1112 | + return redirect("fossil:git_mirror", slug=slug) |
| 1113 | + |
| 1035 | 1114 | |
| 1036 | 1115 | # --- Technotes --- |
| 1037 | 1116 | |
| 1038 | 1117 | |
| 1039 | 1118 | def technote_list(request, slug): |
| 1040 | 1119 | |
| 1041 | 1120 | ADDED templates/fossil/git_mirror.html |