Some checks failed
Android CI Build / check (push) Has been cancelled
Android CI Build / package-apks (push) Has been cancelled
Docs Deploy / build (push) Has been cancelled
Module Market Check / Validate modules/ (push) Has been cancelled
Module Market Publish / Generate submissions.json (push) Has been cancelled
Docs Deploy / deploy (push) Has been cancelled
- Package rename com.webtoapp -> br.com.drukstech.codeapp - Product rename WebToApp/web-to-app -> DruksCode/drukscode - Design system Wta* -> Dkc* - applicationId br.com.drukstech.codeapp (.play for gplay flavor) - rootProject.name DruksCode - Fresh git history (upstream kept as remote for sync)
450 lines
22 KiB
Markdown
450 lines
22 KiB
Markdown
# Contributing to DruksCode
|
||
|
||
Thanks for taking the time to help. DruksCode moves fastest when contributions
|
||
stay **small and well-scoped** — pick one of the lanes below and ignore the
|
||
rest.
|
||
|
||
> **English** · [简体中文](#贡献-webtoapp中文)
|
||
|
||
This guide targets **DruksCode 2.6.0** (`versionCode 62`).
|
||
|
||
---
|
||
|
||
## Lanes
|
||
|
||
| You want to… | Go to | Effort |
|
||
| --- | --- | --- |
|
||
| Publish a JS/CSS module to the in-app **Module Market** | [`modules/README.md`](../modules/README.md) | hours |
|
||
| File a bug, request a feature, or ask a question | [GitHub Issues](https://github.com/shiaho777/web-to-app/issues) | minutes |
|
||
| Fix a bug or build a feature in the Android client | This guide ↓ | days |
|
||
|
||
If you're not sure which lane fits, open an issue or a discussion first. There
|
||
is no need to write code before there's agreement on the shape of the change.
|
||
|
||
---
|
||
|
||
## Module Market submissions
|
||
|
||
The fastest way to ship something useful to every DruksCode user is to publish
|
||
a module. The canonical Module Market guide lives in
|
||
[`modules/README.md`](../modules/README.md). Use that file for the full
|
||
schema, field rules, reviewer checklist, and CI validation details. The short
|
||
version here is only meant to help you pick the right contribution lane:
|
||
|
||
1. Fork the repo.
|
||
2. Add `modules/<your-module>/module.json` and `main.js` (plus `style.css` if
|
||
you need CSS).
|
||
3. Add an entry to `modules/registry.json`.
|
||
4. Open a PR.
|
||
|
||
The market has **no backend**. Clients read `registry.json` and
|
||
`submissions.json`, and only merged modules show up in the catalog. Module
|
||
changes are validated in CI by `.github/scripts/ci/validate_modules.py`:
|
||
|
||
```bash
|
||
python3 .github/scripts/ci/validate_modules.py
|
||
```
|
||
|
||
---
|
||
|
||
## Code contributions
|
||
|
||
> The canonical working guide for AI coding agents and deep code
|
||
> contributors is [`AGENTS.md`](../AGENTS.md) — it documents how the editor,
|
||
> export pipeline, shell template, and runtime connect, the dual preview/export
|
||
> paths, config-field drift rules, packaging constraints, and common change
|
||
> recipes. Read it before any non-trivial change to the build, shell sync,
|
||
> export packaging, or config fields.
|
||
|
||
### Before you write code
|
||
|
||
- Search [issues](https://github.com/shiaho777/web-to-app/issues) for prior
|
||
discussion of the same idea.
|
||
- For non-trivial changes, open an issue first describing the problem and the
|
||
approach you have in mind. This is much cheaper than rewriting after review.
|
||
- **Avoid adding new dependencies.** The lists in `app/build.gradle.kts` and
|
||
`shell/build.gradle.kts` are intentionally restrained — the project signs and
|
||
packages APKs in-process, and the shell template pins `targetSdk = 28` on
|
||
purpose because generated apps rely on fork+exec native runtimes. New
|
||
dependencies need a strong justification, and host-only dependencies must
|
||
never leak into the shell template.
|
||
|
||
### Local setup
|
||
|
||
You'll need:
|
||
|
||
- Android Studio Hedgehog or newer
|
||
- JDK 17
|
||
- The Gradle wrapper pins Gradle 9.4.1 — no system Gradle install required
|
||
|
||
```bash
|
||
git clone https://github.com/shiaho777/web-to-app.git
|
||
cd drukscode
|
||
./gradlew assembleDebug
|
||
```
|
||
|
||
The repo has three Gradle modules: **`app`** (the full builder and host),
|
||
**`shell`** (the runtime template embedded in generated APKs), and
|
||
**`clone-host`** (the host code used by app cloning). Shared runtime code is
|
||
authored **only** under `app/` and synchronized into `shell/` at build time
|
||
(`shell/build/generated/` — never edit `shell/src` by hand; it is
|
||
regenerated and partly git-ignored).
|
||
|
||
Run the checks before submitting:
|
||
|
||
```bash
|
||
./gradlew :app:compileStandardDebugKotlin -x syncCloneHostDex --no-configuration-cache
|
||
./gradlew :app:testStandardDebugUnitTest --no-configuration-cache -PskipShellTemplateSync=true
|
||
./gradlew :app:checkConfigFieldDrift --no-configuration-cache
|
||
```
|
||
|
||
If you touched shell-synced runtime code or export packaging, also rebuild the
|
||
template you touched:
|
||
|
||
```bash
|
||
./gradlew :shell:assembleRelease :app:syncShellTemplateApk --no-configuration-cache
|
||
```
|
||
|
||
> Native code (`node_launcher`, `go_exec_loader`, the APK optimizer) builds
|
||
> via CMake per-ABI and needs the Android NDK + CMake installed through the
|
||
> SDK Manager. CI installs `cmake;3.22.1` and `ndk;28.2.13676358`.
|
||
|
||
### Where things live
|
||
|
||
| Area | Path |
|
||
| --- | --- |
|
||
| App types & central config (`AppType`, `WebApp`) | `app/src/main/java/br/com/drukstech/codeapp/data/model/` |
|
||
| On-device APK builder / signer | `app/src/main/java/br/com/drukstech/codeapp/core/apkbuilder/` |
|
||
| Server runtimes (Node / PHP / Python / Go / WordPress) | `app/src/main/java/br/com/drukstech/codeapp/core/{nodejs,php,python,golang,wordpress}/` |
|
||
| WebView engine, native bridge, fingerprint disguise | `app/src/main/java/br/com/drukstech/codeapp/core/{webview,engine,appearance}/` |
|
||
| Shell config + generated-APK entry points | `app/src/main/java/br/com/drukstech/codeapp/core/shell/` |
|
||
| Preview players (`ui/gallery/`, `ui/media/`) vs packaged players (`ui/shell/`) | `app/src/main/java/br/com/drukstech/codeapp/ui/` |
|
||
| Extension modules, Module Market, Agent | `app/src/main/java/br/com/drukstech/codeapp/core/{extension,market,agent}/` |
|
||
| Compose UI screens & design system | `app/src/main/java/br/com/drukstech/codeapp/ui/` |
|
||
| DI graph (source of truth) | `app/src/main/java/br/com/drukstech/codeapp/di/AppModule.kt` |
|
||
|
||
### Preview ≠ export: the rule behind most rejections
|
||
|
||
The host app (preview) and generated APKs (export) run **different code**:
|
||
|
||
| | Preview (`:app`) | Exported APK |
|
||
| --- | --- | --- |
|
||
| UI | `ui/gallery/`, `ui/media/`, `WebViewManager` live | `ui/shell/*` synced copy |
|
||
| Config | Editor / in-memory models | JSON assets via `ShellModeManager` |
|
||
|
||
A feature is done only when it works on **both** paths. Concretely, an editor
|
||
setting that must affect generated APKs has to flow through the full chain —
|
||
model → `ApkConfig` JSON → shell config → shell-synced runtime — and a
|
||
player-screen behavior has to be implemented in **both** the preview and the
|
||
shell composable. Three gates enforce this; run them, don't argue with them:
|
||
|
||
- `checkConfigFieldDrift` — model/JSON/shell field names must match
|
||
(Gson silently drops mismatches).
|
||
- `WebViewConfigBooleanCoverageTest` — every new `WebViewConfig` Boolean must
|
||
be listed in `flipAllBooleans()` and survive the export round-trip.
|
||
- `ShellUiParityTest` — every model field read by host player UI must also be
|
||
read by shell player UI (or carry an explicit `allow` reason). Add your new
|
||
per-type player pair to it.
|
||
|
||
### Coding conventions
|
||
|
||
DruksCode leans on the Kotlin and Jetpack Compose patterns already in the
|
||
codebase. A few rules worth calling out:
|
||
|
||
- **Comments explain *why*, not *what*.** Non-obvious decisions, cross-file
|
||
contracts, and issue references (`#781`) get a short comment; clear names
|
||
and small functions carry the rest. Don't narrate readable code.
|
||
- **Build new UI on the Dkc design system.** Everything renders through
|
||
`br.com.drukstech.codeapp.ui.design`. The older `Premium*` / `Enhanced*` / `Settings*`
|
||
components are retained as permanent alias layers over the Dkc internals —
|
||
don't add new ones, and you don't need to rip them out. A build-time audit
|
||
(`.github/scripts/audit_ui_design_system.py`, wired into `build.gradle.kts`) tracks
|
||
legacy UI debt against `.github/scripts/ui_design_allowlist.txt`.
|
||
- **Reuse the design tokens** in `ui/design/DkcTokens.kt` for spacing, radius,
|
||
alpha, and elevation. Don't hard-code numbers. Editor config cards share one
|
||
layout grammar (see `AGENTS.md` recipe 12) — copy the neighbouring cards,
|
||
don't invent your own, and verify on the emulator, not just by compiling.
|
||
- **Strings must cover all 10 supported languages.** UI copy lives in
|
||
`core/i18n/Strings.kt` (facade `object Strings` + in-file `StringsA`…`StringsE`,
|
||
split only for the JVM constant pool). Supported: Chinese, English, Arabic,
|
||
Portuguese, Spanish, French, German, Russian, Japanese, Korean.
|
||
Every new or changed user-visible `when (Strings.lang)` block **must** have
|
||
real translations for **all 10** branches with no `else ->` — do not leave
|
||
pt/es/fr/de/ru/ja/ko as English placeholders. Brand names and pure format
|
||
tokens may match English. If you truly cannot translate one language, use
|
||
English there and flag it in the PR.
|
||
- **Never load user-visible text from `R.string`.** Resource files only cover
|
||
zh/en/ar, so lookups silently fall back to Chinese for the other 7 locales.
|
||
`R.string` is reserved for non-localised resources.
|
||
- **No new top-level singletons** unless you discuss it first. The DI graph in
|
||
`di/AppModule.kt` is the source of truth.
|
||
- **The Native Bridge is capability-gated.** Any method exposed to web content
|
||
via `@JavascriptInterface` must be guarded by the per-capability allow-list
|
||
(`NativeBridgeCapabilities`). Never expose a native capability to arbitrary
|
||
pages without a gate. PRs that bypass this will be rejected.
|
||
- **Preview and packaged runtime are two paths.** See *Preview ≠ export*
|
||
above. Shared runtime sources are authored only under `app/` and synced into
|
||
`shell/` at build time — do not hand-edit anything under `shell/src`.
|
||
- **Avoid catching `Exception` to silence errors.** If recovery is impossible,
|
||
log via `AppLogger` and re-throw or return a failed `Result`.
|
||
|
||
### Security
|
||
|
||
Anything touching the WebView, file IO, APK signing, or the native bridge has
|
||
downstream impact on **every generated app**, so it gets extra scrutiny.
|
||
Specifically, PRs will be declined if they:
|
||
|
||
- store or expose credentials/secrets to web content,
|
||
- widen the native surface exposed to arbitrary pages without a capability
|
||
gate,
|
||
- weaken APK signing, isolation, or the fingerprint-disguise defaults,
|
||
- bundle unrelated changes inside a large diff.
|
||
|
||
### Commit messages
|
||
|
||
We don't enforce Conventional Commits, but a clear subject line and a wrapped
|
||
body that explains *why* the change exists make reviews much faster. Example:
|
||
|
||
```
|
||
ModuleMarket: cache registry.json for an hour
|
||
|
||
Repeatedly hitting raw.githubusercontent.com on every screen open is wasteful
|
||
and triggers GitHub's anonymous rate limit on slow connections. Cache the
|
||
parsed registry under cache/module_market/ and treat anything fresher than
|
||
an hour as authoritative; the refresh button always bypasses the cache.
|
||
```
|
||
|
||
### Pull requests
|
||
|
||
- Branch from `main`. Keep PRs focused — one logical change per PR.
|
||
- **Write Issues and PRs in English** — titles, bodies, and review threads.
|
||
- Describe the user-visible effect in the PR body, not just the code change.
|
||
- The standard loop is Issue → branch → PR (`Fixes #N`) → green CI → merge.
|
||
Issues close on merge, never on PR open or red CI.
|
||
- If your PR touches the build system, native code, or APK packaging, attach
|
||
the output of the template rebuild above (or note the failure if it fails
|
||
on your machine).
|
||
- CI runs on every PR. A green CI is required before merge.
|
||
- Never commit secrets, keystores, `local.properties`, or IDE/cache junk.
|
||
|
||
### Reviewer expectations
|
||
|
||
Maintainer reviews look for:
|
||
|
||
- **Correctness.** Does the change do what the PR description says? Was it
|
||
verified by execution (tests, build output), not just by reading?
|
||
- **Safety.** See *Security* above.
|
||
- **Scope discipline.** Drive-by refactors expand the review surface. Land
|
||
them in a separate PR.
|
||
- **Style fit.** See *Coding conventions* above.
|
||
- **Both paths.** Preview-only features and export-only wiring are the two
|
||
classic failure modes — see *Preview ≠ export* above.
|
||
|
||
---
|
||
|
||
## Code of conduct
|
||
|
||
Feedback is required to be precise. "This code is garbage" is acceptable only
|
||
when accompanied by which code, why, and what would be less so. The maintainer
|
||
(**shiaho**) has on file a standing waiver covering criticism of himself, his
|
||
judgment, and his life choices. Praise unaccompanied by a working patch is
|
||
logged and otherwise disregarded.
|
||
|
||
---
|
||
|
||
<a id="贡献-webtoapp中文"></a>
|
||
## 贡献 DruksCode(中文)
|
||
|
||
非常感谢你愿意花时间。DruksCode 的迭代速度取决于"小而聚焦"的贡献——下面三条路
|
||
里挑一条走,其他的先忽略。
|
||
|
||
本指南对应 **DruksCode 2.6.0**(`versionCode 62`)。
|
||
|
||
### 你想做什么?
|
||
|
||
| 你想…… | 路径 | 投入 |
|
||
| --- | --- | --- |
|
||
| 给应用内的 **模块市场** 提交一个 JS/CSS 模块 | [`modules/README.md`](../modules/README.md) | 几小时 |
|
||
| 报 Bug、提 Feature、问问题 | [GitHub Issues](https://github.com/shiaho777/web-to-app/issues) | 几分钟 |
|
||
| 修 Bug 或在 Android 客户端里做新功能 | 见下方代码贡献小节 | 几天 |
|
||
|
||
不确定走哪条,先开 issue 或 discussion——动手前对齐方向,比写完再返工便宜
|
||
得多。
|
||
|
||
### 模块市场贡献
|
||
|
||
让你的工作触达每一个用户最快的方式就是提一个模块。Schema、审核 Checklist 和
|
||
CI 校验细节的主文档是 [`modules/README.md`](../modules/README.md)。这里仅保
|
||
留一个极简入口,方便你先判断自己是不是走这条贡献路线:
|
||
|
||
1. Fork 本仓库
|
||
2. 新建 `modules/<你的模块>/module.json` 和 `main.js`(需要 CSS 时再加
|
||
`style.css`)
|
||
3. 在 `modules/registry.json` 里加一行索引
|
||
4. 提 PR
|
||
|
||
市场**没有后端**。客户端读取 `registry.json` 和 `submissions.json`,只有已合
|
||
并的模块才会在市场出现。模块改动会经过 CI 的
|
||
`.github/scripts/ci/validate_modules.py` 校验,提 PR 前建议先本地跑:
|
||
|
||
```bash
|
||
python3 .github/scripts/ci/validate_modules.py
|
||
```
|
||
|
||
### 代码贡献
|
||
|
||
> 面向 AI 编码助手与深度代码贡献者的权威工作指南是
|
||
> [`AGENTS.md`](../AGENTS.md) —— 它讲清了编辑器、导出流水线、shell 模板与运行时
|
||
> 之间如何连接,以及双路径预览 / 导出、配置字段漂移规则、打包约束和常见改动
|
||
> 配方。对构建、shell 同步、导出打包或配置字段的任何非平凡改动,动手前请先读。
|
||
|
||
**动手前**
|
||
|
||
- 在 [issues](https://github.com/shiaho777/web-to-app/issues) 里先搜一下
|
||
类似讨论
|
||
- 较大的改动请先开 issue 说明要解决的问题和方案
|
||
- **谨慎引入新依赖**。`app/build.gradle.kts` 与 `shell/build.gradle.kts` 的依
|
||
赖列表刻意保持精简——本项目全程在设备内签名打包 APK,shell 模板也特意把
|
||
`targetSdk` 锁在 28,因为生成应用依赖 `fork`、`exec` 原生运行时。新依赖需
|
||
要充分理由,且宿主专用依赖绝不能漏进 shell 模板。
|
||
|
||
**本地环境**
|
||
|
||
- Android Studio Hedgehog 或更新版本
|
||
- JDK 17
|
||
- Gradle wrapper 已锁定 Gradle 9.4.1,无需系统安装 Gradle
|
||
|
||
```bash
|
||
git clone https://github.com/shiaho777/web-to-app.git
|
||
cd drukscode
|
||
./gradlew assembleDebug
|
||
```
|
||
|
||
仓库有三个 Gradle 模块:**`app`**(完整构建器和宿主)、**`shell`**(嵌入生
|
||
成 APK 的运行时模板)和 **`clone-host`**(应用克隆使用的宿主代码)。共享运
|
||
行时代码以 `app/` 为唯一事实来源,构建时同步到 `shell/`(`shell/build/` 下,
|
||
不要手改 `shell/src`——它是再生成的产物,部分被 git 忽略)。
|
||
|
||
提交前请跑通:
|
||
|
||
```bash
|
||
./gradlew :app:compileStandardDebugKotlin -x syncCloneHostDex --no-configuration-cache
|
||
./gradlew :app:testStandardDebugUnitTest --no-configuration-cache -PskipShellTemplateSync=true
|
||
./gradlew :app:checkConfigFieldDrift --no-configuration-cache
|
||
```
|
||
|
||
动到 shell 同步的运行时代码或导出打包,还要重建你碰过的模板:
|
||
|
||
```bash
|
||
./gradlew :shell:assembleRelease :app:syncShellTemplateApk --no-configuration-cache
|
||
```
|
||
|
||
> 原生代码(`node_launcher`、`go_exec_loader`、APK 优化器)按 ABI 经 CMake
|
||
> 编译,需要通过 SDK Manager 安装 Android NDK + CMake。CI 安装的是
|
||
> `cmake;3.22.1` 与 `ndk;28.2.13676358`。
|
||
|
||
**代码大致位置**
|
||
|
||
| 区域 | 路径 |
|
||
| --- | --- |
|
||
| 应用类型与核心配置(`AppType`、`WebApp`) | `app/src/main/java/br/com/drukstech/codeapp/data/model/` |
|
||
| 设备端 APK 打包 / 签名 | `app/src/main/java/br/com/drukstech/codeapp/core/apkbuilder/` |
|
||
| 服务端运行时(Node / PHP / Python / Go / WordPress) | `app/src/main/java/br/com/drukstech/codeapp/core/{nodejs,php,python,golang,wordpress}/` |
|
||
| WebView 引擎、原生桥、指纹伪装 | `app/src/main/java/br/com/drukstech/codeapp/core/{webview,engine,appearance}/` |
|
||
| Shell 配置与生成 APK 入口 | `app/src/main/java/br/com/drukstech/codeapp/core/shell/` |
|
||
| 预览播放器(`ui/gallery/`、`ui/media/`)vs 打包播放器(`ui/shell/`) | `app/src/main/java/br/com/drukstech/codeapp/ui/` |
|
||
| 扩展模块、模块市场、Agent | `app/src/main/java/br/com/drukstech/codeapp/core/{extension,market,agent}/` |
|
||
| Compose UI 与设计系统 | `app/src/main/java/br/com/drukstech/codeapp/ui/` |
|
||
| DI 依赖图(单一事实来源) | `app/src/main/java/br/com/drukstech/codeapp/di/AppModule.kt` |
|
||
|
||
**预览 ≠ 导出:大多数打回的原因**
|
||
|
||
宿主应用(预览)和生成的 APK(导出)跑的是**两套代码**:
|
||
|
||
| | 预览(`:app`) | 导出的 APK |
|
||
| --- | --- | --- |
|
||
| 界面 | `ui/gallery/`、`ui/media/`、实时 `WebViewManager` | `ui/shell/*` 的同步副本 |
|
||
| 配置 | 编辑器 / 内存模型 | 经 `ShellModeManager` 读取的 JSON 资源 |
|
||
|
||
一个功能只有两边都通才算做完。编辑器开关要影响生成 APK,必须走完整条
|
||
链——模型 → `ApkConfig` JSON → shell 配置 → shell 同步的运行时代码;而播放
|
||
器界面的行为要在预览和壳两套 composable 里各实现一遍。三道门禁负责兜底,
|
||
跑过它们,别跟它们争:
|
||
|
||
- `checkConfigFieldDrift`——模型 / JSON / shell 字段名必须一致(Gson 会静默
|
||
丢掉对不上的字段)。
|
||
- `WebViewConfigBooleanCoverageTest`——`WebViewConfig` 每新增一个 Boolean 都
|
||
必须进 `flipAllBooleans()` 并走完导出往返。
|
||
- `ShellUiParityTest`——宿主播放器读的每个模型字段,壳播放器也必须读(或写
|
||
明 `allow` 理由)。新增每类播放器时照样子扩展。
|
||
|
||
**代码风格**
|
||
|
||
- **注释解释 *为什么*,不复述 *干了什么*。** 反直觉的决策、跨文件约定、
|
||
issue 引用(`#781`)值得一句短注释;命名清晰的小函数不需要解说。不要给
|
||
易读的代码写旁白。
|
||
- **新 UI 一律构建在 Dkc 设计系统之上**——所有界面通过 `br.com.drukstech.codeapp.ui.design`
|
||
渲染。旧的 `Premium*` / `Enhanced*` / `Settings*` 组件作为 Dkc 内部实现的
|
||
永久别名层保留——不要再新增,也无需强行替换。构建期有一个审计脚本
|
||
(`.github/scripts/audit_ui_design_system.py`,接进 `build.gradle.kts`)按
|
||
`.github/scripts/ui_design_allowlist.txt` 跟踪历史 UI 债务。
|
||
- 复用 `ui/design/DkcTokens.kt` 里的设计 token(间距、圆角、透明度、高度),
|
||
别硬编码数字。编辑器配置卡片共用一套排版语法(见 `AGENTS.md` recipe 12)——
|
||
照抄相邻卡片,不要自创,跑模拟器验效果,不要只编译。
|
||
- **字符串必须覆盖全部 10 种已支持语言**:文案在 `core/i18n/Strings.kt`
|
||
(facade `object Strings` + 同文件 `StringsA`…`StringsE`,拆分只为常量池)。
|
||
已支持:中 / 英 / 阿 / 葡 / 西 / 法 / 德 / 俄 / 日 / 韩。
|
||
新增或修改面向用户的 `when (Strings.lang)` **必须**为 10 个分支写真实翻译,
|
||
且不许写 `else ->`;禁止把 pt/es/fr/de/ru/ja/ko 继续当英文占位。品牌名、
|
||
纯格式符可与英文相同。某语实在不会翻可暂填英文并在 PR 标明。
|
||
- **面向用户的文案绝不用 `R.string`。** 资源文件只有 zh/en/ar 三套,其他 7
|
||
语会静默回落到中文。`R.string` 只保留给无需本地化的资源。
|
||
- 引入新的全局单例前请先讨论;`di/AppModule.kt` 是单一事实来源
|
||
- **原生桥是按能力门禁的**:任何通过 `@JavascriptInterface` 暴露给网页的方法,
|
||
都必须经过逐能力白名单(`NativeBridgeCapabilities`)。绝不要在没有门禁的
|
||
情况下把原生能力暴露给任意页面。绕过门禁的 PR 会被拒
|
||
- **预览和打包运行时是两条路径**:见上文《预览 ≠ 导出》。共享运行时代码只改
|
||
`app/`,构建时同步进 `shell/`;不要手改 `shell/src` 下的任何东西
|
||
- 不要 catch 然后吞掉异常;用 `AppLogger` 记录后重新抛出或返回失败的 `Result`
|
||
|
||
**安全**
|
||
|
||
动到 WebView、文件 IO、APK 签名或原生桥的改动会影响**每一个生成出来的
|
||
应用**,因此审核更严。出现以下情况的 PR 会被拒:
|
||
|
||
- 把凭据 / 密钥存储或暴露给网页内容
|
||
- 在没有能力门禁的情况下扩大暴露给任意页面的原生面
|
||
- 削弱 APK 签名、隔离或指纹伪装的默认强度
|
||
- 在一个大 diff 里夹带不相关的改动
|
||
|
||
**Commit 消息**
|
||
|
||
不强制 Conventional Commits,但请把"为什么"写进正文。示例见英文段。
|
||
|
||
**Pull Request**
|
||
|
||
- 从 `main` 分出分支,每个 PR 只解决一件事
|
||
- **Issue 与 PR 请用英文写**——标题、正文、评审讨论
|
||
- PR 描述写"用户看得到的效果",不只是代码 diff
|
||
- 标准流程是 Issue → 分支 → PR(`Fixes #N`)→ CI 变绿 → 合并。
|
||
Issue 只在合并时关闭,开 PR 时不关、CI 红时不关
|
||
- 改动涉及构建系统、原生代码或 APK 打包时,附上上面模板重建命令的结果
|
||
- CI 必须绿色才会合并
|
||
- 不要提交密钥、keystore、`local.properties` 或 IDE / 缓存垃圾
|
||
|
||
**Review 标准**
|
||
|
||
- **正确性**——是否真的做了 PR 描述里写的事;是否经过执行验证(测试、
|
||
构建产物),而不只是"读起来对"
|
||
- **安全**——见上面《安全》小节
|
||
- **聚焦**——顺手做的重构请单独发 PR
|
||
- **风格**——参考上面那条
|
||
- **两条路径**——只在预览生效的功能和只在导出接线的配置是两类经典翻车——见
|
||
上文《预览 ≠ 导出》
|
||
|
||
### 行为准则
|
||
|
||
反馈须精准。"这代码是坨屎"仅在同时说明"哪段代码、为何如此、怎样才不至于"
|
||
时方予受理。维护者(**shiaho**)已就针对其本人、其判断力及其人生选择的批评
|
||
出具长期豁免一份并存档。未附可用补丁的赞美,予以记录,余不受理。
|