diff --git a/.github/workflows/release-source.yml b/.github/workflows/release-source.yml index 410dd0466..2b7e08951 100644 --- a/.github/workflows/release-source.yml +++ b/.github/workflows/release-source.yml @@ -1,11 +1,12 @@ name: Source Package Release run-name: Source Package Release${{ !(startsWith(github.ref, 'refs/tags/') || inputs.release_tag != '') && ' (build only)' || '' }} -# Builds the trimmed C++ source package (opencc profile: no Node.js, Python, -# documentation, or packaging files) and attaches it to the release. The -# trimmed package keeps both build systems working, so it is smoke-tested with -# CMake and Bazel before upload. Like the other release workflows it uploads to -# the draft created by release-draft.yml; publishing is manual. +# Builds the trimmed C++ source package (opencc profile: includes the Jieba +# segmentation plugin but excludes Node.js, Python, documentation, or packaging +# files) and attaches it to the release. The trimmed package keeps both build +# systems working, so it is smoke-tested with CMake and Bazel before upload. +# Like the other release workflows it uploads to the draft created by +# release-draft.yml; publishing is manual. on: workflow_dispatch: @@ -45,10 +46,20 @@ jobs: - name: Build trimmed source package run: | - cmake -S . -B build-src -DOPENCC_SOURCE_PACKAGE_PROFILE=opencc + cmake -S . -B build-src \ + -DOPENCC_SOURCE_PACKAGE_PROFILE=opencc \ + -DCPACK_SOURCE_ARCHIVE_TIMESTAMP=0 (cd build-src && cpack --config CPackSourceConfig.cmake -G TGZ) + # Repack for reproducibility: normalize ownership (root:root), + # timestamps (epoch 0), and file order (sorted). + cpack_tarball=$(ls build-src/opencc-*-opencc-src.tar.gz) + base=$(basename "$cpack_tarball" .tar.gz) + tmpdir=$(mktemp -d) + tar xzf "$cpack_tarball" -C "$tmpdir" mkdir -p dist - mv build-src/opencc-*-opencc-src.tar.gz dist/ + tar cf - -C "$tmpdir" --sort=name --owner=root --group=root --mtime=@0 "$base" | gzip -9n > "dist/${base}.tar.gz" + tar cf - -C "$tmpdir" --sort=name --owner=root --group=root --mtime=@0 "$base" | xz -9 > "dist/${base}.tar.xz" + rm -rf "$tmpdir" ls -l dist/ - name: Smoke-test the package (CMake and Bazel) @@ -58,17 +69,17 @@ jobs: workdir=$(mktemp -d) tar xzf "$tarball" -C "$workdir" src=$(echo "$workdir"/opencc-*-opencc-src) - # CMake: configure and build the core library and CLI tools. - cmake -S "$src" -B "$src/build" -DCMAKE_BUILD_TYPE=Release - cmake --build "$src/build" --target opencc opencc_dict --parallel - # Bazel: load, analyze, and build the core targets. Catches a trimmed + # CMake: configure and build the core library, CLI tools, and Jieba plugin. + cmake -S "$src" -B "$src/build" -DCMAKE_BUILD_TYPE=Release -DBUILD_OPENCC_JIEBA_PLUGIN=ON + cmake --build "$src/build" --target opencc opencc_dict opencc-jieba --parallel + # Bazel: build the core and Jieba plugin targets. Catches a trimmed # package that dropped a file the Bazel module or BUILD graph needs. - (cd "$src" && bazel build //src/tools:dict_converter //data/dictionary:binary_dictionaries) + (cd "$src" && bazel build //src/tools:dict_converter //data/dictionary:binary_dictionaries //plugins/jieba:opencc-jieba) - uses: actions/upload-artifact@v4 with: name: opencc-source-package - path: dist/opencc-*-opencc-src.tar.gz + path: dist/opencc-*-opencc-src.tar.* - name: Upload to GitHub release if: startsWith(github.ref, 'refs/tags/') || inputs.release_tag != '' @@ -83,4 +94,5 @@ jobs: done gh release upload "$tag" \ dist/opencc-*-opencc-src.tar.gz \ + dist/opencc-*-opencc-src.tar.xz \ --clobber diff --git a/AGENTS.md b/AGENTS.md index 5158bf9cd..7552717aa 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -54,7 +54,7 @@ This document compiles the Open Chinese Convert (OpenCC) project information to ## Optional Plugin and Release Packaging - `BUILD_OPENCC_JIEBA_PLUGIN` enables the C++ jieba plugin in CMake builds. Since 1.4.1 it defaults to ON for top-level macOS builds (so Homebrew ships the plugin); other platforms, subproject builds (FetchContent / `add_subdirectory`), and Python wheel builds keep it OFF. - The merged jieba dictionary (`jieba_dict/jieba_merged.ocd2`) is generated at build time by `opencc_dict --from cppjieba_utf8`; there is no separate dictionary helper tool. Standalone plugin builds locate an installed `opencc_dict` and require OpenCC >= 1.4.1. -- Source packages: `OPENCC_SOURCE_PACKAGE_PROFILE` (`full` / `opencc` / `opencc-jieba`) selects which CPack source archive is produced. The `opencc` profile is the trimmed C++-only package (no Node.js, Python, docs, packaging, or `plugins/`) and is intentionally buildable with **both** CMake and Bazel, so Bazel workspace files (`BUILD.bazel`, `MODULE.bazel[.lock]`, `.bazelrc`, `.bazelversion`, `.bazelignore`) and the top-level `patches/` directory (referenced by `MODULE.bazel`) are kept; only `.bazelrc.user` is dropped. When editing the trimmed ignore list, do not re-exclude Bazel files or `patches/`. `release-source.yml` builds this package on a `ver.*` tag (or `workflow_dispatch` with `release_tag`), smoke-tests it with CMake and Bazel, and uploads it to the draft release. +- Source packages: `OPENCC_SOURCE_PACKAGE_PROFILE` (`full` / `opencc`) selects which CPack source archive is produced. The `opencc` profile is the trimmed C++ package including the Jieba plugin (no Node.js, Python, docs, or packaging files) and is intentionally buildable with **both** CMake and Bazel, so Bazel workspace files (`BUILD.bazel`, `MODULE.bazel[.lock]`, `.bazelrc`, `.bazelversion`, `.bazelignore`) and the top-level `patches/` directory (referenced by `MODULE.bazel`) are kept; only `.bazelrc.user` is dropped. When editing the trimmed ignore list, do not re-exclude Bazel files or `patches/`. `release-source.yml` builds this package on a `ver.*` tag (or `workflow_dispatch` with `release_tag`), smoke-tests it with CMake and Bazel (including the Jieba plugin), repacks it for reproducibility (normalized ownership, epoch-0 timestamps, sorted entries), and uploads `.tar.gz` and `.tar.xz` to the draft release. - `plugins/README.md` documents plugin loading, ABI expectations, and standalone plugin builds. - `scripts/release-windows-winget.ps1` is the Windows portable/WinGet release path and produces the CLI zip, checksum, and WinGet manifests. - npm release packaging is separate from the native CLI release: `opencc` and `opencc-jieba` are packed as npm `.tgz` artifacts and should be install-tested together when plugin-backed npm configs are changed. diff --git a/CMakeLists.txt b/CMakeLists.txt index ae5573caa..d8b288077 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,9 +52,9 @@ option(ENABLE_BENCHMARK "Build benchmark tests." OFF) # Top-level macOS builds enable the Jieba plugin by default so package # managers that build with default options (e.g. Homebrew) ship it. Other # platforms and subproject builds (FetchContent / add_subdirectory) keep it -# opt-in. Trimmed source packages ship without plugins/, so only default to -# ON when the plugin sources are actually present; an explicit -# -DBUILD_OPENCC_JIEBA_PLUGIN=ON without them still fails loudly below. +# opt-in. Only default to ON when the plugin sources are actually present; +# an explicit -DBUILD_OPENCC_JIEBA_PLUGIN=ON without them still fails +# loudly below. if (APPLE AND CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/plugins/CMakeLists.txt") set(OPENCC_JIEBA_PLUGIN_DEFAULT ON) @@ -83,8 +83,8 @@ option(USE_SYSTEM_MARISA "Use system version of Marisa" OFF) option(USE_SYSTEM_PYBIND11 "Use system version of pybind11" OFF) option(USE_SYSTEM_RAPIDJSON "Use system version of RapidJSON" OFF) option(USE_SYSTEM_TCLAP "Use system version of TCLAP" OFF) -set(OPENCC_SOURCE_PACKAGE_PROFILE "full" CACHE STRING "Source package profile: full, opencc, or opencc-jieba") -set_property(CACHE OPENCC_SOURCE_PACKAGE_PROFILE PROPERTY STRINGS full opencc opencc-jieba) +set(OPENCC_SOURCE_PACKAGE_PROFILE "full" CACHE STRING "Source package profile: full or opencc") +set_property(CACHE OPENCC_SOURCE_PACKAGE_PROFILE PROPERTY STRINGS full opencc) ######## Package information set (PACKAGE_URL https://github.com/BYVoid/OpenCC) @@ -136,20 +136,12 @@ set(_OPENCC_TRIMMED_SOURCE_PACKAGE_IGNORE_FILES ) if(OPENCC_SOURCE_PACKAGE_PROFILE STREQUAL "opencc") set(_OPENCC_SOURCE_PACKAGE_SUFFIX "-opencc-src") - set(_OPENCC_SOURCE_PACKAGE_IGNORE_FILES - ${_OPENCC_TRIMMED_SOURCE_PACKAGE_IGNORE_FILES} - "/plugins/" - ) -elseif(OPENCC_SOURCE_PACKAGE_PROFILE STREQUAL "opencc-jieba") - set(CPACK_SOURCE_PACKAGE_FILE_NAME - "opencc-jieba-${OPENCC_VERSION_MAJOR}.${OPENCC_VERSION_MINOR}.${OPENCC_VERSION_REVISION}-src" - ) set(_OPENCC_SOURCE_PACKAGE_IGNORE_FILES ${_OPENCC_TRIMMED_SOURCE_PACKAGE_IGNORE_FILES} "/plugins/jieba/node/" ) elseif(NOT OPENCC_SOURCE_PACKAGE_PROFILE STREQUAL "full") - message(FATAL_ERROR "OPENCC_SOURCE_PACKAGE_PROFILE must be 'full', 'opencc', or 'opencc-jieba'.") + message(FATAL_ERROR "OPENCC_SOURCE_PACKAGE_PROFILE must be 'full' or 'opencc'.") endif() if(NOT CPACK_SOURCE_PACKAGE_FILE_NAME) @@ -158,7 +150,7 @@ if(NOT CPACK_SOURCE_PACKAGE_FILE_NAME) ) endif() set(CPACK_SOURCE_IGNORE_FILES - "/build[^/]*/;/test/dict.ocd;/test/dict.txt;/test/dict.bin;/dict.ocd;/.DS_Store;/.zig-[^/]*/;/dist[^/]*/;/other/;/opencc.xcodeproj/;/.git/;.gitignore;~$;.pyc;/bazel-[^/]*;/.bazelrc.user;/node_modules;/.github;/.pytest_cache;/.vscode;/packaging/;${_OPENCC_SOURCE_PACKAGE_IGNORE_FILES};${CPACK_SOURCE_IGNORE_FILES}" + "/build[^/]*/;/test/dict.ocd;/test/dict.txt;/test/dict.bin;/dict.ocd;/.DS_Store;/.zig-[^/]*/;/dist[^/]*/;/other/;/opencc.xcodeproj/;/.git/;.gitattributes;.gitignore;.gitmodules;~$;.pyc;/bazel-[^/]*;/.bazelrc.user;/node_modules;/.github;/.pytest_cache;/.vscode;/packaging/;${_OPENCC_SOURCE_PACKAGE_IGNORE_FILES};${CPACK_SOURCE_IGNORE_FILES}" ) include(CPack) diff --git a/NEWS.md b/NEWS.md index 3e44fe4d2..c64c82eae 100644 --- a/NEWS.md +++ b/NEWS.md @@ -29,7 +29,7 @@ * `packaging/debian/` 同步至 Debian 的 `1.4.1+ds1-8`。Debian 已採納上游先前提出的 jieba 插件打包提案(拆為 `opencc-jieba` 與 arch:all 的 `opencc-jieba-data` 兩個套件,內嵌 cppjieba 的理由記於 `debian/README.source`);Debian 端亦重新啟用了 autopkgtest。`packaging/debian/SPLIT_PROPOSAL.md` 隨提案落地移除。另外 `1.4.1+ds1-8` 修復了 `.ocd2` 被放進 `Architecture: all` 套件的問題:`.ocd2` 是依主機位元組序寫出的 marisa-trie 映像,所有架構都會拿到 arch:all buildd 上構建的小端序副本,opencc 在 s390x 上因而以 `size > avail_` 失敗(Debian bug [#1145010](https://bugs.debian.org/1145010),由重新啟用的 s390x autopkgtest 揪出)。`*.ocd2` 已移回 arch:any 的 `libopencc1.4`、`jieba_merged.ocd2` 移回 arch:any 的 `opencc-jieba`;`libopencc-data` 與 `opencc-jieba-data` 現在只含 JSON 配置與純文字 jieba 詞典來源。 * Debian 套件構建改在 `debian:sid` 容器中進行(同步來的打包以 unstable 為目標,Ubuntu LTS runner 無法滿足),並在 `dpkg-buildpackage` 前套用 `debian/patches` quilt series(自動跳過已在樹中的補丁);arm64 改用 `ubuntu-24.04-arm` runner 原生構建,取代先前的交叉構建([#1420](https://github.com/BYVoid/OpenCC/pull/1420))。 * 新增 `packaging/freebsd/`:FreeBSD ports tree `chinese/opencc` 條目的參考副本,供上游審閱與準備提交給 port maintainer 的改動。 - * 新增精簡 C++ 源碼包發佈流程(`release-source.yml`):以 `OPENCC_SOURCE_PACKAGE_PROFILE=opencc` 產生僅含 C++ 核心的 CPack 壓縮包(不含 Node.js、Python、文檔、packaging 與 plugins),並以 CMake 與 Bazel 雙路徑冒煙測試後上傳至 draft release;為此保留 Bazel workspace 檔案與頂層 `patches/`,僅排除可能含 API key 的 `.bazelrc.user`。 + * 新增精簡 C++ 源碼包發佈流程(`release-source.yml`):以 `OPENCC_SOURCE_PACKAGE_PROFILE=opencc` 產生含 C++ 核心與 Jieba 插件的 CPack 壓縮包(不含 Node.js、Python、文檔與 packaging),並以 CMake 與 Bazel 雙路徑冒煙測試(含 Jieba 插件建置)後,重新打包以正規化檔案擁有者、時間戳與排序,產生 `.tar.gz` 與 `.tar.xz` 上傳至 draft release;為此保留 Bazel workspace 檔案與頂層 `patches/`,僅排除可能含 API key 的 `.bazelrc.user`。 * 修正 `cmake/GitVersion.cmake` 的 fallback 版本號:1.4.1 發佈時仍停留在 1.4.0,導致從釋出的 tarball(無 git 資訊)構建時版本回報為 1.4.0;本次發佈同步將其更新至 1.4.2,並讓 `scripts/compute-version.sh` 的 fallback 與之一致(先前停留在 1.2.1)。因此 Debian 打包的 `0010-fix-git-version-fallback.patch` 對 1.4.2 已無作用而移除,`0012-fix-legacy-dict-detection-on-big-endian.patch` 亦已包含於本次發佈。 * Windows 發佈自本版起啟用程式碼簽章憑證:可攜式 CLI 壓縮包中的執行檔,以及 win32-x64 npm 二進位(`opencc.node`、`opencc-jieba.dll`)皆經 Authenticode 簽章,簽章服務由 [SignPath.io](https://about.signpath.io/) 免費提供、憑證由 [SignPath Foundation](https://signpath.org/) 免費提供,發佈流程改用其 release-signing policy;相關聲明與簽章/隱私政策見 README 的「Code Signing 程式碼簽章」一節([#1458](https://github.com/BYVoid/OpenCC/pull/1458), [#1459](https://github.com/BYVoid/OpenCC/pull/1459))。 * **測試**: