-
Notifications
You must be signed in to change notification settings - Fork 1
198 lines (177 loc) · 7.78 KB
/
Copy pathccm-release.yml
File metadata and controls
198 lines (177 loc) · 7.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# ccm-release —— 多平台 Node SEA 单文件二进制构建 + 随 GitHub release 附产物。
#
# 版本线解耦(ADR-022):ccm 与 cc-master plugin 是**两条独立版本线**,各自独立的 tag
# 触发各自独立的 release workflow——
# - 本文件(ccm-release.yml)只认 `ccm-v*` tag,只产 ccm 二进制(build-sea)。
# - plugin 的「解压即装」制品 `cc-master-plugin-<tag>.zip` 已搬去 `plugin-release.yml`,
# 只认裸 `v*` tag。两个 glob 天然互斥(`ccm-v…` 以 `c` 开头,不撞 `v*`),零交叉触发。
#
# 分发模型(ADR-014):ccm 走 per-OS Node SEA 二进制,随 ccm 自己的 GitHub release
# 附带 `ccm-<os>-<arch>` + SHA256SUMS(不走 npm optionalDeps 平台子包——已决策砍掉)。
#
# ⚠️ Node 版本(关键,CI 必读):build-sea.sh 的 postject sentinel 注入只在 Node 22 上可靠工作;
# 本地用 Node 25/26 实测 postject 报「Could not find the sentinel NODE_SEA_FUSE」而失败。
# 故 matrix 全部 pin Node 22。setup-node 装的是 nodejs.org 官方静态 node——这同时满足
# build-sea.sh 头注的自包含前提(homebrew node 动态链接、不自包含;官方 node 才自包含)。
#
# ⚠️ Linux arm64 —— 已加(ubuntu-24.04-arm runner):GitHub 托管 arm64 Linux runner 于
# 2025-08-07 对公开仓库 GA(免费,4 vCPU Cobalt 100),label `ubuntu-24.04-arm`。
# setup-node 在 arm64 runner 上自动取 arm64 官方 node → SEA 即原生 arm64,无需交叉编译。
#
# ⚠️ Windows SEA —— 诚实 deferred(no-silent-cap):build-sea.sh 是 bash + macOS codesign 链,
# Windows SEA 需另一套签名链(signtool / Authenticode,见 build-sea.sh 头注的平台坑)。
# 本 workflow 当前覆盖 macOS(arm64 + x64)+ Linux(x64 + arm64);Windows 待独立签名链落地后再加,
# 不在此编一个跑不通的 Windows 步骤。
name: ccm-release
on:
push:
tags:
- 'ccm-v*'
workflow_dispatch:
permissions:
contents: write # 需写权限把产物 attach 到 GitHub release
jobs:
build-sea:
strategy:
fail-fast: false
# 覆盖 macOS arm64 / macOS x64 / Linux x64 / Linux arm64;Windows deferred(见文件顶部注释)。
matrix:
include:
- os: macos-14 # Apple Silicon
asset: ccm-darwin-arm64
- os: macos-15-intel # Intel (macOS 13 hosted image retired)
asset: ccm-darwin-x64
- os: ubuntu-latest # Linux x64
asset: ccm-linux-x64
- os: ubuntu-24.04-arm # Linux arm64(GA 2025-08-07·公开仓库免费)
asset: ccm-linux-arm64
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4
# pnpm 版本对齐 ccm/package.json 的 packageManager(pnpm@10.22.0)。
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.22.0
# 官方 node 22:满足 SEA sentinel 可靠注入 + 自包含前提(见文件顶部注释)。
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
cache-dependency-path: ccm/pnpm-lock.yaml
- name: Install deps
working-directory: ccm
run: pnpm install --frozen-lockfile
# 先产常规 dist——**必须 turbo 全量 `pnpm -C ccm build`**(非 `-C ccm/apps/cli build`):
# apps/cli 的 build 仅跑 tsdown 自己、不建上游 @ccm/engine;CI fresh checkout 下 engine dist 不存在,
# SEA bundler 解析不到 @ccm/engine → 当外部依赖不 inline → 运行时 ERR_UNKNOWN_BUILTIN_MODULE 全挂。
# turbo build dependsOn ^build 会先建 engine 再建 cli,dist 齐全后 SEA 才能 inline 引擎(v0.10.0 首发踩此坑)。
- name: Build workspace (engine + CLI)
run: pnpm -C ccm build
# build-sea.sh 自己 cd 到 apps/cli,CCM_SEA_OUT 相对该目录解析,
# 故产物落 ccm/apps/cli/dist/${{ matrix.asset }}。
- name: Build SEA binary
run: CCM_SEA_OUT=dist/${{ matrix.asset }} bash ccm/apps/cli/scripts/build-sea.sh
# 冒烟:确认产物可执行且 --version 工作。
- name: Smoke test
run: |
BIN="ccm/apps/cli/dist/${{ matrix.asset }}"
chmod +x "$BIN"
"$BIN" --version
- name: Generate checksum
run: |
cd ccm/apps/cli/dist
if command -v sha256sum >/dev/null 2>&1; then
sha256sum "${{ matrix.asset }}" > "${{ matrix.asset }}.sha256"
sha256sum --check "${{ matrix.asset }}.sha256"
else
shasum -a 256 "${{ matrix.asset }}" > "${{ matrix.asset }}.sha256"
shasum -a 256 -c "${{ matrix.asset }}.sha256"
fi
# 上传 artifact(workflow_dispatch / 非 tag 触发时也留存可下载)。
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset }}
path: ccm/apps/cli/dist/${{ matrix.asset }}
if-no-files-found: error
retention-days: 14
- name: Upload checksum part
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset }}-sha256
path: ccm/apps/cli/dist/${{ matrix.asset }}.sha256
if-no-files-found: error
retention-days: 14
- name: Plan GitHub release metadata
id: release_meta
if: startsWith(github.ref, 'refs/tags/')
run: >-
node scripts/release-metadata.mjs plan
--tag "${GITHUB_REF_NAME}"
--repository "${GITHUB_REPOSITORY}"
--github-output "${GITHUB_OUTPUT}"
# 仅 tag 触发时 attach 到 GitHub release。
- name: Attach to GitHub release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
name: ${{ steps.release_meta.outputs.title }}
prerelease: ${{ steps.release_meta.outputs.prerelease }}
body: ${{ steps.release_meta.outputs.body }}
files: ccm/apps/cli/dist/${{ matrix.asset }}
publish-checksums:
needs: build-sea
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download checksum parts
uses: actions/download-artifact@v4
with:
pattern: ccm-*-sha256
path: checksum-parts
merge-multiple: true
- name: Merge checksum manifest
run: |
mkdir -p dist
cat checksum-parts/*.sha256 | sort -k2 > dist/SHA256SUMS
- name: Upload checksum artifact
uses: actions/upload-artifact@v4
with:
name: ccm-SHA256SUMS
path: dist/SHA256SUMS
if-no-files-found: error
retention-days: 14
- name: Upload license documents artifact
uses: actions/upload-artifact@v4
with:
name: ccm-license-documents
path: |
LICENSE
LICENSING.md
TRADEMARKS.md
if-no-files-found: error
retention-days: 14
- name: Plan GitHub release metadata
id: release_meta
if: startsWith(github.ref, 'refs/tags/')
run: >-
node scripts/release-metadata.mjs plan
--tag "${GITHUB_REF_NAME}"
--repository "${GITHUB_REPOSITORY}"
--github-output "${GITHUB_OUTPUT}"
- name: Attach checksums and license documents to GitHub release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
name: ${{ steps.release_meta.outputs.title }}
prerelease: ${{ steps.release_meta.outputs.prerelease }}
body: ${{ steps.release_meta.outputs.body }}
files: |
dist/SHA256SUMS
LICENSE
LICENSING.md
TRADEMARKS.md