-
Notifications
You must be signed in to change notification settings - Fork 10
225 lines (200 loc) · 7.2 KB
/
Copy pathdotnet-ci.yaml
File metadata and controls
225 lines (200 loc) · 7.2 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
name: .NET CI/CD - Multi-Platform Release
on:
push:
branches: [ main, master ]
paths-ignore:
- '**.md'
- '**.gitignore'
- '.github/**/*.yml'
pull_request:
branches: [ main, master ]
workflow_dispatch:
inputs:
tagSuffix:
description: 'Tag后缀(可选,如 beta1、rc2)'
required: false
default: ''
type: string
preRelease:
description: '是否标记为预发布版本'
required: false
default: 'false'
type: boolean
env:
SOLUTION_PATH: ./src/GeneralUpdate.Tool.Avalonia.sln
PUBLISH_DIR: ./publish
PROJECT_NAME: GeneralUpdate.Tool.Avalonia
# 指定8.0正式版SDK(非预览版),避免调用10.0
DOTNET_SPECIFIC_VERSION: '8.0.400'
jobs:
build:
name: Build ${{ matrix.os }} - ${{ matrix.target-os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest]
target-os: [win-x64, linux-x64]
exclude:
- os: windows-latest
target-os: linux-x64
- os: ubuntu-latest
target-os: win-x64
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
lfs: false
# 关键修复1:强制卸载预览版SDK,安装指定8.0正式版
- name: Force install .NET 8.0.400 (remove preview versions)
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_SPECIFIC_VERSION }}
# 禁用缓存(彻底避开lock文件问题)
cache: false
# 关键修复2:纯依赖还原(无任何lock文件参数)
- name: Restore dependencies (no lock file)
run: |
# 直接还原依赖,不生成/使用lock文件
dotnet restore ${{ env.SOLUTION_PATH }}
if [ $? -ne 0 ]; then
echo "❌ 依赖还原失败,请检查项目依赖配置"
exit 1
fi
echo "✅ 依赖还原成功"
shell: bash
- name: Build Release version
run: |
dotnet build ${{ env.SOLUTION_PATH }} \
-c Release \
-r ${{ matrix.target-os }} \
--no-restore \
/p:WarningLevel=1
shell: bash
- name: Publish application
run: |
mkdir -p ${{ env.PUBLISH_DIR }}/${{ matrix.target-os }}
dotnet publish ${{ env.SOLUTION_PATH }} \
-c Release \
-r ${{ matrix.target-os }} \
-o ${{ env.PUBLISH_DIR }}/${{ matrix.target-os }} \
--no-build \
--self-contained true \
/p:PublishSingleFile=true \
/p:PublishTrimmed=true \
/p:TrimUnusedDependencies=true \
/p:DebugType=None \
/p:DebugSymbols=false \
/p:AssemblyVersion=1.0.${{ github.run_number }} \
/p:FileVersion=1.0.${{ github.run_number }} \
/p:UseAppHost=true
# 兼容Windows/Linux的空目录检查
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
FILE_COUNT=$(powershell "(Get-ChildItem '${{ env.PUBLISH_DIR }}/${{ matrix.target-os }}' | Measure-Object).Count")
else
FILE_COUNT=$(ls -A ${{ env.PUBLISH_DIR }}/${{ matrix.target-os }} | wc -l)
fi
if [ $FILE_COUNT -eq 0 ]; then
echo "❌ 发布目录为空,发布失败"
exit 1
fi
shell: bash
- name: Set execute permission (Linux only)
if: matrix.target-os == 'linux-x64'
run: |
chmod +x ${{ env.PUBLISH_DIR }}/${{ matrix.target-os }}/${{ env.PROJECT_NAME }}
if [ ! -x ${{ env.PUBLISH_DIR }}/${{ matrix.target-os }}/${{ env.PROJECT_NAME }} ]; then
echo "❌ Linux可执行文件权限设置失败"
exit 1
fi
shell: bash
- name: Package release files
id: package
run: |
DATE=$(date +%Y%m%d)
ZIP_NAME="${{ env.PROJECT_NAME }}_${{ matrix.target-os }}_${DATE}.zip"
ZIP_PATH="${{ env.PUBLISH_DIR }}/${ZIP_NAME}"
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
powershell Compress-Archive -Path "${{ env.PUBLISH_DIR }}/${{ matrix.target-os }}/*" -DestinationPath "$ZIP_PATH" -Force
else
zip -r "$ZIP_PATH" "${{ env.PUBLISH_DIR }}/${{ matrix.target-os }}/*"
fi
if [ ! -f "$ZIP_PATH" ]; then
echo "❌ 压缩包生成失败"
exit 1
fi
echo "zip_name=$ZIP_NAME" >> $GITHUB_OUTPUT
echo "zip_path=$ZIP_PATH" >> $GITHUB_OUTPUT
echo "✅ 压缩包生成成功:$ZIP_NAME"
shell: bash
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target-os }}_artifact
path: ${{ steps.package.outputs.zip_path }}
retention-days: 7
if-no-files-found: error
release:
name: Create GitHub Release
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
merge-multiple: false
- name: Configure Git user
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "actions@github.com"
git fetch --tags
shell: bash
- name: Generate date-based Tag
id: create_tag
run: |
BASE_TAG="v$(date +%Y%m%d)"
TAG_SUFFIX="${{ github.event.inputs.tagSuffix }}"
if [ -n "$TAG_SUFFIX" ]; then
FINAL_TAG="${BASE_TAG}-${TAG_SUFFIX}"
else
FINAL_TAG="${BASE_TAG}"
fi
# 兼容无Tag的情况
if ! git rev-parse "$FINAL_TAG" >/dev/null 2>&1; then
git tag "$FINAL_TAG"
git push origin "$FINAL_TAG"
echo "✅ 成功创建Tag:$FINAL_TAG"
else
echo "ℹ️ Tag $FINAL_TAG 已存在,跳过创建"
fi
echo "tag_name=$FINAL_TAG" >> $GITHUB_OUTPUT
shell: bash
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.create_tag.outputs.tag_name }}
name: Release ${{ steps.create_tag.outputs.tag_name }}
body: |
## 🚀 自动构建发布
- 构建日期:${{ steps.create_tag.outputs.tag_name }}
- 构建编号:${{ github.run_number }}
- 包含平台:Windows x64 / Linux x64
- 构建模式:Release | 单文件 | 自包含 | 依赖裁剪
files: |
./artifacts/win-x64_artifact/*.zip
./artifacts/linux-x64_artifact/*.zip
prerelease: ${{ github.event.inputs.preRelease == 'true' || github.event.inputs.tagSuffix != '' }}
draft: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Cleanup artifacts
if: always()
run: |
rm -rf ./artifacts
echo "✅ 产物清理完成"
shell: bash