Skip to content

perf: reuse argument-free attribute initializer text - #6788

Merged
thomhurst merged 1 commit into
mainfrom
perf/blog-generator-work
Sep 12, 2026
Merged

thomhurst merged 1 commit into
mainfrom
perf/blog-generator-work

Conversation

@thomhurst

@thomhurst thomhurst commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Large test suites repeatedly format identical argument-free attribute applications such as [Test]. Cache the emitted initializer text by constructed attribute type within each compilation, while keeping explicit arguments and named properties on the existing per-application path. Optional caller-info parameters retain the same generated syntax as before.

The complete TestMetadataGenerator benchmark (10,000 tests, 100 classes of 100 methods) allocates 12.87 MB less per generation, a 7.8% reduction. Mean elapsed time decreased from 112.5 ms to 107.5 ms, but the timing distributions overlap: this PR claims the allocation improvement, not a statistically established whole-build speedup.

Validation: generator snapshot suite on net10.0 passed (150 passed, one existing skip). Added regression checks for omitted versus explicit/named arguments and different constructed generic attribute types. The benchmark also compares all 100 generated files byte-for-byte between baseline and candidate for both original and edited compilations; output is identical. A separate executable compiled and passed all 10,000 generated tests.

Baseline: 656b66e723. Candidate: 706200fd2c (final local-variable rename only after measurement). Generator assemblies built with repository-selected SDK 11.0.100-preview.7.26381.103. Benchmark host uses .NET 10.0.12, Roslyn 4.14.0 and BenchmarkDotNet 0.15.8 on Windows 11 / Intel i7-12700K. Runs are sequential, with no other builds or tests launched by this task during measurement. The separate-process BDN build stalled, so both versions use InProcessEmitToolchain and isolated AssemblyLoadContexts. Compilation construction is outside measurement; each operation runs the full generator from an unrun immutable driver. This measures generator work, not process startup or end-to-end MSBuild time.


BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.9168/25H2/2025Update/HudsonValley2)
12th Gen Intel Core i7-12700K 3.60GHz, 1 CPU, 20 logical and 12 physical cores
.NET SDK 10.0.401
  [Host] : .NET 10.0.12 (10.0.12, 10.0.1226.42308), X64 RyuJIT x86-64-v3

Toolchain=InProcessEmitToolchain  Categories=Cold  

Method Mean Error StdDev Ratio RatioSD Gen0 Gen1 Gen2 Allocated Alloc Ratio
BeforeCold 112.5 ms 2.50 ms 7.22 ms 1.00 0.09 10500.0000 3000.0000 - 164.1 MB 1.00
AfterCold 107.5 ms 3.75 ms 11.00 ms 0.96 0.11 9800.0000 2800.0000 200.0000 151.23 MB 0.92
Reproduce the comparison

Create separate checkouts of the baseline and this PR. In an external working directory, save the project and Program.cs below as GeneratorBench. Use these commands (replace checkout paths):

$baselineCheckout = 'C:/path/to/baseline'
$candidateCheckout = 'C:/path/to/candidate'
$env:PERF_ROOT = 'C:/path/to/evidence'
dotnet build "$baselineCheckout/src/TUnit.Core.SourceGenerator" -c Release -o "$env:PERF_ROOT/baseline-generator"
dotnet build "$candidateCheckout/src/TUnit.Core.SourceGenerator" -c Release -o "$env:PERF_ROOT/candidate-generator"
dotnet build "$candidateCheckout/src/TUnit.Core" -c Release -f net10.0
Copy-Item "$candidateCheckout/src/TUnit.Core/bin/Release/net10.0/TUnit.Core.dll" "$env:PERF_ROOT/TUnit.Core.dll"
Set-Location "$env:PERF_ROOT/GeneratorBench"
dotnet run -c Release -- --validate
dotnet run -c Release --no-build -- --filter '*Cold*' --job Dry --inProcess --artifacts ../dry
dotnet run -c Release --no-build -- --filter '*Cold*' --inProcess --artifacts ../results --exporters fulljson

GeneratorBench.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
  </ItemGroup>

</Project>

Program.cs:

using System.Runtime.Loader;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Running;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

if (args.Contains("--validate"))
{
    var benchmark = new GeneratorBench();
    benchmark.Setup();
    Console.WriteLine("Baseline and candidate produce identical output for cold and edited compilations.");
    return;
}
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);

[MemoryDiagnoser]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
[CategoriesColumn]
public class GeneratorBench
{
    private CSharpCompilation _compilation = null!;
    private CSharpCompilation _edited = null!;
    private GeneratorDriver _before = null!, _after = null!, _beforeWarm = null!, _afterWarm = null!;
    private static readonly CSharpParseOptions ParseOptions = new(LanguageVersion.Preview);

    [GlobalSetup]
    public void Setup()
    {
        var root = Environment.GetEnvironmentVariable("PERF_ROOT") ?? "C:/git/TUnit-perf-evidence-20260912";
        var references = ((string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")!).Split(Path.PathSeparator)
            .Select(path => MetadataReference.CreateFromFile(path)).ToList();
        references.Add(MetadataReference.CreateFromFile(root + "/TUnit.Core.dll"));
        var trees = Enumerable.Range(0, 100).Select(i => CSharpSyntaxTree.ParseText(
            "using TUnit.Core; public class Tests" + i + " { " +
            string.Join("\n", Enumerable.Range(0, 100).Select(j =>
                $"[Test] public void Test{j}() {{ if (Compute({j}) != {j * j + 1}) throw new System.Exception(); }}")) +
            "private static int Compute(int x) => x*x+1; }", ParseOptions, $"Tests{i}.cs")).ToArray();
        _compilation = CSharpCompilation.Create("BenchmarkTests", trees, references,
            new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
        var errors = _compilation.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).ToArray();
        if (errors.Length > 0) throw new Exception(string.Join("\n", errors.AsEnumerable()));
        _edited = _compilation.ReplaceSyntaxTree(trees[0], CSharpSyntaxTree.ParseText(
            trees[0].ToString().Replace("Compute(0)", "Compute(0 + 0)"), ParseOptions, "Tests0.cs"));
        _before = Load(root + "/baseline-generator/TUnit.Core.SourceGenerator.dll");
        _after = Load(root + "/candidate-generator/TUnit.Core.SourceGenerator.dll");
        _beforeWarm = _before.RunGenerators(_compilation);
        _afterWarm = _after.RunGenerators(_compilation);
        Equal(_beforeWarm, _afterWarm);
        Equal(_beforeWarm.RunGenerators(_edited), _afterWarm.RunGenerators(_edited));
    }

    private static GeneratorDriver Load(string path)
    {
        var context = new AssemblyLoadContext(Path.GetDirectoryName(path), isCollectible: true);
        var assembly = context.LoadFromAssemblyPath(Path.GetFullPath(path));
        var generator = (IIncrementalGenerator)Activator.CreateInstance(
            assembly.GetType("TUnit.Core.SourceGenerator.Generators.TestMetadataGenerator", true)!)!;
        return CSharpGeneratorDriver.Create([generator.AsSourceGenerator()], parseOptions: ParseOptions);
    }

    private static void Equal(GeneratorDriver before, GeneratorDriver after)
    {
        var left = before.GetRunResult();
        var right = after.GetRunResult();
        if (left.Diagnostics.Length != 0 || right.Diagnostics.Length != 0)
            throw new Exception(string.Join("\n", left.Diagnostics.Concat(right.Diagnostics)));
        var a = left.Results.Single().GeneratedSources.OrderBy(s => s.HintName).ToArray();
        var b = right.Results.Single().GeneratedSources.OrderBy(s => s.HintName).ToArray();
        if (a.Length != 100 || a.Length != b.Length) throw new Exception($"Unexpected output count: {a.Length}/{b.Length}");
        for (var i = 0; i < a.Length; i++)
            if (a[i].HintName != b[i].HintName || !a[i].SourceText.ContentEquals(b[i].SourceText))
                throw new Exception("Generated output differs: " + a[i].HintName);
    }

    [Benchmark(Baseline = true), BenchmarkCategory("Cold")]
    public GeneratorDriver BeforeCold() => _before.RunGenerators(_compilation);
    [Benchmark, BenchmarkCategory("Cold")]
    public GeneratorDriver AfterCold() => _after.RunGenerators(_compilation);
    [Benchmark(Baseline = true), BenchmarkCategory("Edit")]
    public GeneratorDriver BeforeEdit() => _beforeWarm.RunGenerators(_edited);
    [Benchmark, BenchmarkCategory("Edit")]
    public GeneratorDriver AfterEdit() => _afterWarm.RunGenerators(_edited);
}

Summary by CodeRabbit

  • Performance
    • Improved handling of repeated argument-free attributes, reducing redundant formatting work while preserving attributes with explicit arguments.
  • Bug Fixes
    • Ensured generic attribute types continue to receive distinct initializers.
  • Tests
    • Added coverage for argument-free attributes with and without parentheses, explicit positional and named arguments, and constructed generic attribute types.

@thomhurst
thomhurst deployed to Pull Requests September 12, 2026 08:59 — with GitHub Actions Active
@thomhurst
thomhurst deployed to Pull Requests September 12, 2026 08:59 — with GitHub Actions Active
@thomhurst
thomhurst deployed to Pull Requests September 12, 2026 08:59 — with GitHub Actions Active
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 12, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-12T09:03:55.177004Z 706200f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Sep 12, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: df4a2c9c-a7be-41e7-95ce-a1ce82113223

📥 Commits

Reviewing files that changed from the base of the PR and between 656b66e and 706200f.

📒 Files selected for processing (2)
  • src/TUnit.Core.SourceGenerator/CodeGenerators/Writers/AttributeWriter.cs
  • tests/TUnit.Core.SourceGenerator.Tests/AttributeInitializerCacheTests.cs

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The source generator now caches initializers for argument-free attributes by attribute type. Tests verify reuse, preservation of explicit arguments, and separation of constructed generic attribute types.

Changes

Attribute initializer cache

Layer / File(s) Summary
Cache argument-free initializers
src/TUnit.Core.SourceGenerator/CodeGenerators/Writers/AttributeWriter.cs
The writer caches parameterless attribute initializers by named attribute type. Applications with positional or named arguments continue to use the existing path.
Validate initializer cache behavior
tests/TUnit.Core.SourceGenerator.Tests/AttributeInitializerCacheTests.cs
Tests verify parameterless applications, explicit arguments, and distinct initializers for constructed generic attribute types.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Refactor

Merge Risk: ⚪ Minimal · up to 70620

The initializer cache preserves per-use caller information and the covered argument and generic-type behaviors remain intact. No actionable merge risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: reusing initializer text for argument-free attributes as a performance optimization.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/blog-generator-work

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit finds a cache in bloom
Parameterless forms share one room
Arguments stay in their own place
Generic types keep distinct face
Tests hop through each case with grace

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Sep 12, 2026

Copy link
Copy Markdown

Greptile Summary

This PR reduces source-generator allocations by caching argument-free attribute initializer text per constructed attribute type within a compilation.

  • Reuses initializer text only for attributes with no explicit constructor or named arguments.
  • Preserves the existing per-application path for explicit and named arguments.
  • Adds regression coverage for empty argument lists, explicit and named arguments, and constructed generic attribute types.

Confidence Score: 5/5

The PR appears safe to merge; no actionable correctness, security, or repository-rule issues were identified.

The cached argument-free initializer is determined entirely by its constructed attribute-type key, while all syntax carrying per-application values bypasses the new cache.

Important Files Changed

Filename Overview
src/TUnit.Core.SourceGenerator/CodeGenerators/Writers/AttributeWriter.cs Adds a compilation-scoped cache for initializer text whose output is determined solely by the constructed attribute type.
tests/TUnit.Core.SourceGenerator.Tests/AttributeInitializerCacheTests.cs Verifies that argument-free reuse does not affect explicit or named arguments and keeps constructed generic types distinct.

Reviews (1): Last reviewed commit: "perf: reuse argument-free attribute init..." | Re-trigger Greptile

@github-actions

Copy link
Copy Markdown
Contributor

Review: perf: reuse argument-free attribute initializer text (#6788)

Small, well-targeted change. Verified the core correctness question directly against AttributeWriter.cs:

Correctness of the new cache is sound. The new _argumentFreeAttributeInitializerCache only intercepts applications where ArgumentList is null or has zero arguments (AttributeWriter.cs:70-79). For that syntactic shape, GetAttributeObjectInitializerInner never reads attributeData.ConstructorArguments -- it only joins the (empty) syntax-level argument list, producing new global::X() unconditionally. That means default parameter values, and even [CallerLineNumber]/[CallerFilePath]/[CallerMemberName] optional parameters, were already resolved by the C# compiler against the generated call site rather than baked in per original application -- true before this PR and unchanged by it. So keying the cache by INamedTypeSymbol (attribute class) instead of by AttributeData instance is a safe optimization: the output was already type-invariant for this syntactic case, never call-site-invariant in a way this PR could break.

Named/explicit arguments correctly bypass the cache. [Marker(Value = 17)] has Arguments.Count == 1 (property syntax still counts as an argument node), so it falls through to the existing per-AttributeData cache -- confirmed by the Named case in the new test.

Constructed generic attribute types are distinguished correctly. SymbolEqualityComparer.Default differentiates MarkerAttribute<int> from MarkerAttribute<string> as distinct INamedTypeSymbols, so they get separate cache entries -- covered by ConstructedAttributeTypesKeepDistinctInitializers.

Minor, non-blocking observation: AttributeWriter is constructed once per Compilation and shared across all RegisterSourceOutput invocations for that compilation (TestMetadataGenerator.cs), so this new Dictionary (like the pre-existing _attributeObjectInitializerCache and _tunitRelatedCache) isn't thread-safe. This matches existing precedent in the file rather than introducing a new risk, so it's not something this PR needs to fix, but worth keeping in mind if incremental generator execution is ever parallelized across outputs for the same compilation -- a ConcurrentDictionary (as already used in CodeWriter._indentCache) would be the fix at that point.

Tests: the two new tests (AttributeInitializerCacheTests.cs) directly exercise the risk surface this PR introduces -- omitted vs. explicit vs. named arguments, and distinct constructed generic types -- which is exactly what I'd want to see for this kind of caching change.

Nit: the diff drops the UTF-8 BOM at the top of AttributeWriter.cs. Harmless, but unrelated to the stated purpose of the PR -- worth confirming it was intentional and not an editor/tooling artifact.

No blocking issues found. The benchmark methodology described in the PR body (byte-identical output validation across cold/edited compilation runs, plus regression tests for constructor-overload/type-argument behavior) is solid support for the allocation-reduction claim.

@thomhurst
thomhurst merged commit b4c3bef into main Sep 12, 2026
14 checks passed
@thomhurst
thomhurst deleted the perf/blog-generator-work branch September 12, 2026 09:32
github-actions Bot pushed a commit to IntelliTect/CodingGuidelines that referenced this pull request Sep 14, 2026
Updated [TUnit.Core](https://github.com/thomhurst/TUnit) from 1.66.27 to
1.67.0.

<details>
<summary>Release notes</summary>

_Sourced from [TUnit.Core's
releases](https://github.com/thomhurst/TUnit/releases)._

## 1.67.0

<!-- Release notes generated using configuration in .github/release.yml
at v1.67.0 -->

## What's Changed
### Other Changes
* docs: clarified and updated attributes comparison for xUnit 3 by
@​304NotModified in thomhurst/TUnit#6774
* perf: read inline argument metadata without reflection by @​thomhurst
in thomhurst/TUnit#6778
* perf: limit converter discovery to declarations by @​thomhurst in
thomhurst/TUnit#6779
* perf: skip teardown analysis when no disposable members need cleanup
by @​thomhurst in thomhurst/TUnit#6780
* perf: avoid line allocations when writing generated source by
@​thomhurst in thomhurst/TUnit#6781
* perf: avoid formatting interface names for data-source checks by
@​thomhurst in thomhurst/TUnit#6782
* perf: skip unannotated property data-source candidates by @​thomhurst
in thomhurst/TUnit#6784
* fix: fold inner exceptions into IDE test failure output by @​thomhurst
in thomhurst/TUnit#6777
* perf: reuse argument-free attribute initializer text by @​thomhurst in
thomhurst/TUnit#6788
* perf: extract test metadata in attribute transforms by @​thomhurst in
thomhurst/TUnit#6789
* perf: skip receiver registration for ordinary objects by @​thomhurst
in thomhurst/TUnit#6790
* perf: cache reporting properties on test contexts by @​thomhurst in
thomhurst/TUnit#6791
* fix: preserve executor registration, limiter precedence, and timeout
classification by @​Nice3point in
thomhurst/TUnit#6768
### Dependencies
* chore(deps): update tunit to 1.66.27 by @​thomhurst in
thomhurst/TUnit#6742
* chore(deps): update dependency bunit to 2.10.3 by @​thomhurst in
thomhurst/TUnit#6745
* chore(deps): update dependency imposter to 0.1.11 by @​thomhurst in
thomhurst/TUnit#6744
* chore(deps): update dependency microsoft.kiota.abstractions to 2.1.2
by @​thomhurst in thomhurst/TUnit#6747
* chore(deps): update dependency microsoft.templateengine.authoring.cli
to v10.0.401 by @​thomhurst in
thomhurst/TUnit#6750
* chore(deps): update dependency fsharp.core to 10.1.401 by @​thomhurst
in thomhurst/TUnit#6748
* chore(deps): update dependency
microsoft.templateengine.authoring.templateverifier to 10.0.401 by
@​thomhurst in thomhurst/TUnit#6751
* chore(deps): update dependency system.commandline to 2.0.12 by
@​thomhurst in thomhurst/TUnit#6752
* chore(deps): update dependency dotnet-sdk to v10.0.401 by @​thomhurst
in thomhurst/TUnit#6754
* chore(deps): update microsoft.extensions to 10.0.12 by @​thomhurst in
thomhurst/TUnit#6755
* chore(deps): update microsoft.aspnetcore to 10.0.12 by @​thomhurst in
thomhurst/TUnit#6753
* chore(deps): update dependency microsoft.entityframeworkcore to
10.0.12 by @​thomhurst in thomhurst/TUnit#6749
* chore(deps): update mcr.microsoft.com/dotnet/sdk docker tag to v11 by
@​thomhurst in thomhurst/TUnit#6756
* chore(deps): update dependency microsoft.net.test.sdk to 18.10.0 by
@​thomhurst in thomhurst/TUnit#6761
* chore(deps): update microsoft.extensions to 10.10.0 by @​thomhurst in
thomhurst/TUnit#6762
* chore(deps): update react to ^19.3.0 by @​thomhurst in
thomhurst/TUnit#6763
* chore(deps): update dependency awssdk.sqs to 4.0.100.13 by @​thomhurst
in thomhurst/TUnit#6764
* chore(deps): update dependency polyfill to 11.3.0 by @​thomhurst in
thomhurst/TUnit#6765
* chore(deps): update dependency polyfill to 11.3.0 by @​thomhurst in
thomhurst/TUnit#6766
* chore(deps): update dependency stackexchange.redis to 3.2.0 by
@​thomhurst in thomhurst/TUnit#6769
* chore(deps): update dependency microsoft.net.stringtools to 18.10.1 by
@​thomhurst in thomhurst/TUnit#6771
* chore(deps): update dependency dotnet-trace to v10.0.745401 by
@​thomhurst in thomhurst/TUnit#6773
* chore(deps): bump colord from 2.9.3 to 2.10.0 in /docs by
@​dependabot[bot] in thomhurst/TUnit#6759
* chore(deps): bump joi from 17.13.4 to 17.13.7 in /docs by
@​dependabot[bot] in thomhurst/TUnit#6758
* chore(deps): bump js-yaml from 4.3.1 to 4.3.2 in /docs by
@​dependabot[bot] in thomhurst/TUnit#6757
* chore(deps): update dependency yaml to v2.9.1 by @​thomhurst in
thomhurst/TUnit#6785
* chore(deps): update verify to 32.0.1 by @​thomhurst in
thomhurst/TUnit#6786
* chore(deps): update dependency nunit.analyzers to 4.15.0 by
@​thomhurst in thomhurst/TUnit#6792

## New Contributors
* @​304NotModified made their first contribution in
thomhurst/TUnit#6774
* @​Nice3point made their first contribution in
thomhurst/TUnit#6768
 ... (truncated)

Commits viewable in [compare
view](thomhurst/TUnit@v1.66.27...v1.67.0).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=TUnit.Core&package-manager=nuget&previous-version=1.66.27&new-version=1.67.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This was referenced Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant