返回 CodeWhale
CNB_MIRROR.md
根目录 / docs / CNB_MIRROR.md
1 # CNB Cool mirror
2
3 `cnb.cool/codewhale.net/codewhale` is a one-way mirror of this
4 GitHub repository for users on networks where GitHub is slow or blocked
5 (primarily mainland China). The mirror receives every push to `main`, every
6 `fix/*`, `rebrand/*`, and `work/v*` branch used for first-party release work,
7 and every `v*` release tag.
8
9 ## Provenance
10
11 **GitHub is the sole canonical source.** All releases, tags, and source code
12 originate at `github.com/Hmbown/CodeWhale`. The CNB mirror is a read-only
13 replica maintained by the `Sync to CNB` workflow — it exists solely to serve
14 users behind GFW-blocked or slow GitHub connections.
15
16 Every CNB release includes `codewhale-artifacts-sha256.txt` — a SHA256 manifest
17 of the CNB-built Linux x64 binaries, generated from the same source commit that
18 is tagged on GitHub. (CNB builds from source, so these checksums cover the
19 CNB-built artifacts, not GitHub's release assets.) Verify a downloaded binary
20 against it:
21
22 ```bash
23 # Verify a downloaded CNB binary against the CNB manifest
24 sha256sum -c codewhale-artifacts-sha256.txt --ignore-missing
25 ```
26
27 ## How it works
28
29 The mirror is maintained by the [`Sync to CNB`](../.github/workflows/sync-cnb.yml)
30 GitHub Actions workflow:
31
32 - **Trigger:** `push` to `main`, `push` of any `v*` tag,
33 release work branches matching `work/v*`, first-party fix and rebrand
34 branches matching `fix/*` and `rebrand/*`, or `workflow_dispatch` for manual
35 recovery.
36 - **Auth:** HTTPS basic auth as user `cnb` with the `CNB_GIT_TOKEN`
37 repository secret as the password.
38 - **Scope:** only the ref that triggered the run is pushed. Tag pushes
39 push exactly that tag. Branch pushes mirror `main`, first-party
40 `fix/*`/`rebrand/*` branches, or explicitly matched release branches. Other
41 feature branches and dependabot refs are intentionally *not* mirrored.
42 - **Concurrency:** runs are serialized via a `cnb-sync` concurrency
43 group so the back-to-back `main` push and tag push from
44 `auto-tag.yml` cannot race each other.
45 - **Retry:** each push is retried up to three times with linear
46 backoff (5s, 10s) before the workflow gives up.
47
48 CNB pipeline configuration is also source-controlled in GitHub at
49 [`/.cnb.yml`](../.cnb.yml). This is deliberate: the sync workflow force-mirrors
50 GitHub refs to CNB, so pipeline files created only on the CNB side will be
51 overwritten. Submit `.cnb.yml` changes through GitHub PRs and let the one-way
52 mirror carry them to CNB.
53
54 ## CNB tag releases
55
56 When CNB receives a `v*` tag, the root `.cnb.yml` tag pipeline builds Linux x64
57 release assets from source and publishes a CNB release with:
58
59 - `codewhale-linux-x64`
60 - `codew-linux-x64`
61 - `codewhale-tui-linux-x64` (compatibility-only release filename; not a third
62 installed command)
63 - `codewhale-artifacts-sha256.txt`
64
65 This gives users who can reach CNB but not GitHub a CNB-native release path.
66 GitHub remains the canonical macOS/Windows release matrix; the CNB tag pipeline
67 is the China-friendly Linux x64 fallback.
68
69 ## CNB Linux CI and release preflight
70
71 First-party `fix/*` and `rebrand/*` branches are mirrored to CNB so the heavy
72 Linux Rust gates run on Tencent-hosted runners instead of GitHub Actions:
73
74 - `./scripts/release/check-versions.sh`
75 - `cargo fmt --all -- --check`
76 - `cargo check --workspace --all-targets --locked`
77 - `cargo clippy --workspace --all-targets --all-features --locked -- -D warnings`
78 - `cargo test --workspace --all-features --locked`
79 - `cargo build --release --locked -p codewhale-cli -p codewhale-tui`
80 - `node scripts/release/npm-wrapper-smoke.js`
81
82 Release branches matching `work/v*` also run
83 `./scripts/release/publish-crates.sh dry-run`. GitHub Actions keeps the cheap
84 drift/fmt statuses plus the macOS and Windows jobs that CNB cannot replace.
85
86 ## Verifying the mirror after a release
87
88 After `release.yml` completes for a `vX.Y.Z` tag, the CNB mirror
89 should have both the new commit on `main` and the new tag:
90
91 ```bash
92 # Quick check: does the new tag exist on CNB?
93 git ls-remote https://cnb.cool/codewhale.net/codewhale.git \
94 refs/tags/vX.Y.Z
95
96 # Quick check: is CNB's main at the same commit as origin/main?
97 gh_main=$(git ls-remote https://github.com/Hmbown/CodeWhale.git refs/heads/main | awk '{print $1}')
98 cnb_main=$(git ls-remote https://cnb.cool/codewhale.net/codewhale.git refs/heads/main | awk '{print $1}')
99 test "$gh_main" = "$cnb_main" && echo "in sync" || echo "DIVERGED: gh=$gh_main cnb=$cnb_main"
100 ```
101
102 Or check the workflow run directly:
103
104 ```bash
105 gh run list --workflow=sync-cnb.yml --repo Hmbown/CodeWhale --limit 5
106 ```
107
108 If the most recent run for the release tag is `success`, the mirror
109 caught it. If it's `failure`, fix or re-run the mirror workflow before
110 directing users to the mirrored tag.
111
112 ## Manual fallback
113
114 Manual mirror repair is maintainer-only. Do not put PATs in remote URLs or
115 publish force-push recipes in contributor-facing docs. Use the configured
116 GitHub Actions secret and the workflow dispatch path whenever possible.
117
118 ### Re-trigger the workflow manually
119
120 If the workflow is healthy but happened to fail on the release run
121 (e.g. a transient CNB outage that's since cleared), retrigger it
122 without pushing anything:
123
124 ```bash
125 # Prefer rerunning the existing failed tag run when one exists.
126 gh run rerun <failed-tag-run-id> --repo Hmbown/CodeWhale
127
128 # If no tag run exists, dispatch from the exact existing release tag.
129 gh workflow run sync-cnb.yml --repo Hmbown/CodeWhale --ref vX.Y.Z
130 ```
131
132 Do not omit `--ref` when repairing a tag: a default-branch dispatch syncs
133 `main`, not `refs/tags/vX.Y.Z`. Afterward, prove the tag and its Linux x64
134 release assets exist before directing users to CNB.
135
136 ## Rotating `CNB_GIT_TOKEN`
137
138 If the workflow starts failing with auth errors and the token has
139 expired:
140
141 1. Log in to `cnb.cool` and generate a new personal access token
142 with `repo` (push) scope.
143 2. Update the `CNB_GIT_TOKEN` repository secret:
144 ```bash
145 gh secret set CNB_GIT_TOKEN --repo Hmbown/CodeWhale
146 ```
147 3. Re-trigger the workflow on a recent commit:
148 ```bash
149 gh workflow run sync-cnb.yml --repo Hmbown/CodeWhale
150 ```
151 4. Confirm the run succeeds via `gh run list --workflow=sync-cnb.yml`.
152
153 ## Binary release assets and `codewhale update`
154
155 CNB now builds Linux x64 assets for `v*` tags from the source-controlled
156 `.cnb.yml` pipeline. GitHub remains the canonical macOS/Windows release matrix.
157
158 ### Automatic source selection (Linux x64)
159
160 On Linux x64, `codewhale update` picks its asset source before it downloads
161 anything large. Once the target tag is known, it requests
162 `codewhale-artifacts-sha256.txt` for that exact tag from GitHub Releases and
163 from the CNB release **at the same time**, and takes the first source that
164 answers with a manifest listing `codewhale-linux-x64`. The straggler's answer is
165 discarded.
166
167 Three properties this relies on:
168
169 - **The manifest is the probe.** It is a few hundred bytes, so a blocked or slow
170 source loses in about the time its connection takes to fail — the user never
171 waits out a stalled multi-megabyte asset download, and no timeout is doing the
172 choosing.
173 - **Manifest and binary come from the same source.** CNB builds its own
174 artifacts from the tagged source (musl-static, not GitHub's glibc build), so
175 the two manifests describe different bytes and are not interchangeable. The
176 winning source supplies both, and a checksum mismatch fails the update rather
177 than falling back to the loser.
178 - **Selection never changes which release is installed.** The tag still comes
179 from GitHub's stable-release or beta-release lookup, so `--beta` keeps its
180 meaning; only where the bytes for that tag are fetched from is decided by the
181 probe.
182
183 `codewhale update` and `codewhale update --check` both print the result as a
184 `Release source:` line, and the post-install summary repeats it, so the source a
185 given binary came from is recoverable after the fact.
186
187 Every other target keeps a single canonical source: CNB publishes Linux x64 and
188 nothing else, so macOS, Windows, Android, and Linux arm64 do not race CNB;
189 Linux riscv64 remains explicitly unsupported. All supported self-update paths
190 are nevertheless checksum-required: the chosen source must publish a valid
191 `codewhale-artifacts-sha256.txt` entry for the exact platform binary, or
192 `codewhale update` stops before downloading that binary. There is no
193 unverified-install fallback.
194
195 Setting `CODEWHALE_RELEASE_BASE_URL` (or a legacy alias) or
196 `CODEWHALE_USE_CNB_MIRROR` turns selection off entirely — an explicitly named
197 source is used as named, including its own checksum manifest, with
198 `CODEWHALE_RELEASE_BASE_URL` outranking `CODEWHALE_USE_CNB_MIRROR`.
199
200 ### Manual paths
201
202 Users behind GitHub-blocking networks can also select a source explicitly:
203
204 - **`cargo install`** from the CNB mirror:
205 ```bash
206 cargo install --git https://cnb.cool/codewhale.net/codewhale --tag vX.Y.Z codewhale-cli --locked
207 ```
208 The current `codewhale` binary runs the TUI in-process. Cargo users who want
209 the optional short command can add a `codew` symlink beside it; a separate
210 `codewhale-tui` install is not required.
211 Linux build-time dependencies (`build-essential`, `pkg-config`,
212 `libdbus-1-dev` on Debian/Ubuntu) are required — see
213 [INSTALL.md](INSTALL.md#4-install-via-cargo-any-tier-1-rust-target).
214
215 - **CNB release assets** for Linux x64, when the matching CNB tag pipeline has
216 completed successfully. Download `codewhale-linux-x64`, `codew-linux-x64`,
217 and `codewhale-artifacts-sha256.txt` from the CNB release for `vX.Y.Z`, then
218 verify the binaries against the manifest. The published
219 `codewhale-tui-linux-x64` file is a legacy-client bridge and is not required
220 by current installs. On Linux x64 and OpenHarmony x64 the npm wrapper probes
221 that CNB checksum manifest concurrently with GitHub Releases for the exact
222 package version and locks onto the first source whose HTTP response and
223 manifest validate — it does not wait for a slow GitHub binary download. Set
224 `CODEWHALE_USE_CNB_MIRROR=1` to force CNB only, or
225 `CODEWHALE_RELEASE_BASE_URL` to skip the race. Other platforms must use
226 GitHub or a complete `CODEWHALE_RELEASE_BASE_URL` mirror.
227
228 - **`CODEWHALE_RELEASE_BASE_URL`** environment variable, if a CDN mirror of
229 release assets exists. The npm wrapper installer and `codewhale update` read
230 this variable to redirect binary downloads. For `codewhale update`, also set
231 `CODEWHALE_VERSION=X.Y.Z` so the updater can label the mirrored
232 release without contacting GitHub. The directory pointed to must contain
233 `codewhale-artifacts-sha256.txt` and the platform binaries; format matches
234 a GitHub Release asset directory. The earlier `DEEPSEEK_TUI_*` names remain
235 accepted as compatibility aliases.
236
237 ## Clone from CNB
238
239 For a stable install, clone `main` or a release tag from:
240
241 ```bash
242 https://cnb.cool/codewhale.net/codewhale.git
243 ```
244
245 The mirror receives `main`, release tags, and matched release branches. GitHub
246 is the fallback when the CNB workflow or credentials are unhealthy.
247
248 CNB deploy-button examples live in `deploy/tencent-lighthouse/cnb/`. They are
249 not active until copied into `.cnb.yml` and `.cnb/tag_deploy.yml`, because live
250 deploy jobs require a Lighthouse deploy key, target host, and explicit CNB
251 quota/billing policy.
252
252 lines MARKDOWN