tryzealot / zealot

开源自部署移动应用、 macOS、Linux 和 Windows 应用分发平台,提供 iOS、Android SDK、fastlane 等丰富组件库 | Self-hosted Beta App Distribution for Android, iOS, macOS, Linux and Windows apps
https://zealot.ews.im
MIT License
1.08k stars 134 forks source link

版本号比较问题 #856

Closed denymz closed 2 years ago

denymz commented 2 years ago

部署方式 | How to Deploy

使用一键部署脚本 | Using zealot-docker on-click install (Default)

部署版本 | Version

nightly (Default)

反代服务 | Reverse Proxy

kong-2.8.1

已阅读文档 | Read the document

描述 | Description

/api/app/latest 接口获取更新版本存在较大问题,不能正确获取最新版本,经过排查定位到以下代码。 https://github.com/tryzealot/zealot/blob/42094ec89ff0d94c4a7ee42f7d55c24f978728ea/app/models/channel.rb#L31-L36 具体表现如下: 数据库认为版本号“1.0.10” 小于 “1.0.2” 大于 “1.0.1”。 SQL语句: select '1.0.10' > '1.0.1'; 结果:t (true) SQL语句: sselect '1.0.10' > '1.0.2'; 结果:f (false) 同时 build_version 的比较也存在类似问题; SQL语句: select '10' > '1'; 结果:t (true) SQL语句: sselect '10' > '2'; 结果:f (false) 根本原因是postgres的字符串比较问题,导致/api/app/latest 产生了一些莫名其妙的Bug。

两种修复方案:

  1. postgres 安装pg_semver 扩展,以支持semver数据类型,修改release_version为semver类型,修改build_version为int类型。
  2. 将build_version字段数据类型改为int,修改build_version查询条件为>=, 并且去掉查询中release_version 的 where条件,仅比较 build_version 字段。

个人建议使用第二种方案进行修复,相比第一种较为简单,同时只根据build_version进行版本更新判断并无不妥, 毕竟build_version 只能为数字,且只能增大不能减小。

问题日志 | Relevant log output

No response

icyleaf commented 2 years ago

感谢反馈,版本比较其实一直是我个人比较头疼的事情,其原因是在于无论是外部还是内部版本虽然有 semver 的规范,但市面上的应用并不会全部遵循这个规范,当前两端的规范也不一样因此不好强制定义两个的类型:

范围 iOS Android
外部版本 CFBundleShortVersionString: String versionName: String
内部版本 CFBundleVersion: String versionCode: Int

目前服务版本比较还是尽量按照 semver 对比,但确实没想到会遇到字符串比较会出现这样的情况。

icyleaf commented 2 years ago

现在的逻辑也是在 zealot 正式开源后调整的,之前其实是会找到当前内外版本后按 id 找更新的上次,那个方案的问题是会遇到新上传的应用可能会是老版本 >.<

https://github.com/tryzealot/zealot/blob/4.0.0.beta1/app/models/channel.rb#L28-L32

denymz commented 2 years ago

我编译安装了pg-semver扩展,经过测试,完美解决了release_version比较的问题;其间修改release_version字段的数据类型时也比较顺利,不需要特殊处理,直接修改类型即可。 目前就只有build_version的比较问题不好处理;不比较build_version么?🤔 我还是认为这个字段改为int比较合适,对于IOS也如是要求。 postgres semver Dockerfile:https://github.com/denymz/pg-semver-docker postgres semver 镜像:https://hub.docker.com/r/denycx/postgres

denymz commented 2 years ago

build_version的字符串比较是否可以考虑使用https://github.com/Zeleo/pg_natural_sort_order 这个插件?不过这个插件很久未更新了,不知道还是否可用。

icyleaf commented 2 years ago

无论是 pg-semver 还是 pg_natural_sort_order 都需要非标准发行的 postgres 镜像,这个对于部署有个更高的要求,考虑到服务的场景,我还是走回老路子在原来的基础上补充新规则:

  1. 从版本中提取符合 semver 的版本号
  2. 新上传的版本列表做二次版本对比
icyleaf commented 2 years ago

PR 已经合并 https://github.com/tryzealot/zealot/actions/runs/2860301981 通过后拉取重新部署 nightly 版本。

半道推荐:内部开发版本号可以考虑用 https://github.com/icyleaf/fastlane-plugin-humanable_build_number 来解决无法解读版本号,这个插件会自动读取当前 git 最新 commit 的提交日期,iOS 可自动更新,Android 需要一点小设置。

icyleaf commented 2 years ago

有问题再开