| 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` |
| 62 | - `codewhale-artifacts-sha256.txt` |
| 63 | |
| 64 | This gives users who can reach CNB but not GitHub a CNB-native release path. |
| 65 | GitHub remains the canonical macOS/Windows release matrix; the CNB tag pipeline |
| 66 | is the China-friendly Linux x64 fallback. |
| 67 | |
| 68 | ## CNB Linux CI and release preflight |
| 69 | |
| 70 | First-party `fix/*` and `rebrand/*` branches are mirrored to CNB so the heavy |
| 71 | Linux Rust gates run on Tencent-hosted runners instead of GitHub Actions: |
| 72 | |
| 73 | - `./scripts/release/check-versions.sh` |
| 74 | - `cargo fmt --all -- --check` |
| 75 | - `cargo check --workspace --all-targets --locked` |
| 76 | - `cargo clippy --workspace --all-targets --all-features --locked -- -D warnings` |
| 77 | - `cargo test --workspace --all-features --locked` |
| 78 | - `cargo build --release --locked -p codewhale-cli -p codewhale-tui` |
| 79 | - `node scripts/release/npm-wrapper-smoke.js` |
| 80 | |
| 81 | Release branches matching `work/v*` also run |
| 82 | `./scripts/release/publish-crates.sh dry-run`. GitHub Actions keeps the cheap |
| 83 | drift/fmt statuses plus the macOS and Windows jobs that CNB cannot replace. |
| 84 | |
| 85 | ## Verifying the mirror after a release |
| 86 | |
| 87 | After `release.yml` completes for a `vX.Y.Z` tag, the CNB mirror |
| 88 | should have both the new commit on `main` and the new tag: |
| 89 | |
| 90 | ```bash |
| 91 | # Quick check: does the new tag exist on CNB? |
| 92 | git ls-remote https://cnb.cool/codewhale.net/codewhale.git \ |
| 93 | refs/tags/vX.Y.Z |
| 94 | |
| 95 | # Quick check: is CNB's main at the same commit as origin/main? |
| 96 | gh_main=$(git ls-remote https://github.com/Hmbown/CodeWhale.git refs/heads/main | awk '{print $1}') |
| 97 | cnb_main=$(git ls-remote https://cnb.cool/codewhale.net/codewhale.git refs/heads/main | awk '{print $1}') |
| 98 | test "$gh_main" = "$cnb_main" && echo "in sync" || echo "DIVERGED: gh=$gh_main cnb=$cnb_main" |
| 99 | ``` |
| 100 | |
| 101 | Or check the workflow run directly: |
| 102 | |
| 103 | ```bash |
| 104 | gh run list --workflow=sync-cnb.yml --repo Hmbown/CodeWhale --limit 5 |
| 105 | ``` |
| 106 | |
| 107 | If the most recent run for the release tag is `success`, the mirror |
| 108 | caught it. If it's `failure`, fix or re-run the mirror workflow before |
| 109 | directing users to the mirrored tag. |
| 110 | |
| 111 | ## Manual fallback |
| 112 | |
| 113 | Manual mirror repair is maintainer-only. Do not put PATs in remote URLs or |
| 114 | publish force-push recipes in contributor-facing docs. Use the configured |
| 115 | GitHub Actions secret and the workflow dispatch path whenever possible. |
| 116 | |
| 117 | ### Re-trigger the workflow manually |
| 118 | |
| 119 | If the workflow is healthy but happened to fail on the release run |
| 120 | (e.g. a transient CNB outage that's since cleared), retrigger it |
| 121 | without pushing anything: |
| 122 | |
| 123 | ```bash |
| 124 | # Prefer rerunning the existing failed tag run when one exists. |
| 125 | gh run rerun <failed-tag-run-id> --repo Hmbown/CodeWhale |
| 126 | |
| 127 | # If no tag run exists, dispatch from the exact existing release tag. |
| 128 | gh workflow run sync-cnb.yml --repo Hmbown/CodeWhale --ref vX.Y.Z |
| 129 | ``` |
| 130 | |
| 131 | Do not omit `--ref` when repairing a tag: a default-branch dispatch syncs |
| 132 | `main`, not `refs/tags/vX.Y.Z`. Afterward, prove the tag and its Linux x64 |
| 133 | release assets exist before directing users to CNB. |
| 134 | |
| 135 | ## Rotating `CNB_GIT_TOKEN` |
| 136 | |
| 137 | If the workflow starts failing with auth errors and the token has |
| 138 | expired: |
| 139 | |
| 140 | 1. Log in to `cnb.cool` and generate a new personal access token |
| 141 | with `repo` (push) scope. |
| 142 | 2. Update the `CNB_GIT_TOKEN` repository secret: |
| 143 | ```bash |
| 144 | gh secret set CNB_GIT_TOKEN --repo Hmbown/CodeWhale |
| 145 | ``` |
| 146 | 3. Re-trigger the workflow on a recent commit: |
| 147 | ```bash |
| 148 | gh workflow run sync-cnb.yml --repo Hmbown/CodeWhale |
| 149 | ``` |
| 150 | 4. Confirm the run succeeds via `gh run list --workflow=sync-cnb.yml`. |
| 151 | |
| 152 | ## Binary release assets and `codewhale update` |
| 153 | |
| 154 | CNB now builds Linux x64 assets for `v*` tags from the source-controlled |
| 155 | `.cnb.yml` pipeline. GitHub remains the canonical macOS/Windows release matrix. Users |
| 156 | behind GitHub-blocking networks should use one of these paths: |
| 157 | |
| 158 | - **`cargo install`** from the CNB mirror: |
| 159 | ```bash |
| 160 | cargo install --git https://cnb.cool/codewhale.net/codewhale --tag vX.Y.Z codewhale-cli |
| 161 | cargo install --git https://cnb.cool/codewhale.net/codewhale --tag vX.Y.Z codewhale-tui |
| 162 | ``` |
| 163 | (Both binaries are required — the dispatcher and the TUI ship |
| 164 | separately; see `AGENTS.md` for the two-binary install rationale.) |
| 165 | Linux build-time dependencies (`build-essential`, `pkg-config`, |
| 166 | `libdbus-1-dev` on Debian/Ubuntu) are required — see |
| 167 | [INSTALL.md](INSTALL.md#4-install-via-cargo-any-tier-1-rust-target). |
| 168 | |
| 169 | - **CNB release assets** for Linux x64, when the matching CNB tag pipeline has |
| 170 | completed successfully. Download `codewhale-linux-x64`, `codew-linux-x64`, |
| 171 | `codewhale-tui-linux-x64`, and `codewhale-artifacts-sha256.txt` from the CNB |
| 172 | release for `vX.Y.Z`, then verify the binaries against the manifest. The npm |
| 173 | wrapper can select this source with `CODEWHALE_USE_CNB_MIRROR=1` on Linux x64 |
| 174 | and OpenHarmony x64 only; other platforms must use GitHub or a complete |
| 175 | `CODEWHALE_RELEASE_BASE_URL` mirror. |
| 176 | |
| 177 | - **`DEEPSEEK_TUI_RELEASE_BASE_URL`** environment variable, if a |
| 178 | CDN mirror of release assets exists. The npm |
| 179 | wrapper installer and `codewhale update` read this variable to redirect |
| 180 | binary downloads. For `codewhale update`, also set |
| 181 | `DEEPSEEK_TUI_VERSION=X.Y.Z` so the updater can label the mirrored |
| 182 | release without contacting GitHub. The directory pointed to must contain |
| 183 | `codewhale-artifacts-sha256.txt` and the platform binaries; format matches |
| 184 | a GitHub Release asset directory. |
| 185 | |
| 186 | ## Clone from CNB |
| 187 | |
| 188 | For a stable install, clone `main` or a release tag from: |
| 189 | |
| 190 | ```bash |
| 191 | https://cnb.cool/codewhale.net/codewhale.git |
| 192 | ``` |
| 193 | |
| 194 | The mirror receives `main`, release tags, and matched release branches. GitHub |
| 195 | is the fallback when the CNB workflow or credentials are unhealthy. |
| 196 | |
| 197 | CNB deploy-button examples live in `deploy/tencent-lighthouse/cnb/`. They are |
| 198 | not active until copied into `.cnb.yml` and `.cnb/tag_deploy.yml`, because live |
| 199 | deploy jobs require a Lighthouse deploy key, target host, and explicit CNB |
| 200 | quota/billing policy. |
| 201 |