1
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% extends "base.html" %}
2
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% block title %}Branch Protection — {{ project.name }} — Fossilrepo{% endblock %}
3
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
4
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% block content %}
5
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<h1 class="text-2xl font-bold text-gray-100 mb-2">{{ project.name }}</h1>
6
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% include "fossil/_project_nav.html" %}
7
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
8
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="flex items-center justify-between mb-6">
9
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div>
10
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<h2 class="text-lg font-semibold text-gray-200">Branch Protection Rules</h2>
11
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<p class="text-sm text-gray-500 mt-1">Protect branches from unreviewed changes and require CI checks to pass.</p>
12
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
13
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="flex items-center gap-3">
14
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<span class="search-wrap">
15
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<input type="search"
16
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
name="search"
17
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
value="{{ search }}"
18
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
placeholder="Search rules..."
19
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
aria-label="Search branch protection rules"
20
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
class="rounded-md border-gray-700 bg-gray-800 text-gray-100 shadow-sm focus:border-brand focus:ring-brand text-sm px-3 py-1.5"
21
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
hx-get="{% url 'fossil:branch_protections' slug=project.slug %}"
22
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
hx-trigger="input changed delay:300ms, search"
23
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
hx-target="#protection-content"
24
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
hx-swap="innerHTML"
25
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
hx-push-url="true"
26
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
hx-indicator="closest .search-wrap" />
27
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<svg class="search-spinner animate-spin h-4 w-4" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg>
28
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</span>
29
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<a href="{% url 'fossil:branch_protection_create' slug=project.slug %}"
30
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
class="inline-flex items-center rounded-md bg-brand px-3 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-brand-hover">
31
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Add Rule
32
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</a>
33
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
34
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
35
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
36
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div id="protection-content">
37
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% if rules %}
38
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="space-y-3">
39
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% for rule in rules %}
40
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="rounded-lg bg-gray-800 border border-gray-700">
41
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="px-5 py-4">
42
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="flex items-start justify-between gap-4">
43
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="flex-1 min-w-0">
44
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="flex items-center gap-3 mb-1">
45
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<code class="text-sm font-mono font-medium text-gray-100">{{ rule.branch_pattern }}</code>
46
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% if rule.restrict_push %}
47
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<span class="inline-flex rounded-full bg-yellow-900/50 px-2 py-0.5 text-xs font-semibold text-yellow-300">Push restricted</span>
48
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% endif %}
49
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% if rule.require_status_checks %}
50
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<span class="inline-flex rounded-full bg-blue-900/50 px-2 py-0.5 text-xs font-semibold text-blue-300">CI required</span>
51
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% endif %}
52
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
53
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="flex items-center gap-3 text-xs text-gray-500 mt-1 flex-wrap">
54
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% if rule.require_status_checks and rule.required_contexts %}
55
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<span>Required contexts: {{ rule.required_contexts|truncatewords:10 }}</span>
56
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% endif %}
57
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<span>Created {{ rule.created_at|timesince }} ago</span>
58
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
59
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
60
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="flex items-center gap-2 flex-shrink-0">
61
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<a href="{% url 'fossil:branch_protection_edit' slug=project.slug pk=rule.pk %}"
62
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
class="text-xs text-gray-400 hover:text-brand-light">Edit</a>
63
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<form method="post" action="{% url 'fossil:branch_protection_delete' slug=project.slug pk=rule.pk %}"
64
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
class="inline" onsubmit="return confirm('Delete this protection rule?')">
65
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% csrf_token %}
66
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<button type="submit" class="text-xs text-red-400 hover:text-red-300">Delete</button>
67
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</form>
68
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
69
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
70
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
71
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
72
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% endfor %}
73
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
74
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% else %}
75
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="rounded-lg bg-gray-800 border border-gray-700 p-8 text-center">
76
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<p class="text-sm text-gray-500">{% if search %}No rules matching "{{ search }}".{% else %}No branch protection rules configured.{% endif %}</p>
77
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% if not search %}
78
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<a href="{% url 'fossil:branch_protection_create' slug=project.slug %}"
79
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
class="mt-3 inline-flex items-center rounded-md bg-brand px-3 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-brand-hover">
80
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Add the first rule
81
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</a>
82
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% endif %}
83
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
84
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% endif %}
85
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% include "includes/_pagination.html" %}
86
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
87
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
88
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<div class="mt-6 rounded-md bg-gray-800/50 border border-gray-700 px-4 py-3">
89
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
<p class="text-xs text-gray-400">Branch protection is enforced on all push operations (HTTP sync, CLI push, SSH). Non-admin users are blocked from pushing when protection rules with "restrict push" are active. Admins bypass all restrictions.</p>
90
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
</div>
91
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
{% endblock %}
92
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!