-
Notifications
You must be signed in to change notification settings - Fork 14
355 lines (302 loc) · 12.9 KB
/
Copy pathbuild-release.yml
File metadata and controls
355 lines (302 loc) · 12.9 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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
name: Build and Release
on:
push:
tags:
- 'v*'
pull_request:
types:
- opened
- synchronize
- reopened
- labeled
workflow_dispatch:
inputs:
create_release:
description: 'Create Release'
required: true
default: false
type: boolean
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
CREATE_RELEASE: ${{ (github.event_name == 'workflow_dispatch' && inputs.create_release == true) || startsWith(github.ref, 'refs/tags/') }}
jobs:
build:
if: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'build') }}
runs-on: windows-latest
outputs:
version: ${{ steps.get_version.outputs.version }}
tag: ${{ steps.get_version.outputs.tag }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Get version
id: get_version
shell: pwsh
run: |
if ($env:GITHUB_REF -like 'refs/tags/*') {
# 已由 tag 推送触发,直接使用该 tag 作为版本
$version = $env:GITHUB_REF.Substring(10)
$tag = $version
} elseif ($env:GITHUB_EVENT_NAME -eq 'pull_request') {
# PR 构建只产出测试包,不创建 / 推送 tag
$shortSha = $env:GITHUB_SHA.Substring(0, 7)
$version = "pr-${{ github.event.pull_request.number }}-$shortSha"
$tag = $version
} else {
# 手动 workflow_dispatch 触发:使用 git 的语义化版本排序,选出最新 tag,然后生成 / 递增 beta 版本
# --refs 可避免出现带 ^{} 的 peeled 行,--sort=-version:refname 以版本名倒序排序,'v*' 仅匹配语义化版本前缀
$latestRef = git ls-remote --refs --tags --sort=-version:refname origin 'v*' |
Where-Object { $_ -match 'refs/tags/(v\d+\.\d+\.\d+(?:-beta\.\d+)?)$' } |
Select-Object -First 1
if (-not $latestRef) {
# 仓库还没有任何符合语义版本的 tag,初始化为 v0.1.0-beta.1
$baseVersion = 'v0.1.0'
$betaNumber = 1
$tag = "$baseVersion-beta.$betaNumber"
} else {
# 行格式: <hash>\trefs/tags/<tagname>
if ($latestRef -match 'refs/tags/(.+)$') {
$latestTag = $matches[1]
} else {
throw "无法从 ls-remote 输出中解析最新 tag:$latestRef"
}
if ($latestTag -match '^(v\d+\.\d+\.\d+)-beta\.(\d+)$') {
# 最新即为 beta,直接在 beta 编号上 +1
$baseVersion = $matches[1]
$betaNumber = [int]$matches[2] + 1
$tag = "$baseVersion-beta.$betaNumber"
} else {
# 最新为稳定版本,从该稳定版本开始新的 beta 序列
$latestTag -match '^(v\d+\.\d+\.)(\d+)$'
$baseVersion = $matches[1] + ([int]$matches[2] + 1)
$betaNumber = 1
$tag = "$baseVersion-beta.$betaNumber"
}
}
$version = $tag
git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions"
# 创建并推送新 beta tag
git tag $tag
git push origin $tag
}
echo "version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
echo "tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
echo "__version__ = '$version'" | Out-File -FilePath src/one_dragon/version.py -Encoding utf8
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11.9'
- name: Install uv
shell: pwsh
run: |
Invoke-WebRequest -Uri https://astral.sh/uv/install.ps1 | Invoke-Expression
- name: Create virtual environment and install dependencies
shell: pwsh
run: |
uv sync
- name: Download and extract UPX into venv Scripts
shell: pwsh
run: |
$venvScripts = ".\.venv\Scripts"
$upxDir = Join-Path $venvScripts "upx"
$sourceUpxPath = Join-Path $upxDir "upx-4.2.3-win64" "upx.exe"
$destinationUpxPath = Join-Path $venvScripts "upx.exe"
$zipPath = "upx.zip"
Invoke-WebRequest -Uri "https://github.com/upx/upx/releases/download/v4.2.3/upx-4.2.3-win64.zip" -OutFile $zipPath
Expand-Archive -Path $zipPath -DestinationPath $upxDir -Force
Move-Item -Path $sourceUpxPath -Destination $destinationUpxPath -Force
Remove-Item -Path $upxDir -Recurse -Force
Remove-Item -Path $zipPath -Force
- name: Build executables
shell: pwsh
run: |
.\.venv\Scripts\Activate.ps1
cd deploy
pyinstaller "OneDragon ScriptChainer.spec"
pyinstaller "OneDragon ScriptChainer Runner.spec"
Copy-Item "dist/OneDragon ScriptChainer Runner.exe" -Destination "dist/OneDragon ScriptChainer/" -Force
- name: Upload Editor
if: ${{ env.CREATE_RELEASE == 'false' }}
uses: actions/upload-artifact@v4
with:
name: Editor-r${{ github.run_number }}
include-hidden-files: true
path: deploy/dist/OneDragon ScriptChainer/
- name: Upload Runner
if: ${{ env.CREATE_RELEASE == 'false' }}
uses: actions/upload-artifact@v4
with:
name: Runner-r${{ github.run_number }}
include-hidden-files: true
path: deploy/dist/OneDragon ScriptChainer Runner.exe
- name: Upload Dist
if: ${{ env.CREATE_RELEASE == 'true' }}
uses: actions/upload-artifact@v4
with:
name: dist
include-hidden-files: true
if-no-files-found: error
path: deploy/dist/OneDragon ScriptChainer/
release:
runs-on: windows-latest
needs: build
if: ${{ (github.event_name == 'workflow_dispatch' && inputs.create_release == true) || startsWith(github.ref, 'refs/tags/') }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download dist
uses: actions/download-artifact@v4
with:
name: dist
path: OneDragon ScriptChainer
- name: Prepare release packages
shell: pwsh
env:
RELEASE_VERSION: ${{ needs.build.outputs.version }}
run: |
$version = $env:RELEASE_VERSION
Compress-Archive -Path "OneDragon ScriptChainer" -DestinationPath "OneDragon-ScriptChainer-$version.zip" -Force
- name: Generate Changelog
id: changelog
shell: pwsh
run: |
$current_version_tag = "${{ needs.build.outputs.version }}" # 从 get_version 步骤获取的标签
$commits = @()
if ($env:GITHUB_REF -like 'refs/tags/*') {
# 这是由标签触发的发布
# 尝试查找当前标签提交的父提交上的最新标签
$previous_tag_candidate = $(git describe --tags --abbrev=0 "$current_version_tag^" 2>$null)
if ($previous_tag_candidate) {
Write-Host "正在生成从 $previous_tag_candidate 到 $current_version_tag 的更新日志"
$commits = git log --pretty=format:"%s|%h" "$previous_tag_candidate..$current_version_tag"
} else {
Write-Host "未找到相对于 $current_version_tag^ 的上一个标签。列出 $current_version_tag 的最后10个提交。"
# 这可能是第一个标签。列出导致它的提交。
$commits = git log --pretty=format:"%s|%h" -n 10 "$current_version_tag"
}
} else {
# 这是手动 workflow_dispatch 或分支推送
Write-Host "手动或分支构建。列出 HEAD 的最后5个提交。"
$commits = git log --pretty=format:"%s|%h" -n 5 HEAD
}
# 按前缀分类提交
$categories = @{
"feat" = @()
"fix" = @()
"perf" = @()
"refactor" = @()
"style" = @()
"docs" = @()
"test" = @()
"ci" = @()
"build" = @()
"chore" = @()
"revert" = @()
"other" = @()
}
foreach ($commit in $commits) {
if ($commit -match "^(.+)\|(.+)$") {
$message = $matches[1]
$hash = $matches[2]
# 兼容带 scope 的 Conventional Commits,例如 feat(ui): xxx / feat(ui)!: xxx
if ($message -match "^([A-Za-z]+)(?:\(([^)!]+)\))?(!)?:\s*(.*)$") {
$prefix = $matches[1].Trim().ToLower()
$scope = if ($null -ne $matches[2]) { $matches[2].Trim() } else { "" }
$content = $matches[4].Trim()
if (-not [string]::IsNullOrWhiteSpace($scope)) {
$content = "$($scope): $content"
}
# 检查前缀是否在已知分类中
if ($categories.ContainsKey($prefix)) {
$categories[$prefix] += "- $content ($hash)"
} else {
$categories["other"] += "- $message ($hash)"
}
} else {
$categories["other"] += "- $message ($hash)"
}
}
}
# 生成分类后的更新日志
$changelog_content = ""
$category_names = @{
"feat" = "✨ 新功能"
"fix" = "🐛 Bug 修复"
"perf" = "⚡ 性能优化"
"refactor" = "♻️ 代码重构"
"style" = "💄 样式调整"
"docs" = "📄 文档更新"
"test" = "✅ 测试"
"ci" = "👷 CI/CD"
"build" = "📦 构建"
"chore" = "🔧 杂项"
"revert" = "⏪ 回滚"
"other" = "📝 其他更改"
}
# 定义输出顺序
$ordered_keys = @("feat", "fix", "perf", "refactor", "style", "docs", "test", "ci", "build", "chore", "revert", "other")
foreach ($key in $ordered_keys) {
if ($categories[$key].Count -gt 0) {
if ($changelog_content -ne "") {
$changelog_content += "`n`n"
}
$changelog_content += "## $($category_names[$key])`n"
$changelog_content += ($categories[$key] -join "`n")
}
}
if ([string]::IsNullOrWhiteSpace($changelog_content)) {
$changelog_content = "没有新的更改或无法确定更新日志。"
}
$output_name = "clean_changelog"
$delimiter = "CHANGELOG_DELIMITER_$(New-Guid)"
echo "$output_name<<$delimiter" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
echo $changelog_content | Out-File -FilePath $env:GITHUB_OUTPUT -Append
echo $delimiter | Out-File -FilePath $env:GITHUB_OUTPUT -Append
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.build.outputs.tag }}
name: "Release ${{ needs.build.outputs.version }}"
body: |
## OneDragon ScriptChainer ${{ needs.build.outputs.version }}
### 下载说明
- `OneDragon-ScriptChainer-${{ needs.build.outputs.version }}.zip` - 包含编辑器和运行器的完整包
### 使用方法
1. 下载 `OneDragon-ScriptChainer-${{ needs.build.outputs.version }}.zip`
2. 如果是更新,请先删除旧版的 `.runtime` 文件夹,再解压覆盖
3. 运行 `OneDragon ScriptChainer.exe` 创建和编辑脚本链
4. 运行 `OneDragon ScriptChainer Runner.exe` 执行脚本链
> 注意:`OneDragon ScriptChainer.exe` 所在目录包含运行时依赖(`.runtime` 文件夹),请勿单独移动该文件。
### 命令行参数
`OneDragon ScriptChainer.exe` 支持以下参数:
| 参数 | 说明 |
|------|------|
| `-o, --onedragon` | 一条龙运行模式(跳过 GUI 直接执行脚本链) |
| `--chain <名称>` | 指定脚本链名称,默认 `01`(仅 `--onedragon` 模式) |
| `-s, --shutdown [秒数]` | 运行后关机,可指定延迟秒数,默认 60 秒(仅 `--onedragon` 模式) |
| `-v, --version` | 显示版本号 |
示例: `OneDragon ScriptChainer.exe -o --chain 02 -s 120`
[更多参考](https://one-dragon.com/tools/zh/script_chainer.html)
# 更新内容
${{ steps.changelog.outputs.clean_changelog }}
files: |
OneDragon-ScriptChainer-${{ needs.build.outputs.version }}.zip
generate_release_notes: false
prerelease: ${{ contains(needs.build.outputs.version, '-beta.') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Trigger MirrorChyanUploading
if: ${{ github.repository_owner == 'OneDragon-Anything' }}
shell: bash
run: |
gh workflow run --repo $GITHUB_REPOSITORY mirrorchyan-release.yml -f tag=${{ needs.build.outputs.tag }}
gh workflow run --repo $GITHUB_REPOSITORY mirrorchyan-release_note.yml -f tag=${{ needs.build.outputs.tag }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}