mole404
|
f4c799477a
|
chore(release): 版本号一律不带 v —— app 显示与镜像 tag 统一为 X.Y.Z
老师 2026-10-03 定:所有版本号逻辑去掉 v 前缀。
· src/config/app.php: 'v3.5.1' → '3.5.1'
· build-image.yaml / backfill-version-tag.yaml 的格式守卫:^v[0-9]+… → ^[0-9]+\.[0-9]+\.[0-9]+$
· 新增 delete-image-tag.yaml:手动删 tag 入口(本机 token 无 packages 权限,只能走 CI)
镜像 tag 由 app.php 的 version 单一事实来源自动跟随 ⇒ 一处改、两处生效。
GHCR 上旧的 v3.5.0 / v3.5.1 用该入口删除,此后版本号只保留 X.Y.Z 形式。
|
2026-10-04 03:26:45 +08:00 |
|
mole404
|
79f9f2ed30
|
fix(ci): 补打工作流避开 pipefail 假红(inspect | head → 先落文件)
上一版补打**其实成功了**:GHCR 上 v3.5.0 的 digest 与 sha-0caef9ca 完全一致。
但运行显示红色 —— 脚本开了 set -o pipefail,而
docker buildx imagetools inspect ... | head -8
里 head 提前退出,docker CLI 吃到 SIGPIPE 后以非 0 退出(本次实测 exit 255)→
整条管道非 0 → 假红。build-image.yaml 里早就踩过同一个坑并写明「不在管道里接 head/grep」,
这里遗漏了。两处都改成「先落文件、再读文件」。
教训(这是今晚同类问题的第 N 次):修复脚本本身必须 set -euo pipefail,且断言要窄 ——
上一稿的修复脚本只写了 set -u,断言又过宽(命中注释里的 | head -1)当场失败后**继续往下跑**,
于是「以为改了、其实没改」,重跑的还是旧版本。
|
2026-10-04 03:13:28 +08:00 |
|
mole404
|
9037691995
|
ci: 加「手动补打版本号 tag」工作流(独立文件,不碰主发布流程)
用途:给**已发布过的历史镜像**补一个版本号 tag,日后能靠版本号拉回旧正式版。
本次要补的:现行正式版 0caef9ca… 补 v3.5.0。
为什么单独一个文件:
· on: 里只有 workflow_dispatch ⇒ 推代码不会启动它,不影响正常发布;
· 也不必改 build-image.yaml 里那段已被反复验证的 promote 逻辑,改动风险为 0。
为什么它不会变成「用版本号拉到 test 镜像」的后门 —— 四道守卫:
① 格式必须 vX.Y.Z;
② Compare API 强制要求目标 commit 在 master 上(test 的 commit 直接拒绝);
③ 目标镜像 sha-<commit> 必须真的存在(不能凭空造 tag);
④ 版本号 tag 已存在则保留原样、绝不覆盖。
(本地补打之所以失败是 401 —— 本地 token 缺 packages:write;CI 里 GITHUB_TOKEN 有。)
|
2026-10-04 03:10:32 +08:00 |
|
mole404
|
cdd4eb7d2e
|
chore(release): 版本号改 v3.5.1 + promote 时同步打版本号 tag
版本号机制(老师 2026-10-03 定):
· latest 永远 = master 最新正式版(原有行为不变);
· 每个正式版额外留一个**不可变**的版本号 tag(vX.Y.Z),日后可靠它拉回旧正式版;
· **无论如何都不能靠版本号拉到 test 分支的镜像** —— 结构性保证:promote 步骤的 if 写死
github.ref == 'refs/heads/master',分支构建根本执行不到打 tag 那几行。
版本号来源 = src/config/app.php 的 version(单一事实来源,与 PIN 从 Dockerfile 解析同一原则),
本次 v3.5 → v3.5.1。
三道守卫:
① 格式必须 vX.Y.Z;
② 用 Compare API 确认本 commit 确实在 master 上(挡住 workflow_dispatch 在别的 ref 上手动跑);
③ 版本号 tag 已存在则保留原样、绝不覆盖(这正是「靠版本号拉旧版」能成立的前提)。
|
2026-10-04 02:59:46 +08:00 |
|
mole404
|
de527c3ecb
|
ci: 纯文档推送不再触发完整构建(paths-ignore)
此前任何 push 都会跑一遍完整构建:约 10 分钟 runner + 一个约 1GB 的新镜像版本
(GHCR 版本堆到 100+ 个的主因),改个 README 也会把 :latest 顶成新 manifest ——
而镜像只 COPY src/ + 3 个 *.template + entrypoint.sh,README 并不进镜像,应用内容一字未变。
只忽略不进镜像、也不被构建/自证读取的文件:**.md、LICENSE、.gitignore。
语义是 fail-open:只有本次推送的改动全部命中忽略列表才跳过;碰到任何代码文件照旧构建。
|
2026-10-02 16:40:44 +08:00 |
|
mole404
|
e2f0b0e2bd
|
ci: 加一个手工触发的 GHCR 旧版本清理工作流
每次构建都会留下一个不可变的 sha-<commit> 版本(约 1GB/个),堆多了 GHCR 页面很乱、
回滚时也容易看错目标。这个 workflow 只在手工触发时运行:
默认 dry=true(只列出计划不删),清理时也永远保留 latest 与最近 N 个版本。
|
2026-10-02 16:29:34 +08:00 |
|
mole404
|
67b0e6e9d5
|
ci: 测试分支触发模式加 test(分支由 test/memory-tuning 改名)
|
2026-10-01 22:53:42 +08:00 |
|
mole404
|
539abe13a3
|
ci: 迁移数守卫基线 10 → 12
上游 pin 快照 10 条未动,新增的 2 条是本 fork 标签功能的表(create_tags_table /
create_image_tag_table,均为新增表、不改原表)。守卫继续钉住 12:之后再变数就报红。
注释里写明这 2 条同样要人工 migrate(线上升级:起新镜像后立刻 php artisan migrate --force)。
|
2026-10-01 22:04:37 +08:00 |
|
mole404
|
2da63c7e9a
|
chore(mem): MaxConnectionsPerChild 默认值改回 5(低流量下取最严内存纪律)
老师决定:他这台图床流量约 3 请求/分钟,MCP=5 意味着每 ~3 分钟才退休一个 worker,
换班开销可忽略;换班越勤,单个 worker 允许积累的内存天花板越低。故取回他原来的 5。
(中途试过 30,现按实测与他的偏好改回;env 覆盖机制 APACHE_MAX_CONNECTIONS_PER_CHILD
与 0=永不回收 的语义完全保留。)
同步改回:entrypoint.sh 默认值与旁注、build-image.yaml 6 处期望值(断言 + 自证清单 + 覆盖用例)、
Dockerfile 概览注释、docker-compose.yaml 注释。README 参数表本来就是 5,无需改。
验证:一次性容器集成跑 5 用例(默认→5、env=10→10、env=0→0、脏值 abc→回退 5 且不启动失败、
PHP_MEMORY_LIMIT 仍生效)+ apache2ctl -t = Syntax OK + memory_limit 仍 64M;
全仓 grep 无遗留的 30 期望值;Dockerfile 9 条 md5 自证 9/9。
|
2026-10-01 18:06:03 +08:00 |
|
mole404
|
5554c28c02
|
feat(mem): 测试版 —— PHP/opcache 收紧 + MaxConnectionsPerChild 放宽 + CI 断言
本提交只在 test/memory-tuning 分支上,master 保持 = 线上稳定版不动。
- 先量后改:镜像里实际生效的 memory_limit 是 512M(上游 memory-limit.ini),
不是 PHP 编译期默认的 128M。本轮改为默认 64M,并做成运行期可覆盖:
entrypoint 新增 PHP_MEMORY_LIMIT(默认 64M),只接受 <数字>[KMG],脏值只忽略该项
并警告、绝不启动失败,幂等;改 env 即可回 128M/256M,不用重建镜像。
- opcache 实测:配置 128M/10000;真实预热集合只用了 827 个脚本 / 25.0MB;
全树编译上限 9949 个脚本 / 255.9MB(走不到)→ memory_consumption 收成 64(约实测 2.6 倍,
省下 64MB 共享内存),max_accelerated_files 保持 10000,validate_timestamps=1 显式写死。
- MaxConnectionsPerChild 默认 5 → 30(减少无谓的 worker 换班),
APACHE_MAX_CONNECTIONS_PER_CHILD 覆盖机制与 0=永不回收 的语义原样保留。
- CI:Verify published image 新增两条断言(memory_limit == 64M、mpm.conf 有
MaxConnectionsPerChild 30),沿用先落文件再比较(不碰 pipefail + grep -q 那个坑);
MPM 自证步骤里的期望值 5 → 30。
- 分支安全:push 触发增加 test/*(保留 master);Promote to latest 本就有
github.ref == refs/heads/master 的条件(本轮补强注释),分支构建只产不可变 sha- 镜像;
retag.yaml 只由 workflow_dispatch 触发且硬拒 latest 目标,无需额外守卫。
|
2026-10-01 12:57:09 +08:00 |
|
mole404
|
c9a4ea1471
|
docs: README 整篇重写为介绍 + 部署;补 CI/构建卫生
README(659 行 → 176 行):只保留「这是什么」与「怎么部署/维护」——快速开始、首次安装、
升级(注明不需要 --force-recreate)、回滚(给真实存在的 sha-<commit> 标签)、备份与恢复
(整目录 tar,并说明 SQLite 开了 WAL 会短暂出现 -wal/-shm)、常见配置(端口/证书路径/
APACHE_* 六个变量与实际默认值)、许可与致谢。不再记录任何修复史或差异逐条。
所有具体值(镜像名、容器名、端口、卷路径、WEB_PORT/HTTPS_PORT、MPM 默认值、PHP/Laravel
版本、回滚标签)都对着源码与实机逐条核过。
构建与 CI:
- .dockerignore 补 src/storage/logs/*(+ 保留 .gitignore 占位):本机开发日志会被
COPY src/ 带进镜像(含本机绝对路径与错误栈)。用一份 moby 语义 matcher 验过排除生效、
且不影响 fontawesome 字体等构建必需品。
- update-composer-lock.yaml:两处 curl … | php 改成与 Dockerfile 同款「先落盘 → 官方
installer.sig → 校验 96 位 hex → sha384sum -c - → 再执行 → 删临时文件」(哈希不写死);
注释里的 9.52.17 与「5 条公告」校正为 9.52.22 / 4 条(OSV 实查)。
- build-image.yaml:扩展自证那段的结论文案改成与实际一致(硬断言只有 pdo_sqlite,
其余仅打印供人工比对)——sqlite3 对本站不是必需,钉死它会在无害变动时误红。
- tools/vendor-upstream.sh:去掉不存在的 test/run.sh,改为 cd test && npm test。
|
2026-09-30 09:03:04 +08:00 |
|
mole404
|
5020c4f01a
|
ci,ui,docs: 响应头断言 + 真升级用例基线动态化 + 钉 SHA 升级 + 顶栏对齐微调
CI:
- Verify published image 步骤新增两条断言:响应头不得出现 X-Powered-By、Server 不得带
具体版本号(沿用『先落文件再 grep』,不碰 SIGPIPE 那个坑);两条都双向验证过
(只注 PHP ini 或只注 Apache conf 都会红)。
- setup-node 换到 v7.0.0(node24)、upload-artifact 换到 v7.0.1(node24),
同时清掉第三个 workflow update-composer-lock.yaml 里那个 node20 的 upload-artifact;
其余 docker/* 与 checkout 本来就是 node24,不动。全部钉不可移动的 commit SHA。
- tools/upgrade-test.sh:真升级用例的基线从写死的 tag 改成动态解析(匿名读 GHCR
tags/list,逐个查镜像 config 的 created 时间取最新,并排除本次 commit 与自身),
不依赖 tags/list 的返回顺序;解析失败明确失败(不再静默变绿),仍可用仓库变量覆盖。
防漂移校验(tag 名里的 sha vs 镜像自带 .code-revision 的 fork_sha)原样保留。
顶栏(src/resources/views/layouts/header.blade.php):
- 折叠按钮 44×44 → 32×32(mt-3 保持 56px 顶栏内垂直居中)。
- 标题组的 pl-10 位置补偿改为 pl-4 md:pl-0:顶栏与页面内容共用同一个 x-container、
同断点内边距相同,所以 md 以上去掉补偿即等于内容左缘(实测 Δ=0.0);
窄屏内容左缘落在按钮底下,物理无法对齐,退回 pl-4(按钮右缘 +8px)。
- 已重建前端产物(public/css/app.css,新增 .pl-4/.pl-0/md:pl-0),钉住产物未变。
工具/文档:
- KNOWN_DEVIATIONS 同步到本轮全部有意偏离;README 补差异清单、CI 说明与验收清单。
|
2026-09-30 08:00:46 +08:00 |
|
mole404
|
235f72e68c
|
ci: 真升级用例 + retag digest 校验 + OSV 依赖门禁 + 修试构建 digest 冲突
- build-image.yaml:试构建时按请求版本自动从 Registry API 解析 php-cli / php-apache 的
index digest 一并传参。实测 tag@digest 时 digest 优先且 tag 被静默忽略 → 旧写法会构建出
默认版本、再被『PHP 版本校验』判红,白烧一次全量构建。另加 deps-scan job 作为 build 前置。
- 新增 tools/upgrade-test.sh:旧镜像 → 新镜像真升级用例(独立容器 / 卷 / 端口 18090),
断言数据面逐字节不变(.env / installed.lock / SQLite 文件与指纹 / 缩略图 / 编译缓存)、
代码确实换成新镜像那一版、终局日志必须是『已同步进卷』而非『跳过同步』。
本机真跑通过,并已用变异副本证明用例真能红(改数据面会红、tag 被挪会红)。
- retag.yaml:retag 后断言目标 digest 与源逐字一致,不一致则打印两个 digest 并失败。
- osv-scanner.toml:11 条已知且接受的告警入库(laravel 9.x 那几条上游无修复版本、
dev-only 与 test-only 各若干),新增漏洞会让 CI 红;抽掉白名单实测确实会红。
|
2026-09-30 07:20:43 +08:00 |
|
mole404
|
be94ecac1b
|
fix(ci): 代码同步自证别再让 pipefail 把「命中」当失败 + 等待信号改成等分支最终行
根因(CI 实撞):该步骤开了 set -euo pipefail,而它用 docker logs <c> | grep -q '<pat>' 判存在 —— grep -q 一命中就退出,docker logs 随即吃 SIGPIPE(141),pipefail 把整条管道判成失败,于是「日志里明明打印了】也判红(正是本项目技能里第 9 条记过的坑)。修法:统一先落文件再 grep;失败时把完整容器日志打出来。另:case C 的等待信号原来是「出现第一条 [lsky]」,入口脚本新增的自签证书日志行排在最前,把时序带偏(技能第 16 条:等待信号必须是该分支最后打的那行),改成直接等「跳过同步」。本地拿真镜像 sha-ae6ec156 复现过:入口脚本行为本身正确(跳过同步 + 手动修补保留)。
|
2026-09-30 06:29:31 +08:00 |
|
mole404
|
0dc245494d
|
docs(ci): README 同步 + 测试入口跑全量 + CI 钉 Node 版本
|
2026-09-30 06:18:56 +08:00 |
|
mole404
|
a2081e859c
|
fix(ci): MPM 自证步骤改为严格串行(每用例独立容器 + 独立卷)
上一版六个用例共用同一个卷、六个容器并发跑 entrypoint:A 的 chown -R 与 B 对
同一批文件的播种写入互踩(chown: ... No such file or directory),entrypoint 是
set -eu,chown 失败容器当场退出,后续 docker exec 报 No such container 而失败。
改法(只动 CI,产品代码零改动 —— 真实用户只跑一个容器,不存在该竞争):
- 每个用例独立容器 + 独立卷,严格串行:run → 等就绪 → 断言 → rm 容器+卷 → 下一个,
任何时刻最多一个容器在跑 entrypoint。
- 就绪信号:CMD 改为 `sh -c 'echo "[lsky-mpm] READY"; sleep 300'`;entrypoint 末尾是
exec "$@",故 READY 必然晚于播种/同步 + chown -R/chgrp -R/chmod -R 全部完成,
即上一个卷的写入者已收工,才进入下一个用例。
- 轮询容器状态,遇到 exited/dead 立即报错并 dump 日志;每个 docker exec 前
need_running 复核容器仍在运行;断言完即 finish_case 释放。
- 四类断言语义、apache2ctl -t 语法检查与 DUMP_RUN_CFG 信息性输出全部保留。
验证:yaml.safe_load 通过;抽取 run 脚本 bash -n 通过;静态走查并发(全脚本仅 1 处
docker run、无 & 后台化、run 前后各有 rm -f);用假 docker 替身真跑该步骤脚本 ——
新脚本 0 条并发违规、四类断言全绿 EXIT=0;同一替身跑旧脚本复现 5 条并发违规 +
15 条共用卷(与线上失败现象一致);并验证"容器启动即退出"路径能快速失败并清理干净。
|
2026-09-30 00:33:57 +08:00 |
|
mole404
|
c5b74cca9e
|
feat(apache): MPM 参数内置为镜像默认值(低配单用户),支持 APACHE_* 逐项覆盖
背景:镜像此前完全吃 Debian/php-apache 的出厂 MPM 值(prefork: StartServers 5 /
MinSpareServers 5 / MaxSpareServers 10 / MaxRequestWorkers 150 /
MaxConnectionsPerChild 0),低配单用户机上光是常驻 10 个空闲 PHP 子进程就已过重。
① 新增 mpm.conf.template(照 000-default.conf.template / ports.conf.template 的既有套路),
Dockerfile COPY 进 /etc/apache2/ 并加构建期护栏(模板缺失 / 占位符被删 → 构建失败)。
② entrypoint.sh 在 exec 之前渲染到 /etc/apache2/conf-enabled/mpm.conf —— Debian 的
apache2.conf 先 include mods-enabled 再 include conf-enabled,后者覆盖出厂 prefork 值。
内置默认:StartServers 2 / MinSpareServers 1 / MaxSpareServers 3 /
MaxRequestWorkers 5 / MaxConnectionsPerChild 5 / KeepAlive Off。
③ 六项各自独立覆盖(写哪个改哪个,没写的保持默认),并带校验与兜底:
非整数 / 越下限 / 一致性不满足(MaxRequestWorkers ≥ MaxSpareServers ≥ MinSpareServers)
→ 该项退回默认值 + [lsky] 警告;KeepAlive 只认 On/Off(大小写不敏感,统一渲染成 On/Off);
MaxConnectionsPerChild 允许 0(0 = 永不回收,合法值)。
渲染或落盘失败只警告,绝不影响容器启动(set -eu 下全部走 if 守卫,另挡掉
「目标路径被目录占住时 mv 静默假成功」那条实测发现的坑)。
④ APACHE_KEEPALIVE_TIMEOUT / APACHE_MAX_KEEPALIVE_REQUESTS 仅在 KeepAlive=On 且显式
设置时才写入;未设则不写该行,跟随 Apache 发行版默认(5 秒 / 100 个请求)。
⑤ README 新增「Apache MPM」一节:默认值、变量表、脏值策略、默认态日志摘要与自查命令、
高配参考值、以及「MaxRequestWorkers × 单进程内存 ≈ 可用内存」的估算提醒;
docker-compose.yaml 的 environment 加注释示例(不改任何生效值)。
⑥ CI 新增真容器步骤「Verify Apache MPM defaults and overrides」:默认态与期望的 6 行
逐行 diff;单项覆盖生效且其余仍默认;脏值退回默认且日志有警告;KeepAlive=On 时
「不设 timeout → 两行都不出现」「设了 → 两行出现且值正确」;大小写归一化;
并跑 apache2ctl -t 确认渲染结果不会让 Apache 报语法错。
本机验证(无 docker,镜像层由 CI 验):bash -n 通过;用抽取的入口脚本真代码跑 15 个场景
(全默认 / 单项覆盖 / 六项全脏 / KeepAlive 各形态 / 前导零 / 一致性破坏 / 目标被目录占住 /
模板缺失)全部 exit 0 且输出符合预期;Dockerfile 的 8 组 md5 自检与补丁字节校验未受影响
(未碰 patches/ 与 src/)。
|
2026-09-30 00:26:45 +08:00 |
|
mole404
|
655f080b82
|
ci: /images 回归断言只钉「首跳不许 301」(未安装状态的下游页 500 不算回归,改为告警 + dump 日志)
|
2026-09-29 20:45:00 +08:00 |
|
mole404
|
a4efab82e8
|
fix(严重): 默认头像挪出 public/images —— 它撞上了 /images 路由,导致整站打不开
事故:为放默认头像新建了真实目录 public/images/,而「我的图片」页路由正是 /images。
Apache 的文件系统优先,遇到真实目录就 301 跳到 /images/(那里没有 index → 403),
而首页 / 会 302 到 /images → 用户一打开就中招(日志证据:GET / → 302、GET /images → 301)。
修复:
① 头像移到 public/static/default-avatar.svg(static 不在顶层路由里;上游自己也只用
css/js/fonts/thumbnails 这类不撞路由的目录名),Utils::getAvatar() 同步改路径。
② entrypoint 无条件清掉卷里残留的 public/images/default-avatar.svg 并删空目录 ——
卷同步是「只增不删」,不做这步旧卷永远残留这个目录。只删我们自己放过的那一个文件。
③ CI 冒烟增加回归断言:/images 首跳不许是 301、跟随重定向必须 200、默认头像必须 200。
|
2026-09-29 20:41:38 +08:00 |
|
mole404
|
2ee1fd21e1
|
ci: 补全漏改的变量引用 + 给 workflow 加"未定义变量"自检(连红两轮的元凶)
- 「Verify code sync」步骤里还有 5 处引用已删除的 CONTEXT_JS_MD5 / BLADE_MD5 ——
它们会静默变成空串,导致该校验必然失败(bash -n 看不出来)
- 现在由「Verify published image」解析后写入 $GITHUB_ENV,后续步骤共用这两个值
- check_wf.py(本机校验脚本)新增检查:把 workflow 里 env:/赋值过的名字当已知变量,
扫出其余大写变量引用,防止这类"删了定义还有人在用"的假失败再次发生
|
2026-09-29 00:41:59 +08:00 |
|
mole404
|
6f3de25dca
|
ci: 镜像校验步骤的补丁 md5 改为从 Dockerfile 解析(消除第二处「事实的副本」)
背景:界面改造后 images.blade.php 的 md5 变了,Dockerfile 里两处都同步更新了,
但 workflow 的「Verify published image」步骤里还硬编码着旧的 f4e100c8 —— 镜像本身是对的
(构建期 md5sum -c 已断言),却被这一步判成失败而整轮变红。这与之前 LSKY_COMMIT 贴错 tag
是同一类病根:事实被抄了多份,改一处忘一处。
- 删掉 env 里的 CONTEXT_JS_MD5 / BLADE_MD5 常量,改为在校验步骤里
从 Dockerfile 的 .code-revision 生成段 grep 出期望值(单一事实来源)
- 解析不到就直接报错退出(避免"静默放过")
|
2026-09-29 00:38:33 +08:00 |
|
mole404
|
f20e2dbc6c
|
ui: 全站前端换新(清爽极简 + 亮/暗/跟随系统),交互逻辑零改动
设计系统
- resources/css/app.css:新增设计令牌(亮/暗两套 CSS 变量)+ 组件层
(ls-card / ls-btn / ls-input / ls-table / ls-nav-item / ls-menu …)
- tailwind.config.js:颜色指向令牌 —— 页面写 bg-surface / text-ink / border-line 即可,亮暗自动正确;
字体改为系统字体栈,去掉 Google Fonts 的 Nunito(国内慢、中文用不上)
主题
- resources/js/stores/theme.js:三态(跟随系统 / 亮 / 暗),存 localStorage,系统偏好变化时自动跟随
- layouts/app.blade.php + guest.blade.php:首屏内联脚本先给 <html> 加 .dark,避免暗色下闪白屏
- components/theme-switch.blade.php:外观切换控件(顶栏 + 登录页右上角)
页面
- 布局(sidebar / header / user-nav / notice / strategies / guest)与全部组件按新设计重排
- 27 个视图约 1000 处硬编码灰阶/蓝色 class 换成令牌;只动样式类,
id / data-* / Alpine 指令 / jQuery 钩子一律未动
- 第三方组件补暗色皮肤(toastr / sweetalert2 / viewer.js)
兼容与自证
- context-js.js(iOS 长按菜单)一行未改,md5 仍是 e114c840…
- images.blade.php 仅改样式类,md5 已在 Dockerfile 同步为 ec25ecc2…(?v=ios-longpress4 断言仍在)
- 70/70 jsdom 行为测试通过;verify_repo.py 通过;npm run prod 编译通过
- 构建资源请用 Node 18/20(Node 22+ 与 laravel-mix 6 不兼容)
|
2026-09-29 00:32:12 +08:00 |
|
mole404
|
e68476b715
|
deps: 镜像改用 composer install --no-dev(去掉 40 个开发包)+ 处理连带的包发现缓存
- 开发包(debugbar / ignition / whoops / phpunit / faker / sail / mockery / collision 等 40 个)
对线上没有用途:既占体积,也是暴露面(debugbar 那类在调试模式下会漏内部信息)
- 连带修复(这是关键,不然会 500):卷里的 bootstrap/cache/packages.php 是"当年装着开发包"时
生成的,记录了这些包的 ServiceProvider 类名。包没了之后 Laravel 引导时加载该清单会
Class not found → 整站 500。entrypoint 的同步分支现在会作废 packages.php / services.php
(两者都是纯缓存,下次请求会按当前 vendor/ 重新生成,删掉无副作用)
- CI 场景 B 新增回归:故意往卷里种一份引用 debugbar 的过期清单 → 断言同步后已被作废;
并新增断言"镜像里确实没有 vendor/phpunit | barryvdh | spatie/ignition | fakerphp"
- 新增 .github/workflows/retag.yaml:把某个 tag 重新指向**已存在**的镜像(用于修正历史贴错的 tag)。
安全闸:不允许 latest 当目标、源必须是 sha- 不可变 tag、打印改前/改后 digest
|
2026-09-28 23:48:54 +08:00 |
|
mole404
|
d298813708
|
fix(build): PHP 8.3 的官方镜像不再自带 ftp —— 两个阶段都显式安装,并加 CI 硬断言
换到 8.3 后构建失败的真因(CI 实测):php:8.1-cli/bookworm 自带 ftp 扩展,
php:8.3 的没有 → builder 阶段 composer install 校验平台要求时直接失败
(league/flysystem-ftp requires ext-ftp *)。
ftp 是 Lsky 的 FTP 存储驱动要用的扩展,不能依赖"从基镜像继承":
- builder 阶段:docker-php-ext-install ftp
- 运行时镜像:install-php-extensions 列表加 ftp
- CI 关键扩展硬断言列表加 ftp(以后基镜像再变也跑不掉)
|
2026-09-28 23:32:24 +08:00 |
|
mole404
|
2c38a89296
|
ci: lock 任务改用 composer config --global(不碰仓库 composer.json,避免 content-hash 不一致)+ 加锁一致性校验
|
2026-09-28 23:24:34 +08:00 |
|
mole404
|
a56b3580ba
|
ci: lock 任务加显式开关 ignore_advisory_policy(调研发现 Composer 2.10 默认拒绝整条 Laravel 9 线的版本,不关掉无法重新解析依赖)
|
2026-09-28 23:12:19 +08:00 |
|
mole404
|
1d2f3c3574
|
ci: lock 任务加 --prefer-stable(Lsky 是 minimum-stability: dev,不钉版本会选到 9.x-dev 开发分支)与低版本 PHP 兼容探针
|
2026-09-28 23:11:12 +08:00 |
|
mole404
|
d173585d46
|
ci: 修 PHP 版本断言(报告里有多行以 PHP 开头,sed 抓到两条 → 必须 head -1)
上一次 a25f758 的构建失败就是这条测试器 bug:变量取成了 8.1\n8.1,于是
「镜像里的 PHP 版本与请求的不一致」误报。产品侧没问题(pin 断言那步是通过的)。
|
2026-09-28 23:09:15 +08:00 |
|
mole404
|
b6ec17df8e
|
ci: lock 任务加依赖冲突诊断 + 镜像自证 dump 已装扩展
- lock 任务:先跑 composer why-not php <ver> / check-platform-reqs,讲清「谁把 PHP 版本卡住了」;
裸 php:cli 没有 ext-ftp(生产镜像有 —— 否则镜像构建期 composer install 早就失败),求解时按平台要求忽略
- 镜像自证报告新增:.code-revision 内容、PHP 版本、已装扩展全量 dump
(供人工比对 composer.lock 里 ext-* 的要求,排查「声明要但镜像没装」的扩展)
|
2026-09-28 23:09:00 +08:00 |
|
mole404
|
d5908b62d4
|
ci: 试构建不提升 latest;新增 composer.lock 定向更新任务
- workflow_dispatch 指定 php_version ≠ Dockerfile 默认时判定为「试构建」:只发不可变 tag,
跳过 Promote 步骤,避免未定案的版本成为线上 docker compose pull 的目标
- 新增 update-composer-lock.yaml:在指定 PHP 版本的容器里对**指定包**跑 composer update
(--with-all-dependencies),composer.lock 作为 artifact 上传,不自动提交;
同时输出 composer audit 与升级前后版本对照,供人工确认(本机没有 php,只有这条路)
|
2026-09-28 23:07:12 +08:00 |
|
mole404
|
0fe22ac24c
|
ci: 上游 pin/PHP 版本改为从 Dockerfile 解析,修掉 tag 贴错
- env.LSKY_COMMIT 硬编码 911275c,Dockerfile 升到 38d52c46 后漂移:
promote 步骤把新镜像贴上了「旧快照」tag,用那个 tag 回滚会拿到新代码(真事故)
- 改为从 Dockerfile 解析 ARG LSKY_COMMIT / ARG PHP_VERSION(单一事实来源)
- 新增断言:镜像内 .code-revision 的 lsky_commit 必须 == Dockerfile pin;PHP 版本必须 == 本次请求
- 新增 UPSTREAM_MIGRATION_COUNT 守卫:上游迁移文件数变了就报红(entrypoint 不跑 migrate)
- concurrency 串行化(不打断在跑的构建),避免旧构建把 latest 覆盖回去
- 5 个 action 全部按 commit SHA 钉住(该作业有 packages: write)
- workflow_dispatch 增加 php_version 输入,可试构建验证版本兼容性(不改仓库默认值)
|
2026-09-28 23:06:37 +08:00 |
|
mole404
|
7c3188e25a
|
refactor(源码): 应用源码 vendored 进 src/ + 上游 pin 升级到 38d52c46(2025-11-24)
上一版是「钉死上游 commit、构建时拉 archive、再用 overlay/ 叠加补丁」。但上游已明示停止维护
(README 里 2024-12-28 起挂着警告:「开源版本已停止维护,不再进行新特性更新和 bug 修复」),
所以把源码放进本仓库:构建不再依赖 github.com/lsky-org 长期可用,之后要改 PHP 代码直接改
src/ 提交即可,不必再维护叠加机制。
1) 上游 pin:911275c(2023-05-16)→ 38d52c4609eb85236b45ac75acac2ced55174953(2025-11-24)。
中间 32 个提交只动了 9 个文件,**数据库迁移 0 处**,所以升级不碰站点数据(SQLite 结构不变)。
吃进三个真实修复:图片格式转换时不同图片共用同一个临时文件(并发上传会变成同一张图,
默认配置即触发)、加水印后丢质量参数、SVG 支持;另有 laravel 9.52.4→9.52.17、
phpseclib 3.0.19→3.0.43、commonmark 2.3.9→2.6.0、aws-sdk-php 等一串依赖安全升级。
2) vendored 源码:src/ = 上游 38d52c46 的完整树(304 个文件、8.1MB,按 commit 精确复制,
文件数与上游 git 树一致)。我们的三个补丁文件就地打上补丁,取消 overlay/。
3) Dockerfile:去掉 curl 下载 archive 那一层,改成 COPY src/;自证拆成两组 ——
「自证 1 上游纯净性」ImageService.php / convention.php / public/index.php / routes/web.php /
composer.lock 必须等于上游 md5;「自证 2 补丁产物」三个补丁文件 md5 + 关键标记 grep。
快照被误改、补丁丢了,构建期就拦下。
4) 新增维护脚本:tools/diff-vs-upstream.sh(拉上游快照做全树对比 + 白名单校验:除三个补丁文件
外不许有别的改动,同时可重生成 patches/ios-longpress.patch)、tools/vendor-upstream.sh
(换 pin 时重新 vendor,自动保留补丁文件并打印上游侧差异)。
5) 测试与文档:jsdom 测试默认路径改指 src/public/js/context-js/context-js.js,新增两条结构自检
(两份 context-js.js 必须一致、blade 必须带 ?v= 版本串)→ 70/70 通过;README 重写
「代码在仓库哪里、怎么改、怎么升 pin」,并修正许可证说明(应用 GPL-3.0 / 打包 AGPL-3.0)。
数据安全逻辑一字未动:entrypoint.sh 仍是「版本标记不一致才同步」,排除
.env / storage / database / bootstrap/cache / public/i。换镜像后容器自动把新代码同步进卷。
|
2026-09-28 22:36:48 +08:00 |
|
mole404
|
ffb7947d89
|
fix(menu): 菜单只要还在屏幕上就不许点穿(修掉 Windows 偶发点穿)+ 诊断转储
老师报:Windows 上偶尔“菜单还在显示时,点一下别的图片就透了”,直接开预览。
根因:拦不拦那一发点击只看内存状态 menuVisible,而外部滚动 / resize / Esc / 关菜单后的
100ms 淡出都会把它提前置 false。其中 scroll 恰恰很容易被“非用户操作”触发 —— 菜单是绝对定位
插进 body 的,**插入这个动作本身**就可能改变页面高度/滚动条、让浏览器自己滚动(滚动锚定、
图片懒加载重排、justified-gallery 重排)。于是“菜单刚打开就被自己引发的滚动关掉”,紧接着
元素淡出的那 100ms 里菜单看着还在、状态已经是关 —— 这时点别的图片就直通开预览。这也解释了
它为什么是“偶尔”:取决于菜单落在哪、要不要出滚动条、浏览器是否触发滚动锚定。
改法(仍然只改 overlay/context-js.js 一个文件):
1) 判据由 menuVisible 换成 menuOnScreen():状态打开 || 关菜单后的淡出窗口(fadeSpeed+50ms)
|| DOM 实测(.dropdown-context 存在且 getBoundingClientRect().height > 0)。
这样任何一条把状态提前置 false 的路径,都不再让“看得见的菜单”失去拦截能力 ——
“看得见就不许点穿”变成硬保证。
2) MENU_OPEN_IGNORE_INPUT = 300ms:菜单刚打开的 300ms 内忽略 scroll/resize/orientation
(这一段里的滚动多半是菜单插入自身引发的);过了之后用户滚动照旧关菜单。
3) 诊断:常驻环缓冲记录最近 240 条菜单事件(打开 / 关闭**原因** / 每次点击的判定),
暴露 context.debugDump()(控制台 copy(context.debugDump()) 即可导出);
context.debug = true 时实时打控制台。
验证:
- test/longpress.test.mjs 68/68 通过。新增 5 条回归:淡出期间点别的图片不许点穿、
状态已 false 但 DOM 实测菜单可见时仍要吞、菜单刚打开 300ms 内的自引发滚动不关菜单、
菜单彻底消失后点击恢复正常(不会一直吞)、debugDump() 含打开记录与关闭原因。
- test/repro-clickthrough.mjs 最小复现(新增):对旧版打印 ❌ 点穿、新版打印 ✅ —— RED→GREEN 证据。
- CI 镜像自证新增 MENU_OPEN_IGNORE_INPUT / menuOnScreen / debugDump 三个标记断言。
- blade 版本串提到 ?v=ios-longpress4(击穿 Safari 启发式缓存);Dockerfile 三处 md5 +
.code-revision 两行 + workflow 的 CONTEXT_JS_MD5/BLADE_MD5 全部同步;
patches/ios-longpress.patch 重新生成并验证可干净应用、结果与 overlay 字节一致。
|
2026-09-28 22:11:58 +08:00 |
|
mole404
|
260560997d
|
test(ci): 镜像自证的报告里补上 isMenuOpen(断言要求它但没 grep 出来,属观测遗漏)
上一轮 CI(36429019512):jsdom 行为测试 56/56 全过 ✅、镜像 md5/阈值/其余三个标记全过 ✅,
只有 isMenuOpen 这条断言失败 —— 容器内那份报告只 grep 了 MENU_OPEN_GRACE / installMenuGuard /
touch-open,没 grep isMenuOpen,于是断言列表里的 isMenuOpen 取不到值。补上 grep 即可。
|
2026-09-28 21:32:37 +08:00 |
|
mole404
|
5151eff2e2
|
feat(menu): 点菜单外只关菜单(不再点穿)+ 触摸端二级菜单点击展开 + 滚动/缩放/Esc 关闭
老师在 iPhone 上提的两个交互问题,根因都在上游 context-js.js 里:
1) 点菜单之外会点穿:上游关闭逻辑只在 document 的冒泡阶段 fadeOut,不 preventDefault
也不 stopPropagation → 点别的图片时"关菜单"和"开预览"同时发生(Viewer.js 的 click
挂在图片网格上);手机上想关菜单只能去点地址栏,而地址栏又窄又难点。
2) 手机上二级菜单一点就没:二级菜单是 CSS :hover 驱动的,手机没光标 —— 点"复制链接"
时浏览器补发的合成 mouseenter 让子菜单闪一下,紧接着那发 click 撞上关闭逻辑,整个
菜单消失 → 复制链接里的 Url/Html/BBCode/Markdown 在手机上根本点不到。
改法(只在 overlay/context-js.js 里,不动主题 CSS):
- 菜单守卫装到 document 的捕获阶段:菜单打开时点菜单外 → 关菜单 + preventDefault +
stopPropagation,事件永远到不了页面处理器;菜单内部点击照旧放行(复制/重命名/删除不变)。
- 手机上"手指按下"就收起来(更跟手),随后补发的 click 用 700ms 时间窗吞掉;
拦截只打在 click 上、不拦 touchstart → 滚动/缩放不受影响。
- 刚打开的保护窗 MENU_OPEN_GRACE=800ms,只对"紧随一次触摸的 click"生效(lastTouchAt),
鼠标点击不受影响:长按抬手补发的那发 click 只吞掉、不关菜单(否则菜单刚开就自己关)。
- 触摸设备(matchMedia('(hover: none)'))点带二级菜单的父项 → 加 touch-open 类 + 注入与
hover 等价的 CSS,点击展开/收起、同层只留一个;有鼠标的设备继续 hover(桌面零改动)。
- 滚动/旋转缩放(含 #images-scroll 内部滚动)、Esc 关菜单;菜单自身滚动不误关。
- 新增 context.isMenuOpen()(上游没有)供测试与诊断观测菜单状态。
测试:test/longpress.test.mjs 25 → 56 个用例,覆盖上述每条分支,含三条回归
(抬手 click 不能关掉刚开的菜单 / 点菜单外必须吞点击 / 菜单关后点击要恢复正常)。
CI 新增 Behavior tests (jsdom) 步骤(构建前跑,npm ci + npm test),
镜像自证新增 installMenuGuard / MENU_OPEN_GRACE / touch-open / isMenuOpen 标记断言
与"Apache 实际吐出的 JS md5"端到端断言。
配套:blade 版本串 ios-longpress2 → ios-longpress3(击穿 Safari 启发式缓存)、
所有哈希断言同步(Dockerfile 自证 2 + .code-revision + workflow env)、
patches/ios-longpress.patch 重新生成(已 git apply --check 验证能干净打回上游并逐字节一致)、
README/test-README 文档更新、新增 .gitignore 与 test/package-lock.json。
|
2026-09-28 21:29:45 +08:00 |
|
mole404
|
7ef392d154
|
ci: 只构建 linux/amd64(老师这台是 x86_64,arm64 白烧一半构建时间)
- workflow 的 platforms 从 linux/amd64,linux/arm64 改成 linux/amd64,
步骤名同步改;注释里写了要 arm64 时怎么改回来(只动 platforms 一行)
- README 的平台示例同步说明
- 顺带掐掉了正在跑的多架构那一轮(自证内容与新一轮相同,没必要等)
|
2026-09-28 20:06:54 +08:00 |
|
mole404
|
6d67510628
|
test(ci): 测速那段改用 bash(sh 里没有 time 内建,exit 127 挂掉了整步)
上一轮 CI(36417548147)三个场景全绿:
A/A2 空卷播种不带 .env、安装页 200 ✓
B 旧标记自动同步、.env(内容)/数据库/上传/配置缓存零丢失、视图缓存已清 ✓
C 同标记跳过同步、手动修补保留、Apache 实际吐出的 JS = 补丁版 md5 ✓
只剩最后一段纯信息量的「同步开销」探测:`time` 是 bash 内建,写成了
`--entrypoint sh -c '... time ...'` → sh: time: not found → exit 127 整步变红。
改成 --entrypoint bash,并加 || echo 容忍(它只是量体积/耗时,不该拦住 promote)。
|
2026-09-28 20:04:02 +08:00 |
|
mole404
|
a38125a435
|
test(ci): 修 C 场景的 apache 就绪竞态(curl 拿到空响应)+ 失败自动打诊断
上一轮 CI(36415910785)结果:A/A2/B 全过(空卷播种无 .env、安装页 200、
旧标记自动同步、三项数据哨兵零丢失、视图缓存已清),只剩 C 的最后一条:
SERVED_JS=d41d8cd98f00b204e9800998ecf8427e 是**空字符串的 md5** ——
`[lsky]` 日志行是在 exec apache 之前打的,我拿它当就绪信号,于是 curl 时
apache 还没起来,拿到空响应。改成轮询「Apache 实际吐出的 JS md5 对上」为止。
顺带给这步加了 ERR trap:失败时自动 tail 三个容器的日志,下次不用翻整个 run 日志。
|
2026-09-28 19:45:17 +08:00 |
|
mole404
|
20273fb5be
|
test(ci): 自证步骤的等待信号改成「分支最后写的东西」(修竞态假失败)
上一轮 CI(36414664596)挂在「空卷里没有版本标记」—— 又是断言/等待逻辑的问题,
不是应用问题:播种分支要拷 115MB 应用树,其中 index.php 在字母序里很早就拷完,
而我拿它当「播种完成」信号,于是 cp 还在跑的时候就去查版本标记(标记是分支最后
才拷的),必然查不到。
- 场景 A:完成信号改成盯 `.code-revision`(播种分支最后一个写入),轮询放宽到 120s
- 场景 B:完成信号改成盯日志行 `已同步进卷`(sync 的 tar 写完之后才 echo),
避免在 tar 还在写卷时断言读到中间状态;JS md5 断言保留为同步后的硬校验
|
2026-09-28 19:28:57 +08:00 |
|
mole404
|
0a321bf49b
|
test(ci): 修掉自证步骤里两处我自己写错的断言
上一轮 CI(36412934705)结果:镜像自证全过(补丁 md5、blade、250ms、扩展、
/install 200),同步自证挂在场景 A —— 但那是**我断言写错**,不是应用问题:
我在 `curl /install` 之后才检查 .env,而 Lsky 的安装向导自己会创建 .env,
所以拿到的是「向导生成的那份」。安装页返回 200 恰好说明 500 已经修好了。
1) 场景 A 拆成 A(播种阶段,未发任何请求时 .env 必须不存在)+ A2(安装页 200)。
检查 .env 时若存在还会打印它与 .env.example / 镜像内 .env 的 md5,一眼分辨
是「镜像泄漏」还是「向导生成」。
2) 去掉 ENV_MODE=640 断言:上游 entrypoint 自带 `chmod -R 755 /var/www/html/`,
会把 .env 权限位归一化成 755,与同步无关(.env 内容仍被严格断言未被覆盖)。
3) 轮询循环改成 if 形式(`cmd && break` 在 set -e 下虽不退出,但语义含糊)。
|
2026-09-28 19:16:17 +08:00 |
|
mole404
|
7ddb15b7bd
|
fix(sync): 改成「按镜像版本标记」条件同步,并修掉首启分支把 .env 带进空卷的 500
老师选定方案甲(按版本标记条件同步),并修掉上一次 CI 抓到的真问题。
1) 修 500(我上一次改动引入的):首启分支还原成与上游逐字一致
`cp -a /var/www/lsky/* /var/www/html/` + 单独拷 .env.example。
镜像是带 .env 的(构建时由 .env.example 生成、APP_KEY 为空),
上一版用 `cp -a /var/www/lsky/.` 把它带进了空卷,Lsky 安装向导撞上已存在的
空 .env 直接 500 —— 全新建站会挂。现在钉了构建期护栏:首启分支必须保持
`/*` 形态且必须拷 .env.example,否则构建失败。
2) 版本标记:build 阶段生成 .code-revision(fork sha + 源码 commit + 两个补丁 md5),
入口脚本比较镜像内与卷内这一份:
空卷 → 全量播种(并写上标记)
已有卷 + 标记不同 → 同步代码 + 清编译视图缓存(= 换了镜像)
已有卷 + 标记相同 → 跳过(不白写整棵应用树,手改保留)
排除清单不变:.env / storage / database / bootstrap/cache / public/i 一律不碰。
附带好处:回滚也变成「换一行 image」—— 旧镜像标记不同会自动把代码同步回去。
3) CI 自证重写为三个真实 docker 场景(不过就不 promote latest):
A) 空卷:安装页 200 + 卷里必须没有 .env(钉住上面那个 500 的根因)
B) 已有卷 + 旧标记:代码被同步、.env(含权限位)/数据库/上传/config 缓存一项不被碰、视图缓存已清
C) 已有卷 + 同标记:跳过同步、手动修补保留、对外服务的 JS 仍是补丁版
本地自证:入口脚本三分支仿真 15/15、jsdom 行为测试 25/25、
Dockerfile 全部构建期断言 grep 命中、workflow 三个 run 脚本 bash/sh -n 通过。
|
2026-09-28 18:59:14 +08:00 |
|
mole404
|
90e151eef0
|
feat: 长按阈值 500→250ms;入口脚本改为每次启动强制同步代码进已有卷
老师的两个要求:
1) 长按 0.5s 偏长 → LONG_PRESS_DELAY 减半到 250ms。
- 配套保留「手指移动 >10px 即取消」,用来抵消阈值变短带来的误触风险
- blade 的资源版本串递增为 ?v=ios-longpress2,击穿 Safari 的启发式缓存
(否则老浏览器还在用 500ms 那份 JS)
- test/ 增加两个阈值回归用例(320ms 必须触发、160ms 必须不触发)
2) 升级不再需要人工 cp 文件:entrypoint.sh 在「已有部署」分支里每次启动都把
镜像代码同步进卷(tar 覆盖式),并自动清掉编译视图缓存。
- 绝不覆盖:.env / database/(SQLite)/ storage/(上传·日志·会话)/
bootstrap/cache/ / public/i —— 这五项是站点数据与配置,不是镜像代码
- Dockerfile 增加静态护栏:排除清单少一项就构建失败
- CI 新增「Verify forced code sync」步骤:模拟已有部署的卷(塞旧代码 +
.env/数据库/上传/编译缓存的哨兵文件),断言代码被更新、数据一项没被碰;
不过就 exit 1,不会 promote 到 latest
- README 重写升级/回滚章节并写明代价:手工改卷里的代码会失效、回滚必须连镜像一起回滚
自证:本地仿真 9/9(代码更新 + 五项数据保全)、jsdom 行为测试 25/25、
patch 能干净打到上游 911275c、Dockerfile 全部断言 grep 命中。
|
2026-09-28 18:24:08 +08:00 |
|
mole404
|
9f077ff974
|
ci: promote 步去掉 head 管道(SIGPIPE 让整步 exit 255),并补 php -m 分段行号诊断
|
2026-09-28 17:41:33 +08:00 |
|
mole404
|
3c9a95169a
|
ci: 修掉自证脚本的单引号截断 bug,并改成「自证通过才发布 latest」
问题:verify 步骤整段被 sh -c '...' 包着,新加的那行 php -r '...' 里的单引号
把外层字符串提前截断 → syntax error near unexpected token `(' ,自证直接挂。
修法:
- 扩展断言改用 php -m | grep -qix "$ext" 循环,内层脚本里彻底不用单引号
- 外层 grep 断言去掉单引号(grep -q pdo_sqlite=1)
- 内层脚本加注释说明这个坑,并补 php --ini / conf.d 列表用于排查 opcache 双列问题
流程改进:改为先推不可变 tag sha-<commit> → 自证 → 自证通过再用 buildx imagetools
把该 digest 提升为 :latest /:<源 commit>。自证不过时 latest 不会动,线上拉到的
永远是上一个已知可用版本。
|
2026-09-28 17:26:29 +08:00 |
|
mole404
|
3882451402
|
ci: 自证报告里补 pdo_sqlite 硬断言与 opcache 加载排查
- pdo_sqlite 断言:线上是 SQLite 数据库,扩展缺失会让站点直接挂,必须拦住
- 打印 conf.d 内容与 opcache 加载计数:上一次自证里 php -m 出现了两个
'Zend OPcache',需要确认是重复加载还是新版 PHP 的显示差异
|
2026-09-28 17:10:59 +08:00 |
|
mole404
|
565aa3fefc
|
feat: iOS 长按菜单修复 + 源码钉死在 911275c + GHCR 发布
问题:iOS WebKit 永远不派发 contextmenu(WebKit bug 213953),长按图片只弹系统
callout,导致"我的图片"页的自定义菜单在 iPhone/iPad 上完全不可用
(resources/js/context-js.js 的菜单只挂在 contextmenu 上)。
改动:
- overlay/context-js.js:纯增量补丁。新增仅 iOS 生效的长按分支(touchstart+500ms,
移动 >10px / 多指 / 短按都取消),复用原本的开菜单逻辑(beforeOpen/afterOpen 照旧);
注入 -webkit-touch-callout:none 压掉原生菜单(只作用于本库绑定的元素范围);
抬手吞掉 iOS 补发的 click,避免长按后误开图片预览;长按与 contextmenu 之间 700ms 去重。
判定只在 iPad/iPhone/iPod(含 iPadOS 伪装的 MacIntel+maxTouchPoints>1)为真,
Android / Windows / 真 Mac(含 M 系列,maxTouchPoints=0)一行新代码都不执行。
- overlay/images.blade.php:只给脚本加 ?v=ios-longpress,绕开 Safari 的启发式缓存
- Dockerfile:源码钉死 911275c(= 2024-04-29 那版线上镜像使用的 master HEAD);
基础镜像显式 bookworm;install-php-extensions 钉版本;构建期两处 md5 自证
- .github/workflows/build-image.yaml:替换上游的定时构建,改推 GHCR + 构建后真机自证
(核 md5、记录 PHP/扩展/Debian、真起容器 curl 安装页)
- test/:node + jsdom 行为测试(23 项,覆盖 iOS/iPad/Mac/Android/Windows 五类场景)
- README:补丁原理、跨平台隔离说明、升级/回滚步骤(含"换镜像不会更新已有卷代码"这个坑)
致谢与许可保留上游全部署名与 LICENSE(AGPL-3.0)。
|
2026-09-28 16:41:41 +08:00 |
|
HalcyonAzure
|
b5a8baf87a
|
revert: remove v7 arch
|
2024-04-21 01:51:44 +00:00 |
|
HalcyonAzure
|
e0fb05f611
|
feat: add armv7 arch
|
2024-04-21 09:48:15 +08:00 |
|
HalcyonAzure
|
2c5424be58
|
fix: github actions push wrong dockerhub branch, update README
|
2023-10-27 13:09:17 +08:00 |
|
HalcyonAzure
|
240bbe029d
|
feat: Integrate build process into Dockerfile and enable multi-platform builds in GitHub Actions
|
2023-10-27 12:58:41 +08:00 |
|