Skip to content

Publish Devolutions.Terminal.Control as a reusable NuGet package - #19

Merged
Marc-André Moreau (mamoreau-devolutions) merged 1 commit into
masterfrom
copilot/rdm-terminal-control-research
Sep 16, 2026
Merged

Marc-André Moreau (mamoreau-devolutions) merged 1 commit into
masterfrom
copilot/rdm-terminal-control-research

Conversation

@mamoreau-devolutions

Copy link
Copy Markdown
Contributor

Summary

Publishes Devolutions.Terminal.Control as a standalone, self-contained NuGet package on nuget.org so the Avalonia terminal control (TermControl) can be embedded in other applications (e.g. as a replacement for RDM's internal Devolutions.TerminalControl package).

Packaging approach

  • Devolutions.Terminal.Core, .Render, .Connection, and .Settings are marked IsPackable=false — they are never published as separate packages.
  • Devolutions.Terminal.Control.csproj bundles their build output directly into lib/net10.0 via a CopyProjectReferencesToPackage MSBuild target, with PrivateAssets="all" on the internal ProjectReferences so they don't leak as dangling nuspec dependencies.
  • SkiaSharp/HarfBuzzSharp PackageReferences (previously only on Render) are re-declared directly on Control.csproj since PrivateAssets="all" also cuts their transitive flow into the nuspec.
  • Package metadata: PackageId, PackageTags, PackageReadmeFile (new PACKAGE.md), PackageLicenseExpression=MIT, PackageProjectUrl, SourceLink (Microsoft.SourceLink.GitHub), symbol package (.snupkg).
  • Downstream in-repo consumers (Devolutions.Terminal.App, Devolutions.Terminal.Control.Tests, Devolutions.Terminal.Bench) needed explicit ProjectReferences added, since PrivateAssets="all" also cuts their transitive compile-time visibility to Core/Render/Connection/Settings types that used to flow through Control.

Consumer smoke test

Added samples/Devolutions.Terminal.Control.Sample — a minimal Avalonia app that consumes the package via a plain PackageReference (never ProjectReference), resolved from a local artifacts/nuget feed via package-source-mapped NuGet.Config. It's excluded from Devolutions.Terminal.slnx (it must resolve the package from a feed) and doubles as living usage documentation.

Building this sample surfaced a real API-usage issue: TermControl has no parameterless constructor usable from XAML (its constructor takes an optional ITerminalEngine), so it must be instantiated in code-behind rather than declared as a XAML element. PACKAGE.md and docs/release.md are updated to show the correct pattern.

CI

  • New nuget-pack job: packs Control.csproj, builds the sample against the freshly packed package as a smoke test, uploads .nupkg/.snupkg as a workflow artifact. Runs on every build.
  • New nuget-publish job: pushes to nuget.org via dotnet nuget push, gated on a tag push + non-dry-run release, using a NUGET_API_KEY secret on a new nuget.org GitHub Environment.
  • Both jobs use plain major-version action tags (@v4) rather than SHA pins.

Docs

  • docs/release.md: new "NuGet package (Devolutions.Terminal.Control)" section — pack command, consumption snippet, sample app, CI wiring, required secret, and rules for keeping the internal-bundling setup in sync as the project graph evolves.
  • README.md: short pointer to the published package and docs.

Verification

  • Full solution build (dotnet build Devolutions.Terminal.slnx -c Release) — 0 errors, unaffected by the new sample (excluded from the .slnx).
  • Full test suite — all passing.
  • dotnet pack src/Devolutions.Terminal.Control -c Release -o artifacts/nuget — produces a correct .nupkg/.snupkg with only genuine third-party dependencies (Avalonia, Avalonia.Skia, SkiaSharp, SkiaSharp.HarfBuzz, Linux native-asset packages) in the nuspec.
  • samples/Devolutions.Terminal.Control.Sample builds and runs successfully against the locally packed package.
  • Workflow YAML validated for syntax correctness.

Not included (out of scope)

  • Actual publish to nuget.org (requires a real NUGET_API_KEY secret + tagged release).

- Bundle Core/Render/Connection/Settings into Control's package (IsPackable=false + PrivateAssets=all + CopyProjectReferencesToPackage)
- Add package metadata, SourceLink, symbol package
- Add samples/Devolutions.Terminal.Control.Sample as a PackageReference-based consumer smoke test, wired into the nuget-pack CI job
- Add nuget-pack/nuget-publish CI jobs (nuget.org, tag-gated)
- Document packaging/consumption in docs/release.md and README.md
@mamoreau-devolutions
Marc-André Moreau (mamoreau-devolutions) merged commit 6ff58a0 into master Sep 16, 2026
17 of 18 checks passed
@mamoreau-devolutions
Marc-André Moreau (mamoreau-devolutions) deleted the copilot/rdm-terminal-control-research branch September 16, 2026 20:16

This branch was successfully deployed

1 active deployment
publish-dry-run — ee500890 Deployed Sep 16, 2026 by mamoreau-devolutions via MSI packages #120
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant