Skip to content

Commit 0d4aa3e

Browse files
Merge branch 'main' into dependabot/github_actions/codecov/codecov-action-5
2 parents b83ac7c + e24be5c commit 0d4aa3e

1,422 files changed

Lines changed: 31121 additions & 15085 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:war
104104
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
105105
dotnet_style_parentheses_in_other_operators = always_for_clarity:suggestion
106106
# Expression-level preferences
107-
dotnet_style_object_initializer = true:warning
108-
dotnet_style_collection_initializer = true:warning
107+
dotnet_style_object_initializer = true:error
108+
dotnet_style_collection_initializer = true:error
109109
dotnet_style_explicit_tuple_names = true:warning
110110
dotnet_style_prefer_inferred_tuple_names = true:warning
111111
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
@@ -135,9 +135,9 @@ csharp_style_prefer_null_check_over_type_check = true:warning
135135
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/language-rules#c-style-rules
136136
[*.{cs,csx,cake}]
137137
# 'var' preferences
138-
csharp_style_var_for_built_in_types = false:warning
139-
csharp_style_var_when_type_is_apparent = false:warning
140-
csharp_style_var_elsewhere = false:warning
138+
csharp_style_var_for_built_in_types = false:error
139+
csharp_style_var_when_type_is_apparent = false:error
140+
csharp_style_var_elsewhere = false:error
141141
# Expression-bodied members
142142
csharp_style_expression_bodied_methods = true:warning
143143
csharp_style_expression_bodied_constructors = true:warning
@@ -160,7 +160,10 @@ csharp_style_pattern_local_over_anonymous_function = true:warning
160160
csharp_style_deconstructed_variable_declaration = true:warning
161161
csharp_style_prefer_index_operator = true:warning
162162
csharp_style_prefer_range_operator = true:warning
163-
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
163+
csharp_style_implicit_object_creation_when_type_is_apparent = true:error
164+
# ReSharper inspection severities
165+
resharper_arrange_object_creation_when_type_evident_highlighting = error
166+
resharper_arrange_object_creation_when_type_not_evident_highlighting = error
164167
# "Null" checking preferences
165168
csharp_style_throw_expression = true:warning
166169
csharp_style_conditional_delegate_call = true:warning
@@ -174,6 +177,9 @@ csharp_using_directive_placement = outside_namespace:warning
174177
csharp_prefer_static_local_function = true:warning
175178
# Primary constructor preferences
176179
csharp_style_prefer_primary_constructors = false:none
180+
# Collection preferences
181+
dotnet_style_prefer_collection_expression = true:error
182+
resharper_use_collection_expression_highlighting =true:error
177183

178184
##########################################
179185
# Unnecessary Code Rules

.gitattributes

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,10 @@
136136
*.ico filter=lfs diff=lfs merge=lfs -text
137137
*.cur filter=lfs diff=lfs merge=lfs -text
138138
*.ani filter=lfs diff=lfs merge=lfs -text
139+
*.heic filter=lfs diff=lfs merge=lfs -text
140+
*.hif filter=lfs diff=lfs merge=lfs -text
141+
*.avif filter=lfs diff=lfs merge=lfs -text
142+
###############################################################################
143+
# Handle ICC files by git lfs
144+
###############################################################################
145+
*.icc filter=lfs diff=lfs merge=lfs -text

.github/workflows/build-and-test.yml

Lines changed: 80 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,79 @@ on:
1111
branches:
1212
- main
1313
- release/*
14-
types: [ labeled, opened, synchronize, reopened ]
14+
types: [ opened, synchronize, reopened ]
15+
1516
jobs:
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
@@ -49,7 +93,7 @@ jobs:
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-

.github/workflows/code-coverage.yml

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
schedule:
55
# 2AM every Tuesday/Thursday
66
- cron: "0 2 * * 2,4"
7+
78
jobs:
89
Build:
910
strategy:
@@ -14,9 +15,15 @@ jobs:
1415
runtime: -x64
1516
codecov: true
1617

17-
runs-on: ${{matrix.options.os}}
18+
runs-on: ${{ matrix.options.os }}
1819

1920
steps:
21+
- name: Install libgdi+, which is required for tests running on ubuntu
22+
if: ${{ contains(matrix.options.os, 'ubuntu') }}
23+
run: |
24+
sudo apt-get update
25+
sudo apt-get -y install libgdiplus libgif-dev libglib2.0-dev libcairo2-dev libtiff-dev libexif-dev
26+
2027
- name: Git Config
2128
shell: bash
2229
run: |
@@ -29,16 +36,21 @@ jobs:
2936
fetch-depth: 0
3037
submodules: recursive
3138

32-
# See https://github.com/actions/checkout/issues/165#issuecomment-657673315
33-
- name: Git Create LFS FileList
34-
run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
39+
# Deterministic list of LFS object IDs, then compute a portable key:
40+
# - `git lfs ls-files -l` lists all tracked LFS objects with their SHA-256
41+
# - `awk '{print $1}'` extracts just the SHA field
42+
# - `sort` sorts in byte order (hex hashes sort the same everywhere)
43+
# This ensures the file content is identical regardless of OS or locale
44+
- name: Git Create LFS id list
45+
shell: bash
46+
run: git lfs ls-files -l | awk '{print $1}' | sort > .lfs-assets-id
3547

3648
- name: Git Setup LFS Cache
3749
uses: actions/cache@v4
3850
id: lfs-cache
3951
with:
4052
path: .git/lfs
41-
key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1
53+
key: lfs-${{ hashFiles('.lfs-assets-id') }}-v1
4254

4355
- name: Git Pull LFS
4456
run: git lfs pull
@@ -62,13 +74,13 @@ jobs:
6274
6375
- name: DotNet Build
6476
shell: pwsh
65-
run: ./ci-build.ps1 "${{matrix.options.framework}}"
77+
run: ./ci-build.ps1 "${{ matrix.options.framework }}"
6678
env:
6779
SIXLABORS_TESTING: True
6880

6981
- name: DotNet Test
7082
shell: pwsh
71-
run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}"
83+
run: ./ci-test.ps1 "${{ matrix.options.os }}" "${{ matrix.options.framework }}" "${{ matrix.options.runtime }}" "${{ matrix.options.codecov }}"
7284
env:
7385
SIXLABORS_TESTING: True
7486
XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit

Directory.Build.props

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@
2121
<!-- Import the shared global .props file -->
2222
<Import Project="$(MSBuildThisFileDirectory)shared-infrastructure\msbuild\props\SixLabors.Global.props" />
2323

24-
<PropertyGroup Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
25-
<!-- Workaround various issues bound to implicit language features. -->
26-
<LangVersion>preview</LangVersion>
24+
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0'">
25+
<LangVersion>12.0</LangVersion>
26+
</PropertyGroup>
27+
28+
<PropertyGroup Condition="'$(TargetFramework)' == 'net10.0'">
29+
<LangVersion>14.0</LangVersion>
2730
</PropertyGroup>
2831

2932
<!--

src/ImageSharp/Advanced/AotCompilerTools.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,11 @@ private static void Seed<TPixel>()
138138
AotCompileResamplers<TPixel>();
139139
AotCompileQuantizers<TPixel>();
140140
AotCompilePixelSamplingStrategys<TPixel>();
141+
AotCompilePixelMaps<TPixel>();
141142
AotCompileDithers<TPixel>();
142143
AotCompileMemoryManagers<TPixel>();
143144

144-
Unsafe.SizeOf<TPixel>();
145+
_ = Unsafe.SizeOf<TPixel>();
145146

146147
// TODO: Do the discovery work to figure out what works and what doesn't.
147148
}
@@ -276,11 +277,11 @@ private static void AotCompileImageDecoders<TPixel>()
276277
private static void AotCompileSpectralConverter<TPixel>()
277278
where TPixel : unmanaged, IPixel<TPixel>
278279
{
279-
default(SpectralConverter<TPixel>).GetPixelBuffer(default);
280-
default(GrayJpegSpectralConverter<TPixel>).GetPixelBuffer(default);
281-
default(RgbJpegSpectralConverter<TPixel>).GetPixelBuffer(default);
282-
default(TiffJpegSpectralConverter<TPixel>).GetPixelBuffer(default);
283-
default(TiffOldJpegSpectralConverter<TPixel>).GetPixelBuffer(default);
280+
default(SpectralConverter<TPixel>).GetPixelBuffer(default, default);
281+
default(GrayJpegSpectralConverter<TPixel>).GetPixelBuffer(default, default);
282+
default(RgbJpegSpectralConverter<TPixel>).GetPixelBuffer(default, default);
283+
default(TiffJpegSpectralConverter<TPixel>).GetPixelBuffer(default, default);
284+
default(TiffOldJpegSpectralConverter<TPixel>).GetPixelBuffer(default, default);
284285
}
285286

286287
/// <summary>
@@ -514,6 +515,20 @@ private static void AotCompilePixelSamplingStrategys<TPixel>()
514515
default(ExtensivePixelSamplingStrategy).EnumeratePixelRegions(default(ImageFrame<TPixel>));
515516
}
516517

518+
/// <summary>
519+
/// This method pre-seeds the all <see cref="IColorIndexCache{T}" /> in the AoT compiler.
520+
/// </summary>
521+
/// <typeparam name="TPixel">The pixel format.</typeparam>
522+
[Preserve]
523+
private static void AotCompilePixelMaps<TPixel>()
524+
where TPixel : unmanaged, IPixel<TPixel>
525+
{
526+
default(EuclideanPixelMap<TPixel, HybridCache>).GetClosestColor(default, out _);
527+
default(EuclideanPixelMap<TPixel, AccurateCache>).GetClosestColor(default, out _);
528+
default(EuclideanPixelMap<TPixel, CoarseCache>).GetClosestColor(default, out _);
529+
default(EuclideanPixelMap<TPixel, NullCache>).GetClosestColor(default, out _);
530+
}
531+
517532
/// <summary>
518533
/// This method pre-seeds the all <see cref="IDither" /> in the AoT compiler.
519534
/// </summary>

0 commit comments

Comments
 (0)