diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6e7a487..e1dc1f7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,8 +89,10 @@ jobs: } "rid=$rid" | Out-File -FilePath $env:GITHUB_OUTPUT -Append $ErrorActionPreference = 'Stop' - Write-Host "Packing WhatsBox pointer + WhatsBox.$rid into bin/ before WhatsDemo restore" + Write-Host "Packing Inbox + WhatsBox pointer + WhatsBox.$rid into bin/ before WhatsDemo restore" # GeneratePackageOnBuild=true makes `dotnet pack` skip Build (NU5026: WhatsBox.dll missing). + dotnet pack src/Inbox/Inbox.csproj -c $env:Configuration -p:GeneratePackageOnBuild=false -bl:inbox-pack.binlog + if ($LASTEXITCODE -ne 0) { throw "Inbox pack failed with exit code $LASTEXITCODE." } dotnet pack src/WhatsBox/WhatsBox.csproj -c $env:Configuration -p:GeneratePackageOnBuild=false -bl:pointer-pack.binlog if ($LASTEXITCODE -ne 0) { throw "WhatsBox pointer pack failed with exit code $LASTEXITCODE." } dotnet pack src/WhatsBox/WhatsBox.csproj -c $env:Configuration -r $rid -p:GeneratePackageOnBuild=false -bl:"pack-$rid.binlog" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3ae4cf2..750cb49 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -55,6 +55,8 @@ jobs: - name: 📦 pack run: | $ErrorActionPreference = 'Stop' + dotnet pack src/Inbox/Inbox.csproj -c $env:Configuration -p:GeneratePackageOnBuild=false -bl:"inbox-pack.binlog" + if ($LASTEXITCODE -ne 0) { throw "Inbox pack failed with exit code $LASTEXITCODE." } dotnet pack src/WhatsBox/WhatsBox.csproj -c $env:Configuration -p:GeneratePackageOnBuild=false -bl:"pointer-pack.binlog" if ($LASTEXITCODE -ne 0) { throw "WhatsBox pointer pack failed with exit code $LASTEXITCODE." } dotnet pack src/WhatsBox/WhatsBox.csproj -c $env:Configuration -r ${{ matrix.rid }} -p:GeneratePackageOnBuild=false -bl:"pack-${{ matrix.rid }}.binlog" @@ -115,7 +117,9 @@ jobs: } $rid = "$os-$cpu" $ErrorActionPreference = 'Stop' - Write-Host "Packing WhatsBox pointer + WhatsBox.$rid into bin/ before WhatsDemo restore" + Write-Host "Packing Inbox + WhatsBox pointer + WhatsBox.$rid into bin/ before WhatsDemo restore" + dotnet pack src/Inbox/Inbox.csproj -c $env:Configuration -p:GeneratePackageOnBuild=false -bl:inbox-pack.binlog + if ($LASTEXITCODE -ne 0) { throw "Inbox pack failed with exit code $LASTEXITCODE." } dotnet pack src/WhatsBox/WhatsBox.csproj -c $env:Configuration -p:GeneratePackageOnBuild=false -bl:pointer-pack.binlog if ($LASTEXITCODE -ne 0) { throw "WhatsBox pointer pack failed with exit code $LASTEXITCODE." } dotnet pack src/WhatsBox/WhatsBox.csproj -c $env:Configuration -r $rid -p:GeneratePackageOnBuild=false -bl:"pack-$rid.binlog" @@ -130,6 +134,8 @@ jobs: - name: 📦 pointer run: | $ErrorActionPreference = 'Stop' + dotnet pack src/Inbox/Inbox.csproj -c $env:Configuration -p:GeneratePackageOnBuild=false -bl:inbox-pack.binlog + if ($LASTEXITCODE -ne 0) { throw "Inbox pack failed with exit code $LASTEXITCODE." } dotnet pack src/WhatsBox/WhatsBox.csproj -c $env:Configuration -p:GeneratePackageOnBuild=false -bl:pointer-pack.binlog if ($LASTEXITCODE -ne 0) { throw "WhatsBox pointer pack failed with exit code $LASTEXITCODE." } dotnet pack src/WhatsDemo/WhatsDemo.csproj -c $env:Configuration -p:GeneratePackageOnBuild=false -bl:pointer-pack-wd.binlog @@ -140,6 +146,7 @@ jobs: with: name: package-pointer path: | + bin/Inbox.*.nupkg bin/WhatsBox.*.nupkg bin/wd.*.nupkg retention-days: 30 diff --git a/readme.md b/readme.md index 25be1a9..ee487c6 100644 --- a/readme.md +++ b/readme.md @@ -57,7 +57,11 @@ Target framework: `net10.0`. The managed surface is AOT-compatible (source-gener You only reference `WhatsBox`. Restore and `dotnet publish -r ` pull the matching `WhatsBox.{rid}` package automatically. The sidecar lands next to the app (`AppContext.BaseDirectory`); `WhatsBoxClient` starts it from there — never -from the current working directory. +from the current working directory. The pointer package depends on [`Inbox`](https://www.nuget.org/packages/Inbox) +(`InboxClient`); Inbox's RID packing targets are **not** transitive. + +Adapters for other products PackageReference `Inbox` directly (or ProjectReference +it and import `Inbox.targets`) so pointer + `dotnet pack -r` packaging is shared. ```bash dotnet add package WhatsBox diff --git a/src/Inbox/Inbox.csproj b/src/Inbox/Inbox.csproj index 41069a5..2f6cfaf 100644 --- a/src/Inbox/Inbox.csproj +++ b/src/Inbox/Inbox.csproj @@ -1,13 +1,29 @@ net10.0 + Inbox Inbox Inbox - Managed reference client for an Inbox Protocol-implementation CLI (JSON-RPC 2.0, NDJSON over stdio). + Managed reference client for an Inbox Protocol-implementation CLI (JSON-RPC 2.0, NDJSON over stdio), plus RID packing targets for native adapters. true - false + + + + + + + + + + + + + + + + diff --git a/src/Inbox/build/Inbox.targets b/src/Inbox/build/Inbox.targets new file mode 100644 index 0000000..7311c6c --- /dev/null +++ b/src/Inbox/build/Inbox.targets @@ -0,0 +1,81 @@ + + + + true + $(PackageId) + + + + + $(NoWarn);NU5128 + true + false + true + $(InboxPackageId).$(RuntimeIdentifier) + $(TargetsForTfmSpecificContentInPackage);PackInboxNativeBinary + + + + + + + + + <_InboxRuntimeJson>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)runtime.json')) + + + <_InboxRid Include="$(RuntimeIdentifiers)" /> + + + + + + + + + + + + + + + + + <_InboxNativeTargetPath Condition="'$(InboxNativeName)' != ''">$(InboxNativeName) + <_InboxNativeTargetPath Condition="'$(_InboxNativeTargetPath)' == ''">$([System.IO.Path]::GetFileName($(InboxNativeBinary))) + + + + PreserveNewest + PreserveNewest + $(_InboxNativeTargetPath) + false + false + + + + + + + + + runtimes/$(RuntimeIdentifier)/native/ + + + + diff --git a/src/Inbox/readme.md b/src/Inbox/readme.md new file mode 100644 index 0000000..624e9a5 --- /dev/null +++ b/src/Inbox/readme.md @@ -0,0 +1,28 @@ +The [`Inbox`](https://www.nuget.org/packages/Inbox) package is the managed +**Inbox Protocol** client (`InboxClient`) plus non-transitive MSBuild targets +for adapters that ship a native sidecar. + +```xml + +``` + +Apps that only want WhatsApp should PackageReference `WhatsBox` instead — these +targets are **not** transitive. + +## Adapter packing + +`Inbox.targets` is imported only by a **direct** reference (nupkg `build/`, not +`buildTransitive/`). In this repo, `WhatsBox` ProjectReferences Inbox and +imports the file by hand. + +Pointer + RID packing is **opt-in**. Declare `RuntimeIdentifiers` on the adapter +(and set `InboxNativeBinary`). Without that property, Inbox packs as a plain +managed library — no `runtime.json`, no `PackageId` suffix, no native RID assets. + +The adapter: + +1. Sets `RuntimeIdentifiers` and builds its native binary (`InboxNativeBinary`, + optionally `InboxNativeName`, `InboxPackNativeDependsOn`, + `InboxIncludeNativeAfterTargets`). +2. Packs the pointer: `dotnet pack` → adapter DLL + `runtime.json`. +3. Packs each RID: `dotnet pack -r {rid}` → `runtimes/{rid}/native/` only. diff --git a/src/Tests/WhatsBoxPackTests.cs b/src/Tests/WhatsBoxPackTests.cs index a8324e8..d7ffd6e 100644 --- a/src/Tests/WhatsBoxPackTests.cs +++ b/src/Tests/WhatsBoxPackTests.cs @@ -39,7 +39,7 @@ public void ResolveBinaryPath_finds_project_reference_native_and_version_runs() } [Fact] - public void WriteWhatsBoxRuntimeJson_maps_six_rids_to_rid_packages() + public void WriteInboxRuntimeJson_maps_six_rids_to_rid_packages() { var repo = FindRepoRoot(); var project = Path.Combine(repo, "src", "WhatsBox", "WhatsBox.csproj"); @@ -61,7 +61,7 @@ public void WriteWhatsBoxRuntimeJson_maps_six_rids_to_rid_packages() start.ArgumentList.Add("msbuild"); start.ArgumentList.Add(project); start.ArgumentList.Add("-restore"); - start.ArgumentList.Add("-t:WriteWhatsBoxRuntimeJson"); + start.ArgumentList.Add("-t:WriteInboxRuntimeJson"); start.ArgumentList.Add("-p:Configuration=" + configuration); start.ArgumentList.Add("-p:DesignTimeBuild=true"); start.ArgumentList.Add("-p:GeneratePackageOnBuild=false"); @@ -98,22 +98,46 @@ public void Pointer_and_rid_csproj_use_calc_pack_split() var slnx = File.ReadAllText(Path.Combine(repo, "WhatsBox.slnx")); Assert.Contains("src/Inbox/Inbox.csproj", slnx); var inbox = File.ReadAllText(Path.Combine(repo, "src", "Inbox", "Inbox.csproj")); + Assert.Contains("Inbox", inbox); Assert.Contains("Inbox", inbox); Assert.Contains("Inbox", inbox); + Assert.Contains(@"PackagePath=""build\Inbox.targets""", inbox); + Assert.Contains(@"false", inbox); Assert.DoesNotContain("whatsbox.exe", inbox, StringComparison.OrdinalIgnoreCase); + + var targets = File.ReadAllText(Path.Combine(repo, "src", "Inbox", "build", "Inbox.targets")); + Assert.Contains("true", targets); + Assert.Contains("buildTransitive", targets); + Assert.Contains("Condition=\"'$(RuntimeIdentifiers)' != ''\"", targets); + Assert.Contains("$(InboxPackageId).$(RuntimeIdentifier)", targets); + Assert.Contains("WriteInboxRuntimeJson", targets); + Assert.Contains("PackInboxNativeBinary", targets); + Assert.DoesNotContain("go build", targets, StringComparison.OrdinalIgnoreCase); + Assert.DoesNotContain("whatsbox.exe", targets, StringComparison.OrdinalIgnoreCase); + Assert.DoesNotContain("WhatsBox", csproj); Assert.Contains(@"..\Inbox\Inbox.csproj", csproj); - Assert.Contains("WhatsBox.$(RuntimeIdentifier)", csproj); - Assert.Contains("true", csproj); - Assert.Contains("false", csproj); + Assert.Contains(@"..\Inbox\build\Inbox.targets", csproj); + Assert.Contains("win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64", csproj); + Assert.DoesNotContain("PrivateAssets=\"all\"", csproj.Substring(csproj.IndexOf(@"..\Inbox\Inbox.csproj", StringComparison.Ordinal))); + Assert.DoesNotContain("WhatsBox.$(RuntimeIdentifier)", csproj); + Assert.DoesNotContain("IncludeBuildOutput", csproj); + Assert.DoesNotContain("WriteWhatsBoxRuntimeJson", csproj); + Assert.DoesNotContain("PackWhatsBoxNativeBinary", csproj); + Assert.DoesNotContain("PackInboxReferenceOutput", csproj); Assert.DoesNotContain(" + net10.0 WhatsBox - WhatsBox.$(RuntimeIdentifier) WhatsBox WhatsBox WhatsApp Inbox Protocol host: PackageReference WhatsBox and publish for your RID to get the native whatsbox sidecar plus the managed Inbox client. true win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64 true - true - false - true - $(NoWarn);NU5128 - whatsbox.exe - whatsbox + whatsbox + whatsbox.exe + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)$(BaseIntermediateOutputPath)native\$(InboxNativeName)')) $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\WhatsBox.Native')) - $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)$(BaseIntermediateOutputPath)native\$(NativeWhatsBoxName)')) + BuildNativeWhatsBox + BuildWhatsBoxRidNative - - $(TargetsForTfmSpecificContentInPackage);PackWhatsBoxNativeBinary - <_WhatsBoxRidGoos Condition="$(RuntimeIdentifier.StartsWith('win-'))">windows @@ -34,10 +28,9 @@ <_WhatsBoxRidGoos Condition="$(RuntimeIdentifier.StartsWith('osx-'))">darwin <_WhatsBoxRidGoarch Condition="$(RuntimeIdentifier.EndsWith('-x64'))">amd64 <_WhatsBoxRidGoarch Condition="$(RuntimeIdentifier.EndsWith('-arm64'))">arm64 - <_WhatsBoxRidNativeName Condition="$(RuntimeIdentifier.StartsWith('win-'))">whatsbox.exe - <_WhatsBoxRidNativeName Condition="'$(_WhatsBoxRidNativeName)' == ''">whatsbox - <_WhatsBoxRidNativeDir>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)runtimes\$(RuntimeIdentifier)\native\')) - <_WhatsBoxRidNativeBinary>$(_WhatsBoxRidNativeDir)$(_WhatsBoxRidNativeName) + whatsbox + whatsbox.exe + $([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)runtimes\$(RuntimeIdentifier)\native\$(InboxNativeName)')) @@ -45,86 +38,31 @@ - + - - $(TargetsForTfmSpecificBuildOutput);PackInboxReferenceOutput - - - - - - %(Filename)%(Extension) - - - - - - - - - - - - - PreserveNewest - PreserveNewest - $(NativeWhatsBoxName) - false - false - - - - - - - <_WhatsBoxRuntimeJson>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)runtime.json')) - - - <_WhatsBoxRid Include="$(RuntimeIdentifiers)" /> - - - - - - - - - - + + + + Outputs="$(InboxNativeBinary)"> - - + - - - - - runtimes/$(RuntimeIdentifier)/native/ - - - + diff --git a/src/WhatsBox/runtime.json b/src/WhatsBox/runtime.json deleted file mode 100644 index 44ec497..0000000 --- a/src/WhatsBox/runtime.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "runtimes": { - } -} diff --git a/src/WhatsDemo.Tests/nuget.config b/src/WhatsDemo.Tests/nuget.config index d10713c..8cd84dc 100644 --- a/src/WhatsDemo.Tests/nuget.config +++ b/src/WhatsDemo.Tests/nuget.config @@ -21,6 +21,8 @@ + + diff --git a/src/WhatsDemo/nuget.config b/src/WhatsDemo/nuget.config index d10713c..8cd84dc 100644 --- a/src/WhatsDemo/nuget.config +++ b/src/WhatsDemo/nuget.config @@ -21,6 +21,8 @@ + +