release
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFreenet Release Skill
Freenet版本发布Skill
Overview
概述
This skill orchestrates a complete Freenet release. It determines the next version, shows what's changed since the last release, confirms with the user, and runs the automated release pipeline.
本Skill可编排完整的Freenet版本发布流程。它会确定下一个版本号、展示自上次发布以来的变更内容、与用户确认后运行自动化发布流水线。
Arguments
参数说明
- If an argument is provided (e.g., ), use that as the target version
/release 0.1.133 - If no argument is provided, auto-detect the next patch version
- 若提供了参数(例如),则将该参数作为目标版本号
/release 0.1.133 - 若未提供参数,则自动检测下一个补丁版本号
Step 1: Determine Current State
步骤1:确定当前状态
Run these commands to gather release context:
bash
undefined运行以下命令收集发布相关信息:
bash
undefinedGet current version from Cargo.toml
从Cargo.toml获取当前版本
grep "^version" crates/core/Cargo.toml | cut -d'"' -f2
grep "^version" crates/core/Cargo.toml | cut -d'"' -f2
Get the last release tag
获取上一个发布标签
git describe --tags --abbrev=0
git describe --tags --abbrev=0
Get commits since last release
获取自上次发布以来的提交记录
git log --oneline $(git describe --tags --abbrev=0)..HEAD
**Auto-version logic:** If no version argument was provided, increment the patch version of the current version (e.g., `0.1.132` -> `0.1.133`).git log --oneline $(git describe --tags --abbrev=0)..HEAD
**自动版本号逻辑:** 若未提供版本参数,则将当前版本的补丁号递增(例如`0.1.132` -> `0.1.133`)。Step 2: Show Changelog and Confirm
步骤2:展示更新日志并确认
Present the user with:
- Current version and target version
- Commits since last release (categorized by conventional commit type)
- fdev version that will be auto-incremented
Then ask the user to confirm before proceeding.
向用户展示以下内容:
- 当前版本号和目标版本号
- 自上次发布以来的提交记录(按规范提交类型分类)
- 将自动递增的fdev版本号
然后在继续执行前请求用户确认。
Step 3: Pre-flight Checks
步骤3:预发布检查
Before running the release script, verify:
bash
undefined在运行发布脚本前,需验证以下内容:
bash
undefinedMust be on main branch (or a release worktree)
必须处于main分支(或发布工作树)
git branch --show-current
git branch --show-current
Must have clean working directory
工作目录必须干净无变更
git status --porcelain # Should be empty
git status --porcelain # 输出应为空
Must be up to date with origin
必须与远程仓库origin保持同步
git fetch origin main
git rev-parse HEAD # Compare with:
git rev-parse origin/main
If any check fails, inform the user and stop.git fetch origin main
git rev-parse HEAD # 与以下命令结果对比:
git rev-parse origin/main
若任何一项验证失败,需告知用户并终止流程。Optional: Create a Release Worktree
可选:创建发布工作树
To avoid disrupting the main worktree:
bash
cd ~/code/freenet/freenet-core/main # or wherever main worktree is
git worktree add -b release-work ../release-X.Y.Z
cd ../release-X.Y.ZClean up after release:
bash
git worktree remove ../release-X.Y.Z
git branch -d release-work为避免干扰主工作树,可执行以下操作:
bash
cd ~/code/freenet/freenet-core/main # 或主工作树所在的其他路径
git worktree add -b release-work ../release-X.Y.Z
cd ../release-X.Y.Z发布完成后清理:
bash
git worktree remove ../release-X.Y.Z
git branch -d release-workStep 4: Run the Release
步骤4:执行发布
Execute the release script:
bash
./scripts/release.sh --version <VERSION> [--skip-tests] [--deploy-local]The script handles the entire pipeline:
- Version bump - Updates and
crates/core/Cargo.tomlcrates/fdev/Cargo.toml - Release PR - Creates a branch, commits, pushes, opens PR with auto-merge
- Wait for CI - Monitors GitHub CI on the release PR (up to 30 min)
- Publish crates - Publishes then
freenetto crates.iofdev - GitHub Release - Creates tag, generates release notes, creates release
- Cross-compile - Triggered automatically by the tag push
- Wait for binaries - Waits for cross-compile to attach binaries to the release
- Announcements - Matrix and River notifications (if tools available)
执行发布脚本:
bash
./scripts/release.sh --version <VERSION> [--skip-tests] [--deploy-local]该脚本会处理完整的发布流水线:
- 版本号更新 - 更新和
crates/core/Cargo.toml中的版本号crates/fdev/Cargo.toml - 创建发布PR - 创建分支、提交变更、推送到远程仓库并开启自动合并的PR
- 等待CI完成 - 监控发布PR的GitHub CI流程(最长等待30分钟)
- 发布到crates.io - 先将发布到crates.io,再发布
freenetfdev - 创建GitHub Release - 创建版本标签、生成发布说明并创建Release
- 交叉编译 - 推送标签后自动触发交叉编译流程
- 等待二进制文件生成 - 等待交叉编译完成并将二进制文件附加到Release中
- 发布通知 - 发送Matrix和River通知(若相关工具可用)
Important Options
重要选项
- - Skip local pre-release tests (CI still runs on the PR)
--skip-tests - - Show what would be done without executing
--dry-run - - Deploy to local gateway after release
--deploy-local - - Deploy to remote gateways after release
--deploy-remote
- - 跳过本地预发布测试(PR上的CI仍会运行)
--skip-tests - - 展示将要执行的操作但不实际执行
--dry-run - - 发布完成后部署到本地网关
--deploy-local - - 发布完成后部署到远程网关
--deploy-remote
Resumability
断点续传
The release script is resumable. If it fails partway through, re-running with the same will auto-detect completed steps and skip them. State is saved to .
--version/tmp/release-<VERSION>.stateYou can also resume explicitly:
./scripts/release.sh --resume /tmp/release-<VERSION>.state发布脚本支持断点续传。若脚本在执行中途失败,使用相同的参数重新运行时,会自动检测已完成的步骤并跳过。状态信息会保存到。
--version/tmp/release-<VERSION>.state你也可以显式指定恢复:
./scripts/release.sh --resume /tmp/release-<VERSION>.stateStep 5: Handle Common Issues
步骤5:处理常见问题
PR title / Conventional Commits check fails:
Release PRs must use "build:" prefix (not "chore:"). The commit-msg hook only allows: feat, fix, docs, style, refactor, perf, test, build, ci.
bash
gh api repos/freenet/freenet-core/pulls/XXXX --method PATCH -f title="build: release X.Y.Z"Auto-merge not triggering:
- GitHub auto-merge can take 5-10 minutes after checks pass
- The script waits up to 30 minutes (showing progress every 30s)
- You can manually merge the PR — the script detects manual merges and continues
Test failures:
Check CI logs. Either fix the issue or inform the user and ask how to proceed.
PR标题/规范提交检查失败:
发布PR的标题必须使用“build:”前缀(不能用“chore:”)。commit-msg钩子仅允许使用以下前缀:feat、fix、docs、style、refactor、perf、test、build、ci。
bash
gh api repos/freenet/freenet-core/pulls/XXXX --method PATCH -f title="build: release X.Y.Z"自动合并未触发:
- GitHub自动合并在检查通过后可能需要5-10分钟
- 脚本会等待最多30分钟(每30秒展示一次进度)
- 你可以手动合并PR — 脚本会检测到手动合并并继续执行后续流程
测试失败:
检查CI日志。要么修复问题,要么告知用户并询问后续处理方式。
Step 6: Verify Release Artifacts
步骤6:验证发布产物
CRITICAL: Do NOT announce until cross-compile binaries are available. The workflow triggers on tag push and takes ~15-20 min to build binaries for all platforms. Gateway auto-update depends on these binaries.
Build and Cross-Compilebash
undefined重要提示:在交叉编译的二进制文件生成完成前,请勿发布通知。 工作流会在推送标签后触发,为所有平台构建二进制文件需要约15-20分钟。网关的自动更新依赖于这些二进制文件。
Build and Cross-Compilebash
undefinedCheck crates.io publication
检查crates.io上的发布情况
cargo search freenet --limit 1
cargo search freenet --limit 1
Check GitHub release exists
检查GitHub Release是否创建成功
gh release view v<VERSION>
gh release view v<VERSION>
Verify binaries are attached
验证二进制文件是否已附加到Release
gh release view v<VERSION> --json assets --jq '.assets[].name'
gh release view v<VERSION> --json assets --jq '.assets[].name'
Should show: freenet-x86_64-unknown-linux-musl.tar.gz, freenet-aarch64-unknown-linux-musl.tar.gz, etc.
应显示:freenet-x86_64-unknown-linux-musl.tar.gz、freenet-aarch64-unknown-linux-musl.tar.gz等文件
Monitor cross-compile workflow if binaries not yet available
若二进制文件尚未生成,监控交叉编译工作流
gh run list --workflow=cross-compile.yml --limit 3
undefinedgh run list --workflow=cross-compile.yml --limit 3
undefinedStep 7: Announcements
步骤7:发布通知
Only after binaries are confirmed available:
Matrix (#freenet-locutus channel):
bash
undefined仅在确认二进制文件生成完成后,再执行以下通知操作:
Matrix(#freenet-locutus频道):
bash
undefinedUse matrix-send wrapper if available (handles E2E encryption, retries, timeouts)
若有matrix-send封装工具请使用(支持端到端加密、重试、超时处理)
matrix-send -r '!ygHfYcXtXmivTbOwjX:matrix.org' -m "Freenet vX.Y.Z released - [summary]. https://github.com/freenet/freenet-core/releases/tag/vX.Y.Z"
**River** (Freenet Official room):
```bash
riverctl message send 69Ht4YjZsT884MndR2uWhQYe1wb9b2x77HRq7Dgq7wYE "Freenet vX.Y.Z released - [summary]. https://github.com/freenet/freenet-core/releases/tag/vX.Y.Z"matrix-send -r '!ygHfYcXtXmivTbOwjX:matrix.org' -m "Freenet vX.Y.Z版本已发布 - [摘要]. https://github.com/freenet/freenet-core/releases/tag/vX.Y.Z"
**River**(Freenet官方房间):
```bash
riverctl message send 69Ht4YjZsT884MndR2uWhQYe1wb9b2x77HRq7Dgq7wYE "Freenet vX.Y.Z版本已发布 - [摘要]. https://github.com/freenet/freenet-core/releases/tag/vX.Y.Z"Step 8: Post-Release Verification
步骤8:发布后验证
A release is NOT complete until the network is verified healthy.
Wait 10-15 minutes for gateways to auto-update, then verify:
- Gateway versions updated — Check that gateways are running the new version
- Gateway logs clean — No new errors, warnings, panics, or log spam
- Network health — Peers connecting, contracts propagating, subscriptions working
If you have access to gateway machines, check logs directly. If you have access to telemetry, monitor network-wide health. The specific verification steps depend on your access level — see your local environment's release skill for machine-specific commands.
What to look for:
- Log spam — Same message repeating hundreds of times (can fill disks within hours)
- Rapid log growth — Normal is ~1MB/hour; much faster indicates a problem
- New error patterns — Errors not present before the release
- Connection failures — "connection refused", "timeout", "handshake failed"
- Resource issues — "out of memory", "no space left", "too many open files"
If critical issues found: Roll back immediately, create GitHub issue, announce rollback.
只有在确认网络状态健康后,发布流程才算完成。
等待10-15分钟让网关完成自动更新,然后验证以下内容:
- 网关版本已更新 — 确认网关正在运行新版本
- 网关日志无异常 — 无新的错误、警告、崩溃或日志刷屏情况
- 网络状态健康 — 节点可正常连接、合约可正常传播、订阅功能正常
若你有权限访问网关机器,请直接检查日志。若有权限访问遥测数据,请监控全网状态。具体的验证步骤取决于你的权限级别——请参考本地环境的发布指南获取机器特定的命令。
需要关注的问题:
- 日志刷屏 — 同一消息重复数百次(可能在数小时内占满磁盘)
- 日志增长过快 — 正常情况约为1MB/小时;若增长过快则表示存在问题
- 新的错误模式 — 发布前未出现过的错误
- 连接失败 — 出现“connection refused”“timeout”“handshake failed”等信息
- 资源问题 — 出现“out of memory”“no space left”“too many open files”等信息
若发现严重问题: 立即执行回滚操作、创建GitHub Issue并发布回滚通知。
Rollback
回滚流程
If a release needs to be rolled back:
bash
undefined若需要回滚版本发布:
bash
undefinedRollback (keeps crates.io versions)
执行回滚(保留crates.io上的版本)
./scripts/release-rollback.sh --version <VERSION>
./scripts/release-rollback.sh --version <VERSION>
Rollback and yank from crates.io (irreversible!)
执行回滚并从crates.io撤回版本(此操作不可撤销!)
./scripts/release-rollback.sh --version <VERSION> --yank-crates
./scripts/release-rollback.sh --version <VERSION> --yank-crates
Dry run
模拟回滚(仅展示操作不实际执行)
./scripts/release-rollback.sh --version <VERSION> --dry-run
undefined./scripts/release-rollback.sh --version <VERSION> --dry-run
undefinedVersion Scheme
版本号规则
- freenet: - patch incremented each release
0.1.X - fdev: - patch auto-incremented by release script (independent versioning)
0.3.X
- freenet: - 每次发布递增补丁版本号
0.1.X - fdev: - 补丁版本号由发布脚本自动递增(独立版本控制)
0.3.X
Incident Learnings
过往问题总结
These are real issues from past releases that the release process has been hardened against:
- "Text file busy" during deployment — Deploy script now disables systemd auto-restart, waits for binary release, re-enables after
- PR title must use "build:" prefix — Changed from "chore:" to comply with commit-msg hook
- Matrix announcements can hang — matrix-send wrapper has 20s timeout and 3 retries; matrix-commander handles E2E encryption that raw curl cannot
- PATH shadowing — Old may leave stale binary at
cargo install freenetshadowing~/.cargo/bin/freenet; always use absolute paths when verifying versions/usr/local/bin/freenet - Binary vs running process mismatch — Deploying a new binary doesn't mean the service is running it; verify via +
systemctl show -p MainPID, not just binary on disk/proc/PID/exe - Don't announce before binaries exist — Cross-compile takes 15-20 min; gateway auto-update (especially aarch64) depends on release binaries being attached
- Log spam can fill disks — Always review logs 10-15 min after release; previous releases introduced logging that consumed disk space within hours
以下是过往发布中遇到的真实问题,发布流程已针对这些问题进行了优化:
- 部署时出现“Text file busy”错误 — 现在部署脚本会先禁用systemd自动重启,等待二进制文件释放后再重新启用
- PR标题必须使用“build:”前缀 — 从“chore:”改为“build:”以符合commit-msg钩子的要求
- Matrix通知可能卡住 — matrix-send封装工具设置了20秒超时和3次重试;matrix-commander可处理原始curl无法实现的端到端加密
- PATH路径覆盖 — 旧的可能会在
cargo install freenet留下过期的二进制文件,覆盖~/.cargo/bin/freenet;验证版本时请始终使用绝对路径/usr/local/bin/freenet - 二进制文件与运行进程版本不匹配 — 部署新的二进制文件并不意味着服务正在运行该版本;请通过+
systemctl show -p MainPID进行验证,而不仅仅检查磁盘上的二进制文件/proc/PID/exe - 在二进制文件生成前请勿发布通知 — 交叉编译需要15-20分钟;网关自动更新(尤其是aarch64架构)依赖于附加到Release的二进制文件
- 日志刷屏可能占满磁盘 — 发布后10-15分钟务必检查日志;过往发布曾引入过在数小时内占满磁盘的日志内容
Gateway Auto-Update
网关自动更新
Gateways poll GitHub every 10 minutes for new releases and auto-update. This is pull-based (no inbound webhooks needed) and architecture-aware (x86_64/aarch64).
Peers also self-update: when a peer detects a version mismatch with the gateway (exit code 42), systemd triggers automatically.
freenet updateManual trigger (if you have gateway access):
gateway-auto-update.sh --force网关每10分钟轮询GitHub一次以检查新版本并自动更新。此机制为拉取式(无需入站Webhook)且支持架构感知(x86_64/aarch64)。
节点也会自动更新:当节点检测到与网关的版本不匹配时(退出码42),systemd会自动触发命令。
freenet update手动触发更新(若有权限访问网关):
gateway-auto-update.sh --forceSuccess Criteria
成功标准
Release is complete when:
- ✓ PR merged to main
- ✓ Published to crates.io
- ✓ GitHub release created with tag and binaries attached
- ✓ Matrix announcement sent
- ✓ River announcement sent
- ✓ Network verified healthy post-release (logs clean, telemetry normal)
满足以下条件时,发布流程才算完成:
- ✓ PR已合并到main分支
- ✓ 已发布到crates.io
- ✓ 已创建GitHub Release并附加了标签和二进制文件
- ✓ 已发送Matrix通知
- ✓ 已发送River通知
- ✓ 发布后网络状态验证健康(日志无异常、遥测数据正常)