Repository navigation
Expand file tree
/
Copy pathTaskfile.yml
More file actions
253 lines (225 loc) · 9.82 KB
/
Copy pathTaskfile.yml
File metadata and controls
253 lines (225 loc) · 9.82 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
# Copyright (C) 2026 ysicing
# SPDX-License-Identifier: AGPL-3.0-or-later
version: '3'
vars:
PROJECT: XStats.xcodeproj
SCHEME: XStats
CONFIG: '{{default "Release" .CONFIG}}'
DERIVED: build/DerivedData-arm64
APP: '{{.DERIVED}}/Build/Products/{{.CONFIG}}/XStats.app'
NETWORK_DERIVED: build/DerivedData-network-arm64
NETWORK_APP: '{{.NETWORK_DERIVED}}/Build/Products/{{.CONFIG}}/XStats Network Monitor.app'
BUMP: '{{default "1" .BUMP}}'
INSTALL: '{{default "1" .INSTALL}}'
CLEAN: '{{default "0" .CLEAN}}'
SIGN_ID:
sh: |
if [ -n "${SIGN_ID:-}" ]; then
printf '%s\n' "$SIGN_ID"
else
security find-identity -v -p codesigning 2>/dev/null | awk '/Developer ID Application/ { print $2; exit }' || true
fi
TEAM_ID:
sh: |
if [ -n '{{.SIGN_ID}}' ]; then
security find-identity -v -p codesigning 2>/dev/null \
| grep -F '{{.SIGN_ID}}' | head -1 | sed -nE 's/.*\(([A-Z0-9]+)\)"$/\1/p' || true
fi
tasks:
format:
desc: 使用 Swift 工具链格式化项目 Swift 源码
cmds:
- git ls-files --cached --others --exclude-standard -z -- '*.swift' | xargs -0 swift format format --in-place --configuration .swift-format
format-check:
desc: 检查项目 Swift 源码格式,不修改文件
cmds:
- git ls-files --cached --others --exclude-standard -z -- '*.swift' | xargs -0 swift format lint --strict --configuration .swift-format
compile-capture:
desc: 只编译独立 XStats Capture,不安装或推进版本
deps: [generate]
cmds:
- |
xcodebuild -project "{{.PROJECT}}" -scheme XStatsCapture -configuration "{{.CONFIG}}" \
-derivedDataPath build/DerivedData-capture-arm64 -destination 'generic/platform=macOS' \
ARCHS=arm64 ONLY_ACTIVE_ARCH=NO \
{{if .TEAM_ID}}CODE_SIGN_IDENTITY="{{.SIGN_ID}}" CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM={{.TEAM_ID}}{{if eq .CONFIG "Release"}} OTHER_CODE_SIGN_FLAGS=--timestamp CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO{{end}}{{else}}CODE_SIGNING_ALLOWED=NO ENABLE_HARDENED_RUNTIME=NO{{end}} \
{{if eq .CLEAN "1"}}clean {{end}}build
- bash scripts/sign_sparkle.sh "build/DerivedData-capture-arm64/Build/Products/{{.CONFIG}}/XStats Capture.app" "{{.SIGN_ID}}" capture
run-capture:
desc: 构建并打开独立 Capture App,不安装或推进版本
deps: [compile-capture]
cmds:
- open "build/DerivedData-capture-arm64/Build/Products/{{.CONFIG}}/XStats Capture.app"
generate:
desc: 由 project.yml 生成 Xcode 工程
cmds:
- xcodegen generate --quiet
build:
desc: 编译 App(含辅助工具)并安装
cmds:
- |
if [ "{{.INSTALL}}" != "0" ] && pgrep -x XStatsWidget >/dev/null; then
pkill -x XStatsWidget 2>/dev/null || true
for _ in $(seq 1 25); do pgrep -x XStatsWidget >/dev/null || break; sleep 0.2; done
if pgrep -x XStatsWidget >/dev/null; then
echo "error: XStatsWidget 尚未退出,无法安全构建安装" >&2
exit 1
fi
fi
- |
if [ "{{.BUMP}}" != "0" ]; then ./scripts/version.sh build; fi
- task: compile
vars:
CONFIG: '{{.CONFIG}}'
SIGN_ID: '{{.SIGN_ID}}'
CLEAN: '{{.CLEAN}}'
- |
if [ "{{.INSTALL}}" != "0" ]; then ./scripts/install_local.sh "{{.APP}}"; fi
compile:
desc: 只编译 App,不安装
deps: [generate]
cmds:
- |
# Xcode 增量构建不会自动移除旧目标留下的扩展目录;主包只保留 Widget。
rm -rf "{{.APP}}/Contents/Library/SystemExtensions"
xcodebuild -project "{{.PROJECT}}" -scheme "{{.SCHEME}}" -configuration "{{.CONFIG}}" \
-derivedDataPath "{{.DERIVED}}" \
-destination 'generic/platform=macOS' ARCHS=arm64 ONLY_ACTIVE_ARCH=NO \
XSTATS_APP_PROFILE="${XSTATS_APP_PROFILE:-}" XSTATS_WIDGET_PROFILE="${XSTATS_WIDGET_PROFILE:-}" \
{{if .TEAM_ID}}CODE_SIGN_IDENTITY="{{.SIGN_ID}}" CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM={{.TEAM_ID}}{{if eq .CONFIG "Release"}} OTHER_CODE_SIGN_FLAGS=--timestamp CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO{{end}}{{else}}CODE_SIGNING_ALLOWED=NO ENABLE_HARDENED_RUNTIME=NO{{end}} \
{{if eq .CLEAN "1"}}clean {{end}}build
- bash scripts/sign_sparkle.sh "{{.APP}}" "{{.SIGN_ID}}"
build-network-component:
desc: 编译并签名独立网络组件与按需 LaunchAgent,不推进版本或安装
cmds:
- task: compile-network-component
vars:
CONFIG: '{{.CONFIG}}'
SIGN_ID: '{{.SIGN_ID}}'
compile-network-component:
desc: 只编译并签名 XStats Network Monitor(macOS 15+、arm64)
deps: [generate]
cmds:
- |
xcodebuild -project "{{.PROJECT}}" -scheme XStatsNetworkMonitor -configuration "{{.CONFIG}}" \
-derivedDataPath "{{.NETWORK_DERIVED}}" \
-destination 'generic/platform=macOS' ARCHS=arm64 ONLY_ACTIVE_ARCH=NO \
XSTATS_COMPONENT_PROFILE="${XSTATS_COMPONENT_PROFILE:-}" XSTATS_NETWORK_PROFILE="${XSTATS_NETWORK_PROFILE:-}" \
{{if .TEAM_ID}}CODE_SIGN_IDENTITY="{{.SIGN_ID}}" CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM={{.TEAM_ID}}{{if eq .CONFIG "Release"}} OTHER_CODE_SIGN_FLAGS=--timestamp CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO{{end}}{{else}}CODE_SIGNING_ALLOWED=NO ENABLE_HARDENED_RUNTIME=NO{{end}} \
build
- bash scripts/sign_sparkle.sh "{{.NETWORK_APP}}" "{{.SIGN_ID}}" network-component
test-network-component:
desc: 定向验证网络组件 LaunchAgent 与服务生命周期,不注册或安装
cmds:
- bash scripts/embed_network_agent_test.sh
- bash scripts/network_component_lifetime_test.sh
release-capture:
desc: 构建、公证独立 Capture;-- 后传 --publish 或 --publish-only
cmds:
- python3 scripts/release_capture.py {{.CLI_ARGS}}
release-network-component:
desc: 签名、公证并打包独立网络组件,不上传
cmds:
- ./scripts/release_network_component.sh {{.CLI_ARGS}}
run:
desc: 编译、安装并启动 App
deps: [build]
install:
desc: 编译、安装并启动 App
deps: [build]
release:
desc: 签名、公证、装订、打包 DMG 并生成 Homebrew cask
cmds:
- ./scripts/release.sh
publish:
desc: 发布已构建且已提交推送的制品
cmds:
- ./scripts/publish_release.sh
release-all:
desc: 测试、构建、公证、提交推送并完成全部发布
cmds:
- ./scripts/release_all.sh
stop:
desc: 停止正在运行的 App
cmds:
- pkill -x XStats
ignore_error: true
test:
desc: 运行版本脚本、API 和 Swift 单元测试
cmds:
- bash scripts/version_test.sh
- bash scripts/arm64_release_test.sh
- python3 scripts/release_build_test.py
- python3 scripts/codesign_retry_test.py
- python3 scripts/install_local_test.py
- python3 scripts/archive_debug_symbols_test.py
- python3 scripts/backup_debug_symbols_test.py
- bash scripts/release_all_test.sh
- bash scripts/publish_release_test.sh
- python3 scripts/object_storage_test.py
- python3 scripts/release_provenance_test.py
- python3 scripts/publish_api_test.py
- python3 scripts/release_capture_test.py
- python3 scripts/homebrew_cask_test.py
- python3 scripts/sync_changelog_test.py
- python3 scripts/sparkle_appcast_test.py
- python3 scripts/github_release_notes_test.py
- python3 scripts/network_geography_test.py
- python3 scripts/perf_test.py
- python3 scripts/helper_recovery_test.py
- bash scripts/release_network_component_test.sh
- task: test-network-component
- task: test-api
- task: test-swift
perf:
desc: 串行运行本机资源测试并更新 docs/PERFORMANCE.md
cmds:
- python3 scripts/perf.py
test-api:
internal: true
dir: server/api
cmds:
- go test ./...
test-swift:
internal: true
dir: Packages/XStatsKit
cmds:
- swift build --build-tests
# 较旧 Swift 工具链把全部模块放在一个测试进程,阻塞型夹具会拖延其他模块的取消与超时。
# 按 Package.swift 中的测试目标隔离运行;UI 同步布局与 Cleaner 的同步进程夹具会拖延异步回调,
# 这些模块显式串行运行,保留其他模块的默认调度、全部断言与现有超时。
# 串行用于避免 UI 调度超时和共享 AppKit 状态互相干扰;UI 用例仍不得修改进程全局的 L10n 语言,翻译测试放在并行的 LocalizationTests。
- |
set -euo pipefail
modules="$(swift package describe --type json | python3 -c 'import json, sys; print("\n".join(t["name"] for t in json.load(sys.stdin)["targets"] if t["type"] == "test"))')"
test -n "$modules"
while IFS= read -r module; do
if [[ "$module" == "XStatsUITests" || "$module" == "CaptureUITests" || "$module" == "CleanerTests" ]]; then
swift test --skip-build --no-parallel --filter "^${module}\."
else
swift test --skip-build --filter "^${module}\."
fi
done <<< "$modules"
snapshot:
desc: 使用当前构建截图;-- 后可传截图模式与语言
vars:
SNAPSHOT_APP: '{{default .APP .SNAPSHOT_APP}}'
SNAPSHOT_DIR: '{{default "build/snapshots" .SNAPSHOT_DIR}}'
preconditions:
- sh: 'test -x "{{.SNAPSHOT_APP}}/Contents/MacOS/XStats"'
msg: '先运行 task build BUMP=0 INSTALL=0,或用 SNAPSHOT_APP 指定已有构建'
cmds:
- '"{{.SNAPSHOT_APP}}/Contents/MacOS/XStats" --snapshot "{{.SNAPSHOT_DIR}}" {{.CLI_ARGS}}'
open:
desc: 生成工程并用 Xcode 打开
deps: [generate]
cmds:
- open "{{.PROJECT}}"
clean:
desc: 删除构建产物
cmds:
- rm -rf build
version:
desc: 显示当前版本
cmds:
- ./scripts/version.sh