From 415a9f5dd30a1174a37496e09492c22d44f5a318 Mon Sep 17 00:00:00 2001 From: hectorqin Date: Fri, 30 Oct 2026 02:03:45 +0000 Subject: [PATCH] chore: drop CNB config; Android package is com.htmake.readerpro - Remove .cnb.yml and CNB references in the Dockerfile and Compose file; the Compose default image is hectorqin/reader-pro:latest. - Rename the Android applicationId/namespace and Kotlin package from cool.cnb.reader to com.htmake.readerpro (shortcuts, ProGuard, shell check). Installs under the old package are a different app and are not migrated. Co-Authored-By: Claude Opus 5.5 --- .cnb.yml | 250 ------------------ android/app/build.gradle.kts | 4 +- android/app/proguard-rules.pro | 2 +- .../htmake/readerpro}/MainActivity.kt | 12 +- .../readerpro}/bridge/ConnectivityMonitor.kt | 2 +- .../htmake/readerpro}/bridge/ReaderBridge.kt | 6 +- .../htmake/readerpro}/bridge/SpeechBridge.kt | 2 +- .../readerpro}/media/MediaAudioCoordinator.kt | 2 +- .../htmake/readerpro}/media/MediaBridge.kt | 4 +- .../readerpro/media/MediaLaunchRoute.kt | 11 + .../readerpro}/media/MediaPlaybackService.kt | 4 +- .../readerpro}/media/MediaProgressSync.kt | 2 +- .../readerpro}/media/MediaRecoverySnapshot.kt | 2 +- .../readerpro}/media/MediaRecoveryStore.kt | 2 +- .../readerpro}/media/MediaVideoActivity.kt | 2 +- .../htmake/readerpro}/media/PlaybackQueue.kt | 2 +- .../readerpro}/media/QueueSessionPlayer.kt | 2 +- .../readerpro}/media/SubtitleRequestGate.kt | 2 +- .../htmake/readerpro}/media/VideoPipPolicy.kt | 2 +- .../htmake/readerpro}/web/NativePageView.kt | 2 +- .../htmake/readerpro}/web/WebHost.kt | 14 +- .../cool/cnb/reader/media/MediaLaunchRoute.kt | 11 - .../app/src/main/res/xml/media_shortcuts.xml | 6 +- .../media/MediaBackgroundSyncTest.kt | 2 +- .../readerpro}/media/MediaLaunchRouteTest.kt | 8 +- .../readerpro}/media/MediaLiveServerTest.kt | 2 +- .../readerpro}/media/MediaProgressSyncTest.kt | 2 +- .../media/MediaRecoverySnapshotTest.kt | 2 +- .../readerpro}/media/PlaybackQueueTest.kt | 2 +- .../media/QueueSessionPlayerTest.kt | 2 +- .../media/SubtitleRequestGateTest.kt | 2 +- .../readerpro}/media/VideoPipPolicyTest.kt | 2 +- android/scripts/check-shell.sh | 14 +- docker-compose.yml | 6 +- server/Dockerfile | 8 +- 35 files changed, 74 insertions(+), 326 deletions(-) delete mode 100644 .cnb.yml rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/MainActivity.kt (96%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/bridge/ConnectivityMonitor.kt (98%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/bridge/ReaderBridge.kt (99%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/bridge/SpeechBridge.kt (99%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaAudioCoordinator.kt (86%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaBridge.kt (99%) create mode 100644 android/app/src/main/java/com/htmake/readerpro/media/MediaLaunchRoute.kt rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaPlaybackService.kt (99%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaProgressSync.kt (99%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaRecoverySnapshot.kt (98%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaRecoveryStore.kt (98%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaVideoActivity.kt (99%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/PlaybackQueue.kt (99%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/QueueSessionPlayer.kt (95%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/SubtitleRequestGate.kt (95%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/media/VideoPipPolicy.kt (93%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/web/NativePageView.kt (99%) rename android/app/src/main/java/{cool/cnb/reader => com/htmake/readerpro}/web/WebHost.kt (96%) delete mode 100644 android/app/src/main/java/cool/cnb/reader/media/MediaLaunchRoute.kt rename android/app/src/test/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaBackgroundSyncTest.kt (99%) rename android/app/src/test/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaLaunchRouteTest.kt (79%) rename android/app/src/test/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaLiveServerTest.kt (99%) rename android/app/src/test/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaProgressSyncTest.kt (99%) rename android/app/src/test/java/{cool/cnb/reader => com/htmake/readerpro}/media/MediaRecoverySnapshotTest.kt (97%) rename android/app/src/test/java/{cool/cnb/reader => com/htmake/readerpro}/media/PlaybackQueueTest.kt (99%) rename android/app/src/test/java/{cool/cnb/reader => com/htmake/readerpro}/media/QueueSessionPlayerTest.kt (96%) rename android/app/src/test/java/{cool/cnb/reader => com/htmake/readerpro}/media/SubtitleRequestGateTest.kt (97%) rename android/app/src/test/java/{cool/cnb/reader => com/htmake/readerpro}/media/VideoPipPolicyTest.kt (95%) diff --git a/.cnb.yml b/.cnb.yml deleted file mode 100644 index 9db2497..0000000 --- a/.cnb.yml +++ /dev/null @@ -1,250 +0,0 @@ -# CI:服务端(Node/TypeScript)、客户端(Web/TypeScript)、Android 壳(Kotlin)。 -# -# 每个任务都用 ifModify 限定到自己那部分,避免改一行 README 就把三条流水线 -# 全跑一遍。 - -# 服务端与客户端都是 Node 生态,共用同一个镜像锚点。 -.node-env: &node-env - docker: - image: node:24 - -.server-check: &server-check - - name: install - script: cd server && npm ci - - name: typecheck - script: cd server && npm run typecheck - - name: test - script: cd server && npm test - - name: build - script: cd server && npm run build - -.client-check: &client-check - - name: install - script: cd web && npm ci - - name: typecheck - script: cd web && npm run typecheck - - name: test - script: cd web && npm test - - name: build - script: cd web && npm run build - -# UI 评审:把真实产物在真实 Chromium(390×844)里逐屏渲染、截图并测量。 -# -# 和 `client-check` 分开,因为两者回答的问题不同:那里问「功能对不对」, -# 这里问「看起来对不对」—— 面板是不是盖住了整页、底部页数和可翻次数是不是 -# 一个数、状态提示出现时正文会不会被推下去。这些都能在功能全绿的同时是错的, -# 而它们的形态只有截图和量出来的数字能发现(见 docs/ui.md §8)。 -# -# 截图作为制品留存,所以一次失败的评审可以被人看到,而不是只看到一行报错。 -.ui-review: &ui-review - docker: - # 镜像里带 Chromium。评审工具只用 CDP 协议驱动浏览器(见 - # `web/tools/ui-review/cdp.mjs`),所以这里只要一个能跑的 Chromium, - # 不需要 playwright 的运行时依赖。 - # - # `/usr/local/bin/chromium` 是镜像自己提供的路径之一,工具会按 - # CHROME_PATH → chromium → chromium-browser → google-chrome 的顺序找, - # 找不到就直接报错,不会静默跳过整轮评审。 - image: mcr.microsoft.com/playwright:v1.49.1-noble - stages: - - name: install - script: cd web && npm ci - # 生产产物,不是 dev server:被评审的必须是用户真正拿到的那份。 - - name: build - script: cd web && npm run build - - name: ui-review - script: cd web && npm run ui:review:only - - name: archive-screenshots - script: | - echo "UI 评审产物:artifacts/ui-review/react-app/" - ls -la artifacts/ui-review/react-app/ - -main: - push: - - name: server-ci - <<: *node-env - ifModify: - - server/** - stages: - - *server-check - failStages: - - name: report-failure - script: echo "服务端 CI 失败:$CNB_BUILD_FAILED_MSG" - - - name: client-ci - <<: *node-env - ifModify: - - web/** - stages: - - *client-check - - # UI 评审只在界面相关文件变化时跑:它要装 Chromium、渲染八屏、量尺寸, - # 比 client-ci 慢一个量级,而它验证的每一条规则都只被样式与组件改动影响。 - - name: client-ui-review - <<: *ui-review - ifModify: - - web/src/ui/** - - web/src/styles/** - - docs/ui.md - - web/tools/ui-review/** - - web/index.html - failStages: - - name: report-failure - script: echo "客户端 CI 失败:$CNB_BUILD_FAILED_MSG" - - # Android 壳。 - # - # 先跑一个不依赖 JDK 的静态检查(秒级),再编译。原因是桥接契约的两半分别 - # 用 Kotlin 和 TypeScript 写,互相没法类型检查:客户端调用一个壳里没有的 - # 方法是最容易出、也最难在本地发现的错误。静态检查把它提前到这里。 - # - # 触发条件包含 `web/src/formats/types.ts`:壳里分支的渲染模式词表来自它, - # 改一个词就会让整条原生渲染通道静默失效,而 Kotlin 编译器不会知道。 - # 镜像走 Docker Hub 命名空间,CNB 会自动经 Docker Hub 代理注入只读令牌。 - # - # 这里曾写 `androidsdk/android-35:latest`,而 Docker Hub 的 `androidsdk` - # 命名空间**没有**这个仓库 —— 它只发布到 `android-31`(`android-33` 及以上 - # 都是 404)。仓库不存在时 Docker Hub 返回 `pull access denied / repository - # does not exist or may require 'docker login'`,daemon 会重试一次,然后 - # prepare 阶段直接失败:`docker pull failed: 任务执行失败,返回码:1`。整条 - # 流水线还没进入任何 stage 就红了,所以 `shell-contract`/`assemble` 全是 - # skipped —— 失败信息指向 `docker pull`,但真正的问题是镜像名指向了一个 - # 不存在的仓库,与令牌、网络、代理都无关。 - # - # 改用 `mobiledevops/android-sdk-image`:Docker Hub 上真实存在且在维护的 - # 社区镜像(2026-07 仍有更新,多架构 amd64/arm64)。它的 `packages.txt` 含 - # `platforms;android-35` 与 `build-tools;35.0.1`,正好匹配本项目的 - # compileSdk/targetSdk=35;基础镜像是 ubuntu:24.04 + openjdk-21(满足 - # Gradle 8.11 与 AGP 8.7 对 JDK 17+ 的要求),并已预接受 SDK 许可, - # assemble 不需要再联网下载平台组件。 - # - # 用 `latest` 而不是 `36.1.0` 之类的构建工具版本号:这个仓库的 tag 是按 - # build-tools 版本命名的,`latest` 始终指向包含 android-35 的最新一份, - # 写死版本反而会在下一次平台升级后被遗漏。若要完全可复现可改钉具体 tag。 - - name: android-ci - docker: - image: mobiledevops/android-sdk-image:latest - ifModify: - - android/** - - web/src/android-bridge.d.ts - - web/src/formats/types.ts - - web/src/ui/native-page.ts - stages: - - name: shell-contract - script: sh android/scripts/check-shell.sh - - name: assemble - script: cd android && ./gradlew --no-daemon :app:assembleDebug - failStages: - - name: report-failure - script: echo "Android 构建失败:$CNB_BUILD_FAILED_MSG" - - # 客户端产物必须能被壳打包。这条单独跑,因为 `client-ci` 只证明 H5 能构建, - # 不证明 assets 里有东西——而一个空的 assets 目录会产出一个启动即白屏的 APK。 - - name: web-assets-ci - <<: *node-env - ifModify: - - web/** - # 触发条件包含脚本自身与 assets 目录布局:改这段逻辑、或改 Gradle 里 - # `assets.srcDirs` 指到哪,本来不会跑任何验证,而它坏掉的形态是 APK 里 - # 没有客户端、启动即白屏 —— 只有跑一遍才知道。 - - android/scripts/build-web-assets.sh - - android/scripts/verify-web-assets.sh - - android/app/build.gradle.kts - - android/app/src/main/assets/** - stages: - - name: stage-for-shell - script: sh android/scripts/build-web-assets.sh - # 只证明脚本写出了 assets 还不够,还要证明「写出来的东西真的会被打进 APK」。 - # 脚本只知道它写到哪,Gradle 只知道哪些目录算 assets,两者之间没有任何 - # 东西把它们连起来 —— 这两条路径此前就漂移过。 - - name: verify-assets-are-packaged - script: sh android/scripts/verify-web-assets.sh - - # 发布镜像到制品库 `docker.cnb.cool/hectorqin/reader`。 - # - # 只在 `server/`、`web/` 或构建文件变更时跑:镜像里只有这两部分。文档改一行 - # 也重新发布一个镜像,会让制品库里堆满内容完全相同的标签。 - # - # 为什么用 CNB 官方的 `services: docker`,而不是 `docker.build` + kaniko - # 插件任务:`docker.build` 的产物只活在 runner 的本地 dockerd 里,而平台 - # 起插件任务容器走的是 `docker pull `,不查本地镜像列表—— - # `docker.build` 那条路要求 `image:` 写成与 `dockerfile` 同名的裸名字或 - # 缓存仓库地址,靠平台去跟已构建的镜像做匹配。这条流水线因此在 `main` 上 - # 连错八次,报错覆盖了 `pull access denied`(被当成 Docker Hub 官方镜像) - # 与 `invalid reference format`(名字里有大写或非法字符)两类;最后是靠把 - # `image:` 指向 `dockerfile-caches` 的完整仓库地址跑通的,代价是那次匹配 - # 依赖把一个**缓存 digest** 写死进流水线。 - # - # 换成 dind 之后整条链路上只剩标准 Docker: - # - 不再依赖平台对 `image:` 的匹配约定,也就不需要把缓存 digest 当镜像名; - # - 没有 kaniko,就不必为了 `COPY server/...` 保住大小写而绕开工作区, - # `GIT_CLONE_PATH` 那个补丁连同它带来的 `--context-sub-path` 需求一起没了; - # - 也不需要单独 `docker login`,CNB 起 dind 服务时会自动登录制品库, - # 用的是同一次构建的临时令牌,权限天然对齐。 - # 之前维护的根目录 `Dockerfile` / `kaniko-plugin.sh` 随之删除。 - - name: docker-image - services: - - docker - ifModify: - - server/** - - web/** - - server/Dockerfile - - .dockerignore - # 触发条件包含自身,否则改完构建逻辑没法验证。 - - .cnb.yml - stages: - - name: docker build and push - # 镜像路径按「同名制品」规则走,即 `docker.cnb.cool/hectorqin/reader`, - # 与 README、docker-compose.yml 里引用的地址一致。用 - # `CNB_REPO_SLUG_LOWERCASE` 而不是写死 `hectorqin/reader`:Docker 要求 - # 仓库名全小写,而 CNB 的仓库路径本身可能带大写。 - # - # 构建上下文是仓库根,`server/Dockerfile` 里那句 `COPY web/...` 依赖 - # 这一点(客户端产物要打进服务端镜像)。`services: docker` 下的任务 - # 工作目录就是仓库根,不需要额外指定 `-f`/`--context`。 - # - # 两个标签:分支名给「跟 main 走」的部署用,短 commit 给需要回滚到 - # 某个确切版本的情况用。`main` 分支上两者分别是 `main` 和当次提交。 - # 逐个 `docker push` 而不是 `--all-tags`:文档里的写法就是显式推标签, - # 不想把这条流水线绑在一个没被文档覆盖的 flag 上。 - script: | - set -eu - image="$CNB_DOCKER_REGISTRY/$CNB_REPO_SLUG_LOWERCASE" - docker build -t "$image:$CNB_BRANCH" -t "$image:$CNB_COMMIT_SHORT" \ - -f server/Dockerfile . - docker push "$image:$CNB_BRANCH" - docker push "$image:$CNB_COMMIT_SHORT" - failStages: - - name: report-failure - script: echo "镜像发布失败:$CNB_BUILD_FAILED_MSG" - -"**": - pull_request: - - name: server-checks - <<: *node-env - ifModify: - - server/** - stages: - - *server-check - - - name: client-checks - <<: *node-env - ifModify: - - web/** - stages: - - *client-check - - # PR 阶段只跑不依赖 JDK/SDK 的那半(秒级)。桥接契约断裂与渲染模式词表漂移 - # 是最容易出、最难在本地发现的错误 —— 两半分别用 Kotlin 和 TypeScript 写, - # 互相没法类型检查 —— 而它们恰好都不需要编译就能查出来。完整 assembleDebug - # 仍只在 main 的 push 上跑,PR 不该为一个 SDK 镜像等几分钟。 - - name: android-contract-checks - <<: *node-env - ifModify: - - android/** - - web/src/android-bridge.d.ts - - web/src/formats/types.ts - - web/src/ui/native-page.ts - stages: - - name: shell-contract - script: sh android/scripts/check-shell.sh diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 97494ac..dffabb3 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -4,11 +4,11 @@ plugins { } android { - namespace = "cool.cnb.reader" + namespace = "com.htmake.readerpro" compileSdk = 35 defaultConfig { - applicationId = "cool.cnb.reader" + applicationId = "com.htmake.readerpro" minSdk = 24 targetSdk = 35 versionCode = 1 diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index 4a18cc5..a115c40 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -2,7 +2,7 @@ # annotation. R8 cannot see those call sites, so without this the release build # would strip them and the client would silently lose connectivity reporting and # the device label. --keepclassmembers class cool.cnb.reader.bridge.ReaderBridge { +-keepclassmembers class com.htmake.readerpro.bridge.ReaderBridge { public *; } -keepattributes JavascriptInterface diff --git a/android/app/src/main/java/cool/cnb/reader/MainActivity.kt b/android/app/src/main/java/com/htmake/readerpro/MainActivity.kt similarity index 96% rename from android/app/src/main/java/cool/cnb/reader/MainActivity.kt rename to android/app/src/main/java/com/htmake/readerpro/MainActivity.kt index 6815658..54ad625 100644 --- a/android/app/src/main/java/cool/cnb/reader/MainActivity.kt +++ b/android/app/src/main/java/com/htmake/readerpro/MainActivity.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader +package com.htmake.readerpro import android.annotation.SuppressLint import android.content.Intent @@ -12,11 +12,11 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import android.widget.FrameLayout -import cool.cnb.reader.bridge.ConnectivityMonitor -import cool.cnb.reader.bridge.ReaderBridge -import cool.cnb.reader.bridge.SpeechBridge -import cool.cnb.reader.web.NativePageView -import cool.cnb.reader.web.WebHost +import com.htmake.readerpro.bridge.ConnectivityMonitor +import com.htmake.readerpro.bridge.ReaderBridge +import com.htmake.readerpro.bridge.SpeechBridge +import com.htmake.readerpro.web.NativePageView +import com.htmake.readerpro.web.WebHost /** * The only activity. diff --git a/android/app/src/main/java/cool/cnb/reader/bridge/ConnectivityMonitor.kt b/android/app/src/main/java/com/htmake/readerpro/bridge/ConnectivityMonitor.kt similarity index 98% rename from android/app/src/main/java/cool/cnb/reader/bridge/ConnectivityMonitor.kt rename to android/app/src/main/java/com/htmake/readerpro/bridge/ConnectivityMonitor.kt index 0135fea..877b41e 100644 --- a/android/app/src/main/java/cool/cnb/reader/bridge/ConnectivityMonitor.kt +++ b/android/app/src/main/java/com/htmake/readerpro/bridge/ConnectivityMonitor.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.bridge +package com.htmake.readerpro.bridge import android.content.Context import android.net.ConnectivityManager diff --git a/android/app/src/main/java/cool/cnb/reader/bridge/ReaderBridge.kt b/android/app/src/main/java/com/htmake/readerpro/bridge/ReaderBridge.kt similarity index 99% rename from android/app/src/main/java/cool/cnb/reader/bridge/ReaderBridge.kt rename to android/app/src/main/java/com/htmake/readerpro/bridge/ReaderBridge.kt index 6b97b1c..919be26 100644 --- a/android/app/src/main/java/cool/cnb/reader/bridge/ReaderBridge.kt +++ b/android/app/src/main/java/com/htmake/readerpro/bridge/ReaderBridge.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.bridge +package com.htmake.readerpro.bridge import android.content.Context import android.os.Build @@ -7,7 +7,7 @@ import android.os.Looper import android.webkit.JavascriptInterface import android.webkit.WebView import android.widget.Toast -import cool.cnb.reader.web.NativePageView +import com.htmake.readerpro.web.NativePageView import org.json.JSONObject import java.text.SimpleDateFormat import java.util.Date @@ -68,7 +68,7 @@ class ReaderBridge( * the web layer decides when to pay that, by calling `init()` when the reader * first opens the朗读 settings rather than on every app start. */ - private val speechBridge = SpeechBridge(context, webView) { cool.cnb.reader.media.MediaAudioCoordinator.pauseMedia?.invoke() } + private val speechBridge = SpeechBridge(context, webView) { com.htmake.readerpro.media.MediaAudioCoordinator.pauseMedia?.invoke() } /** * Runs a UI-thread block and waits for its result. diff --git a/android/app/src/main/java/cool/cnb/reader/bridge/SpeechBridge.kt b/android/app/src/main/java/com/htmake/readerpro/bridge/SpeechBridge.kt similarity index 99% rename from android/app/src/main/java/cool/cnb/reader/bridge/SpeechBridge.kt rename to android/app/src/main/java/com/htmake/readerpro/bridge/SpeechBridge.kt index 019a8f6..be56b7c 100644 --- a/android/app/src/main/java/cool/cnb/reader/bridge/SpeechBridge.kt +++ b/android/app/src/main/java/com/htmake/readerpro/bridge/SpeechBridge.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.bridge +package com.htmake.readerpro.bridge import android.content.Context import android.os.Bundle diff --git a/android/app/src/main/java/cool/cnb/reader/media/MediaAudioCoordinator.kt b/android/app/src/main/java/com/htmake/readerpro/media/MediaAudioCoordinator.kt similarity index 86% rename from android/app/src/main/java/cool/cnb/reader/media/MediaAudioCoordinator.kt rename to android/app/src/main/java/com/htmake/readerpro/media/MediaAudioCoordinator.kt index 8dde695..8534b95 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/MediaAudioCoordinator.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/MediaAudioCoordinator.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media /** Called only on the main looper. Neither subsystem needs to know the other's implementation. */ object MediaAudioCoordinator { diff --git a/android/app/src/main/java/cool/cnb/reader/media/MediaBridge.kt b/android/app/src/main/java/com/htmake/readerpro/media/MediaBridge.kt similarity index 99% rename from android/app/src/main/java/cool/cnb/reader/media/MediaBridge.kt rename to android/app/src/main/java/com/htmake/readerpro/media/MediaBridge.kt index bec3f78..7f82fbd 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/MediaBridge.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/MediaBridge.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import android.content.ComponentName import android.content.Context @@ -18,7 +18,7 @@ import androidx.media3.session.SessionCommand import androidx.webkit.JavaScriptReplyProxy import androidx.webkit.WebViewCompat import androidx.webkit.WebViewFeature -import cool.cnb.reader.web.WebHost +import com.htmake.readerpro.web.WebHost import java.net.URI import org.json.JSONObject import org.json.JSONArray diff --git a/android/app/src/main/java/com/htmake/readerpro/media/MediaLaunchRoute.kt b/android/app/src/main/java/com/htmake/readerpro/media/MediaLaunchRoute.kt new file mode 100644 index 0000000..999fec8 --- /dev/null +++ b/android/app/src/main/java/com/htmake/readerpro/media/MediaLaunchRoute.kt @@ -0,0 +1,11 @@ +package com.htmake.readerpro.media + +/** Launcher shortcuts select fixed local routes, never caller-provided URLs. */ +object MediaLaunchRoute { + fun fragmentForAction(action: String?): String? = when (action) { + "com.htmake.readerpro.OPEN_VIDEO" -> "#/media/video" + "com.htmake.readerpro.OPEN_MUSIC" -> "#/media/music" + "com.htmake.readerpro.OPEN_AUDIOBOOK" -> "#/media/audiobook" + else -> null + } +} diff --git a/android/app/src/main/java/cool/cnb/reader/media/MediaPlaybackService.kt b/android/app/src/main/java/com/htmake/readerpro/media/MediaPlaybackService.kt similarity index 99% rename from android/app/src/main/java/cool/cnb/reader/media/MediaPlaybackService.kt rename to android/app/src/main/java/com/htmake/readerpro/media/MediaPlaybackService.kt index 305ca64..869117d 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/MediaPlaybackService.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/MediaPlaybackService.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import android.app.PendingIntent import android.content.Intent @@ -19,7 +19,7 @@ import androidx.media3.session.SessionCommand import androidx.media3.session.SessionResult import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.ListenableFuture -import cool.cnb.reader.MainActivity +import com.htmake.readerpro.MainActivity import org.json.JSONObject import org.json.JSONArray diff --git a/android/app/src/main/java/cool/cnb/reader/media/MediaProgressSync.kt b/android/app/src/main/java/com/htmake/readerpro/media/MediaProgressSync.kt similarity index 99% rename from android/app/src/main/java/cool/cnb/reader/media/MediaProgressSync.kt rename to android/app/src/main/java/com/htmake/readerpro/media/MediaProgressSync.kt index 27f919d..26267d1 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/MediaProgressSync.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/MediaProgressSync.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import java.net.HttpURLConnection import java.net.URI diff --git a/android/app/src/main/java/cool/cnb/reader/media/MediaRecoverySnapshot.kt b/android/app/src/main/java/com/htmake/readerpro/media/MediaRecoverySnapshot.kt similarity index 98% rename from android/app/src/main/java/cool/cnb/reader/media/MediaRecoverySnapshot.kt rename to android/app/src/main/java/com/htmake/readerpro/media/MediaRecoverySnapshot.kt index ca8439b..a83c95b 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/MediaRecoverySnapshot.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/MediaRecoverySnapshot.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import java.net.URI import org.json.JSONArray diff --git a/android/app/src/main/java/cool/cnb/reader/media/MediaRecoveryStore.kt b/android/app/src/main/java/com/htmake/readerpro/media/MediaRecoveryStore.kt similarity index 98% rename from android/app/src/main/java/cool/cnb/reader/media/MediaRecoveryStore.kt rename to android/app/src/main/java/com/htmake/readerpro/media/MediaRecoveryStore.kt index 22ceddf..a0dc7a8 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/MediaRecoveryStore.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/MediaRecoveryStore.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import android.content.Context import android.security.keystore.KeyGenParameterSpec diff --git a/android/app/src/main/java/cool/cnb/reader/media/MediaVideoActivity.kt b/android/app/src/main/java/com/htmake/readerpro/media/MediaVideoActivity.kt similarity index 99% rename from android/app/src/main/java/cool/cnb/reader/media/MediaVideoActivity.kt rename to android/app/src/main/java/com/htmake/readerpro/media/MediaVideoActivity.kt index 811efa5..2a65dd3 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/MediaVideoActivity.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/MediaVideoActivity.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import android.content.ComponentName import android.app.PictureInPictureParams diff --git a/android/app/src/main/java/cool/cnb/reader/media/PlaybackQueue.kt b/android/app/src/main/java/com/htmake/readerpro/media/PlaybackQueue.kt similarity index 99% rename from android/app/src/main/java/cool/cnb/reader/media/PlaybackQueue.kt rename to android/app/src/main/java/com/htmake/readerpro/media/PlaybackQueue.kt index c117c61..dbbb03f 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/PlaybackQueue.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/PlaybackQueue.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import org.json.JSONObject diff --git a/android/app/src/main/java/cool/cnb/reader/media/QueueSessionPlayer.kt b/android/app/src/main/java/com/htmake/readerpro/media/QueueSessionPlayer.kt similarity index 95% rename from android/app/src/main/java/cool/cnb/reader/media/QueueSessionPlayer.kt rename to android/app/src/main/java/com/htmake/readerpro/media/QueueSessionPlayer.kt index 0d031a1..1f5ad06 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/QueueSessionPlayer.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/QueueSessionPlayer.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import androidx.media3.common.ForwardingPlayer import androidx.media3.common.Player diff --git a/android/app/src/main/java/cool/cnb/reader/media/SubtitleRequestGate.kt b/android/app/src/main/java/com/htmake/readerpro/media/SubtitleRequestGate.kt similarity index 95% rename from android/app/src/main/java/cool/cnb/reader/media/SubtitleRequestGate.kt rename to android/app/src/main/java/com/htmake/readerpro/media/SubtitleRequestGate.kt index 6bf1d97..4aaaaa5 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/SubtitleRequestGate.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/SubtitleRequestGate.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media /** Main-thread ownership of subtitle UI callbacks; independent of player/network lifetime. */ internal class SubtitleRequestGate { diff --git a/android/app/src/main/java/cool/cnb/reader/media/VideoPipPolicy.kt b/android/app/src/main/java/com/htmake/readerpro/media/VideoPipPolicy.kt similarity index 93% rename from android/app/src/main/java/cool/cnb/reader/media/VideoPipPolicy.kt rename to android/app/src/main/java/com/htmake/readerpro/media/VideoPipPolicy.kt index 242126d..8b4a090 100644 --- a/android/app/src/main/java/cool/cnb/reader/media/VideoPipPolicy.kt +++ b/android/app/src/main/java/com/htmake/readerpro/media/VideoPipPolicy.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media /** Android restricts the PiP aspect ratio to approximately 1:2.39 … 2.39:1. */ internal object VideoPipPolicy { diff --git a/android/app/src/main/java/cool/cnb/reader/web/NativePageView.kt b/android/app/src/main/java/com/htmake/readerpro/web/NativePageView.kt similarity index 99% rename from android/app/src/main/java/cool/cnb/reader/web/NativePageView.kt rename to android/app/src/main/java/com/htmake/readerpro/web/NativePageView.kt index c48454c..aeb9c30 100644 --- a/android/app/src/main/java/cool/cnb/reader/web/NativePageView.kt +++ b/android/app/src/main/java/com/htmake/readerpro/web/NativePageView.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.web +package com.htmake.readerpro.web import android.content.Context import android.graphics.Bitmap diff --git a/android/app/src/main/java/cool/cnb/reader/web/WebHost.kt b/android/app/src/main/java/com/htmake/readerpro/web/WebHost.kt similarity index 96% rename from android/app/src/main/java/cool/cnb/reader/web/WebHost.kt rename to android/app/src/main/java/com/htmake/readerpro/web/WebHost.kt index 5e252fb..0bf6eec 100644 --- a/android/app/src/main/java/cool/cnb/reader/web/WebHost.kt +++ b/android/app/src/main/java/com/htmake/readerpro/web/WebHost.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.web +package com.htmake.readerpro.web import android.annotation.SuppressLint import android.content.Context @@ -13,12 +13,12 @@ import android.webkit.WebSettings import android.webkit.WebView import android.webkit.WebViewClient import androidx.webkit.WebViewAssetLoader -import cool.cnb.reader.BuildConfig -import cool.cnb.reader.media.MediaLaunchRoute -import cool.cnb.reader.bridge.ReaderBridge -import cool.cnb.reader.bridge.SpeechBridge -import cool.cnb.reader.media.MediaBridge -import cool.cnb.reader.media.MediaAudioCoordinator +import com.htmake.readerpro.BuildConfig +import com.htmake.readerpro.media.MediaLaunchRoute +import com.htmake.readerpro.bridge.ReaderBridge +import com.htmake.readerpro.bridge.SpeechBridge +import com.htmake.readerpro.media.MediaBridge +import com.htmake.readerpro.media.MediaAudioCoordinator /** * Configures the WebView and serves the bundled client to it. diff --git a/android/app/src/main/java/cool/cnb/reader/media/MediaLaunchRoute.kt b/android/app/src/main/java/cool/cnb/reader/media/MediaLaunchRoute.kt deleted file mode 100644 index 4f4a236..0000000 --- a/android/app/src/main/java/cool/cnb/reader/media/MediaLaunchRoute.kt +++ /dev/null @@ -1,11 +0,0 @@ -package cool.cnb.reader.media - -/** Launcher shortcuts select fixed local routes, never caller-provided URLs. */ -object MediaLaunchRoute { - fun fragmentForAction(action: String?): String? = when (action) { - "cool.cnb.reader.OPEN_VIDEO" -> "#/media/video" - "cool.cnb.reader.OPEN_MUSIC" -> "#/media/music" - "cool.cnb.reader.OPEN_AUDIOBOOK" -> "#/media/audiobook" - else -> null - } -} diff --git a/android/app/src/main/res/xml/media_shortcuts.xml b/android/app/src/main/res/xml/media_shortcuts.xml index 3245a1b..b7a4c8a 100644 --- a/android/app/src/main/res/xml/media_shortcuts.xml +++ b/android/app/src/main/res/xml/media_shortcuts.xml @@ -1,12 +1,12 @@ - + - + - + diff --git a/android/app/src/test/java/cool/cnb/reader/media/MediaBackgroundSyncTest.kt b/android/app/src/test/java/com/htmake/readerpro/media/MediaBackgroundSyncTest.kt similarity index 99% rename from android/app/src/test/java/cool/cnb/reader/media/MediaBackgroundSyncTest.kt rename to android/app/src/test/java/com/htmake/readerpro/media/MediaBackgroundSyncTest.kt index 6bd8d91..615454a 100644 --- a/android/app/src/test/java/cool/cnb/reader/media/MediaBackgroundSyncTest.kt +++ b/android/app/src/test/java/com/htmake/readerpro/media/MediaBackgroundSyncTest.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import java.net.ServerSocket import java.net.InetAddress diff --git a/android/app/src/test/java/cool/cnb/reader/media/MediaLaunchRouteTest.kt b/android/app/src/test/java/com/htmake/readerpro/media/MediaLaunchRouteTest.kt similarity index 79% rename from android/app/src/test/java/cool/cnb/reader/media/MediaLaunchRouteTest.kt rename to android/app/src/test/java/com/htmake/readerpro/media/MediaLaunchRouteTest.kt index f39b6bf..da5ab66 100644 --- a/android/app/src/test/java/cool/cnb/reader/media/MediaLaunchRouteTest.kt +++ b/android/app/src/test/java/com/htmake/readerpro/media/MediaLaunchRouteTest.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import org.junit.Assert.assertEquals import org.junit.Assert.assertNull @@ -6,9 +6,9 @@ import org.junit.Test class MediaLaunchRouteTest { @Test fun shortcutsSelectOnlyFixedMediaRoutes() { - assertEquals("#/media/video", MediaLaunchRoute.fragmentForAction("cool.cnb.reader.OPEN_VIDEO")) - assertEquals("#/media/music", MediaLaunchRoute.fragmentForAction("cool.cnb.reader.OPEN_MUSIC")) - assertEquals("#/media/audiobook", MediaLaunchRoute.fragmentForAction("cool.cnb.reader.OPEN_AUDIOBOOK")) + assertEquals("#/media/video", MediaLaunchRoute.fragmentForAction("com.htmake.readerpro.OPEN_VIDEO")) + assertEquals("#/media/music", MediaLaunchRoute.fragmentForAction("com.htmake.readerpro.OPEN_MUSIC")) + assertEquals("#/media/audiobook", MediaLaunchRoute.fragmentForAction("com.htmake.readerpro.OPEN_AUDIOBOOK")) } @Test fun normalLaunchAndUntrustedActionsDoNotRedirectReading() { diff --git a/android/app/src/test/java/cool/cnb/reader/media/MediaLiveServerTest.kt b/android/app/src/test/java/com/htmake/readerpro/media/MediaLiveServerTest.kt similarity index 99% rename from android/app/src/test/java/cool/cnb/reader/media/MediaLiveServerTest.kt rename to android/app/src/test/java/com/htmake/readerpro/media/MediaLiveServerTest.kt index a811517..91133b6 100644 --- a/android/app/src/test/java/cool/cnb/reader/media/MediaLiveServerTest.kt +++ b/android/app/src/test/java/com/htmake/readerpro/media/MediaLiveServerTest.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import java.io.File import java.net.HttpURLConnection diff --git a/android/app/src/test/java/cool/cnb/reader/media/MediaProgressSyncTest.kt b/android/app/src/test/java/com/htmake/readerpro/media/MediaProgressSyncTest.kt similarity index 99% rename from android/app/src/test/java/cool/cnb/reader/media/MediaProgressSyncTest.kt rename to android/app/src/test/java/com/htmake/readerpro/media/MediaProgressSyncTest.kt index 65a869c..345be71 100644 --- a/android/app/src/test/java/cool/cnb/reader/media/MediaProgressSyncTest.kt +++ b/android/app/src/test/java/com/htmake/readerpro/media/MediaProgressSyncTest.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import java.net.ServerSocket import java.net.InetAddress diff --git a/android/app/src/test/java/cool/cnb/reader/media/MediaRecoverySnapshotTest.kt b/android/app/src/test/java/com/htmake/readerpro/media/MediaRecoverySnapshotTest.kt similarity index 97% rename from android/app/src/test/java/cool/cnb/reader/media/MediaRecoverySnapshotTest.kt rename to android/app/src/test/java/com/htmake/readerpro/media/MediaRecoverySnapshotTest.kt index b1088b4..6a8909c 100644 --- a/android/app/src/test/java/cool/cnb/reader/media/MediaRecoverySnapshotTest.kt +++ b/android/app/src/test/java/com/htmake/readerpro/media/MediaRecoverySnapshotTest.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import org.json.JSONObject import org.junit.Assert.* diff --git a/android/app/src/test/java/cool/cnb/reader/media/PlaybackQueueTest.kt b/android/app/src/test/java/com/htmake/readerpro/media/PlaybackQueueTest.kt similarity index 99% rename from android/app/src/test/java/cool/cnb/reader/media/PlaybackQueueTest.kt rename to android/app/src/test/java/com/htmake/readerpro/media/PlaybackQueueTest.kt index 73c6bbb..1b0db00 100644 --- a/android/app/src/test/java/cool/cnb/reader/media/PlaybackQueueTest.kt +++ b/android/app/src/test/java/com/htmake/readerpro/media/PlaybackQueueTest.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import org.json.JSONObject import org.junit.Assert.* diff --git a/android/app/src/test/java/cool/cnb/reader/media/QueueSessionPlayerTest.kt b/android/app/src/test/java/com/htmake/readerpro/media/QueueSessionPlayerTest.kt similarity index 96% rename from android/app/src/test/java/cool/cnb/reader/media/QueueSessionPlayerTest.kt rename to android/app/src/test/java/com/htmake/readerpro/media/QueueSessionPlayerTest.kt index c899072..fac7040 100644 --- a/android/app/src/test/java/cool/cnb/reader/media/QueueSessionPlayerTest.kt +++ b/android/app/src/test/java/com/htmake/readerpro/media/QueueSessionPlayerTest.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import androidx.media3.common.Player import java.lang.reflect.Proxy diff --git a/android/app/src/test/java/cool/cnb/reader/media/SubtitleRequestGateTest.kt b/android/app/src/test/java/com/htmake/readerpro/media/SubtitleRequestGateTest.kt similarity index 97% rename from android/app/src/test/java/cool/cnb/reader/media/SubtitleRequestGateTest.kt rename to android/app/src/test/java/com/htmake/readerpro/media/SubtitleRequestGateTest.kt index 5146a92..b322ef5 100644 --- a/android/app/src/test/java/cool/cnb/reader/media/SubtitleRequestGateTest.kt +++ b/android/app/src/test/java/com/htmake/readerpro/media/SubtitleRequestGateTest.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import org.junit.Assert.* import org.junit.Test diff --git a/android/app/src/test/java/cool/cnb/reader/media/VideoPipPolicyTest.kt b/android/app/src/test/java/com/htmake/readerpro/media/VideoPipPolicyTest.kt similarity index 95% rename from android/app/src/test/java/cool/cnb/reader/media/VideoPipPolicyTest.kt rename to android/app/src/test/java/com/htmake/readerpro/media/VideoPipPolicyTest.kt index 1d1be67..a5e2089 100644 --- a/android/app/src/test/java/cool/cnb/reader/media/VideoPipPolicyTest.kt +++ b/android/app/src/test/java/com/htmake/readerpro/media/VideoPipPolicyTest.kt @@ -1,4 +1,4 @@ -package cool.cnb.reader.media +package com.htmake.readerpro.media import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue diff --git a/android/scripts/check-shell.sh b/android/scripts/check-shell.sh index 3b64a07..0fa22e5 100755 --- a/android/scripts/check-shell.sh +++ b/android/scripts/check-shell.sh @@ -32,14 +32,14 @@ done # 2. Every import of our own code must resolve to a file that exists. note "==> checking project imports resolve" for file in $(find "$android_dir/app/src" -name '*.kt'); do - sed -n 's/^import cool\.cnb\.reader\.\(.*\)$/\1/p' "$file" | while read -r symbol; do + sed -n 's/^import com\.htmake\.readerpro\.\(.*\)$/\1/p' "$file" | while read -r symbol; do # `BuildConfig` is generated, and a class name is the last dot segment. case "$symbol" in BuildConfig) continue ;; esac - path="$android_dir/app/src/main/java/cool/cnb/reader/$(printf '%s' "$symbol" | tr '.' '/').kt" + path="$android_dir/app/src/main/java/com/htmake/readerpro/$(printf '%s' "$symbol" | tr '.' '/').kt" if [ ! -f "$path" ]; then - err "$file imports cool.cnb.reader.$symbol but $path does not exist" + err "$file imports com.htmake.readerpro.$symbol but $path does not exist" fi done done @@ -55,8 +55,8 @@ done # methods against `ReaderBridge.kt` is what produced eleven false failures the # first time this was run. note "==> checking the JS bridge contract in both directions" -bridge_file="$android_dir/app/src/main/java/cool/cnb/reader/bridge/ReaderBridge.kt" -speech_file="$android_dir/app/src/main/java/cool/cnb/reader/bridge/SpeechBridge.kt" +bridge_file="$android_dir/app/src/main/java/com/htmake/readerpro/bridge/ReaderBridge.kt" +speech_file="$android_dir/app/src/main/java/com/htmake/readerpro/bridge/SpeechBridge.kt" types_file="$repo_dir/web/src/android-bridge.d.ts" # A method is "implemented" if either bridge class exposes it to the page: a @@ -119,7 +119,7 @@ note "==> checking the render-mode vocabulary matches" web_modes=$(sed -n "s/^export type RenderMode = \(.*\);/\1/p" "$repo_dir/web/src/formats/types.ts" \ | tr -d "'" | tr -d ' ' | tr '|' '\n' | sort -u) shell_modes=$(sed -n 's/.*mode != "\([a-z]*\)".*/\1/p' \ - "$android_dir/app/src/main/java/cool/cnb/reader/bridge/ReaderBridge.kt" | sort -u) + "$android_dir/app/src/main/java/com/htmake/readerpro/bridge/ReaderBridge.kt" | sort -u) if [ -z "$web_modes" ]; then err "cannot read RenderMode from web/src/formats/types.ts" fi @@ -130,7 +130,7 @@ for mode in $shell_modes; do done # The shell draws images natively, so it must know the client's image vocabulary. decodable=$(sed -n '/private val DECODABLE = setOf(/,/)/p' \ - "$android_dir/app/src/main/java/cool/cnb/reader/web/NativePageView.kt" \ + "$android_dir/app/src/main/java/com/htmake/readerpro/web/NativePageView.kt" \ | sed -n 's/.*"\(image\/[a-z]*\)".*/\1/p' | sort -u) for mediaType in "image/jpeg" "image/png" "image/webp"; do if ! printf '%s\n' "$decodable" | grep -qx "$mediaType"; then diff --git a/docker-compose.yml b/docker-compose.yml index 4f4828f..765c43d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,9 +6,9 @@ # automatically becomes the instance admin. services: reader: - # CI publishes branch and commit tags; it does not publish :latest. - # Pin READER_IMAGE to a published commit tag for repeatable upgrades. - image: ${READER_IMAGE:-cnb.cool/hectorqin/reader:main} + # Releases (v* tags) publish x.y.z, x.y, latest and sha-* tags to Docker Hub. + # Pin READER_IMAGE to a release version for repeatable upgrades. + image: ${READER_IMAGE:-hectorqin/reader-pro:latest} # To build from source instead of pulling the published image. The context is # the repository root because the image bakes in the H5 client built from # ./web as well as the server. diff --git a/server/Dockerfile b/server/Dockerfile index d9be119..2c4f1d7 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -8,13 +8,11 @@ # fails, so the client stage is gated behind a build arg and the runtime stage # tolerates an absent bundle. A server-only deployment stays possible. # -# The base image is overridable because `docker.cnb.cool` is an authenticated -# mirror: a plain `docker build` on a machine whose token has no pull rights on -# it fails at the very first stage. Docker Hub is the default; pass the mirror -# where it is reachable (CNB pipelines, or anywhere Hub is slow): +# The base image is overridable so a build can pull Node from a registry mirror +# where Docker Hub is slow or unreachable. Docker Hub is the default: # # docker build . -f server/Dockerfile \ -# --build-arg NODE_IMAGE=docker.cnb.cool/dockerhub/node:24-alpine +# --build-arg NODE_IMAGE=/node:24-alpine ARG NODE_IMAGE=node:24-alpine FROM ${NODE_IMAGE} AS web