feat(release): publish release notes from Markdown

Require committed, non-empty notes matching the target release version before
creating a tag. Read notes from the tagged source and place them before the
installation guide and generated release changelog.

Add the 3.3.31 feature summary and keep maintainer instructions in the release
script help and repository skill instead of the deployment README.

Validation: shell syntax and workflow lint passed. Nine isolated checks cover
local publication, stale or missing notes, and release-body rendering.

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Zyy
2026-09-11 03:40:00 +08:00
co-authored by Codex
parent 8b22788746
commit 9b19cf083a
5 changed files with 68 additions and 20 deletions
+31 -9
View File
@@ -88,6 +88,13 @@ jobs:
fail("Release tag #{release_tag} does not match #{version_path} tag #{expected_tag}") unless release_tag == expected_tag
fail("#{version_path}: version #{version} is not a valid semver") unless version.match?(SEMVER)
notes_path = "release/notes.md"
fail("#{notes_path}: release notes are required") unless File.file?(notes_path)
notes = File.readlines(notes_path)
unless notes.first&.strip == "# #{release_tag}" && !notes.drop(1).join.strip.empty?
fail("#{notes_path}: expected non-empty notes starting with '# #{release_tag}'")
end
platforms = platforms_data["platforms"]
fail("#{platforms_path}: platforms must be a non-empty array") unless platforms.is_a?(Array) && !platforms.empty?
@@ -643,15 +650,10 @@ jobs:
cosign sign --yes "${images[@]}"
- name: Publish GitHub Release
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
tag_name: ${{ needs.release-info.outputs.tag }}
generate_release_notes: true
previous_tag: ${{ needs.release-info.outputs.previous_tag }}
prerelease: ${{ needs.release-info.outputs.prerelease == 'true' }}
make_latest: ${{ needs.release-info.outputs.prerelease == 'true' && 'false' || 'true' }}
body: |
- name: Prepare release notes
shell: bash
env:
INSTALLATION_NOTES: |
> [!WARNING]
> **Upgrading across major versions?** Online upgrades across major versions are not supported. Deploy the new major fresh with a new `.runtime/` data directory, then re-import or re-authorize provider accounts and client keys. See the [upgrade notes](https://github.com/${{ github.repository }}/blob/main/deploy/README.md#镜像升级与源码构建).
@@ -672,6 +674,26 @@ jobs:
- [GitHub Repository](https://github.com/${{ github.repository }})
- [Installation Guide](https://github.com/${{ github.repository }}/blob/main/deploy/README.md)
run: |
python3 <<'PY'
import os
from pathlib import Path
notes = "\n".join(Path("release/notes.md").read_text().splitlines()[1:]).strip()
installation = os.environ["INSTALLATION_NOTES"].strip()
output = Path(os.environ["RUNNER_TEMP"]) / "release-notes.md"
output.write_text(f"{notes}\n\n{installation}\n")
PY
- name: Publish GitHub Release
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
tag_name: ${{ needs.release-info.outputs.tag }}
generate_release_notes: true
previous_tag: ${{ needs.release-info.outputs.previous_tag }}
prerelease: ${{ needs.release-info.outputs.prerelease == 'true' }}
make_latest: ${{ needs.release-info.outputs.prerelease == 'true' && 'false' || 'true' }}
body_path: ${{ runner.temp }}/release-notes.md
fail_on_unmatched_files: true
files: |
dist/release/*
-10
View File
@@ -313,16 +313,6 @@ docker compose -f deploy/compose.yaml build codex-proxy-rs
docker compose -f deploy/compose.yaml up -d --no-build --wait
```
仓库维护者发布新版本时必须从干净且已同步上游的分支运行:
```bash
release/publish X.Y.Z
```
将 `X.Y.Z` 替换为待发布版本。脚本需要 Git、Ruby 和已登录的 GitHub CLI,
负责更新 `release/version.yaml`、创建版本提交和带注释 tag,并原子推送分支与 tag。
它不会登录任何服务器,也不会拉取镜像或调用管理端在线更新。
源码提交、仓库发版和运行实例升级是三种独立状态:本地 commit 不等于 Release,Release/tag 和镜像
已生成也不等于实例已升级。判断某项修复是否在线前,应先通过管理端版本接口或容器 image digest
确认运行实例的实际 revision;实例只有在执行上面的 Compose pull/up,或成功完成管理端在线更新后
+21
View File
@@ -0,0 +1,21 @@
# v3.3.31
## What's new
- Add daily and weekly API key spending limits, persistent usage accounting, and audited reconciliation. Set a limit to `0` to leave it unrestricted.
- Support per-account outbound proxies for authentication, imports, and model requests.
- Support importing Codex personal access tokens.
## Improvements
- Configure scheduling, concurrency, weight, and groups before importing account credentials.
- Share account settings across import, individual editing, and batch editing, with consistent modal actions and spacing.
- Improve account plan labels and fill missing plan information from provider quota snapshots.
## Fixes
- Apply updated API key limits and enabled state to new requests on existing WebSocket connections.
- Prevent a flash at the end of light/dark theme transitions.
- Return explicit errors when a requested model is unavailable.
Spending limits use the existing dollar-based accounting rules. Requests already admitted can finish and cause settled usage to exceed a limit; usage-log cleanup does not reset budget accounting.
+14
View File
@@ -3,6 +3,7 @@ set -euo pipefail
APP_NAME="codex-proxy-rs"
VERSION_FILE="release/version.yaml"
NOTES_FILE="release/notes.md"
TAG_PREFIX="v"
SEMVER='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$'
SIGNATURE="Co-authored-by: Codex <noreply@openai.com>"
@@ -14,6 +15,9 @@ Usage:
Example:
release/publish 0.1.4
Before publishing, replace release/notes.md with the new version's notes and
commit it. Its first line must be "# v<version>".
USAGE
}
@@ -103,6 +107,16 @@ current_version="${current_version#v}"
tag="${TAG_PREFIX}${version}"
git ls-files --error-unmatch "$NOTES_FILE" >/dev/null 2>&1 || die "$NOTES_FILE is not tracked"
ruby - "$NOTES_FILE" "$tag" <<'RUBY'
path, tag = ARGV
lines = File.readlines(path)
unless lines.first&.strip == "# #{tag}" && !lines.drop(1).join.strip.empty?
warn "#{path}: replace the contents with notes for #{tag}, starting with '# #{tag}'"
exit 1
end
RUBY
if git rev-parse --quiet --verify "refs/tags/$tag" >/dev/null; then
die "local tag already exists: $tag"
fi
+2 -1
View File
@@ -88,4 +88,5 @@ docker compose -f deploy/compose.yaml config --quiet
- 提交前检查 status、cached/unstaged diff 和 `git diff --check`。
- 使用简短 Conventional Commit subject;按用户要求添加 `Co-authored-by: Codex <noreply@openai.com>`。
- 发布权威是 `release/version.yaml` 与带注释的 `vX.Y.Z` tag。
- 正式发布使用 `release/publish <version>`;提交、Release 和实例升级是三个独立状态。
- 发版前替换并提交 `release/notes.md`,首行必须为目标版本的 `# vX.Y.Z`,正文只记录本次更新。
- 正式发布使用 `release/publish <version>`;工作流读取 tag 中的发版说明。提交、Release 和实例升级是三个独立状态。