Skip to content

Feature/meadow v3 deployment - #651

Merged
adrianstevens merged 11 commits into
developfrom
feature/meadow-v3-deployment
May 11, 2026
Merged

adrianstevens merged 11 commits into
developfrom
feature/meadow-v3-deployment

Conversation

@adrianstevens

Copy link
Copy Markdown
Contributor

No description provided.

alexischr and others added 10 commits March 27, 2026 02:23
…rimming

Meadow OS 3.x moves to MonoVM + .NET 10/11 with System.Private.CoreLib
instead of legacy Mono's mscorlib. New projects use .NET's built-in publish
trimming, eliminating the need for custom ILLink. This adds a clean,
separate V3 deployment path (AppManagerV3) that can coexist with the
legacy 2.x code until it's ready to be removed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…line

At publish time, a temp .targets file is generated and passed via
CustomAfterMicrosoftCommonTargets. It hooks BeforeTargets="_ComputeManagedAssemblyToLink"
to swap standard .NET runtime assemblies with Meadow's custom BCL
(System.Private.CoreLib, etc.) in ResolvedFileToPublish, so the built-in
trimmer links against the Meadow BCL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
For V3 app deploy with netstandard2.1 projects that have no publish/
output, the CLI now automatically runs dotnet publish with:
- PublishTrimmed=true (forced via -p:)
- TFM override to bypass NETSDK1124 (.NET 3.0 requirement)
- Meadow.dll as entry point root (App.dll is a library)
- Meadow BCL assembly injection

Also removes leftover [HCOM-DBG] Console.Error.WriteLine diagnostic
lines from SocketConnection, and bumps package version to 2.6.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When GetAvailableBuiltConfigurations finds App.dll inside an existing
publish/ directory, appFile.DirectoryName already ends with "publish".
Appending "/publish" again caused deployment from a nested path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…projects

- Use --self-contained -r linux-arm so the trimmer includes BCL assemblies,
  which the injected MSBuild targets then swap for Meadow's custom BCL
- Move PublishTrimmed into the targets file (not -p:) so it doesn't cascade
  to netstandard2.1 referenced projects and trigger NETSDK1124
- Detect legacy projects (netstandard/netcoreapp) and only apply TFM
  override for those, avoiding Microsoft.NET.Build.Containers.targets errors
- Suppress trim analysis warnings (IL2062 etc.) from referenced libraries
- Filter native runtime files (.so, .dylib, extensionless binaries) from
  deploy — Meadow has its own runtime, doesn't need libcoreclr.so etc.
- Filter runtimes/ subdirectory from deploy output
- Allow callers to specify PublishDir to control output location
- Version bump to 2.6.7

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…fter trimming

The _InjectMeadowAssemblies target was running too early (BeforeTargets
_ComputeManagedAssemblyToLink), so self-contained runtime pack assemblies
were resolved after injection and overrode Meadow's custom BCL. Now runs
AfterTargets ComputeFilesToPublish so all runtime assemblies are resolved
first. Added _CleanupMeadowAssembliesAfterTrimming to remove untrimmed
Meadow originals after ILLink produces trimmed versions, avoiding
NETSDK1152 duplicate publish output conflicts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Contains overload

CliFx 3.0 dropped CliFx.Attributes; the floating Version="*" was resolving to
3.0 and breaking compilation. Pin to "2.*" to stay on the 2.x API.

Contains(string, StringComparison) was added in netstandard2.1; Meadow.Tooling.Core
multi-targets netstandard2.0 and net8.0, so the netstandard2.0 build failed.
Use IndexOf with StringComparison instead, which is available in netstandard2.0.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…aced publish errors

* Read TargetFramework from csproj when computing PublishDir on clean builds —
  previously fell back to bin/Release/publish/ without the TFM segment, leading to
  bin/Release/publish/publish on the next deploy. Now correctly produces
  bin/Release/<tfm>/publish/.
* Always re-publish on V3 deploys so the Meadow BCL injection always runs (the
  prior "skip if publish dir exists" path could deploy stale output).
* Capture stderr from `dotnet publish` and log full output via LogError on
  failure, replacing silent failures with surfaced build text.
* Trimmer pipeline now picks up an ILLink.Descriptors.xml dropped alongside the
  Meadow BCL when the firmware bundles one — preserves only Mono-required
  CoreLib types and lets the trimmer shrink CoreLib. Falls back to rooting the
  whole assembly when the file is absent (current 4.8MB behavior).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds Meadow OS v3+ deployment support by switching build/deploy flows to dotnet publish with an injected MSBuild targets file to enable trimming and swap in Meadow’s custom BCL assemblies, while keeping the existing Meadow v2.x build + custom ILLink trimming path intact.

Changes:

  • Introduces v3 OS detection (MeadowVersion) and routes app run, app deploy, and cloud package create through a new publish-based pipeline for v3+.
  • Adds IBuildManager.PublishApplication(...) and implements it in BuildManager to run dotnet publish with Meadow-specific trimming/BCL injection targets.
  • Adds a v3-specific deploy implementation (AppManagerV3) and removes some temporary HCOM debug Console.Error logging.

Reviewed changes

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

Show a summary per file
File Description
Source/Meadow.Tooling.Core/App/MeadowVersion.cs Adds OS version parsing helper to detect v3+ behavior.
Source/Meadow.Tooling.Core/App/IBuildManager.cs Extends build interface with PublishApplication for v3+ publish flow.
Source/Meadow.Tooling.Core/App/BuildManager.cs Implements dotnet publish path, injecting MSBuild targets for trimming + Meadow BCL substitution.
Source/Meadow.Tooling.Core/App/AppManagerV3.cs New deploy manager that deploys all publish output files (excluding runtime natives).
Source/Meadow.HCom/Connections/SocketConnection.ListenerProc.cs Removes noisy debug Console.Error prints.
Source/Meadow.HCom/Connections/SocketConnection.cs Removes noisy debug Console.Error prints during file writes.
Source/Meadow.CLI/Properties/AssemblyInfo.cs Bumps CLI version constant.
Source/Meadow.CLI/Meadow.CLI.csproj Bumps package version and constrains CliFx package reference.
Source/Meadow.CLI/Commands/Cloud/Package/CloudPackageCreateCommand.cs Uses publish output as packaging source for v3+; keeps trim flow for v2.x.
Source/Meadow.CLI/Commands/App/AppTrimCommand.cs Skips custom trimming for v3+ with guidance to use publish/run instead.
Source/Meadow.CLI/Commands/App/AppRunCommand.cs Builds via publish for v3+ and deploys from publish output; keeps v2.x build+trim.
Source/Meadow.CLI/Commands/App/AppDeployCommand.cs For v3+, forces publish (with BCL injection) before deploying publish output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if (needsTfmOverride)
{
args += $" -p:TargetFrameworkIdentifier=.NETCoreApp" +
$" -p:TargetFrameworkVersion=v10.0";
Comment on lines +146 to +154
if (MeadowVersion.IsV3OrLater(deviceInfo.OsVersion))
{
// For 3.x, dotnet publish outputs to a publish/ subfolder with trimmed assemblies
var publishDir = System.IO.Path.Combine(file.DirectoryName!, "publish");
if (!Directory.Exists(publishDir))
{
Logger?.LogError($"Cannot find publish output at '{publishDir}'. Ensure the project published successfully.");
return false;
}
Comment on lines +63 to +68
var buildPath = GetAppBuildPath(projectPath);
var publishDir = Path.Combine(buildPath, "publish");
if (!Directory.Exists(publishDir))
{
throw new CommandException($"Cannot find publish output at '{publishDir}'", CommandExitCode.GeneralError);
}
Comment on lines +104 to +110
Logger?.LogInformation("Publishing with Meadow BCL injection and trimming...");

var csproj = Directory.GetFiles(projectPath, "*.csproj").FirstOrDefault();
var publishPath = csproj ?? projectPath;

var file = candidates.OrderByDescending(c => c.LastWriteTime).First();
if (!_buildManager.PublishApplication(publishPath, osVersion, Configuration ?? "Release", clean: false, publishDir: publishDir + System.IO.Path.DirectorySeparatorChar))
{
Comment thread Source/Meadow.CLI/Meadow.CLI.csproj Outdated

<ItemGroup>
<PackageReference Include="CliFx" Version="*" />
<PackageReference Include="CliFx" Version="2.*" />
* AppRunCommand & CloudPackageCreateCommand: apply the same publish/publish
  guard already present in AppDeployCommand. After dotnet publish,
  GetAvailableBuiltConfigurations returns App.dll inside publish/ — appending
  another "publish" segment produced bin/Release/<tfm>/publish/publish.
* AppDeployCommand: walk up from the chosen App.dll's directory to find a
  csproj. Previously Directory.GetFiles(projectPath, "*.csproj") threw when
  the user passed a file path (App.dll) instead of a directory.
* BuildManager: detect the highest installed .NET SDK major version via
  `dotnet --list-sdks` for the legacy-project TFM override, instead of
  hard-coding v10.0. .NET is backwards-compatible, so the newest installed
  SDK is the safest target.
* CliFx: pin to 2.3.6 (was floating 2.*) for reproducible builds.
* Version bump to 3.0.0-beta1. Adds CLI_INFORMATIONAL_VERSION constant so
  the package carries the pre-release tag while AssemblyVersion stays a
  valid four-part numeric.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@adrianstevens
adrianstevens merged commit 7f4c8ac into develop May 11, 2026
1 check passed
@adrianstevens
adrianstevens deleted the feature/meadow-v3-deployment branch May 11, 2026 19:35
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.

3 participants