
【免费下载链接】App-Store-Connect-CLIFast, scriptable CLI for the App Store Connect API. Automate TestFlight, builds, submissions, signing, analytics, screenshots, subscriptions, and more项目地址https://gitcode.com/gh_mirrors/ap/App-Store-Connect-CLI点击查看免费下载本设计文档docs/design/ci-runner-and-artifact-optimization.md记录了 App-Store-Connect-CLI 项目对 GitHub Actions 流水线的系统化优化方案将平台无关的格式化、文档、Lint 与单元测试从 macOS 迁往 Ubuntu把多平台二进制构建拆分为原生托管 Runner 上的独立 Job并移除 Pull Request 与 main 分支上无人消费的开发制品上传。读完本文你将理解该方案的动机、工作流层级结构、被否决的替代方案以及如何通过仓库内的契约测试验证 CI 改动没有削弱任何质量门槛。设计背景当前行为的成本分析文档首先剖析了优化前的流水线形态其核心痛点有三平台无关工作在 macOS 上运行每个非 Wall 类 Pull Request 都会在 macOS Runner 上执行与操作系统无关的格式化format、文档检查docs、Lint 与单元测试。macOS 托管 Runner 的计费与配额成本高于 Linux把这些纯 CPU/内存密集、与平台无关的检查放在 macOS 上是明显浪费。单 Job 并发交叉编译五份二进制一个 macOS 构建 Job 需要同时交叉编译五份二进制macOS amd64/arm64、Linux amd64/arm64、Windows amd64它们共享同一 Runner 的 CPU 与内存互相争抢资源整体耗时被拉长。约 105 MB 的开发制品被上传却无人下载构建产物以actions/upload-artifact上传但没有任何工作流download-artifact消费它们main 分支工作流还会重复一次同样的构建与上传。真正的发布二进制由release.yml独立构建因此这些开发制品既不进入发布链路也无人读取纯粹是存储与上传时长的开销。优化方案按平台职责拆分 Runner文档提出的目标行为可以归纳为五项当前仓库的 pr-checks.yml 与 main-branch.yml 已经完整落实了这套设计维度优化前优化后格式化 / 文档 / Lint / Wall 校验 / 单元测试分片macOSUbuntuubuntu-latestmacOS / Linux / Windows 二进制构建单个 macOS Job 交叉编译各自的macos-latest、ubuntu-latest、windows-latest原生 RunnerDarwin 专属截图测试与交叉编译混跑在 macOS 构建 Runner 上执行必需检查兼容性分散的 Job 名保留稳定的聚合buildJobPR 与 main 分支的跨平台编译保留保留作为 PR 兼容性门禁PR / main 分支的制品上传与开发校验和存在约 105 MB移除官方制品发布完全由release.yml独占聚合 Job为 required-check 兼容性兜底方案特别强调“保留一个稳定的聚合buildJob”。原因在于 GitHub 仓库的required status checks必需状态检查通常按 Job 名称绑定如果直接删掉名为build的 Job仓库保护规则就会失配并阻塞合并。因此优化后的工作流保留build聚合 Job用needs声明依赖并用if: always()保证它在任何条件下都解析出确定结果build: needs: [changes, build-platforms, ordinary-build] if: always() runs-on: ubuntu-latest steps: - name: Verify selected builds run: | ... case ${{ needs.changes.outputs.scope }} in full) result${{ needs.build-platforms.result }} ;; telemetry) result${{ needs.ordinary-build.result }} ;; *) echo No CLI build required for ${{ needs.changes.outputs.scope }} changes exit 0 ;; esac if [ $result ! success ]; then echo selected build result: $result exit 1 fi同样的聚合模式也出现在质量门禁与测试门禁上PR 工作流的format-and-lint、unit-tests、build三个聚合 Job 全部使用if: always()确保即使某个矩阵分支失败聚合 Job 仍会运行并给出明确失败结果由 scripts/test_ci_workflows.py 的main()强制断言。源码佐证工作流的实现细节平台无关检查整体迁移至 Ubuntu在 pr-checks.yml 中quality-checksJob 运行于ubuntu-latest通过make目标并行执行make format-checkgofumpt 格式化校验make check-wall-of-appsWall 数据源校验python3 scripts/test_check_docs.py与make check-docs文档校验器自测与文档检查make lintgolangci-lintMakefile 中GOLANGCI_LINT_TIMEOUT ? 15m为冷 Runner 上的全模块 Lint 预留预算python3 scripts/test_ci_workflows.py与python3 scripts/test_ci_change_scope.pyCI 自身契约自测由于“所有测试 Job 都跑在 ubuntu 上darwin/windows 门控的源码与测试永远不会被类型检查”工作流在质量检查里显式补充了跨平台静态检查GOOSdarwin go vet ./... GOOSwindows go vet ./...golangci-lint 已覆盖GOOSlinux含测试这两条go vet补齐了另外两个平台保证平台门控代码始终被类型检查。这组命令同时被契约测试列为不可删除的必需项见下文。单元测试分片Ubuntu 上的并行 shardunit-test-shardsmain 分支为test-shards在ubuntu-latest上运行使用 scripts/go_test_shard.py 把全模块测试拆成五个并行分片packagesgo test -short ./cmd 全包测试排除./cmd、./internal/cli/cmdtest、./internal/cli/webweb 1/2与web 2/2./internal/cli/web测试按文件均分cmdtest 1/2与cmdtest 2/2./internal/cli/cmdtest测试按文件均分所有测试命令都以ASC_BYPASS_KEYCHAIN1前缀运行。这个环境变量是设计的一部分它绕过 macOS 钥匙串依赖让测试在无头 Runner 上不弹出交互提示、不泄漏宿主机 profile 状态。由于unit-tests与format-and-lint聚合 Job 使用if: always()校验needs.unit-test-shards.result与needs.telemetry-windows-tests.result任一 shard 失败都会让 PR 无法通过必需检查。原生 Runner 矩阵构建build-platformsJob 通过矩阵把三个平台分配到各自的原生 Runnerpr-checks.yml 第 272-323 行build-platforms: needs: changes if: needs.changes.outputs.scope full name: build (${{ matrix.name }}) runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: include: - name: macOS runner: macos-latest command: | ASC_BYPASS_KEYCHAIN1 go test -short ./internal/screenshots ASC_BYPASS_KEYCHAIN1 go test -short -count1 ./internal/rootfs ASC_BYPASS_KEYCHAIN1 go test -short -count1 ./internal/secureopen -run NoInherit ASC_BYPASS_KEYCHAIN1 go test -short -count1 ./internal/cli/certificates -run ACL|OwnerOnlyAtCreation CGO_ENABLED1 GOOSdarwin GOARCHamd64 go build -o build/asc_dev_macos_amd64 . CGO_ENABLED1 GOOSdarwin GOARCHarm64 go build -o build/asc_dev_macos_arm64 . - name: Linux runner: ubuntu-latest command: | CGO_ENABLED0 GOOSlinux GOARCHamd64 go build -o build/asc_dev_linux_amd64 . CGO_ENABLED0 GOOSlinux GOARCHarm64 go build -o build/asc_dev_linux_arm64 . - name: Windows runner: windows-latest command: | ASC_BYPASS_KEYCHAIN1 go test -count1 ./internal/screenshots ... CGO_ENABLED0 GOOSwindows GOARCHamd64 go build -o build/asc_dev_windows_amd64.exe .要点拆解macOS RunnerCGO_ENABLED1构建 Darwin amd64/arm64macOS 二进制需要 cgo 链接系统库并顺带执行 Darwin 专属测试./internal/screenshots截图能力测试、./internal/rootfs根文件系统权限、./internal/secureopen的NoInherit、./internal/cli/certificates的 ACL 用例。这正对应设计文档“Run the Darwin-only screenshot tests on the macOS build runner”的要求——平台专属测试与被测平台放在同一 Runner避免交叉测试失真。Linux RunnerCGO_ENABLED0构建静态链接的 linux amd64/arm64。Windows RunnerCGO_ENABLED0构建 windows amd64并执行 Windows 专属安全测试secureopen、rootfs、shared的符号链接/替换写入防护、xcode的 Windows 边界提示测试等其中./internal/cli/xcode -run TestXcodeHelpScopesMacOSRequirementToXcodeTooling|TestXcodeSigningApplyHelpExplainsWindowsBoundary专门验证 CLI 在 Windows 上正确声明 macOS 能力边界。矩阵还设置了fail-fast: false一个平台的失败不会取消其他平台的构建便于一次 PR 看到全部平台的独立结果。变更范围感知只跑必要的检查PR 与 main 分支工作流都从changesJob 开始用 scripts/ci_change_scope.py 把变更文件分类为wall/docs/website/telemetry/full五档再按档位裁剪后续 Job。其分类规则值得注意触碰docs/wall-of-apps.json→wall只跑 Wall 校验触碰docs/openapi/latest.json或任何.go文件 →full全量质量 测试 构建触碰internal/telemetry/→telemetry轻量测试与ordinary-build触碰网站文件 →website复用 website-checks.yml其中.github/workflows/*、scripts/ci_change_scope.py、scripts/test_ci_change_scope.py、scripts/test_ci_workflows.py四类路径会强制force_fulltrue——即CI 配置本身的任何改动都会触发全量验证防止工作流被静默削弱。这正是设计文档“Preserve a stable aggregate build job for required-check compatibility”背后更深一层的保护逻辑CI 自身也处于自检之下。制品上传的收口release.yml 独占官方发布设计文档要求“Remove pull-request and main-branch artifact uploads and development checksums. Official artifact publication remains owned by release.yml”而 release.yml 是仓库中唯一保留actions/upload-artifact的工作流构建阶段产出candidate-release-version.tar与对应的.commit来源证明文件作为不可变构建制品上传retention-days: 14并在重跑/修复时通过gh api检索并复用已存在的同名制品保证同一 tag 的发布资产字节级一致发布阶段下载候选制品、解包并用 scripts/verify_release_assets.py 校验资产集合再打包为published-release-version.tar供 Homebrew tap 更新与 WinGet 清单生成使用校验和asc_version_checksums.txt只在发布目录release/中生成作为 GitHub Release 的正式资产。相比之下PR 与 main 分支工作流中完全没有upload-artifact/download-artifact引用开发构建只产出build/asc_dev_*文件供当次 Job 使用即结束不再产生任何跨 Job 的制品流量。方案权衡被否决的替代方案设计文档明确记录了三类被否决的路线及其理由理解这些权衡有助于后续维护者避免重复踩坑使用更大的 Runner升级 Runner 规格需要为这个公开仓库支付额外费用ubuntu-latest、macos-latest、windows-latest免费额度内的原生 Runner 组合已经能满足并行需求。在单个 macOS Runner 上并行构建步骤GitHub Actions 的parallel:语法虽然能在同一 Job 内并发但所有步骤共享 Runner 的 CPU 与内存并发交叉编译依旧存在资源争抢只是把“串行争抢”变成“并发争抢”。完全移除跨平台编译构建速度会最快但 PR 兼容性门禁会被明显削弱——跨平台编译能在合并前就暴露GOOS/GOARCH相关的编译错误是公共仓库对第三方贡献最廉价的质量保障。方案选择“保留跨平台编译、改用原生 Runner 并行”本质是在速度与门禁强度之间取了平衡点平台无关检查搬到 Ubuntu 换来配额与速度平台相关构建保持完整以守住兼容性底线。验证方法契约测试 本地复现 时长对比设计文档给出了四条验证路径其中“运行工作流契约测试”已有现成工具工作流契约测试scripts/test_ci_workflows.py 是这套设计的“守护者”。它逐一断言PR 与 main 工作流中不得出现actions/upload-artifact第 225 行quality-checks必须包含make format-check、make check-docs、make check-wall-of-apps、make lint、GOOSdarwin go vet ./...、GOOSwindows go vet ./...等命令测试 Job 必须运行python3 scripts/go_test_shard.py、覆盖--packages ./...、携带ASC_BYPASS_KEYCHAIN1build-platforms必须同时含macos-latest、ubuntu-latest、windows-latest三个原生 Runner必须含CGO_ENABLED1的 Darwin amd64/arm64 构建与CGO_ENABLED0的 Linux/Windows 构建且 macOS 与 Windows 都必须跑./internal/rootfs聚合 Jobformat-and-lint、unit-tests/test、build必须使用if: always()并校验上游结果release.yml必须保留actions/upload-artifact官方发布职责。其中assert_optimized_workflow_rejects_weakened_checks()还会做“削弱反证”把每条必需命令替换成true后重新断言证明守卫确实会在检查被删除时失败——也就是说这套测试不是装饰而是可失效的强契约。本地验证改动落地前在本地完整执行make format-check、make check-docs、make lint与make test后者以ASC_BYPASS_KEYCHAIN1 go test -v ./...运行见 Makefile。PR 实测让 PR 本身驱动 Linux、macOS、Windows 三个原生 Runner 各跑一轮观察平台专属测试是否都在对应平台通过。时长对比与近期成功的 PR 运行对比总时长与单 Job 时长验证 macOS 上不再承载平台无关工作、构建并行化后的实际收益。影响边界只动 CI不动 CLI设计文档在结尾特别强调“This changes CI execution only. CLI commands, flags, output, exit codes, authentication, and API behavior remain unchanged.” 这是一条重要的发布承诺——优化全部发生在.github/workflows/与scripts/层面cmd/、internal/asc/等 CLI 实现、命令输出、退出码、认证与 App Store Connect API 行为均不受影响。这也解释了为什么契约测试被设计为独立于 Go 测试套件运行CI 变更的安全边界是“工作流文件本身”而不是业务代码。从仓库现状看这套设计已经完整落地并被 scripts/test_ci_workflows.py 持续守护。对于后续维护者任何对 PR/main 工作流的改动都会触发force_fulltrue全量验证任何试图恢复 macOS 承载平台无关检查、删除原生 Runner、或向 PR 流水线重新引入制品上传的改动都会被契约测试拦截——这正是该设计文档最大的长期价值它把一个 CI 成本问题转化成了可自动验证的工程约束。赞分享【免费下载链接】App-Store-Connect-CLIFast, scriptable CLI for the App Store Connect API. Automate TestFlight, builds, submissions, signing, analytics, screenshots, subscriptions, and more项目地址https://gitcode.com/gh_mirrors/ap/App-Store-Connect-CLI点击查看免费下载相关推荐LikeC4 完整使用指南CLI 工作流、Vite 插件与编程 API 实战LikeC4 完整使用指南CLI 工作流、Vite 插件与编程 API 实战 导读 likec4 是 LikeC4 项目对外发布的统一工具包它把语言服务LApp-Store-Connect-CLI 本地构建发布 macOS PKG设计契约与源码实现解析App Store Connect CLI 本地构建发布 macOS PKG设计契约与源码实现解析 本篇文章围绕 docs/design/publish loApp-Store-Connect-CLI 的 StoreKit Retention Messaging 支持架构设计与命令行实战指南App Store Connect CLI 的 StoreKit Retention Messaging 支持架构设计与命令行实战指南 导读 本篇技术指南聚焦上一篇Sentinel实战指南双11大促场景下的7个流量控制技巧下一篇Talos Linux 中基于 efivarfs 的 UEFI 运行时变量读写与启动项管理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考