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@v5
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
2367 framework : net7.0
2468 sdk : 7.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
72+ - os : macos-26
2973 framework : net7.0
3074 sdk : 7.0.x
3175 sdk-preview : true
@@ -37,18 +81,19 @@ jobs:
3781 sdk-preview : true
3882 runtime : -x64
3983 codecov : false
40- - os : buildjet-4vcpu- ubuntu-2204 -arm
84+ - os : ubuntu-22.04 -arm
4185 framework : net7.0
4286 sdk : 7.0.x
4387 sdk-preview : true
4488 runtime : -x64
4589 codecov : false
90+
4691 - os : ubuntu-latest
4792 framework : net6.0
4893 sdk : 6.0.x
4994 runtime : -x64
5095 codecov : false
51- - os : macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
96+ - os : macos-26
5297 framework : net6.0
5398 sdk : 6.0.x
5499 runtime : -x64
@@ -58,19 +103,32 @@ jobs:
58103 sdk : 6.0.x
59104 runtime : -x64
60105 codecov : false
61- exclude :
62- - isARM : false
63- options :
64- os : buildjet-4vcpu-ubuntu-2204-arm
106+ - os : ubuntu-22.04-arm
107+ framework : net6.0
108+ sdk : 6.0.x
109+ runtime : -x64
110+ codecov : false
65111
66- runs-on : ${{matrix.options.os}}
112+ runs-on : ${{ matrix.options.os }}
67113
68114 steps :
69115 - name : Install libgdi+, which is required for tests running on ubuntu
70116 if : ${{ contains(matrix.options.os, 'ubuntu') }}
71117 run : |
72- sudo apt-get update
73- sudo apt-get -y install libgdiplus libgif-dev libglib2.0-dev libcairo2-dev libtiff-dev libexif-dev
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"
74132
75133 - name : Git Config
76134 shell : bash
@@ -84,39 +142,42 @@ jobs:
84142 fetch-depth : 0
85143 submodules : recursive
86144
87- # See https://github.com/actions/checkout/issues/165#issuecomment-657673315
88- - name : Git Create LFS FileList
89- run : git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
90-
145+ # Use the warmed key from WarmLFS. Do not recompute or recreate .lfs-assets-id here.
91146 - name : Git Setup LFS Cache
92- uses : actions/cache@v3
93- id : lfs-cache
147+ uses : actions/cache@v5
94148 with :
95149 path : .git/lfs
96- key : ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1
150+ key : ${{ needs.WarmLFS.outputs.lfs_key }}
97151
98152 - name : Git Pull LFS
153+ shell : bash
99154 run : git lfs pull
100155
101156 - name : NuGet Install
102- uses : NuGet/setup-nuget@v1
157+ uses : NuGet/setup-nuget@v2
103158
104159 - name : NuGet Setup Cache
105- uses : actions/cache@v3
160+ uses : actions/cache@v5
106161 id : nuget-cache
107162 with :
108163 path : ~/.nuget
109164 key : ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props', '**/*.targets') }}
110165 restore-keys : ${{ runner.os }}-nuget-
111166
112167 - name : DotNet Setup
113- uses : actions/setup-dotnet@v4
168+ if : ${{ matrix.options.sdk-preview != true }}
169+ uses : actions/setup-dotnet@v5
114170 with :
115171 dotnet-version : |
116- 8.0.x
117- 7.0.x
118172 6.0.x
119173
174+ - name : DotNet Setup Preview
175+ if : ${{ matrix.options.sdk-preview == true }}
176+ uses : actions/setup-dotnet@v5
177+ with :
178+ dotnet-version : |
179+ 7.0.x
180+
120181 - name : DotNet Build
121182 if : ${{ matrix.options.sdk-preview != true }}
122183 shell : pwsh
@@ -148,19 +209,16 @@ jobs:
148209 XUNIT_PATH : .\tests\ImageSharp.Tests # Required for xunit
149210
150211 - name : Export Failed Output
151- uses : actions/upload-artifact@v4
212+ uses : actions/upload-artifact@v6
152213 if : failure()
153214 with :
154215 name : actual_output_${{ runner.os }}_${{ matrix.options.framework }}${{ matrix.options.runtime }}.zip
155216 path : tests/Images/ActualOutput/
156217
157218 Publish :
158219 needs : [Build]
159-
160220 runs-on : ubuntu-latest
161-
162221 if : (github.event_name == 'push')
163-
164222 steps :
165223 - name : Git Config
166224 shell : bash
@@ -175,10 +233,10 @@ jobs:
175233 submodules : recursive
176234
177235 - name : NuGet Install
178- uses : NuGet/setup-nuget@v1
236+ uses : NuGet/setup-nuget@v2
179237
180238 - name : NuGet Setup Cache
181- uses : actions/cache@v3
239+ uses : actions/cache@v5
182240 id : nuget-cache
183241 with :
184242 path : ~/.nuget
@@ -201,4 +259,3 @@ jobs:
201259 run : |
202260 dotnet nuget push .\artifacts\*.nupkg -k ${{secrets.NUGET_TOKEN}} -s https://api.nuget.org/v3/index.json --skip-duplicate
203261 dotnet nuget push .\artifacts\*.snupkg -k ${{secrets.NUGET_TOKEN}} -s https://api.nuget.org/v3/index.json --skip-duplicate
204-
0 commit comments