11name : Build & Release
22
33on :
4- push :
5- tags :
6- - ' v*'
4+ # 在 GitHub 上发布 Release 时自动触发构建
5+ release :
6+ types : [published]
7+
8+ # 手动触发 (用于调试或重新构建)
79 workflow_dispatch :
810 inputs :
9- create_release :
10- description : ' Create GitHub Release'
11- required : false
12- default : false
13- type : boolean
11+ version :
12+ description : ' 版本号 (如 1.2.3,不带 v 前缀)'
13+ required : true
14+ type : string
1415
1516# 同一时间只允许一个构建流水线运行
1617concurrency :
@@ -19,25 +20,90 @@ concurrency:
1920
2021permissions :
2122 contents : write
23+ actions : read
2224
2325jobs :
26+ # ── 准备阶段:提取版本号与发布内容 ──
27+ prepare :
28+ runs-on : ubuntu-latest
29+ outputs :
30+ version : ${{ steps.meta.outputs.version }}
31+ release_body : ${{ steps.meta.outputs.release_body }}
32+ tag_name : ${{ steps.meta.outputs.tag_name }}
33+ is_prerelease : ${{ steps.meta.outputs.is_prerelease }}
34+ release_id : ${{ steps.meta.outputs.release_id }}
35+ steps :
36+ - name : Checkout (gh cli needs repo context)
37+ uses : actions/checkout@v4
38+
39+ - name : Extract release metadata
40+ id : meta
41+ env :
42+ EVENT_NAME : ${{ github.event_name }}
43+ RELEASE_TAG : ${{ github.event.release.tag_name }}
44+ RELEASE_BODY : ${{ github.event.release.body }}
45+ RELEASE_PRERELEASE : ${{ github.event.release.prerelease }}
46+ RELEASE_ID : ${{ github.event.release.id }}
47+ INPUT_VERSION : ${{ github.event.inputs.version }}
48+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
49+ run : |
50+ if [ "$EVENT_NAME" = "release" ]; then
51+ # 从 Release 事件中获取版本号 (去掉 v 前缀)
52+ VERSION="${RELEASE_TAG#v}"
53+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
54+ echo "tag_name=${RELEASE_TAG}" >> "$GITHUB_OUTPUT"
55+ echo "is_prerelease=${RELEASE_PRERELEASE}" >> "$GITHUB_OUTPUT"
56+ echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"
57+
58+ # 获取 Release body 内容 (base64 编码避免多行问题)
59+ BODY=$(printf '%s' "$RELEASE_BODY" | base64 -w 0)
60+ echo "release_body=${BODY}" >> "$GITHUB_OUTPUT"
61+ else
62+ # workflow_dispatch 手动触发:通过 tag 查找已有 Release,找不到则创建
63+ TAG="v${INPUT_VERSION}"
64+ echo "version=${INPUT_VERSION}" >> "$GITHUB_OUTPUT"
65+ echo "tag_name=${TAG}" >> "$GITHUB_OUTPUT"
66+ echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
67+ echo "release_body=$(printf '%s' '手动触发构建' | base64 -w 0)" >> "$GITHUB_OUTPUT"
68+
69+ # 尝试获取已有 Release 的 ID
70+ EXISTING_ID=$(gh release view "$TAG" --json id --jq '.id' 2>/dev/null || true)
71+ if [ -n "$EXISTING_ID" ]; then
72+ echo "release_id=${EXISTING_ID}" >> "$GITHUB_OUTPUT"
73+ echo "✅ Found existing Release: ${TAG} (ID: ${EXISTING_ID})"
74+ else
75+ # 创建 draft Release
76+ NEW_ID=$(gh release create "$TAG" --title "Release ${TAG}" --notes "手动触发构建" --draft --json id --jq '.id')
77+ echo "release_id=${NEW_ID}" >> "$GITHUB_OUTPUT"
78+ echo "✅ Created draft Release: ${TAG} (ID: ${NEW_ID})"
79+ fi
80+ fi
81+
82+ - name : Print build info
83+ run : |
84+ echo "📦 Version: ${{ steps.meta.outputs.version }}"
85+ echo "🏷️ Tag: ${{ steps.meta.outputs.tag_name }}"
86+ echo "🚀 Pre-release: ${{ steps.meta.outputs.is_prerelease }}"
87+
88+ # ── 多平台构建 ──
2489 build :
90+ needs : prepare
2591 strategy :
2692 fail-fast : false
2793 matrix :
2894 include :
2995 - os : windows-latest
3096 platform : win
31- build_script : build:win
3297 - os : macos-latest
3398 platform : mac
34- build_script : build:mac
3599
36100 runs-on : ${{ matrix.os }}
37101
38102 steps :
39103 - name : Checkout
40104 uses : actions/checkout@v4
105+ with :
106+ ref : ${{ needs.prepare.outputs.tag_name }}
41107
42108 - name : Setup Node.js
43109 uses : actions/setup-node@v4
@@ -53,8 +119,15 @@ jobs:
53119 - name : Install dependencies
54120 run : npm ci
55121
56- - name : Build (${{ matrix.platform }})
57- run : npm run ${{ matrix.build_script }}
122+ # 将 Release 版本号同步写入 package.json
123+ - name : Sync version to package.json
124+ run : npm version ${{ needs.prepare.outputs.version }} --no-git-tag-version --allow-same-version
125+
126+ - name : Build (electron-vite)
127+ run : npx electron-vite build
128+
129+ - name : Package (${{ matrix.platform }})
130+ run : npx electron-builder --${{ matrix.platform }}
58131 env :
59132 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
60133 # macOS 代码签名 (可选,配置 secrets 后自动生效)
73146 name : open-cowork-windows
74147 path : |
75148 dist/*.exe
76- dist/*.zip
149+ dist/*.exe.blockmap
77150 if-no-files-found : error
78151 retention-days : 30
79152
@@ -84,17 +157,20 @@ jobs:
84157 name : open-cowork-macos
85158 path : |
86159 dist/*.dmg
160+ dist/*.dmg.blockmap
87161 dist/*.zip
88162 if-no-files-found : error
89163 retention-days : 30
90164
91- # ── 发布 Release ──
92- release :
93- needs : build
94- if : startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && github.event.inputs.create_release == 'true')
165+ # ── 上传产物到 Release ──
166+ upload :
167+ needs : [prepare, build]
95168 runs-on : ubuntu-latest
96169
97170 steps :
171+ - name : Checkout (gh cli needs repo context)
172+ uses : actions/checkout@v4
173+
98174 - name : Download all artifacts
99175 uses : actions/download-artifact@v4
100176 with :
@@ -104,14 +180,16 @@ jobs:
104180 - name : List artifacts
105181 run : ls -lhR artifacts/
106182
107- - name : Create GitHub Release
108- uses : softprops/action-gh-release@v2
109- with :
110- tag_name : ${{ github.ref_name }}
111- name : Release ${{ github.ref_name }}
112- draft : true
113- prerelease : false
114- generate_release_notes : true
115- files : artifacts/*
183+ # 使用 gh cli 精确上传到触发的 Release
184+ - name : Upload assets to Release
116185 env :
117- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
186+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
187+ TAG_NAME : ${{ needs.prepare.outputs.tag_name }}
188+ run : |
189+ echo "📦 Uploading assets to Release: ${TAG_NAME}"
190+ for file in artifacts/*; do
191+ [ -f "$file" ] || continue
192+ echo " ⬆️ $(basename "$file")"
193+ gh release upload "${TAG_NAME}" "$file" --clobber
194+ done
195+ echo "✅ All assets uploaded successfully"
0 commit comments