Skip to content

Commit 0362cf2

Browse files
committed
fix(release): support audited same-tag replacement
1 parent ca4fcbb commit 0362cf2

5 files changed

Lines changed: 46 additions & 16 deletions

File tree

.github/workflows/release.yml

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -240,24 +240,46 @@ jobs:
240240
"${cdn_args[@]}" \
241241
"${previous_args[@]}"
242242
243-
- name: Create draft GitHub Release
243+
- name: Publish GitHub Release assets
244244
env:
245245
GH_TOKEN: ${{ github.token }}
246246
run: |
247247
cd "$RUNNER_TEMP/Artifacts"
248248
sha256sum --check SHA256SUMS.txt
249-
gh release create "$GITHUB_REF_NAME" \
250-
AltForge.ipa \
251-
AltForge-AltServer-macOS.dmg \
252-
AltForge-AltServer-Windows.zip \
253-
apps.json \
254-
flags.json \
255-
sources.json \
256-
recommended-sources.json \
257-
developerdisks.json \
258-
SHA256SUMS.txt \
249+
if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
250+
gh release upload "$GITHUB_REF_NAME" \
251+
AltForge.ipa \
252+
AltForge-AltServer-macOS.dmg \
253+
AltForge-AltServer-Windows.zip \
254+
apps.json \
255+
flags.json \
256+
sources.json \
257+
recommended-sources.json \
258+
developerdisks.json \
259+
SHA256SUMS.txt \
260+
--repo "$GITHUB_REPOSITORY" \
261+
--clobber
262+
else
263+
gh release create "$GITHUB_REF_NAME" \
264+
AltForge.ipa \
265+
AltForge-AltServer-macOS.dmg \
266+
AltForge-AltServer-Windows.zip \
267+
apps.json \
268+
flags.json \
269+
sources.json \
270+
recommended-sources.json \
271+
developerdisks.json \
272+
SHA256SUMS.txt \
273+
--repo "$GITHUB_REPOSITORY" \
274+
--verify-tag \
275+
--generate-notes \
276+
--draft \
277+
--title "AltForge $GITHUB_REF_NAME"
278+
fi
279+
280+
mkdir -p "$RUNNER_TEMP/Published"
281+
gh release download "$GITHUB_REF_NAME" \
259282
--repo "$GITHUB_REPOSITORY" \
260-
--verify-tag \
261-
--generate-notes \
262-
--draft \
263-
--title "AltForge $GITHUB_REF_NAME"
283+
--dir "$RUNNER_TEMP/Published"
284+
cd "$RUNNER_TEMP/Published"
285+
sha256sum --check SHA256SUMS.txt

Scripts/test_repository_contract.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ def png_dimensions(root, path)
188188
prepare_job = workflow[/^ prepare:.*?^ apple:/m]
189189
assert(prepare_job&.include?("submodules: recursive"), "release prepare job must check out submodules before repository policy validation")
190190
assert(workflow.include?("--draft"), "release workflow must create a draft release")
191+
assert(workflow.include?('gh release upload "$GITHUB_REF_NAME"'), "an explicitly re-pushed release tag must replace assets through the release workflow")
192+
assert(workflow.include?("--clobber"), "same-tag recovery must replace every reviewed release asset")
193+
assert(!workflow.include?("gh release delete"), "same-tag recovery must not delete the public release")
191194
assert(workflow.include?("vcpkg_baseline: ${{ steps.version.outputs.vcpkg_baseline }}"), "prepare must expose the manifest vcpkg baseline")
192195
assert(workflow.include?("ref: ${{ needs.prepare.outputs.vcpkg_baseline }}"), "Windows must check out the manifest vcpkg baseline")
193196

@@ -229,6 +232,7 @@ def png_dimensions(root, path)
229232
assert(workflow.match?(/package_macos_dmg\.sh.*?--ad-hoc-sign/m), "release workflow must seal the full app bundle for ServiceManagement login items")
230233
assert(workflow.include?("Scripts/verify_apple_release_artifacts.sh"), "release workflow must verify packaged Apple artifacts")
231234
assert(workflow.include?("sha256sum --check SHA256SUMS.txt"), "release workflow must verify generated checksums before creating the Draft")
235+
assert(workflow.scan("sha256sum --check SHA256SUMS.txt").length == 2, "release workflow must verify both local and downloaded release assets")
232236
assert(workflow.match?(/gh release create "\$GITHUB_REF_NAME".*?--repo "\$GITHUB_REPOSITORY"/m), "Draft creation must identify the repository after entering the artifact directory")
233237
assert(workflow.include?("testALTApplicationIgnoresMalformedOptionalMetadata"), "release CI must run the malformed IPA metadata regression")
234238
assert(workflow.include?("testThemePreferenceDefaultsAndRoundTrips"), "release CI must run the theme preference regression")

docs/changes/active/CHG-20260811-004-ios-install-crash-diagnostics-authentication/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- “我的 App”出现时不再在 `reloadData()` 后 reconfigure 动态 index path;更新状态先计算再 reload,后续只直接更新已经可见的 no-updates cell,不改变 collection structure。
2020
- 验证阶段缺失 prepared app 时返回 `invalidApp`,不再泄漏无上下文的 `invalidParameters (1008)`
2121
- 发布 IPA 不再携带维护者机器的静态设备或 Server 标识;AltForge Server 在针对目标设备签名时注入运行所需值,发布校验会拒绝包含这两项的产物。
22+
- 同版本真机阻断修复通过 tag CI 重建全部平台资产;现有公开 Release 原位覆盖 IPA、桌面端、metadata 和 checksum 后重新下载校验,不删除 Release,也不允许只替换 IPA。
2223
- 安装/刷新操作开始时只持久化有界、脱敏的操作摘要,正常完成后删除;下次启动发现未完成摘要时补写一条可见错误日志。
2324
- pending operation 使用 Application Support 下的原子 JSON journal,UserDefaults 仅作为存储不可用时的兼容 fallback;前台 session 额外保留一条 current/interrupted checkpoint,只有没有更具体的 pending operation 时才生成一条意外退出日志。
2425
- 为每次操作记录随机客户端诊断编号和最多 16 个关键阶段;失败日志持久化最后阶段与相对耗时轨迹,并可从错误菜单一次复制诊断报告。

docs/rules/release-rules.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- 核对 Classic/Marketplace 形态、bundle/version、最低系统、entitlement、submodule gitlink 和 dependency lockfile。
1111
- 运行 release 所需 build/test、artifact smoke test 和 checksum 验证;签名、notarization、真实设备安装等未执行项必须明确披露。
1212
- 标签 workflow 只能创建 Draft Release。维护者必须下载 Draft 资产、执行 checksum 复核并审阅安装说明与已知风险,之后才可人工公开发布。
13+
- 已公开 tag 只有在维护者明确授权同版本紧急替换时才可 force 更新;workflow 必须重新构建全部平台产物、更新 metadata/checksum、原位覆盖同名资产并重新下载校验,禁止先删除公开 Release 或只手工替换 IPA。
1314
- Apple job 必须在上传前验证 IPA Payload、DMG image/Applications link、bundle identity、版本/build number、arm64+x86_64 架构和当前签名策略;publish job 必须在创建 Draft 前重新执行 `SHA256SUMS.txt` 校验。
1415
- Release notes 只描述实际交付行为,区分新功能、修复、兼容限制、升级/回滚步骤和已知风险。
1516

@@ -25,6 +26,6 @@
2526
## 权限与回滚
2627

2728
- 创建/推送 tag、触发发布、上传或删除 artifact、修改 source feed 均需要用户明确授权。
28-
- 发布失败时停止后续步骤,保留可诊断日志并清理临时凭据/产物;禁止对同一 tag 静默换包。
29+
- 发布失败时停止后续步骤,保留可诊断日志并清理临时凭据/产物;禁止对同一 tag 静默换包。同版本紧急替换必须保留旧 commit、run 和 checksum 审计记录。
2930
- 已发布版本需要撤回时,记录原因、影响、替代版本和用户操作;Git 历史与 release 页面处理必须可审计。
3031
- 发布后新增 `docs/releases/vx.y.z.md`,同步 change/issue 状态并验证下载链接与 checksum。

docs/workflow/02-design/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ Classic 版本必须使用未定义 `MARKETPLACE` 且包含 Apple 认证所需 c
103103

104104
标签 preflight 先校验版本、release metadata contract 与 repository policy contract,再并行运行 Apple 测试/构建和 Win32 Windows AltServer 构建,最后汇总 source/checksum 并创建 Draft GitHub Release。Apple runner 使用与 `Podfile.lock` 一致的 CocoaPods 1.16.2;Windows runner 在 workspace 检出 `vcpkg.json` 指定的固定 vcpkg commit,避免依赖 hosted runner 的可变系统 checkout。任一平台失败时 publish job 不运行。产物先写入 runner 临时目录,不回写仓库。
105105

106+
维护者明确授权 force 更新已公开 tag 的紧急恢复是唯一例外:三个平台仍必须从新 tag commit 完整重建,publish job 不删除 Release,而是以 `--clobber` 原位替换九项受审资产。上传完成后重新下载 Release 并按新的 `SHA256SUMS.txt` 校验;不得仅替换 IPA,因为 source metadata 中的 build、size 和 SHA-256 必须同步变化。
107+
106108
### `DES-011` Windows AltServer
107109

108110
`AltServer-Windows/` 是官方 Windows 1.7.4 源码的单仓库快照,保留 C++ AltSign、libimobiledevice 和设备服务分层。产品 source 固定指向本仓库 `apps.json`,安装 bundle identifier 为 `com.legeling.AltForge`;内部历史类型和协议 error domain 不批量改名,以降低协议回归风险。

0 commit comments

Comments
 (0)