
GenieX 版本发布流水线全解析SemVer 策略、S3 分发清单与 HTP 签名门禁【免费下载链接】GenieXRun frontier LLMs and VLMs locally on Qualcomm devices across NPU, GPU, and CPU with a few lines of code项目地址: https://gitcode.com/GitHub_Trending/ne/GenieX本篇技术指南以 GenieX 仓库的 notes/release.md 为核心骨架完整梳理项目的版本发布机制从v前缀 SemVer 标签如何触发 release.yml 流水线到稳定版/预发布版的渠道选择算法再到 S3 镜像布局、manifest 契约、Hexagon HTP 签名门禁与 Windows 安装器签名闸门。读完本文你将掌握 GenieX 的版本号决策流程、发布产物清单的完整形态以及自签名兜底 → 微软签名升级的完整运维路径并能在实际发布场景中照单执行。一、一次发布是如何触发的GenieX 的发布完全由 Git 标签驱动给任意 commit 打上v前缀的 SemVer 2.0 标签并推送即可触发.github/workflows/release.yml中的 Release 工作流git tag v1.2.3 git push origin v1.2.3工作流同时支持workflow_dispatch手动触发但存在严格的防呆约束详见下文resolve-tag。标签语义决定了发布的去向含-的标签是预发布草稿同时会把 sdist 推送到 TestPyPI裸vX.Y.Z标签立即正式发布并把 sdist 推送到生产 PyPI。发布产物清单每次发布产出的资产由package-releasejob 统一打包见 release.yml 中package-release步骤包括geniex-sdk-{linux,windows}-arm64-tag.zipgeniex-cli-linux-arm64-tag.tar.gzgeniex-cli-setup-windows-arm64-tag.exegeniex-android-aar-tag.aargeniex-bench-{linux,windows,android}-arm64-tag.{tar.gz,zip}geniex-pysdist{,-llama_cpp,-qairt}-tag.tar.gz每个文件附带.sha256校验文件CPU-only 变体针对不支持默认构建的基线 ARMv8.0 主板对应 issue #1217项目额外发布 CPU-only 变体在 Linux 与 Android 资产名中插入-cpu中缀即geniex-{sdk,cli}-linux-arm64-cpu-tag.*与geniex-android-aar-cpu-tag.aar。Docker 侧镜像为-cpu标签Maven Central 仅发布默认 AAR。注意没有geniex-bench的 CPU-only 归档Linux 上 SDK zip 已自带bin/geniex-bench且基准测试机队中没有需要 CPU-only 构建的设备。CPU-only 变体的消费方是 Python 打包链路安装时通过GENIEX_SDK_VARIANTcpu环境变量选择对应 SDK见 bindings/python/_sdk_fetch.pyLinux 安装脚本则通过--cpu-only参数切换见 cli/release/linux/install.sh。该构建不带 QAIRT 后端——CPU-only 设备本就没有 NPUPython 侧检测到GENIEX_SDK_VARIANTcpu时会自动把 qairt 后端从安装集合中剔除。重复触发同一标签通过Actions → Release → Run workflow重跑同一标签是安全的前提是下拉框的 Use workflow from 选择了该标签Tags 页签。若从main手动触发resolve-tagjob 会直接拒绝——这样工作流永远不会用错误的 commit 去构建标签。关于 HTP 签名证书导入、测试签名的开发者/用户侧操作请参阅 notes/run.md § Self-signed fallback。二、版本号规则SemVer 与 pre-1.0 特例标签遵循带v前缀的 SemVer 2.0vX.Y.Z表示稳定版vX.Y.Z-channel.n表示预发布。三位数字的含义Bump含义触发示例MAJORX任何公开面的破坏性变更使用者必须适配CLI 标志被删除/重命名、SDK 头文件签名变更、Python API 移除、配置键重命名MINORY向后兼容的特性新增新 runtime、新模型支持、新 CLI 子命令、新 SDK 函数PATCHZ向后兼容的修复或清理Bug 修复、依赖升级、文档/CI-only 变更、内部重构Pre-1.0 规则项目目前仍处于 pre-1.0X 0阶段。在私有/未发布期间不得 bump MAJOR始终保持X 0。破坏性变更改为 bumpMINOR0.Y → 0.(Y1)同时Z归零并必须在 release notes 中明确标注。项目只有在首次公开发布时才进阶到X 1。渠道Channel语义预发布渠道用于传达构建的成熟度排序为alpha beta rc stable渠道用途允许的分支仍可变更的内容alpha.n分享进行中的构建特性形态可能还会变动feature 分支或 main一切包括破坏性变更beta.n针对目标X.Y.Z特性完成寻求反馈main仅 Bug 修复与打磨rc.n发布候选——除非发现 Bug否则即将发布main仅 Bug 修复stable正式发布的版本main不可变——需要新版本只能重新 bump硬性规则进入 stable 之前必须在main上至少经过一个-rc.nstable 标签必须落在 HTP bundle 已由微软签名而非自签名的 commit 上。详见下文Hexagon HTP 签名如果不确定运行gh run list --workflow release.yml --limit 5确认 SDK 产物名不以-selfsigned结尾。若是先完成签名升级绝不重复使用或移动已发布的标签通过新的 patch 版本回退feature 分支上的alpha.n标签是可丢弃的——之后不要 rebase 该 tagged commit。从标签到各分发渠道的版本派生release 工作流通过 .github/actions/version/action.yml 把标签统一派生为各下游需要的版本号SDK/CLI 直接使用vX.Y.Z/vX.Y.Z-rc.1形式Python 则映射为 PEP 440 格式alpha.1 → a1、beta.1 → b1、rc.1 → rc1未知预发布标签回退为 dev 版本is_prerelease标志决定发布到 TestPyPI 还是生产 PyPI。三、版本决策流程/release算法这是/release遵循的算法按顺序执行步骤 1查找本地最新 stable 标签v0.A.B——避免一次gh网络往返git tag --sort-v:refname --list v[0-9]*.[0-9]*.[0-9]* | grep -v -- - | head -1不要使用git describe——它只沿 HEAD 的祖先链查找会漏掉打在侧分支上的 stable 标签。若命令无输出则目标设为v0.1.0并跳到步骤 3。步骤 2确定目标X.Y.Z依据git log v0.A.B..HEAD --format%h %s --stat一次拿到 subject 变更文件仍不明确时再git show sha有破坏性变更的 commit →v0.(A1).0X 0时破坏性变更 bump MINOR否则有 feature commit →v0.(A1).0否则 →v0.A.(B1)。当 subject 有歧义时要同时读 subject 和 diff——Conventional-Commits 前缀feat:、fix:、feat!:)只是提示而非契约本仓库并不强制它们。步骤 3按该目标的周期位置选择渠道面向新目标的第一个标签且在 feature 分支上 →alpha.1面向新目标的第一个标签在main上 →rc.1除非明确要求否则跳过 beta多数周期直接进入 rc已在周期内 → 渠道内递进-rc.1→-rc.2或向前推进一个渠道-beta.3→-rc.1n重置。同一X.Y.Z上渠道只能前进所有-rc.n通过且 HTP 已微软签名 → 打裸vX.Y.Z。步骤 4若周期中途出现破坏性变更导致目标升高放弃当前X.Y.Z保留已有标签不撤回从v0.(new)-alpha.1或-rc.1重新开始。步骤 5计数器n按X.Y.Z与渠道各自重置0.4.0-alpha.{1,2}→0.4.0-beta.{1}→0.4.0-rc.{1,2}→0.4.0。完整示例最新 stable 为v0.3.2git log v0.3.2..HEAD中只有一条fix:和一条docs:。在main上打首个标签 →v0.3.3-rc.1随后v0.3.3。最新 stable 为v0.3.2日志中有添加新 runtime 的feat:。在 feature 分支上 →v0.4.0-alpha.1合并到main后 →v0.4.0-rc.1→v0.4.0。在v0.4.0-rc.2上一次 CLI 标志重命名破坏性落地。目标从0.4.0升到0.5.0。保留-rc.2不动下一个标签是v0.5.0-alpha.1或v0.5.0-rc.1取决于所在分支。工作流侧的标签防呆resolve-tagjob 在流水线最前端做了三层防护见 release.yml 的resolve-tag步骤用正则严格校验 SemVer 2.0 格式手动触发时校验GITHUB_SHA必须等于该标签指向的 commit已发布且有资产的 stable 标签拒绝覆盖预发布可重打stable 一旦产出资产即不可变。随后的_build-*job 都依赖它输出的tag与is_prerelease。四、S3 镜像与 manifest 契约每次发布的一个子集会被镜像到s3://qaihub-public-assets/qai-hub-geniex/可通过https://qaihub-public-assets.s3.us-west-2.amazonaws.com/qai-hub-geniex/...匿名 GET目的是让应用和安装器能在不触发 GitHub-API 速率限制的情况下拉取产物。扁平布局所有对象直接位于该前缀下没有tag/子目录——文件名中的tag承担版本消歧职责对象每标签缓存用途geniex-sdk-windows-arm64-tag.zip(.sha256)每个标签defaultWindows SDKgeniex-sdk-linux-arm64-tag.zip(.sha256)每个标签defaultLinux SDKgeniex-sdk-linux-arm64-cpu-tag.zip(.sha256)每个标签defaultCPU-only Linux SDK由GENIEX_SDK_VARIANTcpu获取geniex-cli-setup-windows-arm64-tag.exe(.sha256)每个标签defaultWindows CLI 安装器带版本geniex-cli-linux-arm64-tag.tar.gz(.sha256)每个标签defaultLinux CLI 归档带版本geniex-cli-linux-arm64-cpu-tag.tar.gz(.sha256)每个标签defaultCPU-only Linux CLI 归档带版本install-tag.sh(.sha256)每个标签defaultLinux 安装脚本带版本通过--version固定geniex-cli.exe仅 stableno-cache指向最新 stable Windows 安装器的可变指针geniex-cli-linux-arm64.tar.gz(.sha256)仅 stableno-cacheinstall.sh消费的可变指针geniex-cli-linux-arm64-cpu.tar.gz(.sha256)仅 stableno-cacheinstall.sh --cpu-only消费的可变指针install.sh仅 stableno-cache可变安装脚本——curl ... \| sh入口manifest-tag.json每个标签immutable每标签资产清单index.json每个标签no-cache完整版本目录latest.json仅 stableno-cache指向最新 stable manifestwindows-signed.txt仅 stableno-cache最新 Windows 安装器的代码签名闸门——见Windows 安装器签名闸门其他资产AAR、sdist、HTP 证书/to-sign 压缩包只通过 GitHub Releases / Maven Central / PyPIstable/ TestPyPI预发布发布不经过 S3。这一架构在 .github/workflows/release.yml 中有明确注释S3 发布实际运行在 geniex 仓库内IAM 角色的 OIDC 信任仅允许qcom-ai-hub/geniex本仓库的publish-s3job 只负责通过GH_PAT派发并监视对端工作流。客户端应用的 manifest 契约manifest 的 schema 定义在 geniex 仓库chore/publish-s3分支的release_s3_manifest.py中所有文件都带schema_version: 1。客户端按三种强度消费1. 更新检查最轻——GETlatest.json把tag与本地安装版本比较。缓存为no-cache响应永远最新只有 stable 标签发布后才存在。2. 版本选择器历史 / 回滚——GETindex.json{ schema_version: 1, updated_at: 2026-05-19T08:23:11Z, latest_stable: v0.1.5, latest_prerelease: v0.1.6-rc.2, versions: [ { tag: v0.1.6-rc.2, is_prerelease: true, released_at: ..., manifest: manifest-v0.1.6-rc.2.json }, { tag: v0.1.5, is_prerelease: false, released_at: ..., manifest: manifest-v0.1.5.json } ] }3. 资产下载——GETversions[].manifest指向的每标签 manifest{ schema_version: 1, tag: v0.1.5, is_prerelease: false, released_at: ..., llama_sha: abc123, htp_signed: true, assets: [ { name: geniex-sdk-windows-arm64-v0.1.5.zip, url: https://qaihub-public-assets.s3.us-west-2.amazonaws.com/qai-hub-geniex/geniex-sdk-windows-arm64-v0.1.5.zip, size: 123456789, sha256: ..., kind: sdk, platform: windows, arch: arm64 } ] }关键约束assets[].url始终指向带版本的对象绝不指向可变的geniex-cli.exe/geniex-cli-linux-arm64.tar.gz/install.sh因此引用的字节是不可变的列出的sha256是权威的。kind取值为sdk/cli-installer/cli-archive/install-script/sha256之一。每标签 manifest 在同一标签的工作流重跑间字节级稳定——released_at保留首次发布的值客户端可以永久缓存。CPU-only 对象刻意不出现在 manifest 中其元数据与默认构建完全相同一个按kind/platform/arch查找的客户端可能把慢速产物交给普通 Snapdragon 设备。而且没有任何机制会这样发现它们——install.sh --cpu-only与GENIEX_SDK_VARIANTcpu都是按命名约定直接拼 URL。客户端代码佐证CLI 的geniex update正是这套契约的参考实现cli/cmd/geniex/update.gogetLatestVersion()GETindex.json取latest_stablegetManifest(tag)GETmanifest-tag.json再用manifest.find(kind, platform, arch)按三元组定位资产下载采用 4 MiB 分块、最多 16 并发的 Range 请求随后用verifySHA256校验哈希再执行安装器。Linux 平台则提示重跑install.sh自动更新尚未接入新版 tar.gz 布局。五、Hexagon HTP 签名Windows ARM64 SDK 内置libggml-htp.cat与libggml-htp-v{73,75,79,81}.so——Windows 拒绝加载未签名版本。发布 CI 在build-cli之前运行一个overlay-htpjob它从qcom-ai-hub/geniex的chore/signed-htp-lfs-store分支稀疏检出sdk/signed-htp/libggml-htp-sha.zipLFS 跟踪其中sha是third-party/llama.cpp的短 SHA。安装器与 SDK zip 最终携带相同的 HTP 文件命中——把微软签名的文件覆盖进 SDK 产物build-cli将其打包进安装器正常发布。未命中——保留自签名构建。SDK 名增加-selfsigned后缀发布同时附带ggml-htp-v1.cer供用户导入与libggml-htp-to-sign-sha.zip供运维提交签名。签名的 bundle 在 zip 根目录必须恰好包含六个文件libggml-htp.cat、libggml-htp.inf与libggml-htp-v{73,75,79,81}.so。package-releasejob 的打包逻辑印证了这一点见 release.yml未签名时复制.github/certs/hexagon/ggml-htp-v1.cer、收集.so/.cat/.inf生成libggml-htp-to-sign-sha.zip并为 SDK 追加-selfsigned后缀。跨仓库检出复用secrets.GH_PAT已按跨仓库访问qcom-ai-hub/geniex授权。若 CI 报告signedfalse但 bundle 确实在chore/signed-htp-lfs-store上首先检查GH_PAT是否过期。自签名 → 微软签名升级流程从 draft release 下载libggml-htp-to-sign-sha.zip提交微软签名 a. 将.cat、.inf与所有.so放入 samba 的ATT\libggml-htp\ b. 提交 Jenkins pipeline路径填\path\to\ATT其余字段用默认或首个参数 c. 从ATT\Glymur\01000\ExtractedDrivers取回签名文件 d. 把签名文件不含.inf按原布局重新打包为 zip将结果提交到qcom-ai-hub/geniex的sdk/signed-htp/libggml-htp-sha.zip分支chore/signed-htp-lfs-store——本地执行git lfs install直接推送 zip或对该分支开 PR 并 squash-merge为同一标签重跑 Release 工作流。六、Windows 安装器签名闸门Windows 安装器在 Authenticode 签名完成之前就会被发布因此geniex update以windows-signed.txt为闸门避免推送未签名构建。在 Windows 上发现新版本后更新器会 GET 该文件见 cli/cmd/geniex/update.go 中的isWindowsSigned内容为true→ 继续下载其余任何内容或缺失 → 视为已是最新并跳过。发布侧约定最新 stable 安装器签名完成后上传内容为true的windows-signed.txt发布下一个尚未签名的安装器之前先把它改回非true值。当前流水线中 Authenticode 签名仍为 TODO 占位见 release.yml 的sign-windowsjob 注释故该闸门是用户侧的最后防线。七、发布前检查清单发布主管在打标签前按以下清单逐项核对确认libggml-htp已签名若未签名结合llama.cppbump 触发一个 alpha 版本标签走自签名 → 微软签名升级流程在main上触发 rc 版本标签并验证以下模型unsloth/Qwen3-0.6B-GGUF与unsloth/Qwen3.5-0.8B-GGUF在cpu/gpu/npu三种计算单元上qualcomm/Qwen3-4B与qualcomm/Qwen3-VL-4B-Instruct在 Qualcomm PC 上测试llama_cpp的 NPU 路径在同一 commit 上创建正式发布标签签名 Windows 安装器将未签名安装器发给 wido 团队替换 S3 上的安装器更新 sha256将windows-signed.txt更新为true。上述验证项与 notes/run.md 中计算单元别名一节直接呼应——--device cpu|gpu|npu|hybrid分别映射到 CPU / OpenCL / 固定单会话 HTP / 逐张量混合调度这正是清单要求覆盖的运行时矩阵。八、关键文件速查notes/release.md——本文的原始规范版本策略与签名门禁的权威定义.github/workflows/release.yml——标签触发、resolve-tag 防呆、HTP 覆盖、打包与多渠道发布的全流程实现.github/scripts/release.js——GitHub Release 资产上传脚本draft/发布状态切换、HTP 说明注入、重复资产清理与失败重试.github/actions/version/action.yml——标签 → SDK/CLI/PEP 440 版本与is_prerelease的派生逻辑cli/cmd/geniex/update.go——geniex update对 S3 index/manifest 契约与windows-signed.txt闸门的消费实现bindings/python/_sdk_fetch.py——Python 安装期 SDK 拉取S3 优先、GitHub 兜底、GENIEX_SDK_VARIANTcpu选择 CPU-only 变体cli/release/linux/install.sh 与 cli/release/linux/check.sh——Linux 安装脚本与前置检查QCOM 驱动库与版本探测notes/run.md——与 HTP 签名相关的用户侧证书导入与测试签名操作。这套体系把谁可以发布、版本号怎么选、产物放哪里、签名是否到位全部固化进了流水线标签语义即发布策略manifest 契约即分发协议签名闸门即质量底线。理解notes/release.md的每一条规则就等于理解了 GenieX 从 commit 到全球分发的完整路径。【免费下载链接】GenieXRun frontier LLMs and VLMs locally on Qualcomm devices across NPU, GPU, and CPU with a few lines of code项目地址: https://gitcode.com/GitHub_Trending/ne/GenieX创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考