diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 345036d4..8de2b1f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,9 +8,9 @@ name: CI on: push: - branches: [main, dev] + branches: [main, beta] pull_request: - branches: [main, dev] + branches: [main, beta] jobs: cross-platform: diff --git a/CLAUDE.md b/CLAUDE.md index d8a70984..5864b121 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -105,6 +105,28 @@ Push a `v*-tauri` tag → `.github/workflows/release-tauri.yml` builds macOS arm When bumping versions, update **both** `version` fields: `openless-all/app/package.json` and `openless-all/app/src-tauri/tauri.conf.json` (and `Cargo.toml`). +### Branch & release-channel workflow + +Two-channel branching. **Branch name = release channel.** + +- **`beta`** — **Beta channel** (开发版). Default branch, integration buffer. **All PRs target `beta`** (never `main`). Beta builds may exist but are not pushed to general users — only opt-in users on the Beta channel see them. +- **`main`** — **Stable channel** (正式版). Always-releasable. Updated only by `beta → main` merges performed by maintainers after a two-platform smoke build. Release tags `v-tauri` are pushed on `main` and trigger `release-tauri.yml` (tag-driven; unaffected by branch renames). + +Per-PR contract: + +- Run the change locally on your target platform before opening the PR (build green + manual verification of the affected feature). +- `pr-agent.yml` runs one AI review pass per PR — treat it as advisory, do not iterate on it. +- Keep AI rework rounds tight (1–2). If a fix resists, escalate to a human or restart with fresh context. +- `ci.yml` runs on push/PR for both `main` and `beta`; no extra wiring needed when adding new branches off `beta`. + +For maintainers: + +- Merge `beta → main` only after the two-platform (macOS + Windows) smoke build passes. **Beta work must not leak to Stable** — that gate exists for a reason. +- Tag `v-tauri` **on `main`**, not on `beta`. The release workflow keys off the tag, but tagging on `main` keeps the release commit linear with the always-releasable line. +- Avoid direct pushes to `main` outside the `beta → main` merge — it bypasses the smoke-test gate. + +Channel distribution (in progress): per-channel updater endpoints + a Settings toggle for "join Beta channel" are tracked as a separate change. Until that lands, every release reaches every user; treat all `v*-tauri` tags as Stable-grade for now and avoid tagging anything from `beta` directly. + ## Repo conventions - **Comments, log messages, user-facing strings, and most docs are in Simplified Chinese.** UI strings additionally route through `react-i18next` (`src/i18n/{zh-CN,en}.ts`) so we ship English alongside; `zh-CN.ts` is source of truth. diff --git a/README.md b/README.md index 442fccbd..84c334fe 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,37 @@ Logs: `~/Library/Logs/OpenLess/openless.log` (macOS) / `%LOCALAPPDATA%\OpenLess\ **Windows build** — see [`openless-all/README.md`](openless-all/README.md) for MSVC vs GNU/MinGW routes. +## Contributing workflow + +OpenLess uses a two-channel branching model. + +- **`beta`** — the **Beta channel**. Default branch and integration buffer; all in-progress development lands here. Beta builds may exist but are **not pushed to regular users** — they only reach people who explicitly opt into the Beta channel. +- **`main`** — the **Stable channel (正式版)**. Always-releasable. The build everyone gets by default. + +```text +your fork / topic branch + │ (test locally on your target platform first) + ▼ + PR → beta ← AI review (one pass, advisory only) + │ ← maintainer lightweight glance (scope, cross-module impact) + ▼ + merged into beta + │ (periodically, after a two-platform smoke build) + ▼ + merged into main → tag `v-tauri` → release CI → Stable users +``` + +Rules of thumb: + +- **Open PRs against `beta`, never against `main`.** GitHub already defaults the base branch to `beta` for new PRs. +- **Verify the change on your target platform before opening the PR** — build green is necessary, manual verification is required. +- **AI review runs once per PR and is advisory.** Don't loop on it. Apply your judgment. +- **Keep AI rework rounds tight (1–2).** If a fix resists, ask a human or restart with fresh context — multi-round AI back-and-forth tends to do more harm than good here. +- **Beta work must not leak to Stable.** `main` only receives merges from `beta`, performed by maintainers after a successful two-platform smoke build. No direct pushes to `main`. +- **Stable releases are cut from `main`** by pushing a `v-tauri` tag — see the maintainer release checklist below. + +Beta release distribution (opt-in, not yet wired): Beta builds are intended for users who consciously join the Beta channel; the in-app updater currently treats every release as Stable, and a follow-up change will introduce per-channel updater endpoints + a Settings toggle. + ## Credentials Credentials live in the OS credential vault (service = `com.openless.app`): macOS Keychain, Windows Credential Manager, or Linux keyring. A legacy plaintext JSON file is read only as a migration source and removed after a successful vault write: diff --git a/README.zh.md b/README.zh.md index 694d4d0f..3200da61 100644 --- a/README.zh.md +++ b/README.zh.md @@ -211,6 +211,37 @@ npm run build **Windows 构建** — MSVC 和 GNU/MinGW 两种路线详见 [`openless-all/README.md`](openless-all/README.md)。 +## 贡献流程 + +OpenLess 采用 **Beta / 正式版** 双渠道分支模型。 + +- **`beta`** —— **Beta 渠道(开发版)**。默认分支,也是日常集成缓冲区;所有进行中的开发都先落到这里。Beta 渠道可以直接出包,但**不会推送给普通用户**——只有主动切换到 Beta 渠道的用户才会拿到 Beta 包。 +- **`main`** —— **正式版渠道(Stable)**。始终保持可发布状态,普通用户默认拿到的就是这条线上的版本。 + +```text +你的 fork / topic 分支 + │ (先在目标平台本地自测通过) + ▼ + PR → beta ← AI Review(一次性,仅供参考) + │ ← 维护者轻量过一眼(范围、跨模块影响) + ▼ + 合入 beta + │ (定期或里程碑节点,跑双端冒烟测试) + ▼ + 合入 main → 打 tag `v<版本>-tauri` → Release CI → 推给正式版用户 +``` + +核心规则: + +- **PR 一律打到 `beta`,不要直接打到 `main`。** GitHub 上新建 PR 的 base 已默认是 `beta`。 +- **开 PR 前先在目标平台跑通功能** —— build 绿是底线,必须做人工验证。 +- **AI Review 每个 PR 只跑一轮,结果仅供参考。** 不要围绕它反复改,最终判断权在贡献者和维护者手里。 +- **AI 改 Review 意见控制在 1–2 轮。** 卡住了直接换人工或重开对话上下文,避免多轮 AI 越改越乱。 +- **Beta 不能溢出到正式版。** `main` 只接收来自 `beta` 的合并,由维护者在双端冒烟测试通过后执行;任何人不要直接 push `main`。 +- **正式版 Release 从 `main` 切出**,通过推送 `v<版本>-tauri` tag 触发,详见下方"维护者:发布检查"。 + +Beta 包的分发(opt-in,尚未接入):Beta 包面向主动加入 Beta 渠道的用户;当前 App 内 updater 把所有 release 都当作正式版处理,后续会在设置页加入"加入 Beta 渠道"开关,并把 updater endpoint 按渠道拆开。 + ## 凭据 凭据保存在系统凭据库(service = `com.openless.app`):macOS Keychain、Windows Credential Manager 或 Linux keyring。旧版明文 JSON 只作为迁移来源读取,成功写入系统凭据库后会被删除: