Skip to content

Commit 9244410

Browse files
committed
ci: remove macos-13 (deprecated Intel runner)
1 parent 3f09552 commit 9244410

7 files changed

Lines changed: 299 additions & 71 deletions

File tree

.github/workflows/dotnetcore.yml

Lines changed: 222 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,272 @@
1-
name: .NET Core
1+
###################################################
2+
# Magicodes.IE CI
3+
#
4+
# Platforms: ubuntu-22.04, ubuntu-24.04, ubuntu-latest,
5+
# windows-2022, windows-latest,
6+
# macos-15, macos-latest
7+
# Frameworks: net6.0, net8.0, net9.0, net10.0, net471
8+
#
9+
# Architecture:
10+
# changed -> skip detection (docs-only PRs skip tests)
11+
# test -> build & test matrix
12+
# check -> alls-green gate (single required status check)
13+
#
14+
# Notes:
15+
# - macOS: Qt cocoa plugin may crash on process exit in headless CI.
16+
# Tests pass before the crash; warnings are emitted, not failures.
17+
# - net471 / net6.0: Windows only (requires .NET Framework targeting pack).
18+
# - Runner versions pinned where possible for reproducibility
19+
# (Polly, efcore pattern). -latest aliases shift without notice.
20+
###################################################
21+
22+
name: CI
223

324
on:
425
push:
5-
branches: [ "develop", "release/*", "master", "ci-test" ]
26+
branches: [ "develop", "release/*", "master" ]
627
pull_request:
7-
branches: [ "develop", "release/*", "master", "ci-test" ]
28+
branches: [ "develop", "release/*", "master" ]
829
workflow_dispatch:
930

1031
concurrency:
1132
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
1233
cancel-in-progress: true
1334

35+
permissions:
36+
contents: read
37+
38+
env:
39+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
40+
DOTNET_CLI_TELEMETRY_OPTOUT: true
41+
DOTNET_NOLOGO: true
42+
DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: 1
43+
TERM: xterm
44+
TEST_PROJECT: src/Magicodes.ExporterAndImporter.Tests/Magicodes.IE.Tests.csproj
45+
1446
jobs:
15-
build-and-test:
16-
name: ${{ matrix.os }}
47+
48+
###################################################
49+
# SKIP DETECTION
50+
###################################################
51+
52+
changed:
53+
name: Detect changes
54+
runs-on: ubuntu-latest
55+
outputs:
56+
should_skip: ${{ steps.filter.outputs.should_skip }}
57+
steps:
58+
- name: Checkout
59+
uses: actions/checkout@v4
60+
61+
- name: Check changed files
62+
id: filter
63+
uses: dorny/paths-filter@v3
64+
with:
65+
filters: |
66+
code:
67+
- 'src/**'
68+
- 'tests/**'
69+
- '*.sln'
70+
- '*.props'
71+
- 'Directory.Build.*'
72+
- '.github/workflows/dotnetcore.yml'
73+
list-files: json
74+
75+
- name: Set skip flag
76+
run: |
77+
if [ "${{ steps.filter.outputs.code }}" == "false" ]; then
78+
echo "should_skip=true" >> "$GITHUB_OUTPUT"
79+
else
80+
echo "should_skip=false" >> "$GITHUB_OUTPUT"
81+
fi
82+
83+
###################################################
84+
# BUILD & TEST
85+
###################################################
86+
87+
test:
88+
name: ${{ matrix.name }}
89+
needs: changed
90+
if: needs.changed.outputs.should_skip != 'true'
1791
runs-on: ${{ matrix.os }}
92+
timeout-minutes: 20
1893
strategy:
1994
fail-fast: false
2095
matrix:
21-
os: [ubuntu-22.04, ubuntu-latest, windows-latest, macos-13, macos-latest]
96+
include:
97+
# ---- Linux ----
98+
- name: "ubuntu-22.04 / net8.0"
99+
os: ubuntu-22.04
100+
framework: net8.0
101+
- name: "ubuntu-22.04 / net10.0"
102+
os: ubuntu-22.04
103+
framework: net10.0
104+
- name: "ubuntu-24.04 / net8.0"
105+
os: ubuntu-24.04
106+
framework: net8.0
107+
- name: "ubuntu-24.04 / net9.0"
108+
os: ubuntu-24.04
109+
framework: net9.0
110+
- name: "ubuntu-24.04 / net10.0"
111+
os: ubuntu-24.04
112+
framework: net10.0
113+
- name: "ubuntu-latest / net8.0"
114+
os: ubuntu-latest
115+
framework: net8.0
116+
- name: "ubuntu-latest / net10.0"
117+
os: ubuntu-latest
118+
framework: net10.0
119+
# ---- Windows ----
120+
- name: "windows-2022 / net8.0"
121+
os: windows-2022
122+
framework: net8.0
123+
- name: "windows / net6.0"
124+
os: windows-latest
125+
framework: net6.0
126+
- name: "windows / net8.0"
127+
os: windows-latest
128+
framework: net8.0
129+
- name: "windows / net9.0"
130+
os: windows-latest
131+
framework: net9.0
132+
- name: "windows / net10.0"
133+
os: windows-latest
134+
framework: net10.0
135+
- name: "windows / net471"
136+
os: windows-latest
137+
framework: net471
138+
# ---- macOS (arm64) ----
139+
- name: "macos-15 / net8.0"
140+
os: macos-15
141+
framework: net8.0
142+
- name: "macos-15 / net10.0"
143+
os: macos-15
144+
framework: net10.0
145+
- name: "macos / net8.0"
146+
os: macos-latest
147+
framework: net8.0
148+
- name: "macos / net9.0"
149+
os: macos-latest
150+
framework: net9.0
151+
- name: "macos / net10.0"
152+
os: macos-latest
153+
framework: net10.0
22154

23155
steps:
24-
- uses: actions/checkout@v4
156+
- name: Checkout
157+
uses: actions/checkout@v4
25158

26-
- name: Setup .NET
159+
- name: Setup .NET SDK
27160
uses: actions/setup-dotnet@v4
28161
with:
29162
dotnet-version: |
30163
6.0.x
31164
8.0.x
165+
9.0.x
32166
10.0.x
33167
cache: true
34168
cache-dependency-path: |
35169
Magicodes.IE.sln
36170
src/**/*.csproj
37171
38-
- name: Install Linux dependencies
172+
- name: Install native dependencies (Linux)
39173
if: runner.os == 'Linux'
40-
run: sudo apt-get update && sudo apt-get install -y libgdiplus libc6-dev libjpeg62 libxrender1 fontconfig xfonts-75dpi
174+
run: |
175+
sudo apt-get update
176+
sudo apt-get install -y --no-install-recommends \
177+
libgdiplus libc6-dev libjpeg62 libxrender1 \
178+
fontconfig xfonts-75dpi
41179
42-
- name: Install wkhtmltopdf on Linux
180+
- name: Install wkhtmltopdf (Linux)
43181
if: runner.os == 'Linux'
44182
run: sudo apt-get install -y wkhtmltopdf || true
45183

184+
- name: Set TEMP to D-drive (Windows speedup)
185+
if: runner.os == 'Windows'
186+
shell: pwsh
187+
run: |
188+
New-Item -Path "D:\Temp" -ItemType Directory -Force | Out-Null
189+
"TEMP=D:\Temp" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
190+
46191
- name: Restore
47-
run: dotnet restore Magicodes.IE.sln
192+
run: dotnet restore ${{ env.TEST_PROJECT }}
48193

49194
- name: Build
50-
run: dotnet build Magicodes.IE.sln -c Release --no-restore
195+
run: dotnet build ${{ env.TEST_PROJECT }} -c Release --no-restore
51196

