Roll back two changes from a1ef8697b/0a5d308c9 that were not justified
by the actual threat model or release-pipeline needs:
- .github/workflows/release.yml: restore the supported `ossutil config -k`
invocation. The earlier switch to writing the .ossutilconfig INI file
in-process was meant to keep the access-key out of /proc/<pid>/cmdline,
but GitHub-hosted runners are single-tenant ephemeral VMs where no other
user can read that namespace. The benefit was theoretical; the cost was
taking on a brittle dependency on ossutil's undocumented config format.
- scripts/upload-aliyun-oss-assets.js: revert the uploadAssets parallel
rewrite (Promise.all + spawn + setTimeout) back to the original sync
spawnSync loop with retry. Release-time uploads of ~6 small files do
not need parallelism, and the async refactor changed the public
contract (sync→async) for no real wall-clock win.
Kept from those commits:
- The cleanup `if: always()` step that removes RUNNER_TEMP/.ossutilconfig
at the end of the publish job.
- The cross-platform sleepSync(ms) helper, since `spawnSync('sleep', ...)`
still does not work on Windows runners.
- The INSTALLATION_GUIDE.md doc fix.
- All other round-2 fixes.
Test assertions updated for the restored sync uploadAssets contract.
Add two integration tests that route a temp-directory ossutil shim onto
PATH so uploadAssets actually spawns the real binary with the real cp
argv:
- happy-path test asserts the destination URI, `-c <config>`, `--acl
public-read`, and per-asset cp invocations land for both inputs.
- failure-path test asserts non-zero ossutil exits surface as an
aggregate `asset uploads failed` error after the retry budget runs out.
- scripts/tests/upload-aliyun-oss-assets.test.js: cover --help short-circuit,
required-option validation (--bucket/--config/--prefix/empty assets),
unknown options, missing option values, and trailing-slash prefix
normalization.
- scripts/verify-installation-release.js: switch the win-only zip branch
from `startsWith('win-')` to the strict `=== 'win-x64'` check used by
build-standalone-release.js, and add a comment recording that the two
derivations must stay aligned. Without this the helpers would diverge
the moment a non-x64 win target gets added.
Workflow:
- Move 'Publish Aliyun OSS Latest VERSION' to run after the hosted installer
assets are uploaded and verified, so the latest/VERSION pointer only flips
once every release artifact is in place. Previously a hosted-sync failure
could leave the pointer ahead of the actual installer scripts.
upload-aliyun-oss-assets.js:
- Replace `spawnSync('sleep', ...)` retry backoff with an Atomics.wait-based
cross-platform sleep so retries also work on Windows runners.
install-qwen-standalone.bat:
- :DetectTarget no longer emits TARGET=win-arm64 because RELEASE_TARGETS has
no win-arm64 archive; ARM64 hosts now fall through to the unsupported-arch
branch and (in detect mode) get the npm fallback instead of a 404.
- Add QWEN_INSTALL_CURL_EXE to :ValidateRawEnvironmentOptions so this curl
override is checked for shell metacharacters like every other knob.
- Replace `call echo %%i>>...` with plain `echo %%i>>...` when capturing
pre-install qwen.cmd paths; `call` triggered an extra parse pass that
could interpret &/|/<,>/etc. inside a directory name as command separators.
- Add `--retry 2` to curl.exe downloads (`:DownloadFile` / `:DownloadFileQuiet`)
to match the shell installer.
- Include expected vs actual hash in the checksum-mismatch error message.
install-qwen-standalone.ps1:
- Stage the downloaded installer at a cryptographically random temp path
(`qwen-installer-<random>.bat`) so a same-user attacker cannot pre-stage a
malicious .bat at a predictable path and race the verify/execute window.
- Atomically install the current-session cmd shim by writing to a sibling
`.new` temp file then renaming, so a partial write cannot leave a
half-written shim on PATH.
- Add `--retry 2` to the curl.exe download path.
- Include expected vs actual hash in the checksum-mismatch error message.
install-qwen-standalone.sh:
- Include expected vs actual hash in the checksum-mismatch error message.
uninstall-qwen-standalone.ps1:
- Accept `-Purge` and `-Help` parameters; previously every CLI flag was
silently dropped, so users running with `-Purge` got no purge and no error.
`-Purge` maps to `QWEN_UNINSTALL_PURGE=1`.
uninstall-qwen-standalone.sh:
- `remove_install_wrapper` additionally requires the wrapper file to start
with a `#!` shebang before it deletes it; a user-authored script that just
happens to mention the install path now stays untouched.
verify-installation-release.js, build-hosted-installation-assets.js:
- Include expected vs actual hash in the checksum-mismatch error messages.
scripts/tests/install-script.test.js:
- Update assertions for the new error wording, the curl `--retry 2` flag,
the dropped ARM64 detection, and the new release-step ordering.
* fix(i18n): Correct zh-TW translations to match Traditional Chinese conventions
Fix ~131 lines of Traditional Chinese (zh-TW) translations that used
Simplified Chinese character forms instead of standard Traditional
Chinese usage.
Changes:
- 文件 → 檔案 (47 occurrences)
- 爲 → 為 (45 occurrences)
- 啓 → 啟 (44 occurrences)
- 曆史 → 歷史 (6 occurrences)
- 鏈接 → 連結 (4 occurrences)
- 菜單 → 選單 (3 occurrences)
* fix(i18n): Replace 服務器 with 伺服器 (15 occurrences)
Align with Traditional Chinese convention where 伺服器 is the standard
term for 'server' in computing contexts.
* fix(i18n): Update zh-TW.js header comment to prevent accidental overwrite
Clarify that the file is the authoritative source and should not be
overwritten with auto-generated output, to prevent future maintainers
from regenerating with raw OpenCC and losing manual corrections.
* fix(i18n): Add zh-TW regression check and maintenance docs
Addresses reviewer feedback on PR #4129 (points 2 and 3):
- scripts/check-i18n.ts: Iterate over parsed zh-TW translation values
(not raw file content) and report the offending key. Replace the
earlier substring list with ZH_TW_FORBIDDEN_PATTERNS, which targets
the three real regression categories: variant Traditional characters
produced by OpenCC s2t (爲, 啓), Mainland-Chinese vocabulary (服務器,
菜單, 鏈接), and pure Simplified characters. Excludes 禁用 / 配置 /
文件 / 打開 to avoid false positives on Taiwan-valid usage.
- scripts/tests/check-i18n.test.ts: Cover the new check, including
negative cases for Taiwan-valid vocabulary.
- docs/users/features/language.md: Document zh-TW maintenance — the
vocabulary table, why raw OpenCC s2t output is not acceptable, and
where the CI-enforced list lives.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(i18n): Address review feedback on zh-TW check (#4129)
- check-i18n.ts: Sort ZH_TW_FORBIDDEN_PATTERNS longest-first and break
on first match so e.g. `历史` reports the specific bigram instead of
also firing the bare `历` rule (no duplicate CI errors).
- check-i18n.ts: Add ZH_TW_ALLOWED_EXCEPTIONS escape hatch so a future
legitimate translation (e.g. 區塊鏈 in a UI string) can opt out by key
without weakening the global pattern list.
- docs/users/features/language.md: Add a "CI enforced?" column so
contributors can tell which rows block CI vs. which are review-only
style guidance. Replace bare `曆` in the table with the `曆史` bigram
and note that `曆` is correct in calendar terms (日曆, 農曆, 西曆) —
prevents a future maintainer from globally replacing 曆→歷.
- Tests: Cover the dedup behavior on overlapping patterns.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs(i18n): Note word-boundary limitation of zh-TW substring check
Document the known limitation that `includes()`-based pattern matching
does not respect Chinese word boundaries — a bigram like `鏈接` will
false-positive on `區塊鏈接口` (區塊鏈 + 接口). Direct contributors to
`ZH_TW_ALLOWED_EXCEPTIONS` when this happens instead of weakening the
pattern list.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
The installer's write_unix_wrapper shell-quotes the binary path, so
paths containing single quotes (or other shell metacharacters) appear
as shell-quoted strings in the generated wrapper file. The uninstall
script's literal grep -qF missed these, leaving the wrapper orphaned.
Add shell_quote to the uninstall script and match against both the raw
and shell-quoted forms before removing the wrapper.
- ensure_managed_install_dir / :EnsureManagedInstallDir now back up
non-qwen directories instead of refusing to install, so users
upgrading from npm or old installers don't hit a hard error
- Simplify header/footer output: remove banner bars, verbose INFO
lines, and redundant "Installation completed!" message
- Match bun.sh / code-server style: minimal, to the point
Prefer curl.exe with -# (hash-mark progress bar) for archive and installer
downloads on Windows 10+. Falls back to Invoke-WebRequest (which shows its
own progress bar) when curl.exe is unavailable. Matches the approach used
by code-server (curl -#fL) and bun.sh (curl.exe -#SfLo).
Add $ProgressPreference = 'SilentlyContinue' to DownloadFile so the
full-screen progress UI does not appear during archive downloads in
interactive PowerShell sessions, consistent with the .ps1 shim.
Add $ProgressPreference = 'SilentlyContinue' to the .ps1 wrapper so
Invoke-WebRequest downloads don't render a progress bar when invoked
via the irm | iex one-liner.
- Add Aliyun OSS sync steps to release workflow: package hosted assets,
install pinned ossutil, configure credentials, upload versioned and
latest paths, and verify upload via verify:installation-release plus
curl probes against the hosted installer endpoint.
- Document required production-release environment secrets and bucket
variables in INSTALLATION_GUIDE.md.
- Restructure hosted endpoint guidance to lead with the pre-sync
warning, splitting "Run today" (local checkout) from "After the OSS
sync" (hosted one-liners) so users no longer copy a one-liner that
silently installs latest.
- Distinguish mirror auto-selection timeout from successful selection
in install-qwen-standalone.sh and install-qwen-standalone.bat: emit
a "timed out; defaulting to github" log instead of pretending the
HEAD probe picked github.
- Support QWEN_INSTALLER_BAT_URL override (https only) in the
PowerShell shim so staging mirrors can be exercised without forking
the file.
- Strip a leading UTF-8 BOM in verify-installation-release.js
parseSha256Sums so BOM-prefixed SHA256SUMS reports a useful
"Missing checksum entry" error instead of "Malformed SHA256SUMS
line 1".
- Add tests for verifier HEAD→Range fallback, partial-failure
formatting, all-failure wording, and BOM tolerance.