Release / release (push) Failing after 8s
- 新增 .gitea/workflows/release.yml:推送 v* 标签触发,构建前端嵌入后 交叉编译 linux/darwin(amd64+arm64),生成变更日志并创建 Gitea Release - 新增 scripts/build-release.sh:make dist 与 CI 共用的产物构建脚本, tar.gz 打包 + SHA256SUMS;不含 windows(internal/store 依赖 Unix Umask) - Makefile 增加 dist 目标;版本注入沿用 git describe + ldflags(pn version)
120 lines
6.1 KiB
Markdown
120 lines
6.1 KiB
Markdown
# Pure Note
|
||
|
||
极简高安全私人笔记 + 博客。最终交付 = **一个二进制程序 + 一个数据文件(目录)**:
|
||
无数据库服务、无缓存服务、无 Node 运行时、无外部依赖。
|
||
|
||
> 设计文档:[docs/design.md](docs/design.md)(v1.1);实施决策记录:[docs/decisions.md](docs/decisions.md);提交规范:[docs/contributing.md](docs/contributing.md)
|
||
|
||
## 功能
|
||
|
||
- **笔记**:Markdown CRUD、粘贴/拖拽图片上传(≤5MB、魔数校验、BLOB 入库去重)、公开/私有两态、置顶、标签、发布日期可自选
|
||
- **博客**:首页(置顶优先 + 分页 + 标签云)、详情(上一篇/下一篇)、标签页、RSS、sitemap、SEO meta 注入(仅公开内容);站点名称前可显示自定义 Logo
|
||
- **管理**:单管理员口令登录(Argon2id)、会话 7 天滑动续期(CSRF 轮换保持不变)、防爆破限流(per-IP + per-账号)、改密
|
||
- **回收站**:删除 = 软删除,30 天内可恢复,可一键清空,`gc` 到期物理清除
|
||
- **界面**:9 页面响应式 SPA(React 19 + Tailwind 4 + Ant Design 6),深色/浅色/跟随系统三态主题
|
||
- **运维**:`init`(含 Markdown 示例文档与示例图片种子)/ `passwd`(重设口令并吊销全部会话)/ `start` / `backup`(在线一致快照)/ `gc`(默认 dry-run)/ `version`(亦可 `-v`)
|
||
|
||
## 快速开始
|
||
|
||
```bash
|
||
# 1. 构建单二进制(前端 + 后端)
|
||
make build
|
||
|
||
# 2. 初始化(设置管理员口令与站点标题,自动写入一篇 Markdown 示例文档)
|
||
./pn init
|
||
# 非交互:PN_ADMIN_PASSWORD=xxx PN_SITE_TITLE=yyy ./pn init
|
||
|
||
# 3. 启动
|
||
./pn start --addr 127.0.0.1:8080
|
||
|
||
# 4. 访问
|
||
# 博客: http://127.0.0.1:8080/
|
||
# 管理后台:http://127.0.0.1:8080/admin
|
||
```
|
||
|
||
开发模式(本机调试,Cookie 允许非 Secure,仅限 loopback 监听):
|
||
|
||
```bash
|
||
./pn start --dev --addr 127.0.0.1:8080
|
||
# 前端热重载(另开终端):
|
||
cd web && npm install && npm run dev # /api 代理到 127.0.0.1:8080
|
||
```
|
||
|
||
> **为什么必须带 `--dev`**:明文 HTTP 下 Safari/WebKit 不保存 `Secure` Cookie(Chrome/Firefox 有 localhost 豁免,Safari 没有),不带 `--dev` 时 `__Host-` 会话被静默丢弃,Safari 登录成功后仍会被弹回登录页。`--dev` 改用无 `Secure` 的 `pn_session` Cookie 并强制仅监听 loopback(§7.3-3);生产走 HTTPS 不带 `--dev`,自动恢复 `__Host-` + `Secure` 完整加固。
|
||
|
||
忘记口令(CLI 可达即具备服务器权限,可直接重设;重设后全部会话被吊销):
|
||
|
||
```bash
|
||
./pn passwd
|
||
# 非交互:PN_ADMIN_PASSWORD=xxx ./pn passwd
|
||
```
|
||
|
||
## 测试
|
||
|
||
```bash
|
||
make test # go vet + go test ./... + 前端 vitest
|
||
make smoke # 构建冒烟:起服务 → SPA 资源 200/MIME → meta 注入 → 可见性抽查
|
||
```
|
||
|
||
测试矩阵覆盖(§13):可见性矩阵(匿名 × 管理员 × {公开, 私有, 回收站, 不存在} × 全部出口)、
|
||
迁移与 user_version 守卫、登录限流 429、CSRF、上传魔数/去重、回收站生命周期、gc 宽限期、
|
||
slug 冲突策略、设置白名单(永不泄露口令哈希)、meta 注入转义。
|
||
|
||
## 部署(生产)
|
||
|
||
```bash
|
||
make linux # 产出 pn-linux-amd64
|
||
sudo cp pn-linux-amd64 /opt/pure-note/pn
|
||
sudo -u purenote ./pn init --data-dir /opt/pure-note/data
|
||
sudo cp deploy/pn.service deploy/pn-maint.{service,timer} /etc/systemd/system/
|
||
sudo systemctl enable --now pn pn-maint.timer
|
||
```
|
||
|
||
反向代理用 Caddy(自动 TLS),示例见 [deploy/Caddyfile](deploy/Caddyfile);
|
||
启动需带 `--behind-proxy`(取 X-Forwarded-For 最右条目)。
|
||
|
||
**升级 SOP**:`pn backup` → 停服 → 换二进制 → 起服(迁移自动执行;
|
||
库版本高于代码支持范围时拒绝启动,`--allow-newer` 显式放行)。
|
||
|
||
**恢复 SOP**:停服 → 删除 `data/pn.db-wal` 与 `-shm` → 以备份文件替换 `pn.db` → 起服。
|
||
|
||
## 版本与发版
|
||
|
||
版本号以 git tag 为唯一来源(语义化版本,从 `v0.0.1` 开始),构建时经 ldflags 注入,
|
||
`./pn version` 可查看:
|
||
|
||
```bash
|
||
git tag -a v0.0.1 -m "v0.0.1"
|
||
git push origin v0.0.1 # 推送 v* 标签即触发自动发版
|
||
```
|
||
|
||
推送 `v*` 标签后,Gitea Actions([.gitea/workflows/release.yml](.gitea/workflows/release.yml))
|
||
自动构建前端并嵌入,交叉编译 linux/darwin(amd64 + arm64)共 4 个产物,
|
||
连同 SHA256SUMS 与上一版本以来的变更日志一起发布到仓库的 Release 页面。
|
||
|
||
本地验证发布产物:`make dist`(版本缺省 `git describe --tags --always`,输出到 `dist/`)。
|
||
|
||
## 架构
|
||
|
||
```
|
||
cmd/pn/ CLI(start/init/passwd/backup/gc/version)
|
||
internal/config/ 命令行解析(--dev loopback 守卫)
|
||
internal/store/ SQLite(modernc 纯 Go 驱动):迁移(user_version) + DAO + 备份 + gc
|
||
internal/auth/ Argon2id(PHC) + 随机 token
|
||
internal/markdown/ goldmark + bluemonday(RSS/meta 服务端渲染)
|
||
internal/middleware/ 安全头 / 日志 / 限流 / Origin 校验 / MaxBytes
|
||
internal/httpapi/ 路由与 handler(公共 / 认证 / 管理 / feed)
|
||
internal/webui/ go:embed 前端产物 + SPA fallback + index.html meta 注入
|
||
web/ React 19 + Vite + Tailwind 4 前端
|
||
├─ src/pages/ 9 页面:首页 / 笔记详情 / 标签页 / 登录 / 后台列表 / 编辑 / 回收站 / 设置 / 404
|
||
├─ src/components/ Layout(导航与主题切换)、Editor、MarkdownViewer
|
||
├─ src/theme/ shadcnTheme(antd ConfigProvider 主题:品牌 token + 明暗算法 + 桥接样式)
|
||
├─ src/hooks/ use-toast(基于 antd notification 的操作反馈)
|
||
└─ src/lib/ api(CSRF 注入)/ auth(会话上下文)/ theme(三态主题)/ sanitize / invalidate
|
||
deploy/ systemd 单元 ×3 + Caddyfile
|
||
```
|
||
|
||
安全要点(详见设计 §9):CSP `script-src 'self'`、CSRF 双保险(token + Origin 校验)、
|
||
`__Host-` Cookie、服务端统一可见性过滤(单一可信点)、图片并集可见性、
|
||
上传魔数校验拒绝 SVG、统一 404 防枚举、安全响应头全家桶。
|