基于 Redmine:在 Redmine 里建问题、改状态、改内容,会同步成飞书任务。飞书里改任务 *不会* 写回 Redmine。
更细的镜像与数据说明见 doc/feishu-task-sync.md。
-
打开 飞书开放平台,创建 *企业自建应用*
-
开通权限并 *发布* 到本企业:
-
task:task:write(创建/更新/删除任务、加人) -
task:tasklist:write(创建/管理共用清单「Redmine」) -
task:section:write(每个项目一个自定义分组) -
contact:user.id:readonly(用邮箱查用户;没有邮箱可跳过,改用默认 open_id)
-
-
记下 App ID、App Secret
-
在开放平台 *API 调试台* 查自己的用户
open_id(ou_开头)。至少准备一个,否则任务可能创建成功但飞书界面找不到
生产(替换已有官方 SQLite 容器,保留原账号和问题):
-
使用 linux/amd64 镜像
redmine-feishu:latest(不要用 Mac ARM 打的包) -
compose *只改*
image: redmine-feishu:latest -
*不要改*:volume 名字、挂载路径、
REDMINE_SECRET_KEY_BASE -
*不要* 执行
docker compose down -v
docker load < redmine-feishu.tar.gz docker compose up -d
官方镜像不读 REDMINE_DB_SQLITE。真正的库文件是:
/usr/src/redmine/sqlite/redmine.db
compose 里即使写着 redmine.sqlite3 也可以留着,本镜像同样只用 redmine.db。
本机从源码构建再导出:
docker compose build docker save redmine-feishu:latest | gzip > redmine-feishu.tar.gz
compose 示例(端口、密钥、volume 按你现网填写):
services:
redmine:
image: redmine-feishu:latest
container_name: redmine-app
restart: always
ports:
- "12323:3000"
environment:
REDMINE_SECRET_KEY_BASE: <必须和原来相同>
volumes:
- redmine_sqlite_data:/usr/src/redmine/sqlite
- redmine_files_data:/usr/src/redmine/files
volumes:
redmine_sqlite_data:
redmine_files_data:
可选环境变量(优先于后台填写):FEISHU_APP_ID、FEISHU_APP_SECRET、FEISHU_API_BASE(默认 open.feishu.cn)。
启动后会自动跑迁移,只加飞书映射表,不会清空用户和 Issue。
本地配过的开关 *不会* 带到生产库。用 *管理员* 登录 *当前这套* Redmine:
-
打开 *管理 → 设置 → 集成*
-
勾选「启用飞书任务同步」
-
填写 App ID、App Secret(若没用环境变量)
-
「抄送人飞书 open_id」填一个或多个,逗号、空格或换行均可。这些人会作为 *关注人* 加入每个飞书问题任务,例如:
ou_aaa ou_bbb, ou_ccc
-
「Redmine 飞书任务清单 GUID」:所有项目和问题都进 *同一个* 飞书清单。留空会自动创建名为「Redmine」的清单并写回;也可填已有清单 GUID。应用需开通并 *发布*
task:tasklist:write与task:section:write(缺权限时任务仍会同步,只是进不了清单/分组) -
填写「飞书任务中的 Redmine 访问地址」,例如
http://118.178.179.139:12323(不要末尾斜杠)。不要用http://localhost:3000,否则飞书里点不开。 -
保存
-
打开要同步的 *项目 → 设置 → 模块*
-
勾选「飞书任务同步」并保存。每个项目都要勾,只开全局不够
-
给每个人配负责人 open_id:*管理 → 用户 → 编辑某人*,填「飞书 open_id」并保存。问题指派给这个人时,他就是飞书任务的 *负责人*。留空则按邮箱自动查找(需要
contact:user.id:readonly权限)
飞书里用 *一个* 任务清单(默认名「Redmine」)。飞书自定义分组不能嵌套,所以每个项目是清单里的一个 *平铺分组*:
清单「Redmine」 分组「父项目」 #35 [进行中] 问题标题 #36 [新建] 子问题 ← 有父问题的,挂在父问题任务下 分组「子项目」 ← 子项目也是同级分组,不是嵌套
在已勾选模块的项目里:
-
新建问题 → 进入该项目对应分组;分组在第一次同步时自动创建
-
有父问题 → 飞书子任务挂在父问题任务下(仍属同一分组)
-
改标题、描述、状态、日期、指派人 → 飞书任务跟着改
-
关闭问题 → 飞书任务完成;重新打开 → 取消完成
-
删除问题,或改成私有 → 删除飞书任务(子问题一起删)
-
把问题换到别的父问题 → 飞书不支持换父任务,会删掉旧任务、在新位置重建(连同它的子任务)
-
改项目名称 → 对应分组改名
-
删除项目 → 删除对应分组(分组内任务会进清单默认分组;问题删除会另删飞书任务)
成员:问题的 *指派人* 是飞书 *负责人*;问题的 *作者* 和「抄送人飞书 open_id」里的人是 *关注人*。创建共用清单时,全局抄送人会作为清单协作人。
已有问题不会自动全部推过去,对旧问题 *再保存一次* 才会同步。私有问题不同步。
到飞书「任务 / 我的任务」查看。
docker logs -f redmine-app
改完问题后:
-
Feishu sync running issue=35:已执行同步 -
global=false:未开「启用飞书任务同步」 -
module=false:当前项目未勾选模块(最常见) -
failed:/error::App ID/Secret、权限或网络有问题
同步失败只写日志,Redmine 里照样能保存问题。
其它:
-
日志成功但飞书看不到:默认 open_id 未填/填错,或应用权限没发布
-
换镜像后像空站:连错库文件,或动了 volume / 密钥。换回官方
redmine:latest能恢复则数据还在
同步:lib/redmine/feishu*、app/jobs/feishu_task_sync_job.rb、app/models/concerns/{issue,project,user}/、mapping 模型与 db/migrate 下的飞书迁移、设置/locale/集成页、用户编辑表单、lib/redmine/preparation.rb、app/models/{issue,project,user}.rb
Docker:Dockerfile、docker-compose.yml、docker/、.dockerignore、config/puma.rb
测试:test/unit/lib/redmine/feishu/task_sync_test.rb、test/unit/jobs/feishu_task_sync_job_test.rb