发布与模块商店指南
将你开发的模块或适配器发布到 ErisPulse 模块商店,让其他用户可以方便地发现和安装。
模块商店概述
ErisPulse 模块商店是一个集中式的模块注册表,用户可以通过 CLI 工具浏览、搜索和安装社区贡献的模块、适配器。
浏览与发现
# 列出远程可用的所有包
epsdk list-remote
# 只查看模块
epsdk list-remote -t modules
# 只查看适配器
epsdk list-remote -t adapters
# 强制刷新远程包列表
epsdk list-remote -r
你也可以访问 ErisPulse 官网 在线浏览模块商店。
支持的提交类型
| 类型 | 说明 | Entry-point 组 |
|---|---|---|
| 模块 (Module) | 扩展机器人功能、实现业务逻辑 | erispulse.module |
| 适配器 (Adapter) | 连接新的消息平台 | erispulse.adapter |
快速发布
整个过程只需要三步:配置项目 → 发布到 PyPI → 提交到模块商店。
1. 配置 pyproject.toml
确保项目目录包含 pyproject.toml、README.md,并根据类型配置 entry-points:
模块
[project]
name = "ErisPulse-MyModule"
version = "1.0.0"
description = "模块功能描述"
requires-python = ">=3.10"
license = { text = "MIT" }
authors = [ { name = "yourname" } ]
dependencies = [
"ErisPulse>=2.0.0",
]
[project.entry-points."erispulse.module"]
"MyModule" = "MyModule:Main"
适配器
[project]
name = "ErisPulse-MyAdapter"
version = "1.0.0"
description = "适配器功能描述"
requires-python = ">=3.10"
[project.entry-points."erispulse.adapter"]
"myplatform" = "MyAdapter:MyAdapter"
注意:包名建议以
ErisPulse-开头,便于用户识别。Entry-point 的键名(如"MyModule")将作为模块在 SDK 中的访问名称。
2. 发布到 PyPI
# 构建 + 发布(需要 PyPI 账号)
pip install build twine
python -m build
python -m twine upload dist/*
发布成功后验证安装:
pip install ErisPulse-MyModule
3. 提交到模块商店
前往 ErisPulse 模块商店,点击「提交模块」,登录后填写模块信息即可。
支持的登录方式:GitHub、Codeberg、云湖,任选其一即可。
填写要点:
- 模块名称、描述、仓库地址
- 最低 SDK 版本:如果不确定,填写 ErisPulse 最新发行版 版本号即可
提交后立即生效,用户可通过模块源安装。模块会被标记为「未验证」,维护者审核通过后改为「已验证」。
关于验证状态:
- 「未验证」仅表示尚未经过官方审核,不代表模块有问题
- 用户通过
epsdk install安装未验证模块时会收到风险提示,需确认后才可继续安装
4. 管理已发布的模块
在模块商店点击「提交模块」并登录后,切换到「我的模块」标签页,可以:
- 编辑 — 修改模块描述、仓库地址、标签等信息,版本号会自动从 PyPI 同步
- 删除 — 从模块商店移除模块(不可撤销)
刚提交的模块可能需要几分钟才会显示在「我的模块」列表中。
更新已发布模块
- 更新
pyproject.toml中的version - 重新构建并上传:
python -m build && python -m twine upload dist/* - 模块商店会自动同步 PyPI 上的最新版本
用户通过 epsdk upgrade MyModule 即可升级。
发布前检查清单
在推送到 PyPI 之前,请逐项确认以下内容:
代码质量
- 所有公开 API 有类型注解(函数签名和返回值)
- 所有公开方法有文档字符串(
"""..."""格式,包含:param/:return/:raises) - 通过
ruff check(无警告) - 测试覆盖率 ≥ 80%
- 通过
pytest全部用例
兼容性
-
pyproject.toml声明了最低 SDK 版本:dependencies = ["ErisPulse>=x.y.z"] - 模块在
get_meta()的ModuleMeta(min_sdk_version="x.y.z")声明了运行时最低 SDK 版本(适配器用类属性min_sdk_version)——用户环境 SDK 过低时框架在加载期明确报错并跳过,而非报出难以定位的运行时异常 - 测试了 Python 3.10 / 3.11 / 3.12 / 3.13
- 测试了目标操作系统(Windows / Linux / macOS,如适用)
- 无循环导入依赖
配置
- 如果使用声明式配置(
ConfigClass+BaseConfig/BotAccountConfig),配置字段有description(推荐 i18n 格式)和ui元数据 - 如果注册了 i18n 翻译键,已覆盖所有 5 种语言(zh-CN / zh-TW / en / ja / ru)
- 敏感字段标记了
secret=True
文档
-
README.md有安装说明和基本使用示例 -
README.md说明了配置方式(配置文件示例 + 环境变量) -
CHANGELOG.md记录了所有变更 - 适配器更新了平台特性文档(支持的 Send 类型、事件类型等)
发布
-
pyproject.toml版本号已更新 - 构建通过:
python -m build - 已推送到 PyPI:
python -m twine upload dist/* - 安装验证通过:
pip install ErisPulse-xxx && epsdk run
开发模式测试
在正式发布前,可以使用可编辑模式在本地测试:
epsdk install -e /path/to/MyModule
# 或
pip install -e /path/to/MyModule
常见问题
包名必须以 ErisPulse- 开头吗?
不强制,但强烈推荐。这有助于用户在 PyPI 上识别 ErisPulse 生态的包。
一个包可以注册多个模块吗?
可以。在 entry-points 中配置多个键值对即可:
[project.entry-points."erispulse.module"]
"ModuleA" = "MyPackage:ModuleA"
"ModuleB" = "MyPackage:ModuleB"
审核需要多长时间?
通常在 1-3 个工作日内完成。你可以在模块商店「我的模块」中查看验证状态。
通过 Docker 镜像分发应用
如果你的应用不适合发布到 PyPI(如包含私有依赖、需要预配置环境),可以通过 GitHub Container Registry (GHCR) 发布 Docker 镜像,让其他用户 docker pull 一键启动。
适用场景
- 你有一个完整的机器人应用(模块 + 配置 + 入口脚本),想一键分发
- 模块/适配器依赖私有包或有特殊安装流程,不适合 PyPI
- 想提供开箱即用的部署方案,降低用户使用门槛
1. 创建 Dockerfile
基于 ErisPulse 官方镜像构建,只需添加你的模块即可:
FROM erispulse/erispulse:latest
LABEL org.opencontainers.image.title="ErisPulse-MyModule" \
org.opencontainers.image.description="模块描述" \
org.opencontainers.image.url="https://github.com/yourname/ErisPulse-MyModule" \
org.opencontainers.image.source="https://github.com/yourname/ErisPulse-MyModule"
COPY pyproject.toml README.md ./
COPY MyModule/ ./MyModule/
RUN uv pip install --system -e .
如果模块需要额外的系统依赖(如 SSH 客户端等),在 RUN uv pip install 之后添加:
RUN apt-get update && apt-get install -y --no-install-recommends \
openssh-client \
&& rm -rf /var/lib/apt/lists/*
erispulse/erispulse:latest已包含 ErisPulse、ErisPulse-Dashboard、Python 运行时和 uv,无需重复安装。
2. 创建 GitHub Actions 工作流
在 .github/workflows/docker-publish.yml 中创建:
name: 发布 Docker 镜像
on:
workflow_dispatch:
push:
branches:
- main
tags:
- "v*"
permissions:
contents: read
packages: write
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/my-bot
jobs:
docker-publish:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 设置 QEMU (多架构支持)
uses: docker/setup-qemu-action@v3
- name: 设置 Docker Buildx
uses: docker/setup-buildx-action@v3
- name: 登录 GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: 提取 Docker 元数据
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest
- name: 构建并推送 Docker 镜像
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
GITHUB_TOKEN由 GitHub Actions 自动提供,无需手动创建密钥。
3. 触发构建
推送代码或打 Tag 即可自动构建:
# 推送到 main 分支触发
git push origin main
# 或打 Tag 触发
git tag v1.0.0
git push origin v1.0.0
也可在 GitHub 仓库的 Actions 页面手动触发。
4. 设置镜像为公开
GHCR 镜像默认为 private,需要在 GitHub 设置为 Public 后其他用户才能免登录拉取:
- 进入仓库 → Packages → 点击对应 Package
- Package settings → Danger Zone → Change visibility → Public
5. 用户使用
构建完成后,用户可以用 docker run 一行启动:
docker run -d \
--name my-bot \
-p 8000:8000 \
-v $(pwd)/config:/app/config \
-e TZ=Asia/Shanghai \
-e ERISPULSE_DASHBOARD_TOKEN=your-token \
--restart unless-stopped \
ghcr.io/<your-username>/my-bot:latest
或使用 docker-compose.yml:
services:
my-bot:
image: ghcr.io/<your-username>/my-bot:latest
container_name: my-bot
ports:
- "8000:8000"
volumes:
- ./config:/app/config
environment:
- TZ=Asia/Shanghai
- ERISPULSE_DASHBOARD_TOKEN=${ERISPULSE_DASHBOARD_TOKEN:-}
restart: unless-stopped
同时发布到 Docker Hub
扩展工作流,在登录步骤前添加 Docker Hub 登录,并在 images 中增加 Docker Hub 地址:
- name: 登录 Docker Hub
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: 提取 Docker 元数据
id: meta
uses: docker/metadata-action@v5
with:
images: |
docker.io/<your-dockerhub-username>/my-bot
ghcr.io/${{ github.repository_owner }}/my-bot
需要在仓库 Settings → Secrets 中添加
DOCKERHUB_USERNAME和DOCKERHUB_TOKEN。
Docker 镜像 vs PyPI 发布
| 特性 | Docker 镜像 (GHCR) | PyPI 发布 |
|---|---|---|
| 分发方式 | docker pull 一键运行 |
pip install + 手动配置 |
| 适用范围 | 完整应用/解决方案 | 单个模块/适配器 |
| 私有依赖 | 天然支持 | 需要私有 PyPI 源 |
| 模块商店 | 不适用 | 可提交到模块商店 |
| 多架构 | 支持 amd64/arm64 | 与架构无关 |
两种方式不冲突——你可以同时通过 PyPI 发布模块到模块商店,又通过 GHCR 提供开箱即用的 Docker 镜像。