Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 63 additions & 17 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
# - Ensure repository Actions permissions allow writing releases, or set a RELEASE_PAT secret (repo scope)
# and it will be used instead of the builtin GITHUB_TOKEN.
# - The release asset uploaded is ./dist.zip (your build must produce dist/).
# - The same dist/ is also published to npm as @talebook/candle-reader, versioned by the tag. Tags are date
# versions vYY.MM.DD (e.g. v26.10.09); semver forbids leading zeros, so the npm version drops them (26.10.9).
# Publishing uses npm Trusted Publishing (GitHub OIDC), so no NPM token secret is needed; the package's
# Trusted Publisher on npmjs.com must point at talebook/candle-reader + release.yml. A version that already
# exists on npm is skipped, so re-running for an old tag only refreshes the GitHub release asset.
on:
push:
tags:
Expand All @@ -19,6 +24,7 @@ name: Build and release dist.zip (tag-only / manual latest-tag)
permissions:
contents: write
packages: write
id-token: write # npm Trusted Publishing

env:
ASSET_NAME: dist.zip
Expand All @@ -34,10 +40,41 @@ jobs:
with:
fetch-depth: 0

- name: Determine tag to use
id: tag
run: |
set -e
# If triggered by a tag push, use that tag
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
TAG="${GITHUB_REF##*/}"
echo "Using tag from push: ${TAG}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
exit 0
fi

# Otherwise (workflow_dispatch), choose the latest tag available locally (sorted by version-like order)
# ensure tags are fetched
git fetch --tags --prune
TAG=$(git tag --sort=-v:refname | head -n1 || true)
if [ -z "$TAG" ]; then
echo "No tags found in repository. Aborting."
exit 1
fi
echo "Using latest tag: ${TAG}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"

- name: Check out the tag being released
env:
TAG: ${{ steps.tag.outputs.tag }}
# A manual run picks the latest tag; build that tag, not the branch the run was started from,
# so dist.zip and the npm package match the version they are published as.
run: git checkout --detach "refs/tags/${TAG}"

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
node-version: '22'
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: npm ci
Expand All @@ -55,28 +92,37 @@ jobs:
exit 1
fi

- name: Determine tag to use
id: tag
- name: Publish to npm
env:
TAG: ${{ steps.tag.outputs.tag }}
run: |
set -e
# If triggered by a tag push, use that tag
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
TAG="${GITHUB_REF##*/}"
echo "Using tag from push: ${TAG}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
# Trusted Publishing needs npm >= 11.5.1
npm install -g npm@^11.5.1
# vYY.MM.DD -> YY.M.D (semver forbids leading zeros)
if ! [[ "$TAG" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
echo "Tag '$TAG' is not vYY.MM.DD, cannot map it to an npm version"
exit 1
fi
VERSION="$((10#${BASH_REMATCH[1]})).$((10#${BASH_REMATCH[2]})).$((10#${BASH_REMATCH[3]}))"
npm version "$VERSION" --no-git-tag-version --allow-same-version
NAME=$(node -p "require('./package.json').name")
if [ "$NAME" != "@talebook/candle-reader" ]; then
echo "Tag ${TAG} predates the npm package (name: ${NAME}), skipping publish"
exit 0
fi

# Otherwise (workflow_dispatch), choose the latest tag available locally (sorted by version-like order)
# ensure tags are fetched
git fetch --tags --prune
TAG=$(git tag --sort=-v:refname | head -n1 || true)
if [ -z "$TAG" ]; then
echo "No tags found in repository. Aborting."
# Publish only on a confirmed 404; any other lookup failure must not be read as "missing"
if OUT=$(npm view "${NAME}@${VERSION}" version 2>&1); then
if [ -n "$OUT" ]; then
echo "${NAME}@${VERSION} already on npm, skipping publish"
exit 0
fi
elif ! echo "$OUT" | grep -q E404; then
echo "npm view failed:"
echo "$OUT"
exit 1
fi
echo "Using latest tag: ${TAG}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
npm publish --provenance
Comment thread
talebook marked this conversation as resolved.

- name: Ensure Release exists (get upload_url or create release)
id: ensure_release
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ make dist # 打包,并生成可直接部署的 dist/demo.html

演示页用《西游记》和一个纯内存版宿主(`demo/memory-host.js`,完整实现下面的回调契约),可以体验划线、评论、回复、赞踩、「我的」和游客登录引导;数据只在内存里,刷新即重置。

## 发版与 npm 包

打包产物以 npm 包 [`@talebook/candle-reader`](https://www.npmjs.com/package/@talebook/candle-reader) 发布,包内只有 `dist/`,宿主(talebook)锁定版本后把 `dist/` 拷到自己的静态目录使用。

```bash
git tag v26.10.09 && git push origin v26.10.09
```

版本号用发版日期 `vYY.MM.DD` 。推送 `v*` tag 后 `.github/workflows/release.yml` 会打包,把 `dist/` 以 tag 对应的版本号发布到 npm(semver 不允许前导零,`v26.10.09` 发布为 `26.10.9` ;同一天只能发一版),同时把 `dist.zip` 上传到 GitHub Release。发布走 npm Trusted Publishing(GitHub OIDC),仓库里不保存 npm token;包在 npmjs.com 的 Trusted Publisher 需指向本仓库的 `release.yml` 。`package.json` 里的 `version` 只作参考,以 tag 为准。

本地联调时不必发版:`make dist install` 把产物直接拷进本地 talebook 的静态目录。

## 划线与评论接入

划线、文字评论和整书评论是同一种记录,统称「评论」。阅读器负责全部界面:选区工具栏、评论抽屉、完整评论页、评论详情页、编辑框、赞踩与回复。**阅读器自身不请求任何评论或账号服务**,数据与登录态全部通过初始化时注入的 `annotation_callbacks` 交给宿主:
Expand Down
Loading
Loading