1111 branches :
1212 - main
1313 - release/*
14- types : [ labeled, opened, synchronize, reopened ]
14+ types : [ opened, synchronize, reopened ]
15+
1516jobs :
17+ # Prime a single LFS cache and expose the exact key for the matrix
18+ WarmLFS :
19+ runs-on : ubuntu-latest
20+ outputs :
21+ lfs_key : ${{ steps.expose-key.outputs.lfs_key }}
22+ steps :
23+ - name : Git Config
24+ shell : bash
25+ run : |
26+ git config --global core.autocrlf false
27+ git config --global core.longpaths true
28+
29+ - name : Git Checkout
30+ uses : actions/checkout@v4
31+ with :
32+ fetch-depth : 0
33+ submodules : recursive
34+
35+ # Deterministic list of LFS object IDs, then compute a portable key:
36+ # - `git lfs ls-files -l` lists all tracked LFS objects with their SHA-256
37+ # - `awk '{print $1}'` extracts just the SHA field
38+ # - `sort` sorts in byte order (hex hashes sort the same everywhere)
39+ # This ensures the file content is identical regardless of OS or locale
40+ - name : Git Create LFS id list
41+ shell : bash
42+ run : git lfs ls-files -l | awk '{print $1}' | sort > .lfs-assets-id
43+
44+ - name : Git Expose LFS cache key
45+ id : expose-key
46+ shell : bash
47+ env :
48+ LFS_KEY : lfs-${{ hashFiles('.lfs-assets-id') }}-v1
49+ run : echo "lfs_key=$LFS_KEY" >> "$GITHUB_OUTPUT"
50+
51+ - name : Git Setup LFS Cache
52+ uses : actions/cache@v4
53+ with :
54+ path : .git/lfs
55+ key : ${{ steps.expose-key.outputs.lfs_key }}
56+
57+ - name : Git Pull LFS
58+ shell : bash
59+ run : git lfs pull
60+
1661 Build :
62+ needs : WarmLFS
1763 strategy :
1864 matrix :
19- isARM :
20- - ${{ contains(github.event.pull_request.labels.*.name, 'arch:arm32') || contains(github.event.pull_request.labels.*.name, 'arch:arm64') }}
2165 options :
2266 - os : ubuntu-latest
23- framework : net9 .0
24- sdk : 9 .0.x
67+ framework : net10 .0
68+ sdk : 10 .0.x
2569 sdk-preview : true
2670 runtime : -x64
2771 codecov : false
28- - os : macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
29- framework : net9 .0
30- sdk : 9 .0.x
72+ - os : macos-26
73+ framework : net10 .0
74+ sdk : 10 .0.x
3175 sdk-preview : true
3276 runtime : -x64
3377 codecov : false
3478 - os : windows-latest
35- framework : net9 .0
36- sdk : 9 .0.x
79+ framework : net10 .0
80+ sdk : 10 .0.x
3781 sdk-preview : true
3882 runtime : -x64
3983 codecov : false
40- - os : buildjet-4vcpu- ubuntu-2204 -arm
41- framework : net9 .0
42- sdk : 9 .0.x
84+ - os : ubuntu-22.04 -arm
85+ framework : net10 .0
86+ sdk : 10 .0.x
4387 sdk-preview : true
4488 runtime : -x64
4589 codecov : false
4993 sdk : 8.0.x
5094 runtime : -x64
5195 codecov : false
52- - os : macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
96+ - os : macos-26
5397 framework : net8.0
5498 sdk : 8.0.x
5599 runtime : -x64
@@ -59,22 +103,32 @@ jobs:
59103 sdk : 8.0.x
60104 runtime : -x64
61105 codecov : false
62- - os : buildjet-4vcpu- ubuntu-2204 -arm
106+ - os : ubuntu-22.04 -arm
63107 framework : net8.0
64108 sdk : 8.0.x
65109 runtime : -x64
66110 codecov : false
67- exclude :
68- - isARM : false
69- options :
70- os : buildjet-4vcpu-ubuntu-2204-arm
71111
72- runs-on : ${{matrix.options.os}}
112+ runs-on : ${{ matrix.options.os }}
73113
74114 steps :
75115 - name : Install libgdi+, which is required for tests running on ubuntu
76- if : ${{ matrix.options.os == 'buildjet-4vcpu-ubuntu-2204-arm' }}
77- run : sudo apt-get -y install libgdiplus libgif-dev libglib2.0-dev libcairo2-dev libtiff-dev libexif-dev
116+ if : ${{ contains(matrix.options.os, 'ubuntu') }}
117+ run : |
118+ sudo apt-get update
119+ sudo apt-get -y install libgdiplus libgif-dev libglib2.0-dev libcairo2-dev libtiff-dev libexif-dev
120+
121+ - name : Install libgdi+, which is required for tests running on macos
122+ if : ${{ contains(matrix.options.os, 'macos-26') }}
123+ run : |
124+ brew update
125+ brew install mono-libgdiplus
126+ # Create symlinks to make libgdiplus discoverable
127+ sudo mkdir -p /usr/local/lib
128+ sudo ln -sf $(brew --prefix)/lib/libgdiplus.dylib /usr/local/lib/libgdiplus.dylib
129+ # Verify installation
130+ ls -la $(brew --prefix)/lib/libgdiplus* || echo "libgdiplus not found in brew prefix"
131+ ls -la /usr/local/lib/libgdiplus* || echo "libgdiplus not found in /usr/local/lib"
78132
79133 - name : Git Config
80134 shell : bash
@@ -88,18 +142,15 @@ jobs:
88142 fetch-depth : 0
89143 submodules : recursive
90144
91- # See https://github.com/actions/checkout/issues/165#issuecomment-657673315
92- - name : Git Create LFS FileList
93- run : git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
94-
145+ # Use the warmed key from WarmLFS. Do not recompute or recreate .lfs-assets-id here.
95146 - name : Git Setup LFS Cache
96147 uses : actions/cache@v4
97- id : lfs-cache
98148 with :
99149 path : .git/lfs
100- key : ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1
150+ key : ${{ needs.WarmLFS.outputs.lfs_key }}
101151
102152 - name : Git Pull LFS
153+ shell : bash
103154 run : git lfs pull
104155
105156 - name : NuGet Install
@@ -125,7 +176,7 @@ jobs:
125176 uses : actions/setup-dotnet@v4
126177 with :
127178 dotnet-version : |
128- 9 .0.x
179+ 10 .0.x
129180
130181 - name : DotNet Build
131182 if : ${{ matrix.options.sdk-preview != true }}
@@ -166,11 +217,8 @@ jobs:
166217
167218 Publish :
168219 needs : [Build]
169-
170220 runs-on : ubuntu-latest
171-
172221 if : (github.event_name == 'push')
173-
174222 steps :
175223 - name : Git Config
176224 shell : bash
@@ -211,4 +259,3 @@ jobs:
211259 run : |
212260 dotnet nuget push .\artifacts\*.nupkg -k ${{secrets.NUGET_TOKEN}} -s https://api.nuget.org/v3/index.json --skip-duplicate
213261 dotnet nuget push .\artifacts\*.snupkg -k ${{secrets.NUGET_TOKEN}} -s https://api.nuget.org/v3/index.json --skip-duplicate
214-
0 commit comments