From 09edec62a5dc299d5105473d2ac8913d7de7e61a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:20:29 +0000 Subject: [PATCH 1/7] Initial plan From b6457d5fdc4a131dc09a5bd5792d8dff5a04b51a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:29:58 +0000 Subject: [PATCH 2/7] Read the Windows pin from the pin, not from an example in a comment --- Directory.Build.props | 31 +++++++++------ .../RepositoryConsistencyTests.cs | 38 +++++++++++++++++++ 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 006cd49..934e257 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -22,7 +22,7 @@ makes the package invisible to `dotnet add package`. --> 2.34.1 - 4 + 5 $(OpenTokVersion).$(OpenTokBindingRevision) 2.34.1.4 diff --git a/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs b/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs index c1f4cd0..95ad7bd 100644 --- a/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs +++ b/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs @@ -122,16 +122,54 @@ public void The_solution_lists_exactly_the_packages_plus_the_test_projects() [InlineData("OpenTokVersion")] [InlineData("OpenTokIosPackageVersion")] [InlineData("OpenTokAndroidPackageVersion")] + [InlineData("OpenTokWinPackageVersion")] + [InlineData("OpenTokClientPackageVersion")] public void Version_properties_are_literal_dotted_version_numbers(string property) { // Literal, not an MSBuild expression: .github/workflows/release.yml reads these with sed and // tests/OpenTok.Net.PackageTests compares them as strings. Neither evaluates MSBuild, so a // "$(OpenTokVersion).1" here would reach the published release notes verbatim. + // + // The same pattern rules out a prerelease, which is the other way a pin goes wrong. Every + // pull request in the platform repositories publishes a -beta.., and + // pinning one is the obvious way to get this repository's Windows leg green while that + // repository's release is still in flight — but whatever is pinned when a tag is cut is what + // consumers of the umbrella resolve, and a released package that depends on something built + // from a branch is not a release. The platform repository publishes first; this one re-pins + // behind it. var value = ReadProperty(property); Assert.Matches(@"^\d+(\.\d+){1,3}$", value); } + [Theory] + [InlineData("OpenTokVersion")] + [InlineData("OpenTokBindingRevision")] + [InlineData("OpenTokIosPackageVersion")] + [InlineData("OpenTokAndroidPackageVersion")] + [InlineData("OpenTokWinPackageVersion")] + [InlineData("OpenTokClientPackageVersion")] + public void Version_properties_are_declared_exactly_once(string property) + { + // Everything that reads these pins outside MSBuild — build/pins.sh, build/check-upstream.sh, + // release.yml, pr.yml, ReadProperty below — matches the element textually and keeps the + // first hit. An XML comment is not a comment to any of them, so a second element written + // into the prose above the real pin *is* the pin as far as they are concerned, and the two + // disagree exactly where it is least visible: MSBuild keeps building against the last value + // in the file while every report about the file describes the first. + // + // That is what an example beta above OpenTokWinPackageVersion did — the daily upstream check + // reported the Windows package as pinned to a prerelease nuget.org had never carried, while + // the packages were built against the release underneath it. + var props = File.ReadAllText(Path.Combine(RepositoryRoot, "Directory.Build.props")); + + var occurrences = props.Split($"<{property}>").Length - 1; + + Assert.True( + occurrences == 1, + $"Directory.Build.props opens <{property}> {occurrences} times; it must appear once, comments included."); + } + [Fact] public void The_binding_revision_is_a_plain_integer() { From 3d97508a09b2eebe913f6255665ddc04b405adfb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:32:41 +0000 Subject: [PATCH 3/7] Cut 2.34.1.5: the release 2.34.1.4 never became --- README.md | 6 ++-- docs/release-notes/2.34.1.4.md | 6 ++++ docs/release-notes/2.34.1.5.md | 62 ++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 docs/release-notes/2.34.1.5.md diff --git a/README.md b/README.md index 9cd8cae..fc07ed3 100755 --- a/README.md +++ b/README.md @@ -183,8 +183,10 @@ Three suites, two of which run anywhere: - **`tests/OpenTok.Net.UnitTests`** checks the repository's own bookkeeping with nothing built — `build/packages.tsv` against the projects under `src/`, the solution against both, dependency - ordering, and the version pins. Including the invariant this repository exists for: **both pinned - platform packages wrapping the same native SDK generation.** + ordering, and the version pins: each declared exactly once in `Directory.Build.props`, comments + included, and each a released version rather than one of the platform repositories' betas. + Including the invariant this repository exists for: **both pinned platform packages wrapping the + same native SDK generation.** - **`tests/OpenTok.Net.PackageTests`** inspects the packed `.nupkg` files: an assembly for every target framework, the right platform binding depended on for each one, an exact-version link between the two packages, and the same same-SDK-generation check read back out of the shipped diff --git a/docs/release-notes/2.34.1.4.md b/docs/release-notes/2.34.1.4.md index 4a08f6e..de54a3e 100644 --- a/docs/release-notes/2.34.1.4.md +++ b/docs/release-notes/2.34.1.4.md @@ -1,5 +1,11 @@ # OpenTok.Net 2.34.1.4 +> **Never published.** This note was merged before `auto-release.yml` existed, and a note only tags +> the push that adds it — so no `v2.34.1.4` tag was ever cut and nuget.org has no such release. +> Everything below shipped in +> [2.34.1.5](https://github.com/sbokatuk/OpenTok.Net/blob/main/docs/release-notes/2.34.1.5.md) +> instead. Kept as written, because it is where the Windows head is documented. + Adds Windows as a third platform. No change to the iOS or Android heads, and no change to the platform pins beyond adding one — 2.34.1.3 already repointed Android. diff --git a/docs/release-notes/2.34.1.5.md b/docs/release-notes/2.34.1.5.md new file mode 100644 index 0000000..d7b2727 --- /dev/null +++ b/docs/release-notes/2.34.1.5.md @@ -0,0 +1,62 @@ +# OpenTok.Net 2.34.1.5 + +The release 2.34.1.4 was supposed to be. The façade's own source is identical to it — what changes +here is that it actually ships, and that the Windows pin is no longer readable as something it is +not. + +2.34.1.4 was written, reviewed and merged, and then never tagged: merging a release note is what +cuts a release in this repository, and `auto-release.yml` landed *after* +`docs/release-notes/2.34.1.4.md` had already gone in. A note only tags the push that adds it, so +nothing tagged that one, and nuget.org's newest release stayed 2.34.1.3 while Windows support sat +on `main` unpublished. This note adds itself, which is that mechanism working as intended. + +## Windows, published this time + +Exactly as +[2.34.1.4's note](https://github.com/sbokatuk/OpenTok.Net/blob/main/docs/release-notes/2.34.1.4.md) +describes it: `OpenTokSession`, `OpenTokPublisher` and `OpenTokSubscriber` run on Windows over +Vonage's `OpenTok.Client`, with the WinUI renderer supplied by +[`OpenTok.Net.Win`](https://github.com/sbokatuk/OpenTok.Net.Win), and both packages carry nine +target frameworks instead of six. Read that note for the two things Windows asks that the other +platforms do not — x64 only, and the first OpenTok object created on the UI thread — and for the +members that are documented no-ops there. + +## The pin is the pin, not an example of one + +`Directory.Build.props` explained how to point the Windows pin at an in-flight beta by spelling one +out, as a complete `OpenTokWinPackageVersion` element, in the comment above the pin. MSBuild does +not read comments at all, so the only assignment in the file was the real one: every package this +repository has built was built against the released `2.34.1.4`, and the pin itself was never wrong. + +Nothing else that reads this file works that way. `build/pins.sh`, `build/check-upstream.sh`, +`release.yml`, `pr.yml` and this repository's own consistency tests all match the element textually +and keep the *first* hit, and the first hit was the example. So the daily upstream check reported +`OpenTok.Net.Win` as pinned to `2.34.1.4-beta.7.3`, a prerelease nuget.org has never carried, and — +correctly, for what it believed it was looking at — that the pinned version no longer downloads. +Two findings about a pin that was fine, with the real one invisible behind them. + +The example is gone, and `RepositoryConsistencyTests` now keeps it gone with two checks: every +pinned version property must appear exactly once in `Directory.Build.props`, comments included, and +every one of them must be a plain release version. The second is the rule the first was hiding — a +released umbrella must not depend on a package built from a branch, so the platform repository +publishes first and this one re-pins behind it, rather than pinning a beta to turn a red leg green. + +## Pins + +Unchanged, and all four confirmed against nuget.org on 2026-07-30 — newest release published, and +the artifact itself downloads rather than merely being indexed: + +| Property | Package | Version | +| --- | --- | --- | +| `OpenTokIosPackageVersion` | `OpenTok.Net.iOS` | [2.34.1.2](https://www.nuget.org/packages/OpenTok.Net.iOS/2.34.1.2) | +| `OpenTokAndroidPackageVersion` | `OpenTok.Net.Android` | [2.34.1.4](https://www.nuget.org/packages/OpenTok.Net.Android/2.34.1.4) | +| `OpenTokWinPackageVersion` | `OpenTok.Net.Win` | [2.34.1.4](https://www.nuget.org/packages/OpenTok.Net.Win/2.34.1.4) | +| `OpenTokClientPackageVersion` | `OpenTok.Client` | [2.34.1](https://www.nuget.org/packages/OpenTok.Client/2.34.1) | + +Nothing is waiting on a platform release this time — all four are live, which is the ordering +2.34.1.4's note asks for and 2.34.1.2 is what happens without. + +## If you are on 2.34.1.3 + +Upgrade. Nothing to change in your code: no API and no behaviour moved on iOS or Android. What you +gain is a Windows head that was not there before. From 585e5d3f5f6e588ad4f3b1f7cd4a95745be2dcab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:33:53 +0000 Subject: [PATCH 4/7] Point the drift report's re-pin hint at what this repository actually does --- .github/workflows/upstream-drift.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/upstream-drift.yml b/.github/workflows/upstream-drift.yml index 5dab6c7..bcca78a 100644 --- a/.github/workflows/upstream-drift.yml +++ b/.github/workflows/upstream-drift.yml @@ -41,8 +41,10 @@ jobs: env: GH_TOKEN: ${{ github.token }} # Named here rather than in the script so each repository says its own thing without the - # shared checker growing repository-specific prose. - REPIN_HINT: 'Pins live in `Directory.Build.props`; `./build/BumpNativeVersion.sh ` does the mechanical part.' + # shared checker growing repository-specific prose. There is no BumpNativeVersion.sh in this + # one — it binds nothing native, so a pin is a hand edit, and the two ways that goes wrong are + # worth naming in every report rather than once in a file nobody rereads. + REPIN_HINT: 'Pins live in `Directory.Build.props` and are edited by hand; this repository binds nothing native, so there is no bump script. Change the property value itself — never a prerelease, and never as an example element inside a comment, since everything that reads these pins outside MSBuild keeps the first textual match.' steps: - uses: actions/checkout@v4 From be46471a4828b7e0b00fd7d98a4c17ec560c005a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:36:35 +0000 Subject: [PATCH 5/7] Say precisely what MSBuild does with the comment --- tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs b/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs index 95ad7bd..6de3b5e 100644 --- a/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs +++ b/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs @@ -155,8 +155,8 @@ public void Version_properties_are_declared_exactly_once(string property) // release.yml, pr.yml, ReadProperty below — matches the element textually and keeps the // first hit. An XML comment is not a comment to any of them, so a second element written // into the prose above the real pin *is* the pin as far as they are concerned, and the two - // disagree exactly where it is least visible: MSBuild keeps building against the last value - // in the file while every report about the file describes the first. + // disagree exactly where it is least visible: MSBuild never sees the comment, so the build + // stays right while every report about the build is wrong. // // That is what an example beta above OpenTokWinPackageVersion did — the daily upstream check // reported the Windows package as pinned to a prerelease nuget.org had never carried, while From c95fba67efa03bf2012a2599b38c80eb737762b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:37:50 +0000 Subject: [PATCH 6/7] Fix a dropped verb in the Windows pin comment --- Directory.Build.props | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 934e257..518e7c7 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -101,9 +101,9 @@ consistency tests — matches the element textually and keeps the first hit, so a second one written into a comment above the real pin *is* the pin as far as all of them are concerned. That is not hypothetical: an example beta spelled out here in full had the daily upstream check - reporting this package as pinned to a prerelease nuget.org had never carried, while every - package built against the release below it. RepositoryConsistencyTests now asserts both halves - — one occurrence per pinned property, and no prerelease in any of them. + reporting this package as pinned to a prerelease nuget.org had never carried, while the + packages themselves were built against the release below it. RepositoryConsistencyTests now + asserts both halves — one occurrence per pinned property, and no prerelease in any of them. --> 2.34.1.4 From df6c618865e1699c6ef40b708f4b331b2576b380 Mon Sep 17 00:00:00 2001 From: Sergei Bokatuk Date: Thu, 30 Jul 2026 12:55:34 +0300 Subject: [PATCH 7/7] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs b/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs index 6de3b5e..a380746 100644 --- a/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs +++ b/tests/OpenTok.Net.UnitTests/RepositoryConsistencyTests.cs @@ -126,8 +126,8 @@ public void The_solution_lists_exactly_the_packages_plus_the_test_projects() [InlineData("OpenTokClientPackageVersion")] public void Version_properties_are_literal_dotted_version_numbers(string property) { - // Literal, not an MSBuild expression: .github/workflows/release.yml reads these with sed and - // tests/OpenTok.Net.PackageTests compares them as strings. Neither evaluates MSBuild, so a + // Literal, not an MSBuild expression: the GitHub workflows (e.g. .github/workflows/release.yml) + // and ReadProperty below read these with plain text matching. Neither evaluates MSBuild, so a // "$(OpenTokVersion).1" here would reach the published release notes verbatim. // // The same pattern rules out a prerelease, which is the other way a pin goes wrong. Every