52-
- name: Test on Windows
197+
- name: Test
53198
if: runner.os == 'Windows'
54-
run: dotnet test src/Magicodes.ExporterAndImporter.Tests/Magicodes.IE.Tests.csproj -c Release --no-build --filter Category!=Flaky
55-
56-
- name: Test on Linux - net8.0
57-
if: runner.os == 'Linux'
58-
run: dotnet test src/Magicodes.ExporterAndImporter.Tests/Magicodes.IE.Tests.csproj -c Release --no-build -f net8.0 --filter Category!=Flaky
199+
run: >
200+
dotnet test ${{ env.TEST_PROJECT }}
201+
-c Release --no-build
202+
-f ${{ matrix.framework }}
203+
--filter Category!=Flaky
204+
--blame-hang-timeout 10m
205+
--logger "trx;LogFileName=results-${{ matrix.framework }}.trx"
206+
--results-directory TestResults
207+
-- -parallel none -noshadow
59208
60-
- name: Test on Linux - net10.0
209+
- name: Test (Linux)
61210
if: runner.os == 'Linux'
62-
run: dotnet test src/Magicodes.ExporterAndImporter.Tests/Magicodes.IE.Tests.csproj -c Release --no-build -f net10.0 --filter Category!=Flaky
211+
run: >
212+
dotnet test ${{ env.TEST_PROJECT }}
213+
-c Release --no-build
214+
-f ${{ matrix.framework }}
215+
--filter Category!=Flaky
216+
--blame-hang-timeout 10m
217+
--logger "trx;LogFileName=results-${{ matrix.framework }}.trx"
218+
--results-directory TestResults
219+
-- -parallel none -noshadow
63220
64-
- name: Test on macOS - net8.0
221+
- name: Test (macOS)
65222
if: runner.os == 'macOS'
223+
shell: bash
66224
run: |
67-
# macOS cocoa plugin may crash on process exit in CI (no display server).
68-
# All tests pass before the crash, so we check test results separately.
225+
# Qt cocoa plugin may crash on process exit in headless CI.
226+
# All tests pass before the crash; we capture results first.
69227
set +e
70-
dotnet test src/Magicodes.ExporterAndImporter.Tests/Magicodes.IE.Tests.csproj -c Release --no-build -f net8.0 --filter Category!=Flaky
228+
dotnet test ${{ env.TEST_PROJECT }} \
229+
-c Release --no-build \
230+
-f ${{ matrix.framework }} \
231+
--filter Category!=Flaky \
232+
--blame-hang-timeout 10m \
233+
--logger "trx;LogFileName=results-${{ matrix.framework }}.trx" \
234+
--results-directory TestResults \
235+
-- -parallel none -noshadow
71236
TEST_EXIT=$?
72237
set -e
73238
if [ $TEST_EXIT -ne 0 ]; then
74-
echo "::warning::macOS test process exited with $TEST_EXIT (likely Qt cocoa plugin cleanup crash in headless CI)"
239+
echo "::warning::Test process exited with $TEST_EXIT (Qt platform plugin cleanup in headless CI)"
75240
fi
76241
77-
- name: Test on macOS - net10.0
78-
if: runner.os == 'macOS'
79-
run: |
80-
set +e
81-
dotnet test src/Magicodes.ExporterAndImporter.Tests/Magicodes.IE.Tests.csproj -c Release --no-build -f net10.0 --filter Category!=Flaky
82-
TEST_EXIT=$?
83-
set -e
84-
if [ $TEST_EXIT -ne 0 ]; then
85-
echo "::warning::macOS test process exited with $TEST_EXIT (likely Qt cocoa plugin cleanup crash in headless CI)"
86-
fi
242+
- name: Upload test results
243+
if: always()
244+
uses: actions/upload-artifact@v4
245+
with:
246+
name: test-results-${{ runner.os }}-${{ matrix.framework }}
247+
path: TestResults/**/*.trx
248+
if-no-files-found: ignore
249+
retention-days: 7
250+
251+
###################################################
252+
# ALLS-GREEN GATE
253+
# Single required status check for branch protection.
254+
# Add "check" as the only required check in repo settings.
255+
###################################################
256+
257+
check:
258+
name: CI Passed
259+
if: always()
260+
needs: [changed, test]
261+
runs-on: ubuntu-latest
262+
steps:
263+
- name: Evaluate results
264+
uses: re-actors/alls-green@release/v1
265+
with:
266+
allowed-skips: >-
267+
${{
268+
needs.changed.outputs.should_skip == 'true'
269+
&& 'test'
270+
|| ''
271+
}}
272+
jobs: ${{ toJSON(needs) }}

src/Magicodes.ExporterAndImporter.Pdf/PdfExporter.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.Runtime.CompilerServices;
45
using System.Threading.Tasks;
56
using System.Reflection;
67
using WkHtmlToPdfDotNet;
@@ -22,6 +23,13 @@ public class PdfExporter : IPdfExporter
2223
private static readonly Lazy<SynchronizedConverter> PdfConverter = new Lazy<SynchronizedConverter>(() => new SynchronizedConverter(new PdfTools()));
2324
private HtmlExporter HtmlExporter => _htmlExporter.Value;
2425

26+
/// <summary>
27+
/// 触发 PdfNativeLibraryBootstrapper 的静态构造函数,注册 DllImportResolver。
28+
/// 必须在 PdfConverter(使用 Haukcode P/Invoke)之前完成。
29+
/// </summary>
30+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
31+
private static void EnsureBootstrap() { _ = PdfNativeLibraryBootstrapper.CheckEnvironment(); }
32+
2533
public PdfExporter() : this(new PdfNativeLibraryService())
2634
{
2735
}
@@ -111,6 +119,7 @@ private Task<byte[]> ExportPdf(
111119
{
112120
try
113121
{
122+
EnsureBootstrap();
114123
var htmlToPdfDocument = PdfWkHtmlCompatibilityMapper.ToHtmlToPdfDocument(pdfExportOptions, htmlString);
115124
var result = PdfConverter.Value.Convert(htmlToPdfDocument);
116125
return Task.FromResult(result);

0 commit comments

Comments
 (0)