<divclass="choice"><label><inputtype="checkbox"name="enabled"value="1"{% ifrow.git_mirror %} checked{% endif %}> keep a read-only Git mirror of <strong>{{ row.default_bookmark }}</strong></label></div>
60
<pclass="small mute">For tools that only speak Git (CI runners, IDEs): <code>git clone {{ shell.base_url }}{{ repo.url }}.git</code>. Private repositories take a personal access token as the password. Pushing to the mirror is refused.{% if row.git_mirror && !row.git_mirror_state.is_empty() %} Last exported state <code>{{ row.git_mirror_state|short }}</code>.{% endif %}</p>
<labelfor="required_checks">Check names that must pass on a proposal's projected state (comma-separated)</label><inputtype="text"id="required_checks"name="required_checks"value="{{ required_checks }}"placeholder="build, test">
67
<pclass="small mute">Any token with <code>checks:write</code> reports checks with <code>POST {{ shell.base_url }}/api/v1/repos/{{ repo.owner }}/{{ repo.name }}/checks</code>.</p>
<p>Pushes to this repository {% if flow_enabled %}<strong>start runs</strong>{% else %}<strong>do not start runs</strong>{% endif %} of its <code>.flow/pipeline.kdl</code>.</p>
{% if site_admin %}<label><inputtype="radio"name="flow"value="on"{% ifrow.flow== "on" %} checked{% endif %}> on, any runner (the site's too)</label>{% endif %}
77
{% if site_admin || own_runner %}<label><inputtype="radio"name="flow"value="own"{% ifrow.flow== "own" %} checked{% endif %}> on, own runners only</label>{% endif %}
<pclass="small mute"><strong>Own runners only</strong>: jobs go only to runners registered for this repository or its owner (Runners, below), never to the site's. Only site administrators let the site's runners take them. It takes effect at the next push.</p>
<pclass="small mute">To run pipelines on your own machines, register a runner for this repository under <ahref="#runners">Runners</a>, then choose <strong>on, own runners only</strong> here. A site administrator can also let the site's runners take its jobs.</p>
<p>A gate is there so a person decides. By default an agent's token (an agent-marked token, or a keyless agent's grant) cannot approve or reject one here; a decision signed with a person's key (a sealed approval) always can.</p>
103
<labelclass="check"><inputtype="checkbox"name="agents"{% ifrow.agents_decide_gates %} checked{% endif %}> Let agents' tokens approve and reject this repository's approval gates (each decision still says which agent)</label>
<p>When a repository this one pins as a subrepo moves on, Diffusion opens a proposal here that moves the pin, tested by this repository's own pipeline, with the upstream's changes listed. By default it never lands anything by itself.</p>
<label><inputtype="radio"name="land"value="propose"{% ifrow.diffusion_land != "auto" %} checked{% endif %}> propose only: a person lands each bump</label>
119
<label><inputtype="radio"name="land"value="auto"{% ifrow.diffusion_land== "auto" %} checked{% endif %}> land by itself when both halves are green: the upstream state it pins passed its own checks and this repository's run on the bump passed</label>
120
</div>
121
<pclass="small mute">An untested (amber) upstream always waits for a person. A landing by Diffusion still needs this repository's required checks and approvals, and a trust policy that lets the hub's key move the bookmark; otherwise the bump waits, and its timeline says why.</p>
122
<pclass="small mute">A subrepo's <code>.oxymodules</code> entry overrides this with <code>follow = green</code>, <code>any</code> or <code>off</code>; <code>land = auto</code> or <code>propose</code> overrides the landing, <code>target</code> names the bookmark to move (else the one this repository's proposals land on) and <code>watch</code> lists paths whose upstream changes are flagged.</p>
<p>{{ row.owner }} backs up {% if b.every == "off" %}only by hand or when a repository asks{% else %}{% if b.every == "hourly" %}every hour{% else %}every day{% endif %}{% endif %} to {% if b.destination == "gcs" %}<code>gs://{{ b.target }}</code>{% else %}a directory on this hub's host{% endif %}. Every repository goes with it unless it says otherwise here.</p>
130
{% else %}
131
<p>{{ row.owner }} has no backup set up yet: a user sets one up in <ahref="/settings/backups">Settings › Backups</a>, an organisation's owners in its settings. What you choose here applies once it has.</p>
132
{% endif %}
133
<divclass="choice">
134
{% for (v, label) in backup_choices() %}<label><inputtype="radio"name="backup"value="{{ v }}"{% ifrow.backup== *v %} checked{% endif %}> {{ label }}</label>{% endfor %}
135
</div>
136
<pclass="small mute">A repository with its own schedule makes its owner's backup run at least that often; each run sends only what changed and keeps every repository, so any run restores everything. Left out, it is in no new run; earlier runs keep it until they are pruned.</p>
<pclass="small mute">A job's <code>coverage</code> artifact (LCOV) gives each run a <code>coverage</code> check, measured against <strong>{{ row.default_bookmark }}</strong>. Without rules it only reports; with them it fails when they are broken, and a required check named <code>coverage</code> then holds a proposal back.</p>
144
<divclass="row">
145
<div><labelfor="cov_min">Fail below this percentage</label><inputtype="number"id="cov_min"name="min"min="0"max="100"step="0.1"value="{% if let Some(m) = coverage.min %}{{ m }}{% endif %}"placeholder="e.g. 80"></div>
146
<div><labelfor="cov_drop">Fail when it falls by more than (points)</label><inputtype="number"id="cov_drop"name="max_drop"min="0"max="100"step="0.1"value="{% if let Some(m) = coverage.max_drop %}{{ m }}{% endif %}"placeholder="e.g. 0.5"></div>
<pclass="small">The OxygenFlow runners that may take this repository's jobs: the site's, {{ row.owner }}'s, and this repository's own.</p>
153
{% if let Some(t) = runner_token %}<pclass="note">Register a runner for this repository with:</p><preclass="snippet">flow runner register {{ shell.base_url }} --token {{ t }} --name NAME</pre>{% endif %}
154
{% if runners.is_empty() %}<pclass="mute small">None yet: runs wait until a runner that serves this repository is added.</p>{% else %}
<formmethod="post"action="{{ repo.url }}/settings/runners/token"><inputtype="hidden"name="_csrf"value="{{ shell.csrf }}"><buttontype="submit">Add a runner for this repository</button></form>
{% call w::panel(repo.url ~ "/settings", hooks, shell.csrf, "Each delivery is signed with the secret (X-Oxyhub-Signature) and retried with backoff for a day.") %}
{% if collaborators.is_empty() %}<pclass="mute small">Nobody beyond the owner{% if !teams.is_empty() %} and the organisation's members{% endif %}.</p>{% else %}
199
<tableclass="small">
200
{% for c in collaborators %}
201
<tr><td>{% if let Some(a) = c.account %}<ahref="/{{ a.username }}">{{ a.username }}</a>{% else if let Some(t) = c.team %}team {{ t.name }}{% endif %}</td><td>{{ c.role }}</td>
202
<td><formclass="tiny"method="post"action="{{ repo.url }}/settings/collaborators"><inputtype="hidden"name="_csrf"value="{{ shell.csrf }}">{% if let Some(a) = c.account %}<inputtype="hidden"name="username"value="{{ a.username }}">{% else if let Some(t) = c.team %}<inputtype="hidden"name="team"value="{{ t.name }}">{% endif %}<buttonname="remove"value="1">remove</button></form></td></tr>
{% if !teams.is_empty() %}<div><labelfor="team">or team</label><selectid="team"name="team"><optionvalue="">—</option>{% for t in teams %}<optionvalue="{{ t.name }}">{{ t.name }}</option>{% endfor %}</select></div>{% endif %}
<pclass="small mute">Settings that change what this repository is. Each asks you to confirm; none can be undone from here except archiving.</p>
218
<divclass="danger-row">
219
<div><strong>Transfer ownership</strong><pclass="small mute">Move this repository to a user or an organisation you may create repositories under. Its address changes to <code>/OWNER/{{ repo.name }}</code>; the old address redirects, and <code>oxy</code> remotes keep working.</p></div>
<labelfor="towner">New owner</label><inputtype="text"id="towner"name="owner"placeholder="an organisation or a user"required>
224
<labelfor="tconfirm">Type <code>{{ repo.owner }}/{{ repo.name }}</code> to confirm</label><inputtype="text"id="tconfirm"name="confirm"requiredautocomplete="off">
225
<buttontype="submit">TRANSFER</button>
226
</form>
227
</details>
228
</div>
229
<divclass="danger-row">
230
<div><strong>{% if row.archived %}Bring this repository back{% else %}Archive this repository{% endif %}</strong><pclass="small mute">{% if row.archived %}It is archived: read-only for everyone, shown with a badge.{% if !row.archived_reason.is_empty() %} Reason: {{ row.archived_reason }}{% endif %}{% else %}Read-only for everyone, including you: no pushes, edits, issues, proposals or comments, until an admin brings it back. Say why, for whoever finds it later.{% endif %}</p></div>
231
<detailsclass="danger-act"><summaryclass="danger-btn">{% if row.archived %}Unarchive{% else %}Archive{% endif %}</summary>
{% if row.archived %}<inputtype="hidden"name="action"value="unarchive"><buttontype="submit">BRING IT BACK</button>{% else %}<inputtype="hidden"name="action"value="archive">
235
<labelfor="areason">Reason (optional)</label><textareaid="areason"name="reason"rows="2"maxlength="500"placeholder="Superseded by …"></textarea>
<div><strong>Delete wiki data</strong><pclass="small mute">{% if repo.wiki %}The wiki's repository moves to the trash with its history; a new first page starts a fresh one.{% else %}This repository has no wiki.{% endif %}</p></div>
242
{% if repo.wiki %}<detailsclass="danger-act"><summaryclass="danger-btn">Delete wiki data</summary>
<div><strong>Delete this repository</strong><pclass="small mute">The repository moves to the trash and is removed after the retention period.</p></div>