kitgit

tirbofish/kitgit

main / templates / repo_settings.html · 16415 bytes

templates/repo_settings.html
{% extends "layout.html" %}

{% block title %}settings · {{ owner.username }}/{{ repo.name }} — kitgit{% endblock %}

{% block content %}
<section class="kg-section">
  <h1 class="kg-title">
    <a href="/{{ owner.username }}/{{ repo.name }}">{{ owner.username }}/{{ repo.name }}</a>
    · settings
  </h1>
  {% let tab = "settings" %}
  {% let archive_ref = repo.default_branch %}
  {% include "partials/repo_tabs.html" %}

  {% if let Some(err) = error %}
    <div class="kg-flash">{{ err }}</div>
  {% endif %}

  <form class="kg-form" method="post" action="/{{ owner.username }}/{{ repo.name }}/settings" style="max-width:none">
    <div class="kg-settings-section" style="margin-top:1rem;border-top:0;padding-top:0">
      <span class="kg-kicker">general</span>
      <label>
        description
        <textarea name="description" rows="3">{{ repo.description }}</textarea>
      </label>
      <label>
        visibility
        <select name="visibility">
          <option value="public"{% if repo.visibility == "public" %} selected{% endif %}>public</option>
          <option value="private"{% if repo.visibility == "private" %} selected{% endif %}>private</option>
        </select>
      </label>
      <label>
        default branch
        {% if branches.is_empty() %}
          <input type="text" name="default_branch" value="{{ repo.default_branch }}" required />
        {% else %}
          <select name="default_branch">
            {% for b in branches %}
              <option value="{{ b }}"{% if b.as_str() == repo.default_branch.as_str() %} selected{% endif %}>{{ b }}</option>
            {% endfor %}
          </select>
        {% endif %}
      </label>
    </div>

    <div class="kg-settings-section">
      <span class="kg-kicker">features</span>
      <label class="row">
        <input type="checkbox" name="issues_enabled"{% if repo.issues_enabled %} checked{% endif %} />
        issues enabled
      </label>
      <label class="row">
        <input type="checkbox" name="pulls_enabled"{% if repo.pulls_enabled %} checked{% endif %} />
        pulls enabled
      </label>
      <label class="row">
        <input type="checkbox" name="releases_enabled"{% if repo.releases_enabled %} checked{% endif %} />
        releases enabled
      </label>
    </div>

    <div class="kg-settings-section">
      <span class="kg-kicker">pull requests</span>
      <label class="row">
        <input type="checkbox" name="allow_merge"{% if repo.allow_merge %} checked{% endif %} />
        allow merge
      </label>
      <label class="row">
        <input type="checkbox" name="allow_squash"{% if repo.allow_squash %} checked{% endif %} />
        allow squash
      </label>
      <label class="row">
        <input type="checkbox" name="allow_rebase"{% if repo.allow_rebase %} checked{% endif %} />
        allow rebase
      </label>
      <label>
        default merge style
        <select name="default_merge_style">
          <option value="merge"{% if repo.default_merge_style == "merge" %} selected{% endif %}>merge</option>
          <option value="squash"{% if repo.default_merge_style == "squash" %} selected{% endif %}>squash</option>
          <option value="rebase"{% if repo.default_merge_style == "rebase" %} selected{% endif %}>rebase</option>
        </select>
      </label>
    </div>

    <div class="kg-settings-section">
      <span class="kg-kicker">branch protection</span>
      <label class="row">
        <input type="checkbox" name="protect_default_branch"{% if repo.protect_default_branch %} checked{% endif %} />
        protect default branch
      </label>
      <label class="row">
        <input type="checkbox" name="protect_block_force_push"{% if repo.protect_block_force_push %} checked{% endif %} />
        block force push
      </label>
      <div class="kg-actions">
        <button class="kg-btn" type="submit">save settings</button>
      </div>
    </div>
  </form>

  <div class="kg-settings-section">
    <span class="kg-kicker">branch rules</span>
    <p class="kg-muted">Pattern-based rules (e.g. <code>main</code>, <code>release/*</code>).</p>
    {% if branch_rules.is_empty() %}
      <p class="kg-muted">No branch rules yet.</p>
    {% else %}
      <ul class="kg-list">
        {% for rule in branch_rules %}
        <li>
          <span>
            <code>{{ rule.pattern }}</code>
            {% if rule.require_pr %}<span class="kg-badge">require PR</span>{% endif %}
            {% if rule.block_force_push %}<span class="kg-badge">no force</span>{% endif %}
            {% if rule.allow_deletions %}<span class="kg-badge">deletions ok</span>{% endif %}
          </span>
          <form method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/branch-rules/{{ rule.id }}/delete">
            <button class="kg-btn kg-btn--danger-ghost" type="submit">delete</button>
          </form>
        </li>
        {% endfor %}
      </ul>
    {% endif %}
    <form class="kg-form" method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/branch-rules" style="margin-top:1rem">
      <label>
        pattern
        <input type="text" name="pattern" required placeholder="main" />
      </label>
      <label class="row">
        <input type="checkbox" name="require_pr" />
        require pull request
      </label>
      <label class="row">
        <input type="checkbox" name="block_force_push" checked />
        block force push
      </label>
      <label class="row">
        <input type="checkbox" name="allow_deletions" />
        allow deletions
      </label>
      <div class="kg-actions">
        <button class="kg-btn" type="submit">add rule</button>
      </div>
    </form>
  </div>

  <div class="kg-settings-section">
    <span class="kg-kicker">mirror</span>
    <p class="kg-muted">Pull from another remote into this repository (fetch heads and tags).</p>
    {% if let Some(m) = mirror %}
      <p class="kg-meta" style="margin:0.5rem 0">
        {% if m.enabled %}
          <span class="kg-badge">enabled</span>
        {% else %}
          <span class="kg-badge">disabled</span>
        {% endif %}
        {% if let Some(synced) = m.last_synced_at %}
          · last synced {{ synced }}
        {% else %}
          · never synced
        {% endif %}
      </p>
      {% if let Some(err) = m.last_error %}
        <div class="kg-flash">{{ err }}</div>
      {% endif %}
      <form class="kg-form" method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/mirror" style="margin-top:1rem">
        <label>
          remote URL
          <input type="text" name="remote_url" required value="{{ m.remote_url }}" placeholder="https://github.com/org/repo.git" />
        </label>
        <label class="row">
          <input type="checkbox" name="enabled"{% if m.enabled %} checked{% endif %} />
          enabled
        </label>
        <div class="kg-actions">
          <button class="kg-btn" type="submit">save mirror</button>
        </div>
      </form>
      <div class="kg-actions" style="margin-top:0.75rem;gap:0.5rem;display:flex;flex-wrap:wrap">
        <form method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/mirror/sync">
          <button class="kg-btn kg-btn--ghost" type="submit">sync now</button>
        </form>
        <form method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/mirror/delete">
          <button class="kg-btn kg-btn--danger-ghost" type="submit">remove mirror</button>
        </form>
      </div>
    {% else %}
      <p class="kg-muted">No mirror configured.</p>
      <form class="kg-form" method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/mirror" style="margin-top:1rem">
        <label>
          remote URL
          <input type="text" name="remote_url" required placeholder="https://github.com/org/repo.git" />
        </label>
        <label class="row">
          <input type="checkbox" name="enabled" checked />
          enabled
        </label>
        <div class="kg-actions">
          <button class="kg-btn" type="submit">save mirror</button>
        </div>
      </form>
    {% endif %}
  </div>

  <div class="kg-settings-section">
    <span class="kg-kicker">labels & milestones</span>
    <p class="kg-muted">Organize issues and pull requests.</p>
    <div class="kg-actions">
      <a class="kg-btn kg-btn--ghost" href="/{{ owner.username }}/{{ repo.name }}/labels">manage labels</a>
      <a class="kg-btn kg-btn--ghost" href="/{{ owner.username }}/{{ repo.name }}/milestones">manage milestones</a>
    </div>
  </div>

  <div class="kg-settings-section">
    <span class="kg-kicker">collaborators</span>
    {% if collaborators.is_empty() %}
      <p class="kg-muted">No collaborators.</p>
    {% else %}
      <ul class="kg-list">
        {% for c in collaborators %}
        <li>
          <span>
            <img class="kg-avatar kg-avatar--sm" src="{{ c.avatar_url }}" alt="" />
            <a href="/{{ c.user.username }}">{{ c.user.username }}</a>
            <span class="kg-badge">{{ c.role }}</span>
          </span>
          <form method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/collaborators/{{ c.user.id }}/remove">
            <button class="kg-btn kg-btn--ghost" type="submit">remove</button>
          </form>
        </li>
        {% endfor %}
      </ul>
    {% endif %}

    <form class="kg-form" method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/collaborators" style="margin-top:1rem">
      <label>
        username
        <input type="text" name="username" required />
      </label>
      <label>
        role
        <select name="role">
          <option value="read">read</option>
          <option value="write" selected>write</option>
          <option value="admin">admin</option>
        </select>
      </label>
      <div class="kg-actions">
        <button class="kg-btn" type="submit">add collaborator</button>
      </div>
    </form>
  </div>

  <div class="kg-settings-section">
    <span class="kg-kicker">deploy keys</span>
    <p class="kg-muted">Repo-scoped SSH keys for CI and automation. Read-only by default; write access allows push to this repository only.</p>
    {% if deploy_keys.is_empty() %}
      <p class="kg-muted">No deploy keys.</p>
    {% else %}
      <ul class="kg-list">
        {% for key in deploy_keys %}
        <li>
          <span>
            <strong>{{ key.name }}</strong>
            <span class="kg-meta">{{ key.fingerprint }}</span>
            <span class="kg-badge">{{ key.permission_label() }}</span>
          </span>
          <form method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/deploy-keys/{{ key.id }}/delete">
            <button class="kg-btn kg-btn--danger-ghost" type="submit">delete</button>
          </form>
        </li>
        {% endfor %}
      </ul>
    {% endif %}

    <form class="kg-form" method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/deploy-keys" style="margin-top:1rem">
      <label>
        name
        <input type="text" name="name" required placeholder="ci" />
      </label>
      <label>
        public key
        <textarea name="public_key" rows="3" required placeholder="ssh-ed25519 AAAA…"></textarea>
      </label>
      <label class="row">
        <input type="checkbox" name="write_access" />
        allow write access (push)
      </label>
      <div class="kg-actions">
        <button class="kg-btn" type="submit">add deploy key</button>
      </div>
    </form>
  </div>

  <div class="kg-settings-section">
    <span class="kg-kicker">webhooks</span>
    <p class="kg-muted">HTTP callbacks for repository events. Optional secret signs payloads as <code>X-Hub-Signature-256</code>.</p>
    {% if webhooks.is_empty() %}
      <p class="kg-muted">No webhooks yet.</p>
    {% else %}
      <ul class="kg-list">
        {% for hook in webhooks %}
        <li>
          <span>
            <code>{{ hook.url }}</code>
            <span class="kg-meta">{{ hook.events_label }}</span>
            {% if hook.has_secret %}<span class="kg-badge">signed</span>{% endif %}
            {% if hook.active %}<span class="kg-badge">active</span>{% else %}<span class="kg-badge">inactive</span>{% endif %}
          </span>
          <span class="kg-actions" style="gap:0.35rem">
            <form method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/webhooks/{{ hook.id }}/toggle">
              <button class="kg-btn kg-btn--ghost" type="submit">{% if hook.active %}disable{% else %}enable{% endif %}</button>
            </form>
            <form method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/webhooks/{{ hook.id }}/delete">
              <button class="kg-btn kg-btn--danger-ghost" type="submit">delete</button>
            </form>
          </span>
        </li>
        {% endfor %}
      </ul>
    {% endif %}
    <form class="kg-form" method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/webhooks" style="margin-top:1rem">
      <label>
        payload URL
        <input type="url" name="url" required placeholder="https://example.com/hooks/kitgit" />
      </label>
      <label>
        secret <span class="kg-muted">(optional)</span>
        <input type="text" name="secret" placeholder="HMAC secret" autocomplete="off" />
      </label>
      <fieldset style="border:0;padding:0;margin:0">
        <legend class="kg-muted" style="margin-bottom:0.35rem">events</legend>
        <label class="row"><input type="checkbox" name="event_push" checked /> push</label>
        <label class="row"><input type="checkbox" name="event_issues" checked /> issues</label>
        <label class="row"><input type="checkbox" name="event_pull_request" checked /> pull_request</label>
        <label class="row"><input type="checkbox" name="event_release" checked /> release</label>
      </fieldset>
      <div class="kg-actions">
        <button class="kg-btn" type="submit">add webhook</button>
      </div>
    </form>
    {% if !webhook_deliveries.is_empty() %}
      <div style="margin-top:1.25rem">
        <span class="kg-kicker">recent deliveries</span>
        <ul class="kg-list">
          {% for d in webhook_deliveries %}
          <li>
            <span>
              <strong>{{ d.event }}</strong>{% if !d.action.is_empty() %}.{{ d.action }}{% endif %}
              <span class="kg-badge">{% if d.success %}ok{% else %}fail{% endif %}</span>
              <span class="kg-meta">{{ d.status_label }} · {{ d.created_at }}</span>
              <span class="kg-meta">{{ d.webhook_url }}</span>
            </span>
          </li>
          {% endfor %}
        </ul>
      </div>
    {% endif %}
  </div>

  {% if access.can_owner() || is_site_admin %}
    <div class="kg-danger-zone">
      <span class="kg-kicker">danger zone</span>

      {% if access.can_owner() %}
      <form class="kg-form" method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/danger/archive">
        <input type="hidden" name="archived" value="{% if repo.archived %}unarchive{% else %}archive{% endif %}" />
        <div class="kg-danger-row">
          <p class="kg-muted" style="margin:0;flex:1">{% if repo.archived %}Unarchive this repository.{% else %}Archive — read-only for everyone.{% endif %}</p>
          <button class="kg-btn kg-btn--danger-ghost" type="submit">{% if repo.archived %}unarchive{% else %}archive{% endif %}</button>
        </div>
      </form>

      <form class="kg-form" method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/danger/transfer">
        <div class="kg-danger-row">
          <label>
            transfer to username
            <input type="text" name="new_owner" required />
          </label>
          <button class="kg-btn kg-btn--danger-ghost" type="submit">transfer</button>
        </div>
      </form>
      {% endif %}

      <form class="kg-form" method="post" action="/{{ owner.username }}/{{ repo.name }}/settings/danger/delete">
        <div class="kg-danger-row">
          <label class="kg-danger-confirm">
            <span>type <code>{{ repo.name }}</code> to delete</span>
            <input type="text" name="confirm" required autocomplete="off" />
          </label>
          <button class="kg-btn kg-btn--danger" type="submit">delete repository</button>
        </div>
      </form>
    </div>
  {% endif %}
</section>
{% endblock %}