mirror of
https://github.com/snowy-yang/qqbotsdk.git
synced 2026-10-21 15:54:48 +00:00
Compare commits
2
Commits
6897205f6b
...
7663ca610d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7663ca610d | ||
|
|
7603db7fd9 |
No files matched your search
@@ -1,59 +0,0 @@
|
|||||||
name: 代码检测
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
pull_request:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
name: ruff + pyright
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
# 固定官方 python 镜像:保证 python3.13 + pip 在场(runner 默认镜像
|
|
||||||
# 工具链不明,实测任务曾 7s 即死);runner 不支持 container 时回落
|
|
||||||
# 宿主机 python,此时 uv 经下方镜像变量自行下载 CPython
|
|
||||||
container: python:3.13-slim
|
|
||||||
steps:
|
|
||||||
# 不用 actions/checkout、不用 git:runner 对 github 连通性不稳
|
|
||||||
# (probe.yml 实测),改走 Gitea archive 接口拉源码 tarball;每步
|
|
||||||
# 结果写进 commit status(日志匿名不可读,status 远程可读)
|
|
||||||
- name: 拉源码、装依赖并执行检测
|
|
||||||
env:
|
|
||||||
TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
||||||
UV_PYTHON_INSTALL_MIRROR: https://registry.npmmirror.com/-/binary/python-build-standalone
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
SERVER="${GITHUB_SERVER_URL:-https://gitea.4i.hk}"
|
|
||||||
note() {
|
|
||||||
curl -s -m 10 -X POST \
|
|
||||||
-H "Authorization: token $TOKEN" \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-d "{\"state\":\"$3\",\"context\":\"ci/$1\",\"description\":\"$2\"}" \
|
|
||||||
"$SERVER/api/v1/repos/$GITHUB_REPOSITORY/statuses/$GITHUB_SHA" \
|
|
||||||
-o /dev/null
|
|
||||||
}
|
|
||||||
trap 'note error "步骤意外失败,详见 Actions 日志" failure' ERR
|
|
||||||
|
|
||||||
curl -sL "$SERVER/api/v1/repos/$GITHUB_REPOSITORY/archive/$GITHUB_SHA.tar.gz" -o src.tgz \
|
|
||||||
&& mkdir src && tar -xzf src.tgz -C src --strip-components=1 && cd src \
|
|
||||||
|| { note fetch "archive 拉取失败" failure; exit 1; }
|
|
||||||
note fetch ok success
|
|
||||||
|
|
||||||
pip install uv >/dev/null 2>&1 \
|
|
||||||
|| { note pip "pip 安装 uv 失败" failure; exit 1; }
|
|
||||||
note pip ok success
|
|
||||||
|
|
||||||
uv sync >/dev/null 2>&1 \
|
|
||||||
|| { note sync "uv sync 失败" failure; exit 1; }
|
|
||||||
note sync ok success
|
|
||||||
|
|
||||||
uv run ruff check src tests examples \
|
|
||||||
|| { note ruff "ruff check 未通过" failure; exit 1; }
|
|
||||||
note ruff ok success
|
|
||||||
|
|
||||||
# pyright 需要 node:镜像里没有就装 Debian 的(保底 pyright 自带下载)
|
|
||||||
command -v node >/dev/null 2>&1 || { apt-get update -qq && apt-get install -y -qq nodejs; } || true
|
|
||||||
uv run pyright \
|
|
||||||
|| { note pyright "pyright 未通过" failure; exit 1; }
|
|
||||||
note pyright ok success
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
name: 部署文档(Cloudflare Pages)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
paths:
|
|
||||||
- "index.html"
|
|
||||||
- "_sidebar.md"
|
|
||||||
- "README.md"
|
|
||||||
- "docs/**"
|
|
||||||
- "examples/**"
|
|
||||||
- "CHANGELOG.md"
|
|
||||||
- "scripts/deploy_docs.sh"
|
|
||||||
- ".gitea/workflows/deploy-docs.yml"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
deploy-docs:
|
|
||||||
name: Cloudflare Pages
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# 不用 actions/checkout、不用 git(runner 对 github 连通性不稳,见
|
|
||||||
# probe.yml):改走 Gitea archive 接口拉源码 tarball
|
|
||||||
- name: 拉源码
|
|
||||||
run: |
|
|
||||||
SERVER="${GITHUB_SERVER_URL:-https://gitea.4i.hk}"
|
|
||||||
curl -sL "$SERVER/api/v1/repos/$GITHUB_REPOSITORY/archive/$GITHUB_SHA.tar.gz" -o src.tgz \
|
|
||||||
&& mkdir src && tar -xzf src.tgz -C src --strip-components=1 \
|
|
||||||
&& mv src/* . && rm -rf src src.tgz
|
|
||||||
|
|
||||||
# 日志匿名不可读:把 secrets 在场情况写进 commit status 便于远程
|
|
||||||
# 排查(只报 set/MISSING,不泄露值)
|
|
||||||
- name: 探测 secrets 是否配置
|
|
||||||
env:
|
|
||||||
TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
||||||
CF_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
||||||
CF_ACCOUNT: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
||||||
run: |
|
|
||||||
SERVER="${GITHUB_SERVER_URL:-https://gitea.4i.hk}"
|
|
||||||
s() { [ -n "$2" ] && echo set || echo MISSING; }
|
|
||||||
curl -s -m 10 -X POST \
|
|
||||||
-H "Authorization: token $TOKEN" \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-d "{\"state\":\"success\",\"context\":\"deploy/secrets\",\"description\":\"CLOUDFLARE_API_TOKEN=$(s x "$CF_TOKEN") CLOUDFLARE_ACCOUNT_ID=$(s x "$CF_ACCOUNT")\"}" \
|
|
||||||
"$SERVER/api/v1/repos/$GITHUB_REPOSITORY/statuses/$GITHUB_SHA" -o /dev/null
|
|
||||||
|
|
||||||
- name: 组装并部署(wrangler Direct Upload)
|
|
||||||
run: bash scripts/deploy_docs.sh
|
|
||||||
env:
|
|
||||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
||||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
name: 网络探测
|
|
||||||
|
|
||||||
# runner 环境盘点:出网连通性 + 基础工具链 + clone/装 uv 迷你实测,
|
|
||||||
# 结果写入 commit status(公开仓库匿名可读)。
|
|
||||||
# 改动本文件推送即触发。
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths: ['.gitea/workflows/probe.yml']
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
probe:
|
|
||||||
name: runner 环境探测
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: 工具链与连通性探测
|
|
||||||
run: |
|
|
||||||
SERVER="${GITHUB_SERVER_URL:-https://gitea.4i.hk}"
|
|
||||||
post() {
|
|
||||||
curl -s -m 10 -X POST \
|
|
||||||
-H "Authorization: token $TOKEN" \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-d "{\"state\":\"success\",\"context\":\"probe/$1\",\"description\":\"$2\"}" \
|
|
||||||
"$SERVER/api/v1/repos/$GITHUB_REPOSITORY/statuses/$GITHUB_SHA" \
|
|
||||||
-o /dev/null -w "probe/$1 = $2 (HTTP %{http_code})\n"
|
|
||||||
}
|
|
||||||
inv() { command -v "$1" >/dev/null 2>&1 && echo yes || echo no; }
|
|
||||||
code() { curl -s -m 8 -o /dev/null -w '%{http_code}' -L "$1"; }
|
|
||||||
|
|
||||||
post python3 "$(python3 -V 2>/dev/null || echo absent)"
|
|
||||||
post pip "$(inv pip)"
|
|
||||||
post pip3 "$(inv pip3)"
|
|
||||||
post uv "$(inv uv)"
|
|
||||||
post git "$(inv git)"
|
|
||||||
post npx "$(inv npx)"
|
|
||||||
post pypi "$(code https://pypi.org/simple/)"
|
|
||||||
post npmmirror "$(code https://registry.npmmirror.com)"
|
|
||||||
|
|
||||||
rm -rf /tmp/src
|
|
||||||
if git clone --depth=1 "$SERVER/$GITHUB_REPOSITORY.git" /tmp/src >/dev/null 2>&1; then
|
|
||||||
post clone ok
|
|
||||||
else
|
|
||||||
post clone fail
|
|
||||||
fi
|
|
||||||
|
|
||||||
if cd /tmp/src 2>/dev/null \
|
|
||||||
&& { pip install uv >/dev/null 2>&1 \
|
|
||||||
|| pip3 install uv >/dev/null 2>&1 \
|
|
||||||
|| python3 -m pip install uv >/dev/null 2>&1; }; then
|
|
||||||
post pip-install-uv ok
|
|
||||||
else
|
|
||||||
post pip-install-uv fail
|
|
||||||
fi
|
|
||||||
|
|
||||||
UV_BIN="$(command -v uv || echo "$HOME/.local/bin/uv")"
|
|
||||||
post uv-version "$("$UV_BIN" --version 2>/dev/null || echo none)"
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: 部署文档(Cloudflare Pages)
|
name: 部署文档(同步 docs 分支)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -10,20 +10,35 @@ on:
|
|||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "examples/**"
|
- "examples/**"
|
||||||
- "CHANGELOG.md"
|
- "CHANGELOG.md"
|
||||||
- "scripts/deploy_docs.sh"
|
|
||||||
- ".github/workflows/deploy-docs.yml"
|
- ".github/workflows/deploy-docs.yml"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-docs:
|
sync-docs:
|
||||||
name: Cloudflare Pages
|
name: 组装并强推 docs 分支
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 检出代码
|
- name: 检出代码
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: 组装并部署(wrangler Direct Upload)
|
# docs 分支只含文档站文件(孤儿分支,与源码历史无关),
|
||||||
run: bash scripts/deploy_docs.sh
|
# 供 Cloudflare Pages 直连:生产分支 docs、构建命令留空、输出目录 /
|
||||||
|
- name: 组装纯文档并推送 docs 分支
|
||||||
env:
|
env:
|
||||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
run: |
|
||||||
|
rm -rf site && mkdir site
|
||||||
|
cp index.html README.md _sidebar.md CHANGELOG.md site/
|
||||||
|
cp -r docs examples site/
|
||||||
|
cp .nojekyll site/ 2>/dev/null || true
|
||||||
|
find site -type d -name __pycache__ -exec rm -rf {} +
|
||||||
|
cd site
|
||||||
|
git init -q -b docs
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
|
git add -A
|
||||||
|
git commit -qm "docs: 同步自 main@${GITHUB_SHA:0:7}"
|
||||||
|
git push -q --force "https://x-access-token:${TOKEN}@github.com/${GITHUB_REPOSITORY}.git" docs
|
||||||
@@ -10,10 +10,6 @@ __pycache__/
|
|||||||
.ruff_cache/
|
.ruff_cache/
|
||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
|
|
||||||
# 文档部署产物(scripts/deploy_docs.sh 组装)
|
|
||||||
dist/
|
|
||||||
.wrangler/
|
|
||||||
|
|
||||||
# 编辑器/IDE
|
# 编辑器/IDE
|
||||||
.vscode/
|
.vscode/
|
||||||
.zcode/
|
.zcode/
|
||||||
+1
-2
@@ -20,9 +20,8 @@
|
|||||||
- OpenAPI 限流与鉴权自愈:`BotApi.request` 对 429 自动重试(最多 3 次,优先 `Retry-After`,脏值容错解析,退避封顶 30s);401 强制刷新 token 后重试一次,token 被服务端提前作废不再直接抛错
|
- OpenAPI 限流与鉴权自愈:`BotApi.request` 对 429 自动重试(最多 3 次,优先 `Retry-After`,脏值容错解析,退避封顶 30s);401 强制刷新 token 后重试一次,token 被服务端提前作废不再直接抛错
|
||||||
- 群消息全量模式:新增 `GROUP_MESSAGE_CREATE` 事件接收,与 `GROUP_AT_MESSAGE_CREATE` 共用 `GroupAtMessage`(需在开放平台开通"接收所有消息"权限,不限 @机器人);`GroupAtMessage` 补齐官方新增的 `message_type`/`message_scene`/`attachments`/`mentions`/`ark_data`/`msg_elements` 字段
|
- 群消息全量模式:新增 `GROUP_MESSAGE_CREATE` 事件接收,与 `GROUP_AT_MESSAGE_CREATE` 共用 `GroupAtMessage`(需在开放平台开通"接收所有消息"权限,不限 @机器人);`GroupAtMessage` 补齐官方新增的 `message_type`/`message_scene`/`attachments`/`mentions`/`ark_data`/`msg_elements` 字段
|
||||||
- **连接寿命主动重连**:服务端约 1 小时后会无预警断开连接(实测),故连接存活到 `_SERVER_LIFETIME - _RECONNECT_MARGIN`(默认 60min − 10min = 50min)时由 SDK 主动收尾重连——走正常 RESUME 续传、期间消息由网关补发,而不是被服务端掐断后由看门狗判成异常断开;收帧超时在"静默阈值"与"寿命余量"两个截止里取先到者,静默仍归看门狗处理
|
- **连接寿命主动重连**:服务端约 1 小时后会无预警断开连接(实测),故连接存活到 `_SERVER_LIFETIME - _RECONNECT_MARGIN`(默认 60min − 10min = 50min)时由 SDK 主动收尾重连——走正常 RESUME 续传、期间消息由网关补发,而不是被服务端掐断后由看门狗判成异常断开;收帧超时在"静默阈值"与"寿命余量"两个截止里取先到者,静默仍归看门狗处理
|
||||||
|
- GitHub Actions:push/PR 自动执行 `ruff check`、`pyright` 与 pytest;文档文件变更时自动把纯文档组装进 `docs` 分支(与源码历史无关的孤儿分支),供 Cloudflare Pages 直连 GitHub 仓库部署(生产分支 `docs`,零构建)
|
||||||
- 文档站点:基于 docsify(侧边栏、全文搜索、代码复制、mermaid 图渲染、分页),`npx docsify-cli serve` 本地预览;新增 `examples/README.md` 示例索引
|
- 文档站点:基于 docsify(侧边栏、全文搜索、代码复制、mermaid 图渲染、分页),`npx docsify-cli serve` 本地预览;新增 `examples/README.md` 示例索引
|
||||||
- Gitea Actions CI:push(main)/Pull Request/手动触发时自动执行 `ruff check` 与 `pyright`(`.gitea/workflows/ci.yml`,uv 同步依赖后运行与本地开发一致的检查命令)
|
|
||||||
- 文档站线上部署:`scripts/deploy_docs.sh` 组装纯文档目录(不携带源码)并经 wrangler 上传 Cloudflare Pages(Direct Upload,零构建);`.gitea/workflows/deploy-docs.yml` 在 main 的文档文件变更时自动部署
|
|
||||||
|
|
||||||
### 变更
|
### 变更
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ uv run ruff check src tests examples && uv run pyright
|
|||||||
npx docsify-cli serve # 打开 http://localhost:3000
|
npx docsify-cli serve # 打开 http://localhost:3000
|
||||||
```
|
```
|
||||||
|
|
||||||
线上部署在 Cloudflare Pages(Direct Upload,Gitea 无法走 Pages 的 Git 直连):`bash scripts/deploy_docs.sh` 组装 `dist/` 并经 wrangler 上传,站点地址 `https://<项目名>.pages.dev`;项目名默认 `qqbotsdk-docs`,可传参或 `PROJECT_NAME` 覆盖。CI 自动部署:Gitea 仓库配置 `CLOUDFLARE_API_TOKEN`(权限 Account → Cloudflare Pages → Edit)与 `CLOUDFLARE_ACCOUNT_ID` 两个 secrets 后,main 上文档文件变更即自动部署([.gitea/workflows/deploy-docs.yml](.gitea/workflows/deploy-docs.yml))。
|
线上部署:文档文件变更时 GitHub Actions 自动把纯文档组装进 `docs` 分支([.github/workflows/deploy-docs.yml](.github/workflows/deploy-docs.yml),与源码历史无关的孤儿分支);Cloudflare Pages 连接本仓库、生产分支选 `docs`、构建命令留空、输出目录填 `/` 即完成接入,站点地址 `https://<项目名>.pages.dev`。
|
||||||
|
|
||||||
## 待完善
|
## 待完善
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -16,7 +16,8 @@ API 细节见 [API.md](API.md),内部架构见 [ARCHITECTURE.md](ARCHITECTURE.
|
|||||||
项目未发布到 PyPI,从 Gitea 仓库安装(或克隆到本地后用路径安装):
|
项目未发布到 PyPI,从 Gitea 仓库安装(或克隆到本地后用路径安装):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv add git+https://gitea.4i.hk/hhhge/qqbotsdk # 从仓库安装
|
uv add git+https://github.com/snowy-yang/qqbotsdk # 从 GitHub 安装
|
||||||
|
uv add git+https://gitea.4i.hk/hhhge/qqbotsdk # 或 Gitea 镜像
|
||||||
uv add /path/to/qqbotsdk # 本地路径安装
|
uv add /path/to/qqbotsdk # 本地路径安装
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@
|
|||||||
<script>
|
<script>
|
||||||
window.$docsify = {
|
window.$docsify = {
|
||||||
name: 'qqbotsdk',
|
name: 'qqbotsdk',
|
||||||
repo: 'https://gitea.4i.hk/hhhge/qqbotsdk',
|
repo: 'https://github.com/snowy-yang/qqbotsdk',
|
||||||
// 相对链接按当前页面所在目录解析(与 GitHub 行为一致),docs/*.md 的互链才能正确跳转
|
// 相对链接按当前页面所在目录解析(与 GitHub 行为一致),docs/*.md 的互链才能正确跳转
|
||||||
relativePath: true,
|
relativePath: true,
|
||||||
loadSidebar: true,
|
loadSidebar: true,
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# 组装纯文档目录并部署到 Cloudflare Pages(docsify 零构建,Direct Upload)。
|
|
||||||
#
|
|
||||||
# 用法:scripts/deploy_docs.sh [项目名] # 项目名默认取 PROJECT_NAME,再默认 qqbotsdk-docs
|
|
||||||
# 本地首次运行会自动唤起 wrangler 浏览器授权(或预先 export CLOUDFLARE_API_TOKEN);
|
|
||||||
# 项目不存在时 wrangler 会自动创建,站点地址 https://<项目名>.pages.dev。
|
|
||||||
# CI(.gitea/workflows/deploy-docs.yml)经 CLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_ID 鉴权调用本脚本。
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
cd "$(dirname "$0")/.."
|
|
||||||
|
|
||||||
PROJECT_NAME="${1:-${PROJECT_NAME:-qqbotsdk-docs}}"
|
|
||||||
|
|
||||||
rm -rf dist
|
|
||||||
mkdir dist
|
|
||||||
# docsify 站点只由这些 markdown 和 index.html 组成,静态资源全部走 CDN——
|
|
||||||
# 只挑文档文件,不把源码仓库整个传上站点
|
|
||||||
cp index.html README.md _sidebar.md CHANGELOG.md dist/
|
|
||||||
cp -r docs examples dist/
|
|
||||||
cp .nojekyll dist/ 2>/dev/null || true
|
|
||||||
# examples/ 里的 Python 字节码缓存不该上站点
|
|
||||||
find dist -type d -name __pycache__ -exec rm -rf {} +
|
|
||||||
|
|
||||||
# 新版 wrangler 的 pages deploy 不再自动建项目:先幂等创建(已存在则忽略报错)
|
|
||||||
npx wrangler pages project create "$PROJECT_NAME" --production-branch=main >/dev/null 2>&1 || true
|
|
||||||
npx wrangler pages deploy dist --project-name="$PROJECT_NAME" --branch=main --commit-dirty=true
|
|
||||||
Reference in new issue
Block a user