一个可移植、脚本友好的 Redmine 命令行工具:优先使用 REST API,也能在旧实例中复用本机浏览器登录会话进行只读查询。
redmine-cli 面向日常运维、测试平台和自动化脚本。编译后只有一个可执行文件,不依赖 Python、Node.js 或 Java;支持多实例、稳定退出码、自动分页、表格/JSON/CSV 输出,以及尚未封装 API 的通用请求入口。
Important
项目目前处于 Pre-1.0 阶段。REST 主流程和 Browser 兼容层已有自动化及真实环境验收,但 Browser 模式依赖 Redmine 网页结构,跨版本、主题和插件兼容矩阵仍需持续补充。
| 场景 | 模式 | 能力 | 需要什么 |
|---|---|---|---|
| Redmine 已启用 REST API | rest(默认) |
完整查询、写操作、附件和 request |
API Key 或 Basic Auth |
| REST API 被禁用,但网页可以登录 | browser |
项目和议题的只读 list/get、保存 Query、自动分页 | 本机 Chrome/Edge 登录会话 |
| 暂时没有 Redmine 数据或权限 | snapshot |
演示、保存和离线查看议题集合 | 无需网络或账号 |
Browser 模式不是绕过权限的工具。它只能读取当前登录用户在网页上本来就能看到的数据,不能替代 REST 写操作,也不能读取没有权限访问的项目。
需要 Go 1.18 或更高版本:
git clone https://github.com/zymk8353/redmine-cli.git
cd redmine-cli
go build -trimpath -o redmine .Windows 输出文件可命名为 redmine.exe。也可以从仓库的 Releases 页面下载已发布构建。
推荐使用 API Key,并通过标准输入保存,避免进入 shell 历史:
redmine profile add company --url https://redmine.example.com --use
"your-api-key" | redmine auth set-key --stdin
redmine profile test
redmine issue list --project demoBasic Auth:
redmine profile add legacy --url https://redmine.example.com --auth basic --username alice --use
"your-password" | redmine auth set-basic --username alice --stdin
redmine profile test也可以完全使用环境变量,适合 CI:
$env:REDMINE_URL = "https://redmine.example.com"
$env:REDMINE_API_KEY = $env:CI_REDMINE_API_KEY
redmine -o json issue list --project demoredmine snapshot demo
redmine -o json snapshot demo --pretty
redmine -o csv snapshot demo --fields id,subject,status.name,done_ratio这组数据完全内置,不访问网络,也不会伪装成真实 Redmine 数据。
# 项目
redmine project list
redmine project get demo
redmine project create --set name=Demo --set identifier=demo
# 议题
redmine issue list --project demo --status open
redmine issue get 123
redmine issue create --set project_id=demo --set subject="CLI created issue"
redmine issue update 123 --set status_id=5 --set done_ratio=100
redmine issue comment 123 --text "Deployment completed"
# 用户、版本、工时
redmine user list --param status=1
redmine version list --project demo
redmine time list --project demo --from 2026-07-01 --to 2026-07-31
# 关系、附件、Wiki
redmine relation list 123
redmine attachment upload .\evidence.zip --issue 123
redmine attachment download 42 --output-file .\evidence.zip
redmine wiki get demo Home复杂请求体支持内联 JSON、文件或标准输入:
redmine issue create --data '{"project_id":"demo","subject":"Build failed"}'
redmine issue update 123 --data-file update.json
Get-Content payload.json -Raw | redmine issue create --data -- 列表命令默认自动读取全部分页,也可限制数量或关闭自动分页。
stdout只输出结果,诊断信息写入stderr。- 支持
table、json、csv和raw输出。 - JSON/CSV 字段支持
status.name、assigned_to.name等点路径。 - 明确区分参数、配置、认证、权限、网络、服务端和部分分页错误。
redmine issue list --project demo --query 7 --page-size 100
redmine issue list -o json --pretty
redmine issue list -o csv --fields id,subject,status.nameredmine profile list
redmine profile use company
redmine --profile legacy issue list凭据来源优先级:环境变量 → Profile 的 secret_command → 本地安全存储。Profile 配置文件本身不保存 API Key 或密码明文。
尚未封装的 Redmine API、插件 API 或私有端点可以通过 request METHOD PATH 调用:
redmine request GET /issues/123.json
redmine request GET /issues.json --param project_id=demo
redmine request PATCH /custom_endpoint.json --data-file body.json
redmine request GET /custom_collection.json --paginate-root itemsrequest 复用当前 Profile 的认证、TLS、超时、脱敏和退出码规则。绝对 URL 必须与当前 Redmine Profile 同源。
先启动一个只监听本机、使用独立用户目录的 Chrome/Edge。首次打开后,在这个浏览器窗口中正常登录 Redmine:
& "$env:ProgramFiles\Google\Chrome\Application\chrome.exe" `
--remote-debugging-address=127.0.0.1 `
--remote-debugging-port=9222 `
--user-data-dir="$env:LOCALAPPDATA\redmine-cli\browser-profile"然后添加只读 Profile:
redmine profile add legacy-web `
--url https://redmine.example.com `
--transport browser `
--browser-debug-url http://127.0.0.1:9222 `
--use
redmine browser status
redmine project list
redmine issue list --project demo --query 7
redmine issue get 42安全边界:
- CLI 不读取或导出浏览器 Cookie;临时标签页由浏览器自行携带登录会话。
- DevTools 地址只允许
127.0.0.1、localhost或::1,不要暴露到局域网或公网。 - 当前仅支持项目和议题的只读 list/get,以及议题保存 Query 和分页。
- 用户、版本、工时、关系、附件、Wiki 和全部写操作仍需要 REST API。
- 页面结构差异过大时会明确报错,不会输出猜测数据。
redmine snapshot capture .\snapshot.json --project demo --query 7
redmine snapshot show .\snapshot.json
redmine -o csv snapshot show .\snapshot.json --fields id,subject,status.nameSnapshot 不包含实例 URL、用户名、API Key、密码、Cookie 或 DevTools 地址,并采用私有权限和原子替换写入。
Warning
Snapshot 中的标题、描述、人员和自定义字段仍可能是业务敏感数据。它不是自动脱敏文件,公开分享前必须由数据所有者检查。
| 资源 | REST 查询 | REST 写入 | Browser 只读 |
|---|---|---|---|
| 项目 | ✓ | ✓ | list/get |
| 议题 | ✓ | ✓ | list/get |
| 用户 | ✓ | ✓ | — |
| 版本 | ✓ | ✓ | — |
| 工时 | ✓ | ✓ | — |
| 关系 | ✓ | ✓ | — |
| 附件 | ✓ | 上传/下载 | — |
| Wiki | ✓ | ✓ | — |
| 元数据 | ✓ | — | — |
| 未封装 REST API | request |
request |
— |
- 本地凭据使用 AES-256-GCM 加密;Windows 使用当前用户 DPAPI 保护主密钥。
- Linux/macOS 主密钥文件限制为当前用户可读写。
- 日志和错误信息不输出 API Key、Authorization、Cookie 或 URL 查询参数。
- 跨域重定向会移除认证头;通用请求限制为同源地址。
- TLS 证书默认严格校验;
--insecure只适合临时可信测试环境。 - HTTP 响应体与 Snapshot 当前上限均为 64 MiB。
完整配置、Secret Manager 接入和代理说明见 配置与凭据。
| 代码 | 含义 |
|---|---|
| 0 | 成功 |
| 1 | 未分类内部错误 |
| 2 | 参数或输入错误 |
| 3 | 配置错误 |
| 4 | 认证失败 |
| 5 | 权限不足 |
| 6 | 资源不存在 |
| 7 | Redmine 校验失败或状态冲突 |
| 8 | 网络、超时或 TLS 错误 |
| 9 | Redmine 服务端错误 |
| 10 | 自动分页只获得部分结果 |
完整映射与脚本处理建议见 退出码说明。
| 项目 | 当前结果 |
|---|---|
| 自动化测试 | 106 项通过,覆盖 9 个 Go package |
| 静态检查 | go vet ./... 通过 |
| 跨平台构建 | Windows、Linux、macOS 的 amd64/arm64 六个目标通过 |
| 本地浏览器链路 | Windows Chrome DevTools 建连、临时标签页、DOM 提取和关闭通过 |
| 真实 Redmine Browser 模式 | 项目/议题 list/get、保存 Query、自动分页与 Snapshot 链路通过 |
真实 Redmine 验收严格保持只读。REST 写操作由本地模拟服务和自动化测试覆盖;在生产环境启用写权限前,仍建议先在测试项目验收权限、字段和插件差异。
go test -count=1 ./...
go vet ./...
go build -trimpath -o redmine.exe .完整跨平台构建:
.\scripts\build.ps1 -Version dev欢迎通过 Issues 报告 Redmine 版本差异、页面兼容问题和脚本场景。
本项目采用 MIT License。你可以使用、复制、修改、合并、发布、分发、再许可或销售本软件,但必须保留原始版权声明和许可声明;软件按“原样”提供,不附带任何担保。