Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ce9979ce5
|
||
|
|
06174bbd06
|
||
|
|
101a3db393
|
||
|
|
64a531f999
|
||
|
|
7f9236777f
|
||
|
|
92ebed0f34
|
||
|
|
e62584b31f
|
||
|
|
39026fd41e
|
||
|
|
81c253b86e
|
||
|
|
f4d5fa4013
|
||
|
|
7d22dc14a5
|
||
|
|
9f15d42c2c
|
@@ -18,16 +18,16 @@ This fork carries the OmarchyCN China-integration layer on top of upstream `base
|
||||
- `bin/omarchycn` routes to `omarchy cn <command>`; all cn commands are `bin/omarchy-cn-*` and follow the upstream bin conventions (metadata, helpers, `$OMARCHY_PATH` — bootstrap exceptions: the overlay installer resolves its own checkout, and `omarchy-cn-convert` / `omarchy-cn-revert` are curl-able standalone scripts that default `OMARCHY_PATH` because they run before/while the cn tree exists)
|
||||
- Convert/revert: `omarchy-cn-convert` turns a vanilla package-based Omarchy into OmarchyCN (registry key + [omarchycn] repo, `--ask=4` package swap to the cn-built omarchy-dev/omarchy-settings-dev published by `packages/publish-cn-packages.sh`, [omarchy] mirror line, zh_CN locale, fcitx5 seeding, plymouth rebrand) recording pre-state in `/var/lib/omarchycn/convert-state`; `omarchy-cn-revert` restores that state; checkout installs are refused toward the overlay
|
||||
- `cn/` holds the data layer: `mirrors.json`, `dev-mirrors.json`, `apps.json`, `registry/` (AI providers/harnesses/compatibility), `fcitx5/`, `fontconfig/`, `keys/`, `lib/` (sourced helpers), `release` (cn release number)
|
||||
- cn migrations live in `cn/migrations/*.sh`, run by `omarchy-cn-update` with per-file completion markers under `~/.local/state/omarchycn/`
|
||||
- cn migrations live in `cn/migrations/*.sh`, run by `omarchy-cn-migrate` with per-file completion markers under `~/.local/state/omarchycn/`; `bin/omarchy-migrate` calls it after the upstream migrations, and `omarchy-cn-update` serves both install forms (overlay: git pull + reinstall + migrate; package: exec `omarchy-update`)
|
||||
- Packaging: `packages/omarchy-pkgs-cn.patch` must be applied to the sibling `omarchy-pkgs` checkout so `omarchy-dev` ships `cn/`; keyring in `packages/omarchycn-keyring/`
|
||||
- Upstream repo mirror: `packages/sync-omarchy-repo.sh` + `.gitea/workflows/pkg-repo-sync.yml` mirror the upstream `[omarchy]` stable channel into the Gitea Arch registry every 6h; `pacman-stable.conf` lists the mirror first (upstream fallback), clients must trust the registry key (install import + cn migration), `omarchycn doctor mirror --fix` re-heals the line; see `docs/pacman-repo.md`
|
||||
- ISO: `packages/omarchy-iso-cn.patch` must be applied to the sibling `omarchy-iso` checkout — Chinese installer (cage+foot graphical console with English VT fallback) and live-env packages
|
||||
- Release process: `docs/release-checklist.md`; signing: `docs/release-signing.md`; pacman repo: `docs/pacman-repo.md`
|
||||
- Release process: `docs/release-checklist.md`; signing: `docs/release-signing.md`; pacman repo: `docs/pacman-repo.md`; ISO distribution: Cloudflare R2 bucket behind `dl.zacharyzhang.com` via `packages/upload-release-r2.sh` (Gitea releases carry only the small artifacts)
|
||||
- Site: `site/` is the omarchycn.zacharyzhang.com landing page (Vite 8 vanilla + GSAP + self-hosted Fusion Pixel + reicon, kami palette on a 12-col grid); deploy with `npx wrangler deploy` from `site/`, rendered-state checks via `node shots.mjs` against a preview or the live URL
|
||||
- Chinese-first defaults: OmarchyCN ships Simplified Chinese as the default UX. User-visible strings in `default/omarchy/omarchy-menu.jsonc` (all labels), `default/hypr/bindings/*.lua` (bind descriptions, including the generated workspace/group/panel loops), `bin/omarchy-menu-keybindings` (its merge list and priority patterns must match the shipped Chinese descriptions), `bin/omarchy-update-confirm`, and `install/user/first-run/*` notifications are Chinese with brand names kept in English; menu search stays reachable in English through leaf ids. When syncing upstream, translate new strings in these files and resolve string conflicts toward our Chinese text.
|
||||
- Default set changes vs upstream: `install/omarchy-base.packages` adds fcitx5-rime/chinese-addons/configtool and drops aether/libreoffice-fresh/obs-studio; the Basecamp/Discord/HEY/Google/WhatsApp/X launchers, their webapp keybindings, the whatsapp-slim extension, and the HEY mailto handler are removed (preinstall add/remove lists, launcher.hides, chromium flags, and mimeapps stay in sync); `install/user/cn-chinese.sh` seeds IME/font config on zh_CN systems
|
||||
- AI: `cn/registry/` drives providers (DeepSeek/Kimi/Z.AI/MiniMax/Ollama-local) with zero-code adapters; Ollama uses a fixed `static_token` and runtime-listed models (`models_dynamic`); `omarchy-default-agent` also accepts kimi (official installer script, not mise), deepcode, dim, and dsh (mise npm); the Default Agent menu carries them plus an AI Hub combo entry
|
||||
- Upstream sync: `.gitea/workflows/upstream-sync.yml` opens a PR per upstream change; keep upstream file edits minimal and inventoried (currently: one `GROUP_DESCRIPTIONS[cn]` line in `bin/omarchy`, the localized menu/bindings/update/first-run surfaces above, the western-app removals above, the cn agent roster in `bin/omarchy-default-agent` / `bin/omarchy-agent` (kimi/deepcode/dim/dsh), the `[omarchy]` mirror line in `default/pacman/pacman-stable.conf`, the registry-key import in `install/post-install/pacman.sh`, a rewritten `README.md` (known recurring sync conflict, resolve toward ours), `AGENTS.md` additions, and two `.gitignore` lines)
|
||||
- Upstream sync: `.gitea/workflows/upstream-sync.yml` opens a PR per upstream change; keep upstream file edits minimal and inventoried (currently: one `GROUP_DESCRIPTIONS[cn]` line in `bin/omarchy`, the `omarchy-cn-migrate` line in `bin/omarchy-migrate`, the localized menu/bindings/update/first-run surfaces above, the western-app removals above, the cn agent roster in `bin/omarchy-default-agent` / `bin/omarchy-agent` (kimi/deepcode/dim/dsh), the `[omarchy]` mirror line in `default/pacman/pacman-stable.conf`, the registry-key import in `install/post-install/pacman.sh`, a rewritten `README.md` (known recurring sync conflict, resolve toward ours), `AGENTS.md` additions, and two `.gitignore` lines)
|
||||
- cn tests: `test/shell.d/omarchycn-test.sh`, `test/shell.d/omarchycn-ai-test.sh`; localized UI expectations live in the upstream suites (menu, keybindings-menu, hyprland-default-config, binding-conflicts, clock, screenrecording, update-disk-space)
|
||||
|
||||
# Documentation Layout
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
面向中国开发者的 [Omarchy](https://omarchy.org) 下游发行版:完整保留 Omarchy 的 Arch + Hyprland 桌面体验,为中国网络环境、中文使用习惯与国内 AI 服务做系统级增强。
|
||||
|
||||
当前版本 `4.0.0.alpha-cn.4`(基于上游 `quattro` 分支构建的基线 ISO)。
|
||||
当前版本 `4.0.0.alpha-cn.6`(基于上游 `quattro` 分支构建的基线 ISO)。
|
||||
|
||||
## 特性
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
- **中文环境开箱即用**:zh_CN locale、思源黑体 / 宋体字体栈、高分屏分数缩放预设
|
||||
- **中文输入法**:Fcitx5 + Rime 预配置,Wayland / GTK / Qt / Electron 全栈兼容,快捷键冲突自动处理
|
||||
- **AI Hub**:Kimi、DeepSeek、Z.AI/GLM、MiniMax 与本地 Ollama 的一等 Provider 支持,与 Claude Code、Codex、OpenCode、Kimi Code、Deep Code 等 Harness 的统一配置向导、凭据安全存储与连接诊断;另有 Dim、DSH 等自管登录的 Agent CLI 一键安装
|
||||
- **国内应用中心**:微信、QQ、飞书、钉钉、腾讯会议、WPS 等应用的可信安装入口
|
||||
- **国内应用中心**:微信、企业微信、QQ、飞书、钉钉、腾讯会议、WPS 等应用的可信安装入口
|
||||
- **一键转换**:原版 Omarchy(包安装)一条命令转成 OmarchyCN,logo/菜单/键位/输入法/软件源全套切换,`omarchy cn revert` 一键还原
|
||||
- **Overlay 安装器**:在现有 Omarchy checkout 上叠加 OmarchyCN,全程可逆、可卸载
|
||||
- **统一诊断**:`omarchycn doctor` 覆盖网络、镜像、输入法、显示与 AI 配置
|
||||
|
||||
Regular → Executable
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# omarchy:summary=Run pending OmarchyCN migrations
|
||||
# omarchy:examples=omarchycn migrate
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
MIGRATIONS_DIR="$OMARCHY_PATH/cn/migrations"
|
||||
DONE_DIR="$HOME/.local/state/omarchycn/migrations-done"
|
||||
|
||||
[[ -d $MIGRATIONS_DIR ]] || exit 0
|
||||
|
||||
mkdir -p "$DONE_DIR"
|
||||
for m in "$MIGRATIONS_DIR"/*.sh; do
|
||||
[[ -f $m ]] || continue
|
||||
name="${m##*/}"
|
||||
if [[ ! -f $DONE_DIR/$name ]]; then
|
||||
echo "OmarchyCN migration: $name"
|
||||
bash -euo pipefail "$m"
|
||||
touch "$DONE_DIR/$name"
|
||||
fi
|
||||
done
|
||||
Regular → Executable
+11
-21
@@ -1,15 +1,17 @@
|
||||
#!/bin/bash
|
||||
# omarchy:summary=Update an overlay install: pull source, reinstall, run migrations
|
||||
# omarchy:summary=Full OmarchyCN update: system, cn data, and migrations
|
||||
# omarchy:examples=omarchycn update
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
MANIFEST="$HOME/.local/state/omarchycn/overlay-manifest"
|
||||
MIGRATION_DONE_DIR="$HOME/.local/state/omarchycn/migrations-done"
|
||||
|
||||
if [[ ! -f $MANIFEST ]]; then
|
||||
echo "Not an overlay install (no $MANIFEST)." >&2
|
||||
echo "Package-based installs update through 'omarchy update' / pacman." >&2
|
||||
# Package install: the pipeline brings the new cn tree and runs cn migrations
|
||||
if [[ -d $OMARCHY_PATH/cn ]]; then
|
||||
exec omarchy-update
|
||||
fi
|
||||
echo "未检测到 OmarchyCN($OMARCHY_PATH/cn 不存在,也没有 overlay manifest)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -52,11 +54,11 @@ stable)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Never move onto a tree that predates the channel mechanism: its update
|
||||
# command cannot switch back, stranding the install
|
||||
if [[ ! -f $src/bin/omarchy-cn-channel ]]; then
|
||||
# Never move onto a tree that predates the channel or migrate mechanism:
|
||||
# it cannot switch back or finish this update's migration step
|
||||
if [[ ! -f $src/bin/omarchy-cn-channel || ! -f $src/bin/omarchy-cn-migrate ]]; then
|
||||
git -C "$src" checkout -q "$old"
|
||||
echo "$channel 通道的目标发布早于通道机制,已回退;请使用 nightly 或更新的发布" >&2
|
||||
echo "$channel 通道的目标发布早于当前更新机制,已回退;请使用 nightly 或更新的发布" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -65,18 +67,6 @@ echo "Channel: $channel, source: $old -> $new"
|
||||
|
||||
"$src/bin/omarchy-cn-install-overlay"
|
||||
|
||||
# Run each not-yet-completed migration in filename order, one marker per file
|
||||
if [[ -d $src/cn/migrations ]]; then
|
||||
mkdir -p "$MIGRATION_DONE_DIR"
|
||||
for m in "$src"/cn/migrations/*.sh; do
|
||||
[[ -f $m ]] || continue
|
||||
name="${m##*/}"
|
||||
if [[ ! -f $MIGRATION_DONE_DIR/$name ]]; then
|
||||
echo "Migration: $name"
|
||||
bash -euo pipefail "$m"
|
||||
touch "$MIGRATION_DONE_DIR/$name"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
"$src/bin/omarchy-cn-migrate"
|
||||
|
||||
echo "OmarchyCN update complete ($(omarchy-cn-version 2>/dev/null || echo unknown))"
|
||||
|
||||
@@ -96,6 +96,9 @@ while IFS=$'\t' read -r name file marker; do
|
||||
fi
|
||||
done < <(migration_entries)
|
||||
|
||||
# Here (not omarchy-update) so the first update from a pre-cn package runs them
|
||||
OMARCHY_PATH="$OMARCHY_PATH" omarchy-cn-migrate
|
||||
|
||||
# Clear a login-time notification the user left sitting there and then resolved
|
||||
# by running migrations some other way. The substring matches both the current
|
||||
# and legacy notification titles.
|
||||
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"_verified": "2026-08-24, AUR RPC 实证在维护且未 out-of-date",
|
||||
"_verified": "2026-08-28, AUR RPC 实证在维护且未 out-of-date",
|
||||
"apps": {
|
||||
"wechat": { "name": "微信", "source": "aur", "package": "wechat-universal-bwrap", "license": "proprietary" },
|
||||
"wecom": { "name": "企业微信", "source": "aur", "package": "com.qq.weixin.work.deepin", "license": "proprietary" },
|
||||
"qq": { "name": "QQ", "source": "aur", "package": "linuxqq", "license": "proprietary" },
|
||||
"feishu": { "name": "飞书", "source": "aur", "package": "feishu-bin", "license": "proprietary" },
|
||||
"dingtalk": { "name": "钉钉", "source": "aur", "package": "dingtalk-bin", "license": "proprietary" },
|
||||
|
||||
@@ -385,6 +385,7 @@
|
||||
"omarchycn.ai.doctor": {"icon":"","label":"AI 诊断","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ai-doctor"},
|
||||
"omarchycn.apps": {"icon":"","label":"国内应用"},
|
||||
"omarchycn.apps.wechat": {"icon":"","label":"微信","disabled":"omarchy-pkg-present wechat-universal-bwrap","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install wechat'"},
|
||||
"omarchycn.apps.wecom": {"icon":"","label":"企业微信","disabled":"omarchy-pkg-present com.qq.weixin.work.deepin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install wecom'"},
|
||||
"omarchycn.apps.qq": {"icon":"","label":"QQ","disabled":"omarchy-pkg-present linuxqq","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install qq'"},
|
||||
"omarchycn.apps.feishu": {"icon":"","label":"飞书","disabled":"omarchy-pkg-present feishu-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install feishu'"},
|
||||
"omarchycn.apps.dingtalk": {"icon":"","label":"钉钉","disabled":"omarchy-pkg-present dingtalk-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-app-install dingtalk'"},
|
||||
@@ -417,7 +418,7 @@
|
||||
"omarchycn.diagnostics.doctor": {"icon":"","label":"系统诊断","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-doctor all'"},
|
||||
"omarchycn.diagnostics.mirror-fix": {"icon":"","label":"镜像修复","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-cn-doctor mirror --fix'"},
|
||||
"omarchycn.diagnostics.ime": {"icon":"","label":"输入法状态","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-ime-status"},
|
||||
"omarchycn.update": {"icon":"","label":"更新","when":"[[ -f ~/.local/state/omarchycn/overlay-manifest ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-update"},
|
||||
"omarchycn.update": {"icon":"","label":"更新","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-update"},
|
||||
"omarchycn.revert": {"icon":"","label":"回退为原版 Omarchy","when":"[[ -f /var/lib/omarchycn/convert-state ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-revert"},
|
||||
"omarchycn.about": {"icon":"","label":"关于","action":"omarchy-launch-floating-terminal-with-presentation omarchy-cn-status"},
|
||||
}
|
||||
|
||||
+20
-12
@@ -2,28 +2,36 @@
|
||||
|
||||
每次发布 `<upstream>-cn.<n>` 按序执行,任一步失败即停止:
|
||||
|
||||
1. `./test/all`:相对上游基线零新增失败;`test/shell.d/omarchycn-*.sh` 全绿
|
||||
2. 用 `--local-source` 重建 ISO(`packages/omarchy-pkgs-cn.patch` 已应用到 omarchy-pkgs)
|
||||
3. 验证 omarchy-dev 包含 cn 层(`tar -tf … | grep usr/share/omarchy/cn/`)
|
||||
4. QEMU OVMF UEFI 冒烟:进入安装器欢迎屏
|
||||
5. `sha256sum` → `SHA256SUMS.txt`;签名 SUMS 与 ISO(发布子钥)
|
||||
6. SBOM 两份:syft(live airootfs)+ 离线仓库 .PKGINFO 采集
|
||||
7. `release.json`(版本、双向提交、包版本表、迁移列表、min_compatible、产物清单)→ 签名 release.json
|
||||
8. 把本次构建的 `omarchy-dev` / `omarchy-settings-dev` 发布到 [omarchycn] registry
|
||||
1. `cn/release` 写入本次发布号 `<n>`(上次 +1)并提交;此后所有构建产物自称 cn.`<n>`
|
||||
2. `./test/all`:相对上游基线零新增失败;`test/shell.d/omarchycn-*.sh` 全绿
|
||||
3. 用 `--local-source` 重建 ISO(`packages/omarchy-pkgs-cn.patch` 已应用到 omarchy-pkgs)
|
||||
4. 验证 omarchy-dev 包含 cn 层(`tar -tf … | grep usr/share/omarchy/cn/`)
|
||||
5. QEMU OVMF UEFI 冒烟:进入安装器欢迎屏
|
||||
6. `sha256sum` → `SHA256SUMS.txt`;签名 SUMS 与 ISO(发布子钥)
|
||||
7. SBOM 两份:syft(live airootfs)+ 离线仓库 .PKGINFO 采集
|
||||
8. `release.json`(版本、双向提交、包版本表、迁移列表、min_compatible、产物清单)→ 签名 release.json
|
||||
9. 把本次构建的 `omarchy-dev` / `omarchy-settings-dev` 发布到 [omarchycn] registry
|
||||
(`packages/publish-cn-packages.sh`;先于公开 Release,一键转换才不会装到旧包)
|
||||
9. 建 tag 与 Release,上传全部产物,Release Notes 写明上游基线与已知问题
|
||||
10. 匿名回读已发布 ISO 并 sha256 复核 == 本地构建值
|
||||
11. `cn/release` 数字 +1,提交
|
||||
10. ISO 上传 R2 下载站:`packages/upload-release-r2.sh <版本> <iso>`(脚本自带匿名回读 sha256 复核,
|
||||
并自动只保留最新 2 个版本目录;公网地址 `https://dl.zacharyzhang.com/<版本>/<文件名>`,
|
||||
凭据在 `~/omarchycn-build/.r2.env`)
|
||||
11. 建 tag 与 Release,上传其余小件产物(SUMS/签名/SBOM/release.json),Release Notes 写明上游基线、
|
||||
已知问题与 R2 ISO 下载链接;ISO 不再挂 Gitea 附件(带宽走 R2)
|
||||
12. 匿名回读 R2 ISO 与 Release 附件并 sha256 复核 == 本地构建值
|
||||
|
||||
## 版本规则
|
||||
|
||||
`<omarchy-upstream-version>-cn.<n>`;`min_compatible` 只在有破坏性迁移时前移。
|
||||
|
||||
`cn/release` 表示当前树所属的发布号:发布的第一步把它写成本次发布号,两次发布之间 HEAD 保持上一
|
||||
发布号(与上游 `version` 文件同语义)。发布之间构建并发到 [omarchycn] 的中间包因此自称上一发布号,
|
||||
不会出现自称未发布版本的产物。
|
||||
|
||||
# 上游同步 SLA
|
||||
|
||||
- `upstream-sync.yml` 每日拉取 basecamp/omarchy quattro,自动开同步 PR(含试合并冲突标注)
|
||||
- 常规变更:7 天内完成审查合并;上游安全修复:48 小时内
|
||||
- 合并后必须重跑第 1 步测试门禁
|
||||
- 合并后必须重跑第 2 步测试门禁
|
||||
|
||||
# 安全响应
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 下载与校验
|
||||
|
||||
从 [Releases](https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases) 下载最新 ISO 及 `SHA256SUMS.txt`、`SHA256SUMS.txt.asc`:
|
||||
ISO 从下载站 `https://dl.zacharyzhang.com/<版本>/<文件名>` 获取([Releases](https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases) 页面给出各版本的具体链接),`SHA256SUMS.txt`、`SHA256SUMS.txt.asc` 仍从 Releases 附件下载:
|
||||
|
||||
```bash
|
||||
curl -sSf https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/raw/branch/quattro/cn/keys/omarchycn-release.asc | gpg --import
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
## 更新
|
||||
|
||||
- ISO 安装:系统随上游 `omarchy update`;cn 层当前随新版 ISO 迭代([omarchycn] pacman 仓库暂只分发 keyring,omarchy-dev 包上仓后将改为 pacman 更新)
|
||||
- Overlay 安装:`omarchycn update`(拉取源码 → 重装 overlay → 执行未跑过的 cn 迁移)
|
||||
所有安装形态都可以用 `omarchycn update`(即 `omarchy cn update`):
|
||||
|
||||
- ISO / 一键转换等包安装:完整更新管线(系统包 + [omarchycn] 仓库里的 cn 包 → 应用目录、镜像表、AI registry 随包更新 → 上游迁移与 cn 迁移);直接跑 `omarchy update` 效果相同(cn 迁移已并入其管线)
|
||||
- Overlay 安装:只更新 cn 层(拉取源码 → 重装 overlay → 执行未跑过的 cn 迁移);底下的 Omarchy 系统仍用 `omarchy update` 更新
|
||||
|
||||
## 备份位置
|
||||
|
||||
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# Upload release artifacts to the omarchycn-releases R2 bucket, then verify each
|
||||
# by anonymous public re-read (sha256 must match the local file).
|
||||
# Usage: upload-release-r2.sh <version> <file...>
|
||||
# Public URL shape: https://dl.zacharyzhang.com/<version>/<name>
|
||||
# Credentials: ~/omarchycn-build/.r2.env (rclone S3 env config, mode 0600)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BUCKET=omarchycn-releases
|
||||
PUBLIC=https://dl.zacharyzhang.com
|
||||
|
||||
version="${1:?usage: upload-release-r2.sh <version> <file...>}"
|
||||
shift
|
||||
(($#)) || { echo "no files given" >&2; exit 1; }
|
||||
|
||||
source "$HOME/omarchycn-build/.r2.env"
|
||||
|
||||
for f in "$@"; do
|
||||
[[ -f $f ]] || { echo "no such file: $f" >&2; exit 1; }
|
||||
name=$(basename "$f")
|
||||
echo "==> $name -> $PUBLIC/$version/$name"
|
||||
rclone copyto --s3-upload-cutoff 200M --s3-chunk-size 100M --retries 6 "$f" "r2:$BUCKET/$version/$name"
|
||||
want=$(sha256sum "$f" | cut -d' ' -f1)
|
||||
got=$(curl -fsSL "$PUBLIC/$version/$name" | sha256sum | cut -d' ' -f1)
|
||||
if [[ $want != "$got" ]]; then
|
||||
echo "sha256 mismatch for $name: local $want public $got" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "verified $want"
|
||||
done
|
||||
|
||||
# Keep the newest two release prefixes (current + rollback), purge older ones
|
||||
keep=2
|
||||
mapfile -t versions < <(rclone lsf --dirs-only "r2:$BUCKET" | sed 's|/$||' | sort -V)
|
||||
if ((${#versions[@]} > keep)); then
|
||||
for old in "${versions[@]:0:${#versions[@]}-keep}"; do
|
||||
echo "==> purge old release $old"
|
||||
rclone purge "r2:$BUCKET/$old"
|
||||
done
|
||||
fi
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
<div class="actions" style="grid-column: 1 / 13">
|
||||
<a
|
||||
class="btn"
|
||||
href="https://git.zacharyzhang.com/ZacharyZhang-NY/omarchycn/releases/download/4.0.0.alpha-cn.6/omarchy-2026.08.27-x86_64-local.iso"
|
||||
href="https://dl.zacharyzhang.com/4.0.0.alpha-cn.6/omarchy-2026.08.27-x86_64-local.iso"
|
||||
>
|
||||
<span class="i" data-icon="Download" aria-hidden="true"></span>下载 ISO<span class="btn-meta">5.9 GB</span>
|
||||
</a>
|
||||
|
||||
@@ -4,8 +4,9 @@ set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
# cn-convert is a curl-able bootstrap like upgrade-to-quattro: helpers may not exist yet
|
||||
raw_command_checks=$(rg -l 'command -v' "$ROOT/bin" \
|
||||
| rg -v '/omarchy-(cmd-|pkg-|upgrade-to-quattro)' || true)
|
||||
| rg -v '/omarchy-(cmd-|pkg-|upgrade-to-quattro|cn-convert$)' || true)
|
||||
[[ -z $raw_command_checks ]] || fail "bin commands use command helpers" "$raw_command_checks"
|
||||
pass "bin commands use command helpers"
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ SH
|
||||
|
||||
calls="$test_tmp/calls"
|
||||
|
||||
if ! HOME="$test_home" OMARCHY_PATH="$test_root" "$ROOT/bin/omarchy-migrate" --pending >"$test_tmp/pending.out"; then
|
||||
if ! HOME="$test_home" OMARCHY_PATH="$test_root" PATH="$ROOT/bin:$PATH" "$ROOT/bin/omarchy-migrate" --pending >"$test_tmp/pending.out"; then
|
||||
fail "migration runner reports pending migrations before state exists"
|
||||
fi
|
||||
grep -q '^100-first\.sh$' "$test_tmp/pending.out" || fail "migration runner lists first pending migration filename"
|
||||
@@ -33,6 +33,7 @@ HOME="$test_home" \
|
||||
OMARCHY_PATH="$test_root" \
|
||||
TEST_EXPECTED_OMARCHY_PATH="$test_root" \
|
||||
TEST_CALLS="$calls" \
|
||||
PATH="$ROOT/bin:$PATH" \
|
||||
"$ROOT/bin/omarchy-migrate" >"$test_tmp/first-run.out"
|
||||
[[ $(sed -n '1p' "$calls") == "first" ]] || fail "migration runner runs first migration"
|
||||
[[ $(sed -n '2p' "$calls") == "second" ]] || fail "migration runner runs second migration"
|
||||
@@ -44,11 +45,12 @@ HOME="$test_home" \
|
||||
OMARCHY_PATH="$test_root" \
|
||||
TEST_EXPECTED_OMARCHY_PATH="$test_root" \
|
||||
TEST_CALLS="$calls" \
|
||||
PATH="$ROOT/bin:$PATH" \
|
||||
"$ROOT/bin/omarchy-migrate" >"$test_tmp/second-run.out"
|
||||
[[ $(wc -l <"$calls") -eq 2 ]] || fail "migration runner skips completed migrations"
|
||||
pass "migration runner skips completed migrations"
|
||||
|
||||
if HOME="$test_home" OMARCHY_PATH="$test_root" "$ROOT/bin/omarchy-migrate" --pending >"$test_tmp/not-pending.out"; then
|
||||
if HOME="$test_home" OMARCHY_PATH="$test_root" PATH="$ROOT/bin:$PATH" "$ROOT/bin/omarchy-migrate" --pending >"$test_tmp/not-pending.out"; then
|
||||
fail "migration runner reports no pending migrations after state exists"
|
||||
fi
|
||||
pass "migration runner detects no pending migrations"
|
||||
@@ -67,6 +69,7 @@ set +e
|
||||
HOME="$failure_home" \
|
||||
OMARCHY_PATH="$failure_root" \
|
||||
TEST_CALLS="$calls" \
|
||||
PATH="$ROOT/bin:$PATH" \
|
||||
"$ROOT/bin/omarchy-migrate" >"$test_tmp/failure.out" 2>"$test_tmp/failure.err"
|
||||
failure_status=$?
|
||||
set -e
|
||||
|
||||
@@ -121,6 +121,48 @@ revert_mirror=$(grep -m1 '^MIRROR_LINE=' "$ROOT/bin/omarchy-cn-revert" | cut -d'
|
||||
fail "revert MIRROR_LINE drifted from cn/lib/mirror.sh" "$revert_mirror"
|
||||
pass "convert/revert pair: parse, main() guard, ask=4, mirror constant in sync"
|
||||
|
||||
# Update pipeline: cn migrations ride omarchy-migrate, cn update serves both forms
|
||||
bash -n "$ROOT/bin/omarchy-cn-migrate" || fail "omarchy-cn-migrate parses"
|
||||
grep -q '^OMARCHY_PATH="\$OMARCHY_PATH" omarchy-cn-migrate$' "$ROOT/bin/omarchy-migrate" ||
|
||||
fail "omarchy-migrate runs cn migrations (upstream-sync drift)"
|
||||
grep -qE '^\s*exec omarchy-update$' "$ROOT/bin/omarchy-cn-update" ||
|
||||
fail "omarchy-cn-update serves package installs via omarchy-update"
|
||||
grep -q '^if \[\[ .* ! -f \$src/bin/omarchy-cn-migrate \]\]' "$ROOT/bin/omarchy-cn-update" ||
|
||||
fail "downgrade guard checks for omarchy-cn-migrate"
|
||||
pass "update pipeline: cn migrate wired into omarchy-migrate, package branch present"
|
||||
|
||||
# cn migrate runner: pending run once, markers at the contract path suppress and persist
|
||||
mig_root=$(mktemp -d)
|
||||
mig_done="$HOME/.local/state/omarchycn/migrations-done"
|
||||
mkdir -p "$mig_root/cn/migrations" "$mig_done"
|
||||
printf 'echo seeded >> "$HOME/mig-calls"\n' > "$mig_root/cn/migrations/999999999.sh"
|
||||
printf 'echo ran >> "$HOME/mig-calls"\n' > "$mig_root/cn/migrations/1000000000.sh"
|
||||
touch "$mig_done/999999999.sh"
|
||||
OMARCHY_PATH="$mig_root" omarchy-cn-migrate > /dev/null
|
||||
OMARCHY_PATH="$mig_root" omarchy-cn-migrate > /dev/null
|
||||
[[ $(cat "$HOME/mig-calls") == "ran" ]] || fail "cn migrate runs pending once, honors seeded markers" "$(cat "$HOME/mig-calls")"
|
||||
[[ -f $mig_done/1000000000.sh ]] || fail "cn migrate writes markers to the contract path"
|
||||
rm -rf "$mig_root"
|
||||
pass "omarchy-cn-migrate marker contract holds"
|
||||
|
||||
# Every cn command must be executable (the menu launches them directly)
|
||||
nonexec=$(find "$ROOT/bin" -maxdepth 1 \( -name omarchycn -o -name 'omarchy-cn-*' \) ! -perm -u+x)
|
||||
[[ -z $nonexec ]] || fail "non-executable cn commands" "$nonexec"
|
||||
if [[ -d $ROOT/.git ]]; then
|
||||
badmode=$(git -C "$ROOT" ls-files -s bin/omarchycn 'bin/omarchy-cn-*' | grep -v '^100755' || true)
|
||||
[[ -z $badmode ]] || fail "cn commands tracked without exec mode" "$badmode"
|
||||
fi
|
||||
pass "all cn commands carry the executable bit"
|
||||
|
||||
# App catalog and menu install entries stay in sync
|
||||
catalog_ids=$(jq -r '.apps | keys[]' "$ROOT/cn/apps.json" | sort)
|
||||
menu_ids=$(grep -v '^\s*//' "$ROOT/default/omarchy/omarchy-menu.jsonc" |
|
||||
grep -o '"omarchycn\.apps\.[a-z-]*"' |
|
||||
sed 's/.*apps\.//; s/"//' | sort)
|
||||
diff <(printf '%s\n' "$catalog_ids") <(printf '%s\n' "$menu_ids") > /dev/null ||
|
||||
fail "menu app entries drift from cn/apps.json"
|
||||
pass "menu app entries match the catalog"
|
||||
|
||||
# Menu: OmarchyCN entries parse and reference only existing commands
|
||||
node -e '
|
||||
const fs = require("fs");
|
||||
|
||||
Reference in New Issue
Block a user