Skip to content

ci: publish releases from explicit release PRs - #580

Open
wangl-cc wants to merge 2 commits into
mainfrom
codex/stable-release-automation
Open

wangl-cc wants to merge 2 commits into
mainfrom
codex/stable-release-automation

Conversation

@wangl-cc

@wangl-cc wangl-cc commented Sep 13, 2026 •

Copy link
Copy Markdown
Member

Stable 发布现在由带 release 标签的同仓库 PR 合入 main 明确触发。版本和 changelog 在 PR 中一起审核,普通版本 bump 不再触发发布;已单独更新版本时,可以创建只更新 changelog 的 release PR。

  • 新增 Prepare Stable Release,支持 auto、patch、minor、major 和指定版本,使用 git-cliff 2.13.1 推导版本和生成 changelog。PR 检查及实际合并后的发布检查都会拒绝过期的 changelog。
  • Beta/Alpha 在构建时通过 MAA_VERSION 注入版本,不修改 main 的 Cargo.toml、Cargo.lock 或 changelog。编号由已发布索引维护;Beta tag 或 Nightly 发布超前于索引时,先恢复索引再分配序号。
  • 将发布计划、说明和打包产物保存为 artifacts,失败重试复用原内容。打包直接输出 bundle,保持输入索引只读。独立更新 version 分支,拒绝 tag 冲突及旧发布覆盖较新索引。
  • 下游发布等待索引更新成功,且每次重试都重新检查当前 stable 身份,防止旧 AUR 任务在新版发布后回退包版本。手动 WinGet 发布也核对实际请求的 tag。
  • 移除独立的 changelog 发布工作流,新增发布工具回归测试工作流并补充操作和恢复文档。

验证:

  • cargo +nightly fmt、cargo clippy -p xtask --all-targets --locked -- -D warnings 和 cargo test -p xtask --locked 通过,xtask 共 21 项测试。
  • 使用 git-cliff 2.13.1 的文件集成测试、发布恢复测试及脚本 ShellCheck 通过,覆盖 changelog-only PR、过期说明刷新、Beta 不写源码、Nightly 索引滞后与恢复、打包不写输入索引、旧下游任务重试、手动 WinGet tag 错配和 API 失败。
  • cargo x test --no-core-tests、Markdown lint 和 git diff --check 通过。完整 cargo x test 因本机找不到 MaaCore 停在初始化。
  • actionlint 1.7.12 在忽略尚未支持的 concurrency.queue 字段诊断后通过;AUR 工作流仅做 actionlint 结构检查,未处理其原有内联 shell 警告。新下游索引检查脚本已用真实 GitHub API 做只读验证。

尚未运行真实 GitHub Actions 发布。启用自动创建 release PR 前,需要在仓库设置中开启 Allow GitHub Actions to create and approve pull requests;本 PR 不修改该设置,也不更新源码版本或 changelog。

Sourcery 总结

采用由带有 release 标签的稳定版发布 PR 和不可变发布制品驱动的、明确、可审查且可恢复的发布流程。

新功能:

  • 添加明确的稳定版发布准备工作流,用于选择版本、生成经过审查的变更日志内容,并创建或更新带有发布标签的 PR。
  • 支持注入 beta 和 alpha 版本以及跟踪渠道索引,同时不会修改 main 上的发布文件。
  • 将发布计划和打包捆绑包持久化为不可变制品,以便在发布任务失败时进行重试和恢复。

Bug 修复:

  • 防止在发布或重试过程中覆盖过时的变更日志、冲突的标签、废弃的发布计划以及更新的渠道索引。
  • 当稳定版索引与正在发布的版本不再匹配时,阻止下游软件包发布。

改进:

  • 要求合并同一仓库中带有 release 标签的 PR 才能触发稳定版发布,并在发布前验证最终合并的变更日志。
  • 围绕明确的提交和发布身份检查,重构发布元数据、打包、索引、预发布版本编号和发布验证流程。

CI:

  • 用发布就绪检查和发布工具回归工作流替代独立的变更日志工作流,覆盖准备流程、预发布行为、制品恢复和发布冲突。

文档:

  • 记录新发布流程对稳定版、beta、alpha、重试、恢复和仓库权限的要求。

测试:

  • 添加针对版本选择、变更日志新鲜度、预发布版本编号、索引更新、标签冲突和制品复用的单元测试、文件集成测试、打包测试和恢复测试。

维护:

  • 收紧 git-cliff 的版本递增和提交分类规则,以改进发布自动化。
Original summary in English

Summary by Sourcery

Adopt an explicit, reviewable, and recoverable release process driven by labeled stable release PRs and immutable publication artifacts.

New Features:

  • Add an explicit stable-release preparation workflow that selects a version, generates reviewed changelog content, and opens or updates a labeled release PR.
  • Support beta and alpha version injection and channel index tracking without modifying release files on main.
  • Persist release plans and packaged bundles as immutable artifacts so failed publication jobs can be retried and recovered.

Bug Fixes:

  • Prevent stale changelogs, conflicting tags, obsolete release plans, and newer channel indexes from being overwritten during publication or retries.
  • Block downstream package publishing when the stable index no longer matches the release being published.

Enhancements:

  • Require merging a same-repository PR labeled release to trigger stable publication and validate the final merged changelog before publishing.
  • Refactor release metadata, packaging, indexing, prerelease numbering, and publication validation around explicit commit and release identity checks.

CI:

  • Replace the standalone changelog workflow with release-readiness checks and release-tool regression workflows covering preparation, prerelease behavior, artifact recovery, and publication conflicts.

Documentation:

  • Document the stable, beta, alpha, retry, recovery, and repository-permission requirements for the new release process.

Tests:

  • Add unit, file-integration, packaging, and recovery tests for version selection, changelog freshness, prerelease numbering, index updates, tag conflicts, and artifact reuse.

Chores:

  • Tighten git-cliff version-bump and commit-classification rules for release automation.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你好——我发现了 1 个问题

面向 AI Agent 的提示
请处理此次代码审查中的评论:

## 单独评论

### 评论 1
<location path=".github/workflows/release.yml" line_range="45-47" />
<code_context>
+    if: >-
+      github.event_name == 'pull_request' &&
+      github.event.action != 'closed' &&
+      (contains(github.event.pull_request.labels.*.name, 'release') ||
+       startsWith(github.event.pull_request.head.ref, 'release-prep/')) &&
+      github.event.pull_request.head.repo.full_name == github.repository
     runs-on: ubuntu-latest
-    outputs:
</code_context>
<issue_to_address>
**小问题:** Release Readiness 作业会对任何头部分支以 `release-prep/` 开头的同仓库 PR 运行,即使该 PR 没有 `release` 标签。这与所述的显式标签触发条件相矛盾,并导致未添加标签的发布准备分支也会接收特定于发布的验证和状态检查。

**触发场景:** 同仓库 PR 使用以 `release-prep/` 开头的头部分支,但尚未添加 `release` 标签时。

**建议修复:** 在作业条件中要求存在 `release` 标签,或移除 `startsWith(github.event.pull_request.head.ref, 'release-prep/')` 这一备选条件。
</issue_to_address>

Sourcery 对开源项目免费——如果你喜欢我们的审查,请考虑分享它们 ✨
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path=".github/workflows/release.yml" line_range="45-47" />
<code_context>
+    if: >-
+      github.event_name == 'pull_request' &&
+      github.event.action != 'closed' &&
+      (contains(github.event.pull_request.labels.*.name, 'release') ||
+       startsWith(github.event.pull_request.head.ref, 'release-prep/')) &&
+      github.event.pull_request.head.repo.full_name == github.repository
     runs-on: ubuntu-latest
-    outputs:
</code_context>
<issue_to_address>
**nitpick:** The Release Readiness job runs for any same-repository PR whose head branch starts with `release-prep/`, even when the PR has no `release` label. This contradicts the stated explicit-label trigger and causes unlabelled release-preparation branches to receive release-specific validation and status checks.

**Triggers:** When a same-repository PR uses a `release-prep/` head branch before the `release` label is added.

**Suggested fix:** Require the `release` label in the job condition, or remove the `startsWith(github.event.pull_request.head.ref, 'release-prep/')` alternative.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment on lines +45 to +47
(contains(github.event.pull_request.labels.*.name, 'release') ||
startsWith(github.event.pull_request.head.ref, 'release-prep/')) &&
github.event.pull_request.head.repo.full_name == github.repository

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

小问题: Release Readiness 作业会对任何头部分支以 release-prep/ 开头的同仓库 PR 运行,即使该 PR 没有 release 标签。这与所述的显式标签触发条件相矛盾,并导致未添加标签的发布准备分支也会接收特定于发布的验证和状态检查。

触发场景: 同仓库 PR 使用以 release-prep/ 开头的头部分支,但尚未添加 release 标签时。

建议修复: 在作业条件中要求存在 release 标签,或移除 startsWith(github.event.pull_request.head.ref, 'release-prep/') 这一备选条件。

Original comment in English

nitpick: The Release Readiness job runs for any same-repository PR whose head branch starts with release-prep/, even when the PR has no release label. This contradicts the stated explicit-label trigger and causes unlabelled release-preparation branches to receive release-specific validation and status checks.

Triggers: When a same-repository PR uses a release-prep/ head branch before the release label is added.

Suggested fix: Require the release label in the job condition, or remove the startsWith(github.event.pull_request.head.ref, 'release-prep/') alternative.

@codecov

codecov Bot commented Sep 13, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.59%. Comparing base (dc7d1a9) to head (5ff3e83).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #580      +/-   ##
==========================================
+ Coverage   72.07%   72.59%   +0.52%     
==========================================
  Files          72       72              
  Lines        6679     6759      +80     
  Branches     6679     6759      +80     
==========================================
+ Hits         4814     4907      +93     
- Misses       1523     1557      +34     
+ Partials      342      295      -47     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant