Skip to content

Use SDK NativeCompile hook for ILC publish integration#125629

Merged
sbomer merged 12 commits intodotnet:mainfrom
sbomer:sdk-nativecompile-hook
Apr 2, 2026
Merged

Use SDK NativeCompile hook for ILC publish integration#125629
sbomer merged 12 commits intodotnet:mainfrom
sbomer:sdk-nativecompile-hook

Conversation

@sbomer
Copy link
Copy Markdown
Member

@sbomer sbomer commented Mar 16, 2026

...instead of BeforeTargets/AfterTargets.

Redefine the SDK's empty NativeCompile placeholder target with the actual NativeAOT compilation pipeline, replacing the fragile BeforeTargets/AfterTargets hooks that previously sequenced ILC into the publish flow.

  • Rename ComputeLinkedFilesToPublish to NativeCompile in Publish.targets, removing AfterTargets="ComputeResolvedFilesToPublishList"
  • Remove BeforeTargets="Publish" from SetupProperties, ComputeIlcCompileInputs, and ImportRuntimeIlcPackageTarget (all reachable via DependsOnTargets chains)
  • Keep empty ComputeLinkedFilesToPublish and CopyNativeBinary for back-compat

…ILC publish integration

Redefine the SDK's empty NativeCompile placeholder target with the actual
NativeAOT compilation pipeline, replacing the fragile BeforeTargets/AfterTargets
hooks that previously sequenced ILC into the publish flow.

- Rename ComputeLinkedFilesToPublish to NativeCompile in Publish.targets,
  removing AfterTargets="ComputeResolvedFilesToPublishList"
- Remove BeforeTargets="Publish" from SetupProperties, ComputeIlcCompileInputs,
  and ImportRuntimeIlcPackageTarget (all reachable via DependsOnTargets chains)
- Keep empty ComputeLinkedFilesToPublish and CopyNativeBinary for back-compat
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates NativeAOT publish integration to use the .NET SDK’s NativeCompile hook as the primary publish pipeline entry point, replacing prior sequencing via BeforeTargets/AfterTargets to make ordering more explicit and less fragile.

Changes:

  • Redefines the SDK NativeCompile placeholder target to run the NativeAOT pipeline and update ResolvedFileToPublish.
  • Renames the prior publish hook target (ComputeLinkedFilesToPublish) out of the execution path and keeps it as an empty back-compat target.
  • Removes BeforeTargets="Publish" from several targets, relying on DependsOnTargets chains instead.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets Removes BeforeTargets="Publish" from SetupProperties and ComputeIlcCompileInputs, relying on dependency chains to run them when needed.
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets Implements NativeAOT publish integration by redefining NativeCompile; adds empty ComputeLinkedFilesToPublish for compatibility.
src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets Removes BeforeTargets="Publish" from ImportRuntimeIlcPackageTarget, relying on dependency chains.

Comment thread src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 16, 2026 19:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors NativeAOT publish integration to use the .NET SDK’s NativeCompile hook (instead of BeforeTargets/AfterTargets-based sequencing) so the ILC + native link pipeline runs at an explicit, stable point in the publish target graph.

Changes:

  • Replaces the previous ComputeLinkedFilesToPublish publish hook with an implementation of NativeCompile that runs NativeAOT compilation and updates ResolvedFileToPublish.
  • Removes BeforeTargets="Publish" from several preparatory targets so they execute via dependency chains rather than fragile publish hooks.
  • Keeps ComputeLinkedFilesToPublish (and existing CopyNativeBinary) as empty/back-compat targets.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets Stops forcing SetupProperties/ComputeIlcCompileInputs to run via BeforeTargets="Publish"; relies on existing dependency flow.
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets Implements NativeCompile as the NativeAOT publish integration point; leaves ComputeLinkedFilesToPublish as an empty compatibility target.
src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets Removes BeforeTargets="Publish" from runtime ILC pack import target to rely on dependency chains.

The test infrastructure directly imported SingleEntry.targets from
Directory.Build.targets, which is evaluated before Microsoft.NET.Sdk.targets.
This caused the SDK's empty NativeCompile placeholder (in Publish.targets)
to overwrite the NativeAOT redefinition (MSBuild last-definition-wins),
resulting in no native compilation during NativeAOT test runs.

Use AfterMicrosoftNETSdkTargets to defer the import to after all SDK
targets, matching the pattern already used for ReadyToRun targets in
tests.singlefile.targets.
Copy link
Copy Markdown
Member

@agocke agocke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good except the stuff about AfterMicrosoftNETSdkTargets -- I'm not sure I understand well enough what's going on there to say whether or not it's correct.

@sbomer
Copy link
Copy Markdown
Member Author

sbomer commented Mar 16, 2026

The import order is:

  1. This repo's test build targets (which used to directly import the SingleEntry.targets, eventually defining the NativeCompile target)
  2. SDK targets that define empty NativeCompile target
  3. NuGet package targets

We needed a way to ensure the repo testing imports SingleEntry.targets after the empty NativeCompile target is defined, like what happens in the nuget flow. Hopefully using AfterMicrosoftNETSdkTargets to delay the import doesn't cause other ordering issues...

… load

Deferring the ILC import via AfterMicrosoftNETSdkTargets also deferred
the PublishTrimmed=true that Microsoft.NETCore.Native.targets sets at
evaluation time. This caused liveILLink.targets to compute
_RequiresLiveILLink=false (since PublishTrimmed was not yet set),
so ILLink targets were never loaded, and _PrepareTrimConfiguration
was missing at build time.

Set PublishTrimmed=true explicitly in the NativeAOT test PropertyGroups
before liveILLink.targets is imported. NativeAOT always enables trimming,
so this is semantically correct.
Copilot AI review requested due to automatic review settings March 16, 2026 23:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Switches NativeAOT publish integration to use the SDK’s NativeCompile placeholder hook instead of BeforeTargets/AfterTargets, improving sequencing reliability in the publish pipeline.

Changes:

  • Redefines NativeCompile to run the NativeAOT compilation/linking pipeline and updates publish items accordingly.
  • Removes BeforeTargets="Publish" hooks from several NativeAOT targets, relying on dependency chains instead.
  • Defers importing ILC targets via AfterMicrosoftNETSdkTargets and sets PublishTrimmed earlier to ensure trim configuration targets are available.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/tests/Directory.Build.targets Defers ILC target import via AfterMicrosoftNETSdkTargets and sets PublishTrimmed early for NativeAOT test builds.
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets Removes BeforeTargets="Publish" from NativeAOT setup/inputs targets.
src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets Moves publish integration work into NativeCompile, leaving an empty ComputeLinkedFilesToPublish for back-compat.
src/coreclr/nativeaot/BuildIntegration/Microsoft.DotNet.ILCompiler.SingleEntry.targets Removes BeforeTargets="Publish" from runtime pack import target.
eng/testing/tests.singlefile.targets Defers ILC import via AfterMicrosoftNETSdkTargets and sets PublishTrimmed early for single-file NativeAOT tests.

Comment thread src/tests/Directory.Build.targets Outdated
Comment thread eng/testing/tests.singlefile.targets Outdated
Comment thread eng/testing/tests.singlefile.targets Outdated
@steveisok
Copy link
Copy Markdown
Member

@sbomer I believe this should fix the forward flow build failure in dotnet/dotnet#5506, correct?

@sbomer
Copy link
Copy Markdown
Member Author

sbomer commented Mar 17, 2026

No, that's not the intention (though it might help) - I think that needs a separate fix.

Copilot AI review requested due to automatic review settings March 23, 2026 21:20
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread src/tests/Directory.Build.targets
Comment thread eng/testing/tests.singlefile.targets
@MichalStrehovsky
Copy link
Copy Markdown
Member

The failures in the _Bootstrapped legs look related

…builds

Replace the direct <Import> of ILC targets with the SDK's ILCompilerTargetsPath
hook, fixing bootstrap builds where the SDK's empty NativeCompile placeholder
was overriding the ILC NativeCompile target. Also set _IlcReferencedAsPackage
to skip NuGet package resolution and remove the unnecessary RID-swapping
workaround (all affected projects already use PortableTargetRid).
@sbomer
Copy link
Copy Markdown
Member Author

sbomer commented Mar 31, 2026

/azp run runtime-extra-platforms

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@sbomer
Copy link
Copy Markdown
Member Author

sbomer commented Apr 1, 2026

@MichalStrehovsky PTAL, I think this is ready to go.

Copy link
Copy Markdown
Member

@MichalStrehovsky MichalStrehovsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thank you! Fingers crossed propagating this across repos will be smooth sailing.

@sbomer sbomer enabled auto-merge (squash) April 2, 2026 16:28
@sbomer
Copy link
Copy Markdown
Member Author

sbomer commented Apr 2, 2026

/ba-g "Only unknown failure is unrelated failure in runtime-extra-platforms"

@sbomer sbomer merged commit f15d677 into dotnet:main Apr 2, 2026
193 of 237 checks passed
@github-project-automation github-project-automation Bot moved this to Done in AppModel Apr 2, 2026
radekdoulik pushed a commit to radekdoulik/runtime that referenced this pull request Apr 9, 2026
...instead of BeforeTargets/AfterTargets.

Redefine the SDK's empty NativeCompile placeholder target with the
actual NativeAOT compilation pipeline, replacing the fragile
BeforeTargets/AfterTargets hooks that previously sequenced ILC into the
publish flow.

- Rename ComputeLinkedFilesToPublish to NativeCompile in
Publish.targets, removing
AfterTargets="ComputeResolvedFilesToPublishList"
- Remove BeforeTargets="Publish" from SetupProperties,
ComputeIlcCompileInputs, and ImportRuntimeIlcPackageTarget (all
reachable via DependsOnTargets chains)
- Keep empty ComputeLinkedFilesToPublish and CopyNativeBinary for
back-compat

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
jonathanpeppers added a commit to dotnet/android that referenced this pull request Apr 15, 2026
dotnet/runtime#125629 moved the NativeAOT entry point from
ComputeLinkedFilesToPublish (AfterTargets=ComputeResolvedFilesToPublishList)
to NativeCompile (an SDK Publish hook). Since Android uses 'dotnet build'
rather than 'dotnet publish', NativeCompile was never invoked and
IlcCompile/LinkNative never ran.

Add NativeCompile to the _AfterCompileDex hook so the ILC pipeline
executes during Build.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit to dotnet/android that referenced this pull request Apr 15, 2026
dotnet/runtime#125629 moved the NativeAOT entry point from
ComputeLinkedFilesToPublish (AfterTargets=ComputeResolvedFilesToPublishList)
to NativeCompile (an SDK Publish hook). Since Android uses 'dotnet build'
rather than 'dotnet publish', NativeCompile was never invoked and
IlcCompile/LinkNative never ran.

Add _AndroidRunNativeCompile with AfterTargets=ComputeResolvedFilesToPublishList
to restore the old scheduling. This runs in the inner per-RID build
(via _ComputeFilesToPublishForRuntimeIdentifiers) where RuntimeIdentifier
is set, matching the original ComputeLinkedFilesToPublish behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit to dotnet/android that referenced this pull request Apr 15, 2026
Changes: dotnet/dotnet@d702068...b94d039

- **Dependency Updates**:
  - From [11.0.0-beta.26179.102 to 11.0.0-beta.26214.103][3]
     - Microsoft.DotNet.Build.Tasks.Feed
  - From [0.11.5-preview.26179.102 to 0.11.5-preview.26214.103][3]
     - Microsoft.DotNet.Cecil
  - From [11.0.0-preview.3.26179.102 to 11.0.0-preview.4.26214.103][3]
     - Microsoft.NET.ILLink
     - Microsoft.NETCore.App.Ref
  - From [11.0.100-preview.3.26179.102 to 11.0.100-preview.4.26214.103][3]
     - Microsoft.NET.Sdk
     - Microsoft.TemplateEngine.Authoring.Tasks
  - From [11.0.100-preview.4.26210.111 to 11.0.100-preview.4.26214.103][4]
     - Microsoft.NET.Workload.Emscripten.Current.Manifest-11.0.100-preview.4
     - Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest-11.0.100-preview.4

[3]: dotnet/dotnet@d702068...b94d039
[4]: dotnet/dotnet@5bed449...b94d039

### Other Changes

Manually updated version bands.

* `darc update-dependencies --id 309919`

### Fix NativeAOT builds after dotnet/runtime#125629

dotnet/runtime#125629 moved the NativeAOT entry point from
ComputeLinkedFilesToPublish (AfterTargets=ComputeResolvedFilesToPublishList)
to NativeCompile (an SDK Publish hook). Since Android uses 'dotnet build'
rather than 'dotnet publish', NativeCompile was never invoked and
IlcCompile/LinkNative never ran.

Add _AndroidRunNativeCompile with AfterTargets=ComputeResolvedFilesToPublishList
to restore the old scheduling. This runs in the inner per-RID build
(via _ComputeFilesToPublishForRuntimeIdentifiers) where RuntimeIdentifier
is set, matching the original ComputeLinkedFilesToPublish behavior.

Co-authored-by: Jonathan Peppers <jonathan.peppers@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sbomer added a commit that referenced this pull request Apr 21, 2026
…em from publish output (#127089)

NativeAOT publish was leaking satellite `.dll` files from NuGet packages
into the publish directory and failing to pass them to ILC via
`--satellite:` (required for resource embedding at link time).

**Root cause:** `ComputeManagedAssembliesToCompileToNative` classified
satellites by PE-inspecting items flagged `PostprocessAssembly=true`.
The SDK never sets this metadata on resource items
(`AssetType=resources`), so the satellite branch was dead code —
`SatelliteAssemblies` output was always empty. PR #111514 introduced
this regression; PR #124192 partially fixed project-own satellites via
`IntermediateSatelliteAssembliesWithTargetPath` but left the package
case broken.

## Changes

**`Microsoft.NETCore.Native.Publish.targets`**
- Populate `IlcSatelliteAssembly` via
`Condition="'%(ResolvedFileToPublish.AssetType)' == 'resources'"`
(package satellites) in addition to the existing
`IntermediateSatelliteAssembliesWithTargetPath` (project satellites)
- Replace `Remove="@(IntermediateSatelliteAssembliesWithTargetPath)"`
with `Remove="@(IlcSatelliteAssembly)"` so both package and project
satellites are pruned from `ResolvedFileToPublish`
- Drop the now-unused `<Output TaskParameter="SatelliteAssemblies" ...>`
wire-up

**`ComputeManagedAssembliesToCompileToNative.cs`**
- Remove dead `SatelliteAssemblies` `[Output]` property, PE-reading
culture classification loop, `PostprocessAssembly` guard block, and the
now-unused `System.Reflection.Metadata` /
`System.Reflection.PortableExecutable` usings (~45 lines removed, none
of it ever ran)

# Customer Impact

NativeAOT apps that reference NuGet packages containing satellite
assemblies (e.g. `System.CommandLine`) would fail to resolve localized
resources at runtime and would have stray `.dll` files in the publish
output, defeating the single-file native binary guarantee.

# Regression

Yes — regressed in PR #111514 ("Run ILC after
ComputeResolvedFilesToPublishList"). PR #124192 closed the gap for
project-own satellites but missed package satellites.

# Testing

End-to-end validated with a repro app (`PublishAot=true`,
`System.CommandLine 2.0.6` package dependency, project `Strings.resx` +
`Strings.es.resx`): publish output is clean (only native binary + debug
symbols), ILC receives the expected `--satellite:` arguments for all
cultures, and runtime correctly resolves `es`/`de`/`ja` resources from
both package and project sources.

# Risk

Low. The targets change is purely additive for the satellite item
population and replaces a narrower `Remove` with a broader one that is a
strict superset of the previous behavior. The task change removes code
that was provably never executed under the current SDK contract.

# Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet
package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older
versions.

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

<analysis>
Chronological review:
1. User asked to read dotnet/runtime PR #124192 + related SDK issue
comments
2. Asked for a repro in /tmp
3. Asked to root cause
4. Asked for logging / both app and package resources in repro
5. Asked about runtime behavior
6. Asked how SDK populates ResolvedFileToPublish
7. Asked what gets passed as --satellite
8. Asked to fix
9. Asked if I tested
10. Asked about task's satellite filtering being moot → led to cleanup
11. Asked about `_IlcReferenceSatelliteAssemblies` naming → kept
(consistency)
12. Then asked: "What if we consider IlcSatelliteAssembly to be the
snapshot?" → simplified to inline include +
`Remove="@(IlcSatelliteAssembly)"`
13. Asked to remove two comments
14. Asked to re-test
15. Asked to commit → committed as `e765e126dcb`
16. Most recent: asked "Why weren't we passing satellites, did that
regress at some point?" → I investigated git history, found PR #111514
was the regression point.

Recent commands and results:
- `git log --oneline --all -S 'SatelliteAssemblies'` on task file →
found b134fa2 (#86689, 2023, MichalStrehovsky, original satellite
support)
- `git show b134fa2` → showed original implementation: task read ALL
items, PE-inspected, classified by Culture
- `git log --oneline --all -S 'PostprocessAssembly'` → found e144870
"Skip non-PostprocessAssembly files..." (Feb 17 2026) and a5cee7c
"Derive ILC inputs from ResolvedFileToPublish..." (Feb 25 2026), both by
Sven Boemer
- `git log --all --oneline --ancestry-path` → showed these were part of
branch ilc-compile-order / ilcPublish
- `git log main --grep='Run ILC after'` → confirmed squash-merged as
`44e21b71149 Run ILC after ComputeResolvedFilesToPublishList (#111514)`

Final answer given: PR #111514 regressed satellite passing. Original PR
#86689 (2023) worked. PR #124192 partially fixed project-own case. This
commit closes package case.

Commit created: e765e126dcb on branch satellite-fix, not pushed.
</analysis>

<summary>
1. Conversation Overview:
- Primary Objectives: Investigate dotnet/runtime PR #124192 /
dotnet/sdk#53422 regression where NativeAOT publish leaks package
satellite `.dll` files AND fails to embed them via ILC. Root-cause, fix,
validate, commit.
- Session Context: Progressed through reading comments → repro → root
cause → logging → SDK trace → fix implementation → code review/cleanup
iterations → test → commit → regression history.
- User Intent Evolution: From fixing the surface bug to cleaning up dead
code, then simplifying the fix (inlining `IlcSatelliteAssembly` as the
snapshot), then historical attribution.

2. Technical Foundation:
- .NET 11 preview 3 SDK (`11.0.100-preview.3.26172.108`) pinned via
global.json in the repro
- NativeAOT publish pipeline: `_ComputeIlcCompileInputs` →
`NativeCompile` (post PR #125629 at HEAD) /
`ComputeLinkedFilesToPublish` (pre #125629 in installed SDK)
- SDK `_ComputeAssembliesToPostprocessOnPublish` deliberately excludes
satellites from `PostprocessAssembly=true` metadata
- Package/ref satellites land in `ResolvedFileToPublish` with
`AssetType=='resources'`; project's own satellites arrive via
`IntermediateSatelliteAssembliesWithTargetPath`
- `IlcSatelliteAssembly` item → `--satellite:` ILC args (required for
embedding; NAOT can't load from disk)

3. Codebase Status:
-
`/home/sven/src/satellite-fix/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets`:
- Changed `<IlcSatelliteAssembly
Include="@(_SatelliteAssembliesToPublish)" />` to `<IlcSatelliteAssembly
Include="@(ResolvedFileToPublish)"
Condition="'%(ResolvedFileToPublish.AssetType)' == 'resources'" />`
- Changed `<ResolvedFileToPublish
Remove="@(IntermediateSatelliteAssembliesWithTargetPath)" />` to
`<ResolvedFileToPublish Remove="@(IlcSatelliteAssembly)" />`
- Dropped `<Output TaskParameter="SatelliteAssemblies"
ItemName="_SatelliteAssembliesToPublish" />`
-
`/home/sven/src/satellite-fix/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs`:
- Removed `SatelliteAssemblies` `[Output]` property, PE-reading culture
classification, `PostprocessAssembly` late-filter check,
`System.Reflection.Metadata`/`PortableExecutable` usings
     - Net −45 lines; +3/−3 on targets file
- Repro at `/tmp/aot-satellite-repro/app/` with diagnostic dump targets,
`PublishAot=true`, `System.CommandLine 2.0.6`,
`Strings.resx`+`Strings.es.resx`

4. Problem Resolution:
- Root cause: Task's classification logic gated on
`PostprocessAssembly=true` which SDK never sets on satellites, making
satellite branch unreachable
- Fix: Classify via `AssetType=='resources'` in MSBuild directly; use
`IlcSatelliteAssembly` as snapshot consumed by both ILC and the
`ResolvedFileToPublish` remove
- Dead code cleanup: task's `SatelliteAssemblies` output never produced
anything under current SDK contract

5. Progress Tracking:
   - Completed: investigation, repro, fix, cleanup, end-to-end val...

</details>

Adding a test for this in dotnet/sdk#53971.

<!-- START COPILOT CODING AGENT SUFFIX -->

Created from Copilot CLI via the copilot delegate command.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants