Files
rdgen/rdgenerator/templates/site_settings.html
T

352 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}构建平台配置 · RustDesk 客户端定制平台{% endblock %}
{% block content %}
<nav class="breadcrumb">
<a href="{% url 'dashboard' %}">后台管理</a>
<span class="breadcrumb-sep">/</span>
<span>构建平台配置</span>
</nav>
<div class="page-head">
<h1 class="page-title">
<svg class="icon"><use href="#i-sliders"/></svg>
构建平台配置
</h1>
<p class="page-subtitle">
选择实际执行构建任务的平台:GitHub Actions(云托管构建机)或自建 Gitea Actions(构建机自备、可全内网运行)。
支持在本页直接配置(优先级最高),也继续兼容 docker-compose 环境变量方式。
</p>
</div>
{# ===== 配置状态总览 ===== #}
<div class="card config-card">
<div class="card-header">
<svg class="icon"><use href="#i-shield"/></svg> 配置状态检查<span class="platform-tag" style="margin-left:8px">当前平台:{{ build_platform_label }}</span>
</div>
<div class="card-body">
{% if build_ready and not warnings %}
<div class="config-ok">
<svg class="icon"><use href="#i-check-circle"/></svg>
{{ build_platform_label }} 构建服务配置完整,可以正常提交客户端构建任务。
</div>
{% else %}
<ul class="config-check-list">
{% if build_ready %}
<li class="is-ok"><svg class="icon"><use href="#i-check-circle"/></svg> {{ build_platform_label }} 连接信息已配置</li>
{% else %}
<li class="is-bad"><svg class="icon"><use href="#i-alert"/></svg> {{ build_platform_label }} 连接信息缺失,暂无法触发构建</li>
{% endif %}
{% for w in warnings %}
<li class="is-warn"><svg class="icon"><use href="#i-alert"/></svg> {{ w }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{# ===== 配置表单 ===== #}
<form method="post" action="{% url 'github_settings' %}" class="settings-form">
{% csrf_token %}
{# --- 构建平台选择(自定义平台卡,单选) --- #}
<div class="card">
<div class="card-header"><svg class="icon"><use href="#i-sliders"/></svg> 构建平台</div>
<div class="card-body">
<p class="card-desc">切换后仅影响新提交的构建任务;历史任务仍保存在原平台并可继续查询状态与日志。</p>
<div class="build-platform-grid">
<label class="platform-card {% if build_platform != 'gitea' %}active{% endif %}" data-platform-card="github">
<input type="radio" name="build_platform" value="github" class="visually-hidden"
{% if build_platform != 'gitea' %}checked{% endif %}>
<svg class="icon brand-github"><use href="#b-github"/></svg>
<div class="platform-name">GitHub Actions</div>
<div class="platform-desc">官方云托管 Windows / macOS / Linux 构建机,零运维;国内网络可能需要代理。</div>
</label>
<label class="platform-card {% if build_platform == 'gitea' %}active{% endif %}" data-platform-card="gitea">
<input type="radio" name="build_platform" value="gitea" class="visually-hidden"
{% if build_platform == 'gitea' %}checked{% endif %}>
<svg class="icon"><use href="#b-gitea"/></svg>
<div class="platform-name">Gitea Actions(自建)</div>
<div class="platform-desc">API 与工作流语法兼容 GitHub,可全内网运行、回传快;需自备全部构建机。</div>
</label>
</div>
</div>
</div>
{# --- 各配置分组(platform 组已在上方自定义渲染) --- #}
{% for group_key, group_title, group_desc in groups %}{% if group_key != 'platform' %}
<div class="card backend-panel
{% if group_key == 'gitea' %}panel-gitea{% if build_platform != 'gitea' %} panel-hidden{% endif %}
{% elif group_key == 'basic' or group_key == 'network' %}panel-github{% if build_platform == 'gitea' %} panel-hidden{% endif %}{% endif %}">
<div class="card-header"><svg class="icon"><use href="#i-sliders"/></svg> {{ group_title }}</div>
<div class="card-body">
<p class="card-desc">{{ group_desc }}</p>
{% for row in rows %}{% if row.group == group_key %}
<div class="field setting-row{% if row.key == 'SH_SECRET' %} panel-github{% if build_platform == 'gitea' %} panel-hidden{% endif %}{% endif %}">
<label class="setting-label" for="{{ row.field.id_for_label }}">
{{ row.label }}
<span class="source-badge source-{{ row.source }}">{{ row.source_label }}</span>
</label>
{{ row.field }}
{% if row.sensitive %}
<div class="secret-meta">
<label class="clear-check" for="{{ row.clear_field.id_for_label }}">
{{ row.clear_field }} 清除后台配置,回退到环境变量/默认值
</label>
{% if row.source == 'db' %}
<span class="secret-state is-set">已在后台保存</span>
{% elif row.source == 'env' %}
<span class="secret-state is-env">已通过环境变量配置</span>
{% else %}
<span class="secret-state is-empty">未配置(使用默认值)</span>
{% endif %}
</div>
{% endif %}
{% if row.help %}<div class="field-hint">{{ row.help }}</div>{% endif %}
</div>
{% endif %}{% endfor %}
</div>
</div>
{% endif %}{% endfor %}
{# --- 保存与连接测试(始终可见,测试目标跟随当前所选平台) --- #}
<div class="card settings-submit-card">
<div class="card-body settings-actions">
<div class="btn-row">
<button type="submit" class="btn btn-primary">
<svg class="icon"><use href="#i-save"/></svg> 保存配置
</button>
<button type="button" class="btn btn-secondary" id="testBuildBtn">
<svg class="icon"><use href="#i-zap"/></svg> <span id="testBuildBtnLabel">测试 GitHub 连接</span>
</button>
</div>
<div id="testResult" class="test-result" hidden></div>
</div>
</div>
</form>
{# ===== GitHub 配置引导 ===== #}
<div class="card guide-card guide-panel guide-github {% if build_platform == 'gitea' %}panel-hidden{% endif %}">
<div class="card-header">
<svg class="icon brand-github"><use href="#b-github"/></svg> GitHub 首次配置引导(约 5 分钟)
</div>
<div class="card-body">
<ol class="guide-steps">
<li>
<div class="guide-title">Fork 构建仓库</div>
<p>
打开上游仓库 <a href="https://github.com/bryangerlach/rdgen" target="_blank" rel="noopener">github.com/bryangerlach/rdgen
<svg class="icon icon-inline"><use href="#i-external"/></svg></a>,
点击右上角 <strong>Fork</strong> 复制到你自己的 GitHub 账号下。
</p>
</li>
<li>
<div class="guide-title">启用 GitHub Actions</div>
<p>
进入 Fork 后的仓库页面,打开
<a href="https://github.com/{% if gh_user %}{{ gh_user }}{% else %}你的用户名{% endif %}/{% if gh_repo %}{{ gh_repo }}{% else %}rdgen{% endif %}/actions"
target="_blank" rel="noopener">Actions 页面
<svg class="icon icon-inline"><use href="#i-external"/></svg></a>,
如页面提示则点击绿色的 <strong>Enable Actions</strong> 按钮。
</p>
</li>
<li>
<div class="guide-title">创建 Fine-grained 访问令牌(PAT)</div>
<p>
打开
<a href="https://github.com/settings/personal-access-tokens/new" target="_blank" rel="noopener">
Generate new token <svg class="icon icon-inline"><use href="#i-external"/></svg></a>,
按如下设置后生成,并把令牌(github_pat_ 开头)填入上方「GitHub 访问令牌」:
</p>
<ul class="guide-sublist">
<li><strong>Repository access</strong>:选择 Only select repositories,勾选你 Fork 的仓库</li>
<li><strong>Repository permissions</strong>:Actions 设为 <strong>Read and write</strong>,Workflows 设为 <strong>Read and write</strong></li>
<li>Expiration 建议按需设置,过期后需要回到这里更新令牌</li>
</ul>
</li>
<li>
<div class="guide-title">添加两个仓库 Secret</div>
<p>
打开仓库
<a href="https://github.com/{% if gh_user %}{{ gh_user }}{% else %}你的用户名{% endif %}/{% if gh_repo %}{{ gh_repo }}{% else %}rdgen{% endif %}/settings/secrets/actions"
target="_blank" rel="noopener">Settings → Secrets and variables → Actions
<svg class="icon icon-inline"><use href="#i-external"/></svg></a>,
分别 New repository secret:
</p>
<ul class="guide-sublist">
<li><strong>GENURL</strong>:本平台的公网访问地址,须与上方「本平台外部访问地址」一致,例如 https://rdgen.example.com</li>
<li><strong>ZIP_PASSWORD</strong>:一个随机强密码(可用 <code>python3 -c 'import secrets; print(secrets.token_hex(100))'</code> 生成),
须与上方「配置压缩包密码」<strong>完全一致</strong></li>
</ul>
</li>
<li>
<div class="guide-title">保存并验证</div>
<p>填写上方表单后点击「保存配置」,再点击「测试 GitHub 连接」,看到「连接正常」提示即配置完成,可以去客户端定制页提交构建了。</p>
</li>
</ol>
</div>
</div>
{# ===== Gitea 配置引导 ===== #}
<div class="card guide-card guide-panel guide-gitea {% if build_platform != 'gitea' %}panel-hidden{% endif %}">
<div class="card-header">
<svg class="icon"><use href="#b-gitea"/></svg> Gitea 首次配置引导(需自备 Gitea 与构建机)
</div>
<div class="card-body">
<ol class="guide-steps">
<li>
<div class="guide-title">部署 Gitea 1.27+ 并准备构建仓库</div>
<p>
自建一个 Gitea 实例(建议 1.27 或更高版本,低版本不支持运行详情回传),
把本项目仓库推送到该实例(仓库内含 <code>.gitea/workflows</code> 适配工作流)。
<a href="https://docs.gitea.com/usage/actions/quickstart" target="_blank" rel="noopener">
官方 Quick Start <svg class="icon icon-inline"><use href="#i-external"/></svg></a>
</p>
</li>
<li>
<div class="guide-title">启用仓库 Actions</div>
<p>
进入
{% if gitea_server and gitea_owner %}
<a href="{{ gitea_server }}/{{ gitea_owner }}/{{ gitea_repo|default:'rdgen' }}/settings" target="_blank" rel="noopener">
仓库设置页 <svg class="icon icon-inline"><use href="#i-external"/></svg></a>
{% else %}仓库设置页{% endif %}
,勾选 <strong>Enable Repository Actions</strong>。
</p>
</li>
<li>
<div class="guide-title">注册 act_runner 构建机</div>
<p>在仓库 Settings → Actions → Runners 创建注册令牌,并在构建机上安装注册 act_runner:</p>
<ul class="guide-sublist">
<li><strong>Linux</strong>:可用 Docker 模式(需预装 QEMU 以构建 arm64);</li>
<li><strong>Windows</strong>:只能 host 模式直接跑在 Windows 机器上(MSVC/Flutter/vcpkg 环境);</li>
<li><strong>macOS</strong>:只能 host 模式跑在 Apple 硬件上;</li>
<li>runner 自定义标签需与工作流一致:<code>ubuntu-22.04</code>、<code>ubuntu-22.04-arm</code>、<code>windows-2022</code>、<code>macos-14</code>、<code>macos-15-intel</code>。</li>
</ul>
</li>
<li>
<div class="guide-title">配置仓库 Secrets</div>
<p>
在仓库 Settings → Actions → Secrets 中添加
<strong>GENURL</strong>(本平台地址)与 <strong>ZIP_PASSWORD</strong>(与上方完全一致);
如需 Android/macOS 签名,再添加 ANDROID_SIGNING_KEY、MACOS_P12_BASE64、SIGN_BASE_URL、SIGN_API_KEY。
</p>
</li>
<li>
<div class="guide-title">第三方 actions 的网络说明</div>
<p>
工作流使用的第三方 action 默认从 github.com 拉取;纯内网环境请为 runner 配置出网白名单,
或在 Gitea 的 <code>app.ini</code> 配置 <code>[actions].DEFAULT_ACTIONS_URL</code> 走自建 action 镜像。
完整部署步骤(含 vcpkg 文件缓存配置)见项目 setup.md 的「Gitea 部署附录」。
</p>
</li>
<li>
<div class="guide-title">保存并验证</div>
<p>填写上方 Gitea 配置后点击「保存配置」,再点击「测试 Gitea 连接」,看到「连接正常」提示即可提交构建。</p>
</li>
</ol>
</div>
</div>
{# ===== 环境变量方式说明 ===== #}
<div class="card">
<div class="card-header">
<svg class="icon"><use href="#i-server"/></svg> 环境变量方式(可选,继续支持)
</div>
<div class="card-body">
<p class="card-desc">
也可以在 <code>docker-compose.yml</code> 的 environment 中配置以下变量,容器重启后自动生效;
本页保存的同名配置优先级更高(值与环境变量相同时会自动回退,不产生重复覆盖)。
</p>
<div class="table-wrap">
<table class="table">
<thead><tr><th>环境变量</th><th>对应配置</th><th>说明</th></tr></thead>
<tbody>
<tr><td class="mono">BUILD_PLATFORM</td><td>构建平台</td><td>github(默认)或 gitea</td></tr>
<tr><td class="mono">GHUSER</td><td>GitHub 用户名</td><td>Fork 仓库所在账号</td></tr>
<tr><td class="mono">GHBEARER</td><td>GitHub 访问令牌</td><td>Fine-grained PAT,Actions/Workflows 读写</td></tr>
<tr><td class="mono">GENURL</td><td>平台外部访问地址</td><td>两平台共用,供构建机回传产物,公网/内网可访问</td></tr>
<tr><td class="mono">ZIP_PASSWORD</td><td>配置压缩包密码</td><td>两平台共用,须与仓库 Secret 一致</td></tr>
<tr><td class="mono">REPONAME</td><td>GitHub 仓库名称</td><td>默认 rdgen</td></tr>
<tr><td class="mono">GHBRANCH</td><td>GitHub 工作流分支</td><td>默认 master</td></tr>
<tr><td class="mono">PROTOCOL</td><td>平台访问协议</td><td>https(默认)或 http</td></tr>
<tr><td class="mono">SH_SECRET</td><td>GitHub 自托管 Runner 密钥</td><td>仅 GitHub 自托管构建时使用</td></tr>
<tr><td class="mono">WEBHOOK_SECRET</td><td>回调校验密钥</td><td>两平台共用,留空不校验</td></tr>
<tr><td class="mono">GH_PROXY</td><td>GitHub 访问代理</td><td>如 http://host:port,留空直连</td></tr>
<tr><td class="mono">GITEA_SERVER_URL</td><td>Gitea 服务器地址</td><td>如 https://gitea.example.com</td></tr>
<tr><td class="mono">GITEA_TOKEN</td><td>Gitea 访问令牌</td><td>需仓库 Actions 读写权限</td></tr>
<tr><td class="mono">GITEA_OWNER</td><td>Gitea 仓库属主</td><td>用户名或组织名</td></tr>
<tr><td class="mono">GITEA_REPO</td><td>Gitea 仓库名称</td><td>默认 rdgen</td></tr>
<tr><td class="mono">GITEA_BRANCH</td><td>Gitea 工作流分支</td><td>默认 master</td></tr>
<tr><td class="mono">GITEA_PROXY</td><td>Gitea 访问代理</td><td>内网直连通常留空</td></tr>
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
{% block head_extra %}
<script>
document.addEventListener('DOMContentLoaded', function () {
var radios = document.querySelectorAll('input[name=build_platform]');
var btn = document.getElementById('testBuildBtn');
var btnLabel = document.getElementById('testBuildBtnLabel');
var box = document.getElementById('testResult');
function currentPlatform() {
var checked = document.querySelector('input[name=build_platform]:checked');
return checked ? checked.value : 'github';
}
function syncPanels() {
var platform = currentPlatform();
document.querySelectorAll('.panel-gitea, .guide-gitea').forEach(function (el) {
el.classList.toggle('panel-hidden', platform !== 'gitea');
});
document.querySelectorAll('.panel-github, .guide-github').forEach(function (el) {
el.classList.toggle('panel-hidden', platform !== 'github');
});
document.querySelectorAll('[data-platform-card]').forEach(function (card) {
card.classList.toggle('active', card.getAttribute('data-platform-card') === platform);
});
btnLabel.textContent = platform === 'gitea' ? '测试 Gitea 连接' : '测试 GitHub 连接';
}
radios.forEach(function (radio) { radio.addEventListener('change', syncPanels); });
syncPanels();
btn.addEventListener('click', function () {
var platform = currentPlatform();
btn.disabled = true;
box.hidden = false;
box.className = 'test-result is-loading';
box.textContent = platform === 'gitea' ? '正在调用 Gitea API 验证配置…' : '正在调用 GitHub API 验证配置…';
var csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
fetch('{% url "test_build" %}', {
method: 'POST',
headers: {
'X-CSRFToken': csrfToken,
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: 'platform=' + encodeURIComponent(platform),
})
.then(function (r) { return r.json().then(function (j) { return {ok: r.ok && j.ok, message: j.message}; }); })
.then(function (res) {
box.className = 'test-result ' + (res.ok ? 'is-ok' : 'is-bad');
box.textContent = res.message;
})
.catch(function () {
box.className = 'test-result is-bad';
box.textContent = '测试请求失败,请检查网络或服务日志。';
})
.finally(function () {
btn.disabled = false;
});
});
});
</script>
{% endblock %